From a42c845ad3c7cd64b1c738134b3dd874b83716d6 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Thu, 16 Dec 2021 09:45:44 +0100 Subject: [PATCH] project: Implement the new menu entry handling --- .../java/com/openosrs/injector/Injector.java | 3 + .../injectors/raw/CopyRuneLiteClasses.java | 3 +- .../injectors/raw/RuneliteMenuEntry.java | 99 ++++++ .../main/java/net/runelite/api/Client.java | 18 -- .../main/java/net/runelite/api/MenuEntry.java | 234 ++------------ .../runelite/client/menus/MenuManager.java | 4 +- .../plugins/banktags/BankTagsPlugin.java | 4 +- .../plugins/banktags/tabs/TabInterface.java | 4 +- .../chathistory/ChatHistoryPlugin.java | 8 +- .../plugins/friendlist/FriendListPlugin.java | 4 +- .../friendnotes/FriendNotesPlugin.java | 4 +- .../groundmarkers/GroundMarkerPlugin.java | 8 +- .../client/plugins/hiscore/HiscorePlugin.java | 4 +- .../inventorytags/InventoryTagsPlugin.java | 4 +- .../MenuEntrySwapperPlugin.java | 4 +- .../npchighlight/NpcIndicatorsPlugin.java | 10 +- .../ObjectIndicatorsPlugin.java | 4 +- .../client/plugins/wiki/WikiPlugin.java | 4 +- .../worldhopper/WorldHopperPlugin.java | 4 +- .../plugins/xptracker/XpTrackerPlugin.java | 4 +- .../client/ui/overlay/OverlayRenderer.java | 4 +- .../ui/overlay/worldmap/WorldMapOverlay.java | 4 +- .../runelite/client/menus/TestMenuEntry.java | 2 +- .../java/net/runelite/mixins/MenuMixin.java | 32 +- .../net/runelite/mixins/RSClientMixin.java | 274 ++++++++++++----- .../rs/api/RSRuneLiteIterableHashTable.java | 4 - .../api/RSRuneLiteIterableNodeHashTable.java | 4 + .../runelite/rs/api/RSRuneLiteMenuEntry.java | 13 + runescape-client/runescape-client.gradle.kts | 2 + .../src/main/java/ChatChannel.java | 2 +- runescape-client/src/main/java/Client.java | 2 +- .../src/main/java/FileSystem.java | 3 +- runescape-client/src/main/java/Message.java | 3 +- .../src/main/java/RuneLiteMenuEntry.java | 285 ++++++++++++++++++ runescape-client/src/main/java/class10.java | 2 +- 35 files changed, 665 insertions(+), 402 deletions(-) create mode 100644 injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java delete mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java create mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java create mode 100644 runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java create mode 100644 runescape-client/src/main/java/RuneLiteMenuEntry.java diff --git a/injector/src/main/java/com/openosrs/injector/Injector.java b/injector/src/main/java/com/openosrs/injector/Injector.java index 643bd17886..2264ff15f1 100644 --- a/injector/src/main/java/com/openosrs/injector/Injector.java +++ b/injector/src/main/java/com/openosrs/injector/Injector.java @@ -24,6 +24,7 @@ import com.openosrs.injector.injectors.raw.RasterizerAlpha; import com.openosrs.injector.injectors.raw.RenderDraw; import com.openosrs.injector.injectors.raw.CopyRuneLiteClasses; import com.openosrs.injector.injectors.raw.RuneLiteIterables; +import com.openosrs.injector.injectors.raw.RuneliteMenuEntry; import com.openosrs.injector.injectors.raw.RuneliteObject; import com.openosrs.injector.injectors.raw.ScriptVM; import com.openosrs.injector.rsapi.RSApi; @@ -150,6 +151,8 @@ public class Injector extends InjectData implements InjectTaskHandler inject(new AddPlayerToMenu(this)); + inject(new RuneliteMenuEntry(this)); + validate(new InjectorValidator(this)); transform(new SourceChanger(this)); diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java index 43a1c46822..9296d10b8f 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java @@ -38,7 +38,8 @@ public class CopyRuneLiteClasses extends AbstractInjector "RuneLiteObject", "RuneLiteIterableLinkDeque", "RuneLiteIterableNodeDeque", - "RuneLiteIterableNodeHashTable" + "RuneLiteIterableNodeHashTable", + "RuneLiteMenuEntry" ); public CopyRuneLiteClasses(InjectData inject) diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java new file mode 100644 index 0000000000..fe67fb85a3 --- /dev/null +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021, Owain van Brakel + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this submodule. + */ +package com.openosrs.injector.injectors.raw; + +import com.openosrs.injector.InjectUtil; +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.AbstractInjector; +import java.util.List; +import java.util.ListIterator; +import net.runelite.asm.ClassFile; +import net.runelite.asm.Method; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.InstructionType; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.BAStore; +import net.runelite.asm.attributes.code.instructions.Dup; +import net.runelite.asm.attributes.code.instructions.ILoad; +import net.runelite.asm.attributes.code.instructions.InvokeSpecial; +import net.runelite.asm.attributes.code.instructions.InvokeStatic; +import net.runelite.asm.attributes.code.instructions.New; +import net.runelite.asm.attributes.code.instructions.Return; +import net.runelite.asm.signature.Signature; + +public class RuneliteMenuEntry extends AbstractInjector +{ + private static final String RUNELITE_MENU_ENTRY = "RuneLiteMenuEntry"; + + public RuneliteMenuEntry(InjectData inject) + { + super(inject); + } + + public void inject() + { + addInvoke(); + addSwap(InjectUtil.findMethod(inject, "incrementMenuEntries")); + addSwap(InjectUtil.findMethod(inject, "decrementMenuEntries")); + } + + private void addInvoke() + { + ClassFile runeliteMenuEntryVanilla = inject.vanilla.findClass(RUNELITE_MENU_ENTRY); + + final ClassFile clientVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass("Client") + ); + + Method copy = clientVanilla.findMethod("newRuneliteMenuEntry"); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteMenuEntryVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ILoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteMenuEntryVanilla.getPoolClass(), "", new Signature("(I)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } + + private void addSwap(Method method) + { + final ClassFile clientVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass("Client") + ); + + Instructions ins = method.getCode().getInstructions(); + ListIterator iterator = ins.getInstructions().listIterator(); + while (iterator.hasNext()) + { + Instruction i = iterator.next(); + + if (!(i instanceof BAStore)) + { + continue; + } + + ILoad i1 = new ILoad(ins, 2); + InvokeStatic i2 = new InvokeStatic(ins, new net.runelite.asm.pool.Method(clientVanilla.getPoolClass(), "swapMenuEntries", new Signature("(I)V"))); + + iterator.add(i1); + iterator.add(i2); + + return; + } + } +} diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 83d0c1cf1b..318deaf0f8 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -2124,24 +2124,6 @@ public interface Client extends GameEngine */ void scaleSprite(int[] canvas, int[] pixels, int color, int pixelX, int pixelY, int canvasIdx, int canvasOffset, int newWidth, int newHeight, int pixelWidth, int pixelHeight, int oldWidth); - /** - * Get the MenuEntry at client.getMenuOptionCount() - 1 - *

- * This is useful so you don't have to use getMenuEntries, - * which will create a big array, when you only want to change - * the left click one. - */ - MenuEntry getLeftClickMenuEntry(); - - /** - * Set the MenuEntry at client.getMenuOptionCount() - 1 - *

- * This is useful so you don't have to use setMenuEntries, - * which will arraycopy a big array to several smaller arrays lol, - * when you only want to change the left click one. - */ - void setLeftClickMenuEntry(MenuEntry entry); - /** * If this field is set to true, getting 5 minute logged won't show * the "You have been disconnected." message anymore. diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index 2e17407dec..e607e2aca2 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -24,240 +24,72 @@ */ package net.runelite.api; -import java.util.Arrays; import java.util.function.Consumer; -import lombok.Data; -import lombok.NoArgsConstructor; /** * A menu entry in a right-click menu. */ -@Data -@NoArgsConstructor -public class MenuEntry implements Cloneable +public interface MenuEntry { /** * The option text added to the menu. (ie. "Walk here", "Use") */ - private String option; + String getOption(); + MenuEntry setOption(String option); + /** * The target of the action. (ie. Item or Actor name) *

* If the option does not apply to any target, this field * will be set to empty string. */ - private String target; + String getTarget(); + MenuEntry setTarget(String target); + /** * An identifier value for the target of the action. */ - private int identifier; + int getIdentifier(); + MenuEntry setIdentifier(int identifier); + /** * The action the entry will trigger. - * {@link MenuAction} */ - private int opcode; + MenuAction getType(); + MenuEntry setType(MenuAction type); + /** * An additional parameter for the action. */ - private int param0; + int getParam0(); + MenuEntry setParam0(int param0); + /** * A second additional parameter for the action. */ - private int param1; + int getParam1(); + MenuEntry setParam1(int param1); + /** - * If this field is true and you have single mouse button on and this entry is + * If this is true and you have single mouse button on and this entry is * the top entry the right click menu will not be opened when you left click * * This is used for shift click */ - private boolean forceLeftClick; - - public MenuEntry(String option, String target, int type, int opcode, int param0, int param1, boolean forceLeftClick) - { - this.option = option; - this.target = target; - this.identifier = type; - this.opcode = opcode; - this.param0 = param0; - this.param1 = param1; - this.forceLeftClick = forceLeftClick; - } - - @Override - public MenuEntry clone() - { - try - { - return (MenuEntry) super.clone(); - } - catch (CloneNotSupportedException ex) - { - throw new RuntimeException(ex); - } - } - - public String getOption() - { - return option; - } - - public MenuEntry setOption(String option) - { - this.option = option; - return this; - } - - public String getTarget() - { - return target; - } - - public MenuEntry setTarget(String target) - { - this.target = target; - return this; - } - - public int getIdentifier() - { - return this.identifier; - } - - public MenuEntry setIdentifier(int identifier) - { - this.identifier = identifier; - return this; - } - - public MenuAction getType() - { - return MenuAction.of(this.opcode); - } - - public MenuEntry setType(MenuAction type) - { - this.opcode = type.getId(); - return this; - } - - public int getParam0() - { - return this.param0; - } - - public MenuEntry setParam0(int param0) - { - this.param0 = param0; - return this; - } - - public int getParam1() - { - return this.param1; - } - - public MenuEntry setParam1(int param1) - { - this.param1 = param1; - return this; - } - - public boolean isForceLeftClick() - { - return this.forceLeftClick; - } - - public MenuEntry setForceLeftClick(boolean forceLeftClick) - { - this.forceLeftClick = forceLeftClick; - return this; - } - - public boolean isDeprioritized() - { - return opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; - } - - public MenuEntry setDeprioritized(boolean deprioritized) - { - if (deprioritized) - { - if (opcode < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) - { - opcode += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; - } - } - else - { - if (opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) - { - opcode -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; - } - } - - return this; - } - - public MenuEntry onClick(Consumer callback) - { - return this; - } - - public void setActionParam0(int i) - { - this.param0 = i; - } - - public int getActionParam0() - { - return this.param0; - } - - public void setActionParam1(int i) - { - this.param1 = i; - } - - public int getActionParam1() - { - return this.param1; - } - - public void setType(int i) - { - this.opcode = i; - } - - public void setId(int i) - { - this.identifier = i; - } - - public int getId() - { - return this.identifier; - } + boolean isForceLeftClick(); + MenuEntry setForceLeftClick(boolean forceLeftClick); /** - * Get opcode, but as it's enum counterpart + * Deprioritized menus are sorted in the menu to be below the other menu entries. + * @return */ - public MenuAction getMenuAction() - { - return MenuAction.of(getOpcode()); - } + boolean isDeprioritized(); + MenuEntry setDeprioritized(boolean deprioritized); - // TODO: Remove this after properly implementing the menu - public void add(Client client) - { - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(option); - menuEntry.setTarget(target); - menuEntry.setParam0(param0); - menuEntry.setParam1(param1); - menuEntry.setIdentifier(identifier); - menuEntry.setType(MenuAction.of(getOpcode())); - client.setMenuEntries(menuEntries); - } -} + /** + * Set a callback to be called when this menu option is clicked + * @param callback + * @return + */ + MenuEntry onClick(Consumer callback); +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 93459b761c..69e9dca77c 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -142,9 +142,7 @@ public class MenuManager .setTarget(currentMenu.getMenuTarget()) .setType(MenuAction.RUNELITE) .setParam1(widgetId) - .onClick(currentMenu.callback) - // TODO: remove - .add(client); + .onClick(currentMenu.callback); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 3ee0513b06..bacab9beae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -362,9 +362,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener .setOption(text) .setType(MenuAction.RUNELITE) .setIdentifier(event.getIdentifier()) - .onClick(this::editTags) - // TODO: remove - .add(client); + .onClick(this::editTags); } tabInterface.handleAdd(event); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 1601e0d71f..7a1954e656 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -1196,8 +1196,6 @@ public class TabInterface .setTarget(target) .setOption(option) .setType(MenuAction.RUNELITE) - .setIdentifier(event.getIdentifier()) - // TODO: remove - .add(client); + .setIdentifier(event.getIdentifier()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index c5f1996275..2b11c3318b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -242,9 +242,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener { final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); - }) - // TODO: remove - .add(client); + }); } @Subscribe @@ -290,9 +288,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener } optionBuilder.append(CLEAR_HISTORY); - clearEntry.setOption(optionBuilder.toString()) - // TODO: remove - .add(client); + clearEntry.setOption(optionBuilder.toString()); } private void clearMessageQueue(ChatboxTab tab) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index cadefce9c0..b3d85305ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -185,9 +185,7 @@ public class FriendListPlugin extends Plugin .type(ChatMessageType.CONSOLE) .value("Login notifications for " + friend + " are now " + (hidden ? "shown." : "hidden.")) .build()); - }) - // TODO: remove - .add(client); + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java index 24e321ae08..c274b74834 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java @@ -266,9 +266,7 @@ public class FriendNotesPlugin extends Plugin log.debug("Set note for '{}': '{}'", sanitizedTarget, content); setFriendNote(sanitizedTarget, content); }).build(); - }) - // TODO: remove - .add(client); + }); } else if (hoveredFriend != null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index baebf52248..e8de79d73e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -251,9 +251,7 @@ public class GroundMarkerPlugin extends Plugin { markTile(target.getLocalLocation()); } - }) - // TODO: remove - .add(client); + }); if (exists) { @@ -268,9 +266,7 @@ public class GroundMarkerPlugin extends Plugin { labelTile(target); } - }) - // TODO: remove - .add(client); + }); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index ecb68c64d0..8e567d37d7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -178,9 +178,7 @@ public class HiscorePlugin extends Plugin HiscoreEndpoint endpoint = findHiscoreEndpointFromPlayerName(e.getTarget()); String target = Text.removeTags(e.getTarget()); lookupPlayer(target, endpoint); - }) - // TODO: remove - .add(client); + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java index c0e7a60cde..d588ed42aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java @@ -198,9 +198,7 @@ public class InventoryTagsPlugin extends Plugin { unsetTag(itemId); } - }) - // TODO: remove - .add(client); + }); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index a06ad3cbf7..58c2a66a6a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -598,9 +598,7 @@ public class MenuEntrySwapperPlugin extends Plugin .setOption(RESET) .setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET) .setType(MenuAction.RUNELITE) - .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)) - // TODO: remove - .add(client); + .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index ff775e7129..4ee62c2545 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -296,19 +296,15 @@ public class NpcIndicatorsPlugin extends Plugin .setTarget(event.getTarget()) .setIdentifier(event.getIdentifier()) .setType(MenuAction.RUNELITE) - .onClick(this::tag) - // TODO: remove - .add(client); + .onClick(this::tag); } - client.createMenuEntry(-1) + MenuEntry i = client.createMenuEntry(-1) .setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG) .setTarget(event.getTarget()) .setIdentifier(event.getIdentifier()) .setType(MenuAction.RUNELITE) - .onClick(this::tag) - // TODO: remove - .add(client); + .onClick(this::tag); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java index 2985ca8d12..526ffe7f91 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java @@ -235,9 +235,7 @@ public class ObjectIndicatorsPlugin extends Plugin .setParam1(event.getActionParam1()) .setIdentifier(event.getIdentifier()) .setType(MenuAction.RUNELITE) - .onClick(this::markObject) - // TODO: remove - .add(client); + .onClick(this::markObject); } private void markObject(MenuEntry entry) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java index 9761c5935e..9ac225d4ba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java @@ -418,9 +418,7 @@ public class WikiPlugin extends Plugin .addPathSegment("w") .addPathSegment(Text.removeTags(ev.getTarget())) .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) - .build().toString())) - // TODO: remove - .add(client); + .build().toString())); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index a6df02a7c5..82d44972e2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -405,9 +405,7 @@ public class WorldHopperPlugin extends Plugin { hop(p.getWorld()); } - }) - // TODO: remove - .add(client); + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 772d1f8c85..5407226a99 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -532,9 +532,7 @@ public class XpTrackerPlugin extends Plugin { addOverlay(skill); } - }) - // TODO: remove - .add(client); + }); } XpStateSingle getSkillState(Skill skill) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index 535587d409..7bd2d7cbad 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -185,9 +185,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener .setOption(overlayMenuEntry.getOption()) .setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)) .setType(overlayMenuEntry.getMenuAction()) - .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))) - // TODO: remove - .add(client); + .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 4ec9d466f9..16ca444f8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -114,9 +114,7 @@ public class WorldMapOverlay extends Overlay .setOption(FOCUS_ON) .setType(MenuAction.RUNELITE) .onClick(m -> client.getRenderOverview().setWorldMapPositionTarget( - MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))) - // TODO: remove - .add(client); + MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))); }); bottomBar.setHasListener(true); diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java index 6665f40ec3..5427f76540 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -30,7 +30,7 @@ import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; @EqualsAndHashCode(callSuper = false) -public class TestMenuEntry extends MenuEntry +public class TestMenuEntry implements MenuEntry { private String option; private String target; diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java index 6fb4d17233..21a59cd3fa 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java @@ -163,36 +163,6 @@ public abstract class MenuMixin implements RSClient } } - @Inject - @Override - public MenuEntry getLeftClickMenuEntry() - { - final int i = getMenuOptionCount() - 1; - return new MenuEntry( - getMenuOptions()[i], - getMenuTargets()[i], - getMenuIdentifiers()[i], - getMenuOpcodes()[i], - getMenuArguments1()[i], - getMenuArguments2()[i], - getMenuForceLeftClick()[i] - ); - } - - @Inject - @Override - public void setLeftClickMenuEntry(final MenuEntry entry) - { - final int i = getMenuOptionCount() - 1; - getMenuOptions()[i] = entry.getOption(); - getMenuTargets()[i] = entry.getTarget(); - getMenuIdentifiers()[i] = entry.getIdentifier(); - getMenuOpcodes()[i] = entry.getOpcode(); - getMenuArguments1()[i] = entry.getParam0(); - getMenuArguments2()[i] = entry.getParam1(); - getMenuForceLeftClick()[i] = entry.isForceLeftClick(); - } - @Inject @FieldHook("tempMenuAction") public static void onTempMenuActionChanged(int idx) @@ -213,7 +183,7 @@ public abstract class MenuMixin implements RSClient } tempMenuAction.setOption(entry.getOption()); - tempMenuAction.setOpcode(entry.getOpcode()); + tempMenuAction.setOpcode(entry.getType().getId()); tempMenuAction.setIdentifier(entry.getIdentifier()); tempMenuAction.setParam0(entry.getParam0()); tempMenuAction.setParam1(entry.getParam1()); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 06bea2ec7d..b1f1d79763 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -156,6 +156,7 @@ import net.runelite.rs.api.RSNodeDeque; import net.runelite.rs.api.RSNodeHashTable; import net.runelite.rs.api.RSPacketBuffer; import net.runelite.rs.api.RSPlayer; +import net.runelite.rs.api.RSRuneLiteMenuEntry; import net.runelite.rs.api.RSScene; import net.runelite.rs.api.RSScriptEvent; import net.runelite.rs.api.RSSpritePixels; @@ -294,6 +295,12 @@ public abstract class RSClientMixin implements RSClient @Inject private static ArrayList hiddenWidgets = new ArrayList<>(); + @Inject + private static final RSRuneLiteMenuEntry[] rl$menuEntries = new RSRuneLiteMenuEntry[500]; + + @Inject + private static int tmpMenuOptionsCount; + @Inject @Override public void setPrintMenuActions(boolean yes) @@ -789,119 +796,210 @@ public abstract class RSClientMixin implements RSClient setChatCycle(getCycleCntr()); } + @Inject + public static RSRuneLiteMenuEntry newRuneliteMenuEntry(int idx) + { + return null; + } + @Inject @Override public MenuEntry createMenuEntry(int idx) { - // TODO: Implement this + if (client.getMenuOptionCount() >= 500) + { + throw new IllegalStateException(); + } + else + { + if (idx < 0) + { + idx = client.getMenuOptionCount() + idx + 1; + if (idx < 0) + { + throw new IllegalArgumentException(); + } + } - return new MenuEntry(); + RSRuneLiteMenuEntry menuEntry; + if (idx < client.getMenuOptionCount()) + { + RSRuneLiteMenuEntry tmpEntry = rl$menuEntries[client.getMenuOptionCount()]; + if (tmpEntry == null) + { + tmpEntry = rl$menuEntries[client.getMenuOptionCount()] = newRuneliteMenuEntry(client.getMenuOptionCount()); + } + + for (int i = client.getMenuOptionCount(); i > idx; rl$menuEntries[i].setIdx(i--)) + { + client.getMenuOptions()[i] = client.getMenuOptions()[i - 1]; + client.getMenuTargets()[i] = client.getMenuTargets()[i - 1]; + client.getMenuIdentifiers()[i] = client.getMenuIdentifiers()[i - 1]; + client.getMenuOpcodes()[i] = client.getMenuOpcodes()[i - 1]; + client.getMenuArguments1()[i] = client.getMenuArguments1()[i - 1]; + client.getMenuArguments2()[i] = client.getMenuArguments2()[i - 1]; + client.getMenuForceLeftClick()[i] = client.getMenuForceLeftClick()[i - 1]; + + rl$menuEntries[i] = rl$menuEntries[i - 1]; + } + + client.setMenuOptionCount(client.getMenuOptionCount() + 1); + tmpMenuOptionsCount = client.getMenuOptionCount(); + + menuEntry = tmpEntry; + rl$menuEntries[idx] = tmpEntry; + + tmpEntry.setIdx(idx); + } + else + { + if (idx != client.getMenuOptionCount()) + { + throw new IllegalArgumentException(); + } + + menuEntry = rl$menuEntries[client.getMenuOptionCount()]; + + if (menuEntry == null) + { + menuEntry = rl$menuEntries[client.getMenuOptionCount()] = newRuneliteMenuEntry(client.getMenuOptionCount()); + } + + client.setMenuOptionCount(client.getMenuOptionCount() + 1); + tmpMenuOptionsCount = client.getMenuOptionCount(); + } + + menuEntry.setOption(""); + menuEntry.setTarget(""); + menuEntry.setIdentifier(0); + menuEntry.setType(MenuAction.RUNELITE); + menuEntry.setParam0(0); + menuEntry.setParam1(0); + menuEntry.setConsumer(null); + + return menuEntry; + } } @Inject @Override public MenuEntry[] getMenuEntries() { - int count = getMenuOptionCount(); - String[] menuOptions = getMenuOptions(); - String[] menuTargets = getMenuTargets(); - int[] menuIdentifiers = getMenuIdentifiers(); - int[] menuTypes = getMenuOpcodes(); - int[] params0 = getMenuArguments1(); - int[] params1 = getMenuArguments2(); - boolean[] leftClick = getMenuForceLeftClick(); - - MenuEntry[] entries = new MenuEntry[count]; - for (int i = 0; i < count; ++i) - { - MenuEntry entry = entries[i] = new MenuEntry(); - entry.setOption(menuOptions[i]); - entry.setTarget(menuTargets[i]); - entry.setIdentifier(menuIdentifiers[i]); - entry.setOpcode(menuTypes[i]); - entry.setParam0(params0[i]); - entry.setParam1(params1[i]); - entry.setForceLeftClick(leftClick[i]); - } - return entries; + return Arrays.copyOf(rl$menuEntries, client.getMenuOptionCount()); } @Inject @Override - public void setMenuEntries(MenuEntry[] entries) + public void setMenuEntries(MenuEntry[] menuEntries) { - int count = 0; - String[] menuOptions = getMenuOptions(); - String[] menuTargets = getMenuTargets(); - int[] menuIdentifiers = getMenuIdentifiers(); - int[] menuTypes = getMenuOpcodes(); - int[] params0 = getMenuArguments1(); - int[] params1 = getMenuArguments2(); - boolean[] leftClick = getMenuForceLeftClick(); - - for (MenuEntry entry : entries) + for (int i = 0; i < menuEntries.length; ++i) { - if (entry == null) + RSRuneLiteMenuEntry menuEntry = (RSRuneLiteMenuEntry) menuEntries[i]; + if (menuEntry.getIdx() != i) { - continue; + sortMenuEntries(menuEntry.getIdx(), i); } - - menuOptions[count] = entry.getOption(); - menuTargets[count] = entry.getTarget(); - menuIdentifiers[count] = entry.getIdentifier(); - menuTypes[count] = entry.getOpcode(); - params0[count] = entry.getParam0(); - params1[count] = entry.getParam1(); - leftClick[count] = entry.isForceLeftClick(); - ++count; } - setMenuOptionCount(count); - oldMenuEntryCount = count; + client.setMenuOptionCount(menuEntries.length); + tmpMenuOptionsCount = menuEntries.length; + } + + @Inject + public static void sortMenuEntries(int left, int right) + { + String menuOption = client.getMenuOptions()[left]; + client.getMenuOptions()[left] = client.getMenuOptions()[right]; + client.getMenuOptions()[right] = menuOption; + + String menuTarget = client.getMenuTargets()[left]; + client.getMenuTargets()[left] = client.getMenuTargets()[right]; + client.getMenuTargets()[right] = menuTarget; + + int menuIdentifier = client.getMenuIdentifiers()[left]; + client.getMenuIdentifiers()[left] = client.getMenuIdentifiers()[right]; + client.getMenuIdentifiers()[right] = menuIdentifier; + + int menuOpcode = client.getMenuOpcodes()[left]; + client.getMenuOpcodes()[left] = client.getMenuOpcodes()[right]; + client.getMenuOpcodes()[right] = menuOpcode; + + int menuArguments1 = client.getMenuArguments1()[left]; + client.getMenuArguments1()[left] = client.getMenuArguments1()[right]; + client.getMenuArguments1()[right] = menuArguments1; + + int menuArgument2 = client.getMenuArguments2()[left]; + client.getMenuArguments2()[left] = client.getMenuArguments2()[right]; + client.getMenuArguments2()[right] = menuArgument2; + + boolean menuForceLeftClick = client.getMenuForceLeftClick()[left]; + client.getMenuForceLeftClick()[left] = client.getMenuForceLeftClick()[right]; + client.getMenuForceLeftClick()[right] = menuForceLeftClick; + + RSRuneLiteMenuEntry tmpEntry = rl$menuEntries[left]; + rl$menuEntries[left] = rl$menuEntries[right]; + rl$menuEntries[right] = tmpEntry; + + rl$menuEntries[left].setIdx(left); + rl$menuEntries[right].setIdx(right); + } + + @Inject + public static void swapMenuEntries(int var0) + { + RSRuneLiteMenuEntry var1 = rl$menuEntries[var0]; + RSRuneLiteMenuEntry var2 = rl$menuEntries[var0 + 1]; + + rl$menuEntries[var0] = var2; + rl$menuEntries[var0 + 1] = var1; + + var1.setIdx(var0 + 1); + var2.setIdx(var0); } @FieldHook("menuOptionsCount") @Inject public static void onMenuOptionsChanged(int idx) { - int oldCount = oldMenuEntryCount; - int newCount = client.getMenuOptionCount(); + int tmpOptionsCount = tmpMenuOptionsCount; + int optionCount = client.getMenuOptionCount(); - oldMenuEntryCount = newCount; + tmpMenuOptionsCount = optionCount; - final String[] options = client.getMenuOptions(); - final String[] targets = client.getMenuTargets(); - final int[] identifiers = client.getMenuIdentifiers(); - final int[] opcodes = client.getMenuOpcodes(); - final int[] arguments1 = client.getMenuArguments1(); - final int[] arguments2 = client.getMenuArguments2(); - final boolean[] forceLeftClick = client.getMenuForceLeftClick(); - - if (newCount == oldCount + 1) + if (optionCount < tmpOptionsCount) { - MenuEntryAdded event = new MenuEntryAdded( - options[oldCount], - targets[oldCount], - identifiers[oldCount], - opcodes[oldCount], - arguments1[oldCount], - arguments2[oldCount], - forceLeftClick[oldCount] - ); - - client.getCallbacks().post(event); - - if (event.isModified() && client.getMenuOptionCount() == newCount) + for (int i = optionCount; i < tmpOptionsCount; ++i) { - options[oldCount] = event.getOption(); - targets[oldCount] = event.getTarget(); - identifiers[oldCount] = event.getIdentifier(); - opcodes[oldCount] = event.getType(); - arguments1[oldCount] = event.getActionParam0(); - arguments2[oldCount] = event.getActionParam1(); - forceLeftClick[oldCount] = event.isForceLeftClick(); + rl$menuEntries[i].setConsumer(null); } } + else if (optionCount == tmpOptionsCount + 1) + { + String menuOption = client.getMenuOptions()[tmpOptionsCount]; + String menuTarget = client.getMenuTargets()[tmpOptionsCount]; + int menuOpcode = client.getMenuOpcodes()[tmpOptionsCount]; + int menuIdentifier = client.getMenuIdentifiers()[tmpOptionsCount]; + int menuArgument1 = client.getMenuArguments1()[tmpOptionsCount]; + int menuArgument2 = client.getMenuArguments2()[tmpOptionsCount]; + if (rl$menuEntries[tmpOptionsCount] == null) + { + rl$menuEntries[tmpOptionsCount] = newRuneliteMenuEntry(tmpOptionsCount); + } + else + { + rl$menuEntries[tmpOptionsCount].setConsumer(null); + } + + MenuEntryAdded menuEntryAdded = new MenuEntryAdded( + menuOption, + menuTarget, + menuOpcode, + menuIdentifier, + menuArgument1, + menuArgument2 + ); + client.getCallbacks().post(menuEntryAdded); + } } @Inject @@ -1479,6 +1577,17 @@ public abstract class RSClientMixin implements RSClient @Replace("menuAction") static void copy$menuAction(int param0, int param1, int opcode, int id, String option, String target, int canvasX, int canvasY) { + RSRuneLiteMenuEntry menuEntry = null; + + for (int i = client.getMenuOptionCount() - 1; i >= 0; --i) + { + if (client.getMenuOptions()[i] == option && client.getMenuTargets()[i] == target && client.getMenuIdentifiers()[i] == id && client.getMenuOpcodes()[i] == opcode) + { + menuEntry = rl$menuEntries[i]; + break; + } + } + /* * The RuneScape client may deprioritize an action in the menu by incrementing the opcode with 2000, * undo it here so we can get the correct opcode @@ -1501,6 +1610,11 @@ public abstract class RSClientMixin implements RSClient client.getCallbacks().post(menuOptionClicked); + if (menuEntry != null && menuEntry.getConsumer() != null) + { + menuEntry.getConsumer().accept(menuEntry); + } + if (menuOptionClicked.isConsumed()) { return; diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java deleted file mode 100644 index 29833ca736..0000000000 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.runelite.rs.api; - -public interface RSRuneLiteIterableHashTable -{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java new file mode 100644 index 0000000000..6337285901 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableNodeHashTable +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java new file mode 100644 index 0000000000..ba16a2c48d --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java @@ -0,0 +1,13 @@ +package net.runelite.rs.api; + +import java.util.function.Consumer; +import net.runelite.api.MenuEntry; + +public interface RSRuneLiteMenuEntry extends MenuEntry +{ + Consumer getConsumer(); + void setConsumer(Consumer consumer); + + int getIdx(); + void setIdx(int idx); +} diff --git a/runescape-client/runescape-client.gradle.kts b/runescape-client/runescape-client.gradle.kts index fe52c6c012..5fc7078743 100644 --- a/runescape-client/runescape-client.gradle.kts +++ b/runescape-client/runescape-client.gradle.kts @@ -27,6 +27,8 @@ group = "com.openosrs.rs" description = "RuneScape Client" dependencies { + api(project(":runelite-api")) + implementation(project(":injection-annotations")) implementation(group = "org.bouncycastle", name = "bcprov-jdk15on", version = "1.52") diff --git a/runescape-client/src/main/java/ChatChannel.java b/runescape-client/src/main/java/ChatChannel.java index 4ff9e9bd1b..9bd2622d45 100644 --- a/runescape-client/src/main/java/ChatChannel.java +++ b/runescape-client/src/main/java/ChatChannel.java @@ -161,7 +161,7 @@ public class ChatChannel { Client.meslayerContinueWidget = null; } - FileSystem.method3084(); + FileSystem.decrementMenuEntries(); class115.revalidateWidgetScroll(MouseRecorder.Widget_interfaceComponents[var0 >> 16], var4, false); class33.runWidgetOnLoadListener(var1); if (Client.rootInterface != -1) { diff --git a/runescape-client/src/main/java/Client.java b/runescape-client/src/main/java/Client.java index 40e1149835..42e7d5c191 100644 --- a/runescape-client/src/main/java/Client.java +++ b/runescape-client/src/main/java/Client.java @@ -6401,7 +6401,7 @@ public final class Client extends GameEngine implements Usernamed, OAuthTokens { ) @Export("menu") final void menu() { - Message.method1115(); + Message.incrementMenuEntries(); if (class143.dragInventoryWidget == null) { if (clickedWidget == null) { int var1 = MouseHandler.MouseHandler_lastButton; diff --git a/runescape-client/src/main/java/FileSystem.java b/runescape-client/src/main/java/FileSystem.java index 8dd33ebc91..d26b04189b 100644 --- a/runescape-client/src/main/java/FileSystem.java +++ b/runescape-client/src/main/java/FileSystem.java @@ -30,7 +30,8 @@ public class FileSystem { descriptor = "(I)V", garbageValue = "497428397" ) - static void method3084() { + @Export("decrementMenuEntries") + static void decrementMenuEntries() { for (int var0 = 0; var0 < Client.menuOptionsCount; ++var0) { if (InvDefinition.method3157(Client.menuOpcodes[var0])) { if (var0 < Client.menuOptionsCount - 1) { diff --git a/runescape-client/src/main/java/Message.java b/runescape-client/src/main/java/Message.java index a6b0243341..fda1fa3c4b 100644 --- a/runescape-client/src/main/java/Message.java +++ b/runescape-client/src/main/java/Message.java @@ -166,7 +166,8 @@ public class Message extends DualNode { descriptor = "(I)V", garbageValue = "1989735073" ) - static final void method1115() { + @Export("incrementMenuEntries") + static final void incrementMenuEntries() { boolean var0 = false; while (!var0) { diff --git a/runescape-client/src/main/java/RuneLiteMenuEntry.java b/runescape-client/src/main/java/RuneLiteMenuEntry.java new file mode 100644 index 0000000000..72e9c392b4 --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteMenuEntry.java @@ -0,0 +1,285 @@ +import java.util.function.Consumer; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; + +public class RuneLiteMenuEntry implements MenuEntry +{ + public Consumer consumer; + public int idx; + + public RuneLiteMenuEntry(int idx) + { + this.idx = idx; + } + + public Consumer getConsumer() + { + return consumer; + } + + public void setConsumer(Consumer consumer) + { + this.consumer = consumer; + } + + public int getIdx() + { + return idx; + } + + public void setIdx(int idx) + { + this.idx = idx; + } + + @Override + public String getOption() + { + return Client.menuActions[this.idx]; + } + + @Override + public MenuEntry setOption(String option) + { + Client.menuActions[this.idx] = option; + return this; + } + + @Override + public String getTarget() + { + return Client.menuTargets[this.idx]; + } + + @Override + public MenuEntry setTarget(String target) + { + Client.menuTargets[this.idx] = target; + return this; + } + + @Override + public MenuAction getType() + { + int opcode = Client.menuOpcodes[this.idx]; + if (opcode >= 2000) + { + opcode -= 2000; + } + + return MenuAction.of(opcode); + } + + @Override + public MenuEntry setType(MenuAction menuAction) + { + int opcode = Client.menuOpcodes[this.idx]; + short mod = 0; + if (opcode >= 2000) + { + mod = 2000; + } + + Client.menuOpcodes[this.idx] = menuAction.getId() + mod; + return this; + } + + @Override + public int getIdentifier() + { + return Client.menuIdentifiers[this.idx]; + } + + @Override + public MenuEntry setIdentifier(int identifier) + { + Client.menuIdentifiers[this.idx] = identifier; + return this; + } + + @Override + public int getParam0() + { + return Client.menuArguments1[this.idx]; + } + + @Override + public MenuEntry setParam0(int param0) + { + Client.menuArguments1[this.idx] = param0; + return this; + } + + @Override + public int getParam1() + { + return Client.menuArguments2[this.idx]; + } + + @Override + public MenuEntry setParam1(int param1) + { + Client.menuArguments2[this.idx] = param1; + return this; + } + + @Override + public boolean isDeprioritized() + { + return Client.menuOpcodes[this.idx] >= 2000; + } + + @Override + public MenuEntry setDeprioritized(boolean deprioritize) + { + int[] opcodes; + + if (deprioritize) + { + if (Client.menuOpcodes[this.idx] < 2000) + { + opcodes = Client.menuOpcodes; + opcodes[this.idx] += 2000; + } + } + else if (Client.menuOpcodes[this.idx] >= 2000) + { + opcodes = Client.menuOpcodes; + opcodes[this.idx] -= 2000; + } + + return this; + } + + @Override + public boolean isForceLeftClick() + { + return Client.menuShiftClick[this.idx]; + } + + @Override + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + Client.menuShiftClick[this.idx] = forceLeftClick; + return this; + } + + @Override + public MenuEntry onClick(Consumer consumer) + { + this.consumer = consumer; + return this; + } + + public boolean instanceOf(Object o) + { + return o instanceof RuneLiteMenuEntry; + } + + @Override + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + else if (!(o instanceof RuneLiteMenuEntry)) + { + return false; + } + else + { + RuneLiteMenuEntry menuEntry = (RuneLiteMenuEntry) o; + if (!menuEntry.instanceOf(this)) + { + return false; + } + else if (this.getIdentifier() != menuEntry.getIdentifier()) + { + return false; + } + else if (this.getParam0() != menuEntry.getParam0()) + { + return false; + } + else if (this.getParam1() != menuEntry.getParam1()) + { + return false; + } + else if (this.isForceLeftClick() != menuEntry.isForceLeftClick()) + { + return false; + } + else if (this.isDeprioritized() != menuEntry.isDeprioritized()) + { + return false; + } + else + { + String option = this.getOption(); + String menuEntryOption = menuEntry.getOption(); + if (option == null) + { + if (menuEntryOption != null) + { + return false; + } + } + else if (!option.equals(menuEntryOption)) + { + return false; + } + + String target = this.getTarget(); + String menuEntryTarget = menuEntry.getTarget(); + if (target == null) + { + if (menuEntryTarget != null) + { + return false; + } + } + else if (!target.equals(menuEntryTarget)) + { + return false; + } + + MenuAction type = this.getType(); + MenuAction menuEntryType = menuEntry.getType(); + if (type == null) + { + if (menuEntryType == null) + { + return true; + } + } + else if (type.equals(menuEntryType)) + { + return true; + } + + return false; + } + } + } + + @Override + public int hashCode() + { + byte b = 1; + + int hash = b * 59 + this.getIdentifier(); + hash = hash * 59 + this.getParam0(); + hash = hash * 59 + this.getParam1(); + hash = hash * 59 + (this.isForceLeftClick() ? 79 : 97); + hash = hash * 59 + (this.isDeprioritized() ? 79 : 97); + String option = this.getOption(); + hash = hash * 59 + (option == null ? 43 : option.hashCode()); + String target = this.getTarget(); + hash = hash * 59 + (target == null ? 43 : target.hashCode()); + MenuAction type = this.getType(); + hash = hash * 59 + (type == null ? 43 : type.hashCode()); + + return hash; + } +} diff --git a/runescape-client/src/main/java/class10.java b/runescape-client/src/main/java/class10.java index 211323be03..6ec5f93e9e 100644 --- a/runescape-client/src/main/java/class10.java +++ b/runescape-client/src/main/java/class10.java @@ -320,7 +320,7 @@ public class class10 { SecureRandomCallable.invalidateWidget(var4); } - FileSystem.method3084(); + FileSystem.decrementMenuEntries(); if (Client.rootInterface != -1) { Message.runIntfCloseListeners(Client.rootInterface, 1); }