From 64f76268b761f81d9e97625634eb19be335572e6 Mon Sep 17 00:00:00 2001 From: ipkpjersi Date: Wed, 27 May 2026 20:25:54 -0400 Subject: [PATCH] Command improvements 1. `::tele ` (tele case) - accepts the SpellTeleport enum cities (varrock, lumbridge, falador, camelot, ardougne, watchtower, trollheim, ape_atoll) alongside the existing `::tele x y [z]`. Multi-word names work via space or underscore (e.g. `::tele ape atoll`). 2. `::item [amount]` (item case) - if the first arg isn't numeric, resolves the name to an id (exact match preferred, else first prefix match), with an optional trailing amount. Numeric `::item 995 1000` is unchanged. 3. `::npc ` (npc case, developer group) - resolves an NPC name to an id, then spawns using the existing stat lookup. Numeric `::npc ` unchanged. 4. `::itemsearch ` (player group, aliases searchitem/finditem) and `::npcsearch ` (developer group, aliases searchnpc/findnpc) - list matching "name - ID: n", capped at 25 results with a total count. 5. `::spellbook [modern|ancient|swap]` - modern/normal and ancient/ancients set a specific book; swap/toggle or bare `::spellbook` toggles. Same sidebar/autocast behavior as before, plus an "already on X" message when no change is needed. --- .../com/rs2/net/packets/impl/Commands.java | 236 +++++++++++++++++- 1 file changed, 224 insertions(+), 12 deletions(-) diff --git a/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java b/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java index 6b7617936..88bcd879c 100644 --- a/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java +++ b/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java @@ -8,8 +8,10 @@ import com.rs2.Constants; import com.rs2.GameEngine; import com.rs2.game.bots.BotHandler; +import com.rs2.game.content.combat.magic.SpellTeleport; import com.rs2.game.npcs.NPCDefinition; import com.rs2.game.npcs.NpcHandler; +import org.apollo.cache.def.ItemDefinition; import com.rs2.game.players.*; import com.rs2.game.players.antimacro.AntiSpam; import com.rs2.integrations.discord.JavaCord; @@ -423,6 +425,34 @@ public void run() { case "tele": if (player.connectedFrom.equals("127.0.0.1")) { try { + if (arguments.length < 1) { + player.getPacketSender().sendMessage("Must specify coordinates or a city: ::tele 3222 3218 0 or ::tele varrock"); + return; + } + boolean numericTele; + try { + Integer.parseInt(arguments[0]); + numericTele = true; + } catch (NumberFormatException notNumber) { + numericTele = false; + } + if (!numericTele) { + String cityName = String.join("_", arguments).toUpperCase(); + SpellTeleport city = null; + for (SpellTeleport t : SpellTeleport.values()) { + if (t.getType().equals("modern") && t.name().equals(cityName)) { + city = t; + break; + } + } + if (city == null) { + player.getPacketSender().sendMessage("Unknown city. Valid: varrock, lumbridge, falador, camelot, ardougne, watchtower, trollheim, ape_atoll"); + return; + } + player.getPlayerAssistant().movePlayer(city.getDestX(), city.getDestY(), city.getDestZ()); + player.getPacketSender().sendMessage("Teleported to " + city.name().toLowerCase().replace('_', ' ') + "."); + return; + } if (arguments.length < 2) { player.getPacketSender().sendMessage("Must specify x, y and optionally z coordinates: ::tele 3222 3218 0"); return; @@ -959,27 +989,75 @@ public static void adminCommands(Player player, String playerCommand, String[] a if (player.inWild()) { return; } - if (player.playerMagicBook == 0) { - player.playerMagicBook = 1; - player.getPacketSender().setSidebarInterface(6, 12855); - player.getPacketSender().sendMessage("An ancient wisdomin fills your mind."); - player.getPlayerAssistant().resetAutocast(); - } else if (player.playerMagicBook == 1) { + String spellbookTarget = arguments.length > 0 ? arguments[0].toLowerCase() : "swap"; + boolean toModern; + switch (spellbookTarget) { + case "modern": + case "normal": + toModern = true; + break; + case "ancient": + case "ancients": + toModern = false; + break; + case "swap": + case "toggle": + toModern = player.playerMagicBook == 1; + break; + default: + player.getPacketSender().sendMessage("Usage: ::spellbook [modern|ancient|swap]"); + return; + } + if (toModern) { + if (player.playerMagicBook == 0) { + player.getPacketSender().sendMessage("You are already on the modern spellbook."); + return; + } player.getPacketSender().setSidebarInterface(6, 1151); // modern player.playerMagicBook = 0; player.getPacketSender().sendMessage("You feel a drain on your memory."); player.autocastId = -1; player.getPlayerAssistant().resetAutocast(); + } else { + if (player.playerMagicBook == 1) { + player.getPacketSender().sendMessage("You are already on the ancient spellbook."); + return; + } + player.playerMagicBook = 1; + player.getPacketSender().setSidebarInterface(6, 12855); + player.getPacketSender().sendMessage("An ancient wisdomin fills your mind."); + player.getPlayerAssistant().resetAutocast(); } break; case "item": try { if (arguments.length == 0) { - player.getPacketSender().sendMessage("Must specify an item id: ::item 995 1000"); + player.getPacketSender().sendMessage("Must specify an item id or name: ::item 995 1000 or ::item coins 1000"); return; } - int newItemID = Integer.parseInt(arguments[0]); - int newItemAmount = arguments.length >= 2 ? Integer.parseInt(arguments[1]) : 1; + int newItemID; + int newItemAmount; + try { + newItemID = Integer.parseInt(arguments[0]); + newItemAmount = arguments.length >= 2 ? Integer.parseInt(arguments[1]) : 1; + } catch (NumberFormatException notNumber) { + int amount = 1; + String[] nameTokens = arguments; + if (arguments.length >= 2) { + try { + amount = Integer.parseInt(arguments[arguments.length - 1]); + nameTokens = Arrays.copyOfRange(arguments, 0, arguments.length - 1); + } catch (NumberFormatException ignore) { + } + } + String itemName = String.join(" ", nameTokens); + newItemID = findItemIdByName(itemName); + if (newItemID == -1) { + player.getPacketSender().sendMessage("No item found matching: " + itemName); + return; + } + newItemAmount = amount; + } if (newItemID <= 10000 && newItemID >= 0) { player.getItemAssistant().addItem(newItemID, newItemAmount); if (player.isBusy()) { @@ -992,6 +1070,42 @@ public static void adminCommands(Player player, String playerCommand, String[] a } catch (Exception e) { } break; + case "itemsearch": + case "searchitem": + case "finditem": + if (arguments.length == 0) { + player.getPacketSender().sendMessage("Specify an item name to search: ::itemsearch dragon scimitar"); + return; + } + { + String query = String.join(" ", arguments).toLowerCase(); + int found = 0; + int limit = 25; + for (int id = 0; id < ItemDefinition.count(); id++) { + ItemDefinition def = ItemDefinition.lookup(id); + if (def == null) { + continue; + } + String defName = def.getName(); + if (defName == null || defName.isEmpty() || defName.equalsIgnoreCase("null")) { + continue; + } + if (defName.toLowerCase().contains(query)) { + found++; + if (found <= limit) { + player.getPacketSender().sendMessage(defName + " - ID: " + id); + } + } + } + if (found == 0) { + player.getPacketSender().sendMessage("No items found matching: " + query); + } else if (found > limit) { + player.getPacketSender().sendMessage("Showing first " + limit + " of " + found + " matches. Refine your search."); + } else { + player.getPacketSender().sendMessage(found + " item(s) found."); + } + } + break; case "master": for (int i = 0; i < 25; i++) { player.playerLevel[i] = 99; @@ -1128,11 +1242,21 @@ public static void developerCommands(Player player, String playerCommand, String case "npc": try { if (arguments.length == 0) { - player.getPacketSender().sendMessage("You must specify an ID: ::npc 1000"); + player.getPacketSender().sendMessage("You must specify an ID or name: ::npc 1000 or ::npc goblin"); return; } - int newNPC = Integer.parseInt(arguments[0]), - maxHit = NpcHandler.getNpcListCombat(newNPC) / 10, + int newNPC; + try { + newNPC = Integer.parseInt(arguments[0]); + } catch (NumberFormatException notNumber) { + String npcName = String.join(" ", arguments); + newNPC = findNpcIdByName(npcName); + if (newNPC == -1) { + player.getPacketSender().sendMessage("No NPC found matching: " + npcName); + return; + } + } + int maxHit = NpcHandler.getNpcListCombat(newNPC) / 10, attack = NpcHandler.getNpcListCombat(newNPC), defence = NpcHandler.getNpcListCombat(newNPC); boolean attackPlayer = NpcHandler.getNpcListCombat(newNPC) > 0; @@ -1146,6 +1270,46 @@ public static void developerCommands(Player player, String playerCommand, String } catch (Exception e) { } break; + case "npcsearch": + case "searchnpc": + case "findnpc": + if (arguments.length == 0) { + player.getPacketSender().sendMessage("Specify an NPC name to search: ::npcsearch goblin"); + return; + } + { + String query = String.join(" ", arguments).toLowerCase(); + int found = 0; + int limit = 25; + for (int id = 0; id <= 3789; id++) { + try { + NPCDefinition def = NPCDefinition.forId(id); + if (def == null) { + continue; + } + String defName = def.getName(); + if (defName == null || defName.isEmpty() || defName.equalsIgnoreCase("null")) { + continue; + } + if (defName.toLowerCase().contains(query)) { + found++; + if (found <= limit) { + player.getPacketSender().sendMessage(defName + " - ID: " + id); + } + } + } catch (Exception e) { + break; + } + } + if (found == 0) { + player.getPacketSender().sendMessage("No NPCs found matching: " + query); + } else if (found > limit) { + player.getPacketSender().sendMessage("Showing first " + limit + " of " + found + " matches. Refine your search."); + } else { + player.getPacketSender().sendMessage(found + " NPC(s) found."); + } + } + break; case "cantattack": player.npcCanAttack = !player.npcCanAttack; player.getPacketSender().sendMessage("Npcs " + (player.npcCanAttack ? "can" : "can no longer") + " attack you."); @@ -1195,4 +1359,52 @@ public static void developerCommands(Player player, String playerCommand, String break; } } + + private static int findItemIdByName(String name) { + int exact = -1, partial = -1; + for (int id = 0; id < ItemDefinition.count(); id++) { + ItemDefinition def = ItemDefinition.lookup(id); + if (def == null) { + continue; + } + String defName = def.getName(); + if (defName == null || defName.isEmpty() || defName.equalsIgnoreCase("null")) { + continue; + } + if (defName.equalsIgnoreCase(name)) { + exact = id; + break; + } + if (partial == -1 && defName.toLowerCase().startsWith(name.toLowerCase())) { + partial = id; + } + } + return exact != -1 ? exact : partial; + } + + private static int findNpcIdByName(String name) { + int exact = -1, partial = -1; + for (int id = 0; id <= 3789; id++) { + try { + NPCDefinition def = NPCDefinition.forId(id); + if (def == null) { + continue; + } + String defName = def.getName(); + if (defName == null || defName.isEmpty() || defName.equalsIgnoreCase("null")) { + continue; + } + if (defName.equalsIgnoreCase(name)) { + exact = id; + break; + } + if (partial == -1 && defName.toLowerCase().startsWith(name.toLowerCase())) { + partial = id; + } + } catch (Exception e) { + break; + } + } + return exact != -1 ? exact : partial; + } }