diff --git a/runelite-api/src/main/java/net/runelite/api/events/CommandExecuted.java b/runelite-api/src/main/java/net/runelite/api/events/CommandExecuted.java new file mode 100644 index 0000000000..6580899208 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/CommandExecuted.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api.events; + +import lombok.Value; + +@Value +public class CommandExecuted +{ + private String command; + private String[] arguments; +} diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index afd072ea69..73be75e72f 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -41,6 +41,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.client.account.SessionManager; import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.CommandManager; import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.game.ClanManager; @@ -81,6 +82,9 @@ public class RuneLite @Inject private ChatMessageManager chatMessageManager; + @Inject + private CommandManager commandManager; + @Inject private OverlayRenderer overlayRenderer; @@ -163,6 +167,7 @@ public class RuneLite eventBus.register(overlayRenderer); eventBus.register(menuManager); eventBus.register(chatMessageManager); + eventBus.register(commandManager); eventBus.register(pluginManager); eventBus.register(itemManager); eventBus.register(clanManager); diff --git a/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java b/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java new file mode 100644 index 0000000000..a0f0592226 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Kamiel + * Copyright (c) 2018, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.chat; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; +import java.util.Arrays; +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.VarClientStr; +import net.runelite.api.Varcs; +import net.runelite.api.events.CommandExecuted; +import net.runelite.api.events.ScriptCallbackEvent; + +@Slf4j +@Singleton +public class CommandManager +{ + private static final String CALLBACK_NAME = "runeliteCommand"; + private final Provider clientProvider; + private final EventBus eventBus; + + @Inject + public CommandManager(Provider clientProvider, EventBus eventBus) + { + this.clientProvider = clientProvider; + this.eventBus = eventBus; + } + + @Subscribe + private void scriptEvent(ScriptCallbackEvent event) + { + if (!CALLBACK_NAME.equals(event.getEventName())) + { + return; + } + + Client client = clientProvider.get(); + Varcs varcs = client.getVarcs(); + String typedText = varcs.getStrVar(VarClientStr.CHATBOX_TYPED_TEXT).substring(2); // strip :: + + log.debug("Command: {}", typedText); + + String[] split = typedText.split(" "); + + String command = split[0]; + String[] args = Arrays.copyOfRange(split, 1, split.length); + + CommandExecuted commandExecuted = new CommandExecuted(command, args); + eventBus.post(commandExecuted); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index 1ba336967e..96cd2cbd35 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.devtools; +import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.awt.Font; import java.awt.image.BufferedImage; @@ -31,6 +32,8 @@ import java.util.Arrays; import java.util.Collection; import javax.imageio.ImageIO; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.events.CommandExecuted; import net.runelite.api.widgets.Widget; import net.runelite.client.config.ConfigManager; import net.runelite.client.plugins.Plugin; @@ -44,6 +47,7 @@ import net.runelite.client.ui.overlay.Overlay; name = "Developer Tools", developerPlugin = true ) +@Slf4j public class DevToolsPlugin extends Plugin { @Inject @@ -118,6 +122,13 @@ public class DevToolsPlugin extends Plugin return Arrays.asList(overlay, locationOverlay, borderOverlay); } + @Subscribe + public void onCommand(CommandExecuted commandExecuted) { + if (commandExecuted.getCommand().equalsIgnoreCase("test")) { + log.debug("Test!"); + } + } + Font getFont() { return font; diff --git a/runelite-scripts/scripts/CommandScript.hash b/runelite-scripts/scripts/CommandScript.hash new file mode 100644 index 0000000000..6fc023efb2 --- /dev/null +++ b/runelite-scripts/scripts/CommandScript.hash @@ -0,0 +1 @@ +CDE382CF5E33BD256AE1ED092D45E816D5F8C04130C23D73FA9DE38D3333D778 \ No newline at end of file diff --git a/runelite-scripts/scripts/CommandScript.rs2asm b/runelite-scripts/scripts/CommandScript.rs2asm new file mode 100644 index 0000000000..d5afbddc02 --- /dev/null +++ b/runelite-scripts/scripts/CommandScript.rs2asm @@ -0,0 +1,295 @@ +.id 73 +.int_stack_count 2 +.string_stack_count 0 +.int_var_count 4 +.string_var_count 0 + load_int 10616876 + widget_get_hidden_widget + load_int 1 + if_icmpeq LABEL9 + load_int 10616877 + widget_get_hidden_widget + load_int 1 + if_icmpeq LABEL9 + jump LABEL10 +LABEL9: + return +LABEL10: + get_varc 203 + load_int 0 + if_icmpeq LABEL22 + get_varc 203 + load_int -1 + if_icmpeq LABEL22 + load_int -1 + load_int 162 + invoke 1701 + load_int 0 + if_icmpeq LABEL22 + jump LABEL23 +LABEL22: + return +LABEL23: + get_varc_string 1 + string_length + istore 2 + load_int 0 + istore 3 + get_rights + load_int 0 + if_icmpgt LABEL32 + jump LABEL34 +LABEL32: + load_int 1 + istore 3 +LABEL34: + iload 3 + load_int 1 + if_icmpeq LABEL38 + jump LABEL49 +LABEL38: + load_string "`" + iload 1 + string_indexof + load_int -1 + if_icmpne LABEL44 + jump LABEL49 +LABEL44: + iload 2 + load_int 0 + if_icmpeq LABEL48 + jump LABEL49 +LABEL48: + return +LABEL49: + iload 0 + load_int 84 + if_icmpeq LABEL53 + jump LABEL159 +LABEL53: + invoke 1984 + iload 2 + load_int 0 + if_icmpgt LABEL58 + jump LABEL158 +LABEL58: + get_varc_string 1 + load_string "/" + load_int 0 + string_indexof_from + load_int 0 + if_icmpeq LABEL65 + jump LABEL92 +LABEL65: + get_clanchatcount + load_int 0 + if_icmpgt LABEL69 + jump LABEL88 +LABEL69: + iload 2 + load_int 1 + if_icmple LABEL73 + jump LABEL74 +LABEL73: + return +LABEL74: + get_varbit 4394 + load_int 1 + if_icmpeq LABEL78 + jump LABEL84 +LABEL78: + get_clanchatcount + load_int 0 + if_icmpgt LABEL82 + jump LABEL83 +LABEL82: + part_clanchat +LABEL83: + jump LABEL87 +LABEL84: + get_varc_string 1 + load_int 2 + invoke 96 +LABEL87: + jump LABEL91 +LABEL88: + get_varc_string 1 + load_int 0 + invoke 96 +LABEL91: + jump LABEL154 +LABEL92: + get_varc_string 1 + load_string "::" + load_int 0 + string_indexof_from + load_int 0 + if_icmpeq LABEL99 + jump LABEL151 +LABEL99: + iload 2 + load_int 2 + if_icmpgt LABEL103 + jump LABEL147 +LABEL103: + get_varc_string 1 + load_string "::toggleroof" + load_int 0 + string_indexof_from + load_int 0 + if_icmpeq LABEL110 + jump LABEL124 +LABEL110: + get_hideroofs + load_int 1 + if_icmpeq LABEL114 + jump LABEL119 +LABEL114: + load_int 0 + set_hideroofs + load_string "Roofs will only be removed selectively." + send_game_message + jump LABEL123 +LABEL119: + load_int 1 + set_hideroofs + load_string "Roofs are now all hidden." + send_game_message +LABEL123: + jump LABEL146 +LABEL124: + get_varc_string 1 + load_string "::bank" + load_int 0 + string_indexof_from + load_int 0 + if_icmpeq LABEL131 + load_string "runeliteCommand" ; load callback name + runelite_callback ; invoke callback + jump LABEL135 +LABEL131: + load_string "Hey, everyone, I just tried to do something very silly!" + load_int 0 + invoke 96 + jump LABEL146 +LABEL135: + get_varc_string 1 + invoke 224 + put_varc_string 1 + get_varc_string 1 + string_length + istore 2 + get_varc_string 1 + load_int 2 + iload 2 + string_substring + run_command +LABEL146: + jump LABEL150 +LABEL147: + get_varc_string 1 + load_int 0 + invoke 96 +LABEL150: + jump LABEL154 +LABEL151: + get_varc_string 1 + load_int 0 + invoke 96 +LABEL154: + get_varc_string 1 + invoke 77 + load_string "" + put_varc_string 1 +LABEL158: + jump LABEL227 +LABEL159: + iload 0 + load_int 104 + if_icmpeq LABEL163 + jump LABEL169 +LABEL163: + iload 3 + load_int 1 + if_icmpeq LABEL167 + jump LABEL168 +LABEL167: + invoke 75 +LABEL168: + jump LABEL227 +LABEL169: + iload 0 + load_int 105 + if_icmpeq LABEL173 + jump LABEL179 +LABEL173: + iload 3 + load_int 1 + if_icmpeq LABEL177 + jump LABEL178 +LABEL177: + invoke 76 +LABEL178: + jump LABEL227 +LABEL179: + iload 0 + load_int 80 + if_icmpeq LABEL183 + jump LABEL221 +LABEL183: + get_varc_string + string_length + load_int 0 + if_icmpgt LABEL188 + jump LABEL208 +LABEL188: + get_varc_string + is_friend + load_int 1 + if_icmpeq LABEL193 + jump LABEL196 +LABEL193: + get_varc_string + invoke 107 + return +LABEL196: + get_varc 60 + get_gamecycle + if_icmpgt LABEL200 + jump LABEL201 +LABEL200: + return +LABEL201: + get_gamecycle + load_int 50 + iadd + put_varc 60 + load_string "That player was not found on your Friends list." + send_game_message + return +LABEL208: + get_varc 60 + get_gamecycle + if_icmpgt LABEL212 + jump LABEL213 +LABEL212: + return +LABEL213: + get_gamecycle + load_int 50 + iadd + put_varc 60 + load_string "You haven't received any messages to which you can reply." + send_game_message + return + jump LABEL227 +LABEL221: + get_varc_string 1 + load_int 0 + iload 0 + iload 1 + invoke 74 + put_varc_string 1 +LABEL227: + invoke 223 + return