diff --git a/build.gradle.kts b/build.gradle.kts index e0f2a98d5b..d883b23595 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,13 +29,13 @@ import org.ajoberstar.grgit.Grgit buildscript { repositories { gradlePluginPortal() - mavenLocal() + maven(url = "https://repo.openosrs.com/repository/maven/") maven(url = "https://raw.githubusercontent.com/open-osrs/hosting/master") } dependencies { classpath("org.ajoberstar.grgit:grgit-core:4.0.2") classpath("com.github.ben-manes:gradle-versions-plugin:0.28.0") - classpath("com.openosrs:injector-plugin:1.1.3") + classpath("com.openosrs:injector-plugin:1.1.4") } } diff --git a/runelite-api/src/main/java/net/runelite/api/events/ScriptPreFired.java b/runelite-api/src/main/java/net/runelite/api/events/ScriptPreFired.java index a338145e4f..55c58ac4a3 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/ScriptPreFired.java +++ b/runelite-api/src/main/java/net/runelite/api/events/ScriptPreFired.java @@ -24,22 +24,22 @@ */ package net.runelite.api.events; -import lombok.Data; +import lombok.Value; import net.runelite.api.ScriptEvent; /** * An event that is fired before the designated script is ran */ -@Data +@Value public class ScriptPreFired implements Event { /** * The script id of the invoked script */ - private final int scriptId; + int scriptId; /** * The input of the script invoke, this will be null unless it is the root script */ - private ScriptEvent scriptEvent; + ScriptEvent scriptEvent; } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java index 20b713e16b..08b559a8c8 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java @@ -25,14 +25,9 @@ */ package net.runelite.mixins; -import java.util.ArrayList; -import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.runelite.api.Client; -import static net.runelite.api.Opcodes.INVOKE; -import static net.runelite.api.Opcodes.RETURN; -import static net.runelite.api.Opcodes.RUNELITE_EXECUTE; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptPostFired; import net.runelite.api.events.ScriptPreFired; @@ -45,6 +40,7 @@ import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSScript; import net.runelite.rs.api.RSScriptEvent; +import static net.runelite.api.Opcodes.*; @Mixin(RSClient.class) public abstract class ScriptVMMixin implements RSClient @@ -52,7 +48,6 @@ public abstract class ScriptVMMixin implements RSClient @Shadow("client") private static Client client; - // This field is set by the ScriptVM raw injector @Inject private static RSScript currentScript; @@ -60,81 +55,70 @@ public abstract class ScriptVMMixin implements RSClient @Inject private static int currentScriptPC; + // Call is injected by the raw injector @Inject - private static ScriptPostFired deferredEvent = null; - - @Inject - private static Stack scriptIds = new Stack<>(); + static void setCurrentScript(RSScript script) + { + currentScript = script; + } // Call is injected into runScript by the ScriptVM raw injector @Inject static boolean vmExecuteOpcode(int opcode) { - if (deferredEvent != null) + switch (opcode) { - client.getCallbacks().post(ScriptPostFired.class, deferredEvent); - deferredEvent = null; - } - if (opcode == RUNELITE_EXECUTE) - { - assert currentScript.getInstructions()[currentScriptPC] == RUNELITE_EXECUTE; - - int stringStackSize = client.getStringStackSize(); - String stringOp = client.getStringStack()[--stringStackSize]; - client.setStringStackSize(stringStackSize); - - if ("debug".equals(stringOp)) - { - int intStackSize = client.getIntStackSize(); - - String fmt = client.getStringStack()[--stringStackSize]; - StringBuffer out = new StringBuffer(); - Matcher m = Pattern.compile("%(.)").matcher(fmt); - for (; m.find(); ) - { - m.appendReplacement(out, ""); - switch (m.group(1).charAt(0)) - { - case 'i': - case 'd': - out.append(client.getIntStack()[--intStackSize]); - break; - case 's': - out.append(client.getStringStack()[--stringStackSize]); - break; - default: - out.append(m.group(0)).append("=unknown"); - } - } - m.appendTail(out); - - client.getLogger().debug(out.toString()); + case RUNELITE_EXECUTE: + assert currentScript.getInstructions()[currentScriptPC] == RUNELITE_EXECUTE; + int stringStackSize = client.getStringStackSize(); + String stringOp = client.getStringStack()[--stringStackSize]; client.setStringStackSize(stringStackSize); - client.setIntStackSize(intStackSize); - return true; - } - ScriptCallbackEvent event = new ScriptCallbackEvent(); - event.setScript(currentScript); - event.setEventName(stringOp); - client.getCallbacks().post(ScriptCallbackEvent.class, event); - return true; - } - else if (opcode == INVOKE) - { - int id = currentScript.getIntOperands()[currentScriptPC]; - scriptIds.push(id); - ScriptPreFired event = new ScriptPreFired(id); - event.setScriptEvent(null); - client.getCallbacks().post(ScriptPreFired.class, event); - } - else if (opcode == RETURN) - { - if (scriptIds.size() > 1) // let the runScript method handle the final script - { - deferredEvent = new ScriptPostFired(scriptIds.pop()); // fire the event when we've left the script - } + if ("debug".equals(stringOp)) + { + int intStackSize = client.getIntStackSize(); + + String fmt = client.getStringStack()[--stringStackSize]; + StringBuffer out = new StringBuffer(); + Matcher m = Pattern.compile("%(.)").matcher(fmt); + while (m.find()) + { + m.appendReplacement(out, ""); + switch (m.group(1).charAt(0)) + { + case 'i': + case 'd': + out.append(client.getIntStack()[--intStackSize]); + break; + case 's': + out.append(client.getStringStack()[--stringStackSize]); + break; + default: + out.append(m.group(0)).append("=unknown"); + } + } + m.appendTail(out); + + client.getLogger().debug(out.toString()); + + client.setStringStackSize(stringStackSize); + client.setIntStackSize(intStackSize); + return true; + } + + ScriptCallbackEvent event = new ScriptCallbackEvent(); + event.setScript(currentScript); + event.setEventName(stringOp); + client.getCallbacks().post(ScriptCallbackEvent.class, event); + return true; + case INVOKE: + int scriptId = currentScript.getIntOperands()[currentScriptPC]; + client.getCallbacks().post(ScriptPreFired.class, new ScriptPreFired(scriptId, null)); + return false; + case RETURN: + client.getCallbacks().post(ScriptPostFired.class, new ScriptPostFired((int) currentScript.getHash())); + return false; } return false; } @@ -149,20 +133,14 @@ public abstract class ScriptVMMixin implements RSClient static void rl$runScript(RSScriptEvent event, int maxExecutionTime) { Object[] arguments = event.getArguments(); - if (arguments != null && arguments.length > 0 && arguments[0] instanceof JavaScriptCallback) + assert arguments != null && arguments.length > 0; + if (arguments[0] instanceof JavaScriptCallback) { try { - ScriptPreFired preFired = new ScriptPreFired(-1); - preFired.setScriptEvent(event); - client.getCallbacks().post(ScriptPreFired.class, preFired); - ((JavaScriptCallback) arguments[0]).run(event); - - ScriptPostFired postFired = new ScriptPostFired(-1); - client.getCallbacks().post(ScriptPostFired.class, postFired); } - catch (Exception e) // wont catch assertions + catch (Exception e) { client.getLogger().error("Error in JavaScriptCallback", e); } @@ -171,34 +149,13 @@ public abstract class ScriptVMMixin implements RSClient { try { - try - { - scriptIds.push((Integer) event.getArguments()[0]); // this is safe because it will always be the script id - - ScriptPreFired preFired = new ScriptPreFired(scriptIds.peek()); // peek doesn't remove the top item - preFired.setScriptEvent(event); - client.getCallbacks().post(ScriptPreFired.class, preFired); - } - catch (ClassCastException ignored) - { - } - + final ScriptPreFired pre = new ScriptPreFired((int) arguments[0], event); + client.getCallbacks().post(ScriptPreFired.class, pre); rs$runScript(event, maxExecutionTime); - - if (!scriptIds.empty()) - { - ScriptPostFired postFired = new ScriptPostFired(scriptIds.pop()); // hopefully the stack should be dry at this point - assert scriptIds.empty() : "Script ID stack should be empty! Contains: " + getAllScriptIds(); - client.getCallbacks().post(ScriptPostFired.class, postFired); - } } finally { currentScript = null; - while (!scriptIds.empty()) - { - scriptIds.pop(); // make sure the stack is empty, something disastrous happened - } } } } @@ -214,25 +171,4 @@ public abstract class ScriptVMMixin implements RSClient se.setArguments(args); runScript(se, 5000000); } - - @Inject - private static String getAllScriptIds() - { - ArrayList ids = new ArrayList<>(scriptIds); - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (Object item : ids) - { - if (first) - { - first = false; - } - else - { - sb.append(", "); - } - sb.append(item); - } - return sb.toString(); - } } \ No newline at end of file