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 8f2464dd4d..8c0e99df93 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 @@ -25,8 +25,10 @@ */ package net.runelite.client.plugins.menuentryswapper; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; +import java.util.List; import java.util.Set; import javax.inject.Inject; import lombok.Getter; @@ -130,6 +132,8 @@ public class MenuEntrySwapperPlugin extends Plugin @Setter private boolean shiftModifier = false; + private final ArrayListMultimap optionIndexes = ArrayListMultimap.create(); + @Provides MenuEntrySwapperConfig provideConfig(ConfigManager configManager) { @@ -354,13 +358,22 @@ public class MenuEntrySwapperPlugin extends Plugin @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { + final String option = Text.removeTags(event.getOption()).toLowerCase(); + + if (event.getType() == MenuAction.CANCEL.getId()) + { + optionIndexes.clear(); + } + + int size = optionIndexes.size(); + optionIndexes.put(option, size); + if (client.getGameState() != GameState.LOGGED_IN) { return; } final int eventId = event.getIdentifier(); - final String option = Text.removeTags(event.getOption()).toLowerCase(); final String target = Text.removeTags(event.getTarget()).toLowerCase(); final NPC hintArrowNpc = client.getHintArrowNpc(); @@ -624,21 +637,33 @@ public class MenuEntrySwapperPlugin extends Plugin private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) { - for (int i = entries.length - 1; i >= 0; i--) + if (strict) { - MenuEntry entry = entries[i]; - String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); - String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); + List indexes = optionIndexes.get(option); - if (strict) + // We want the last index which matches the target, as that is what is top-most + // on the menu + for (int i = indexes.size() - 1; i >= 0; --i) { - if (entryOption.equals(option) && entryTarget.equals(target)) + int idx = indexes.get(i); + MenuEntry entry = entries[idx]; + String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); + + if (entryTarget.equals(target)) { - return i; + return idx; } } - else + } + else + { + // Without strict matching we have to iterate all entries... + for (int i = entries.length - 1; i >= 0; i--) { + MenuEntry entry = entries[i]; + String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); + String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); + if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target)) { return i;