From f6f66b6be32375d116888a32d4e7a4399ce04137 Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sat, 29 Jun 2019 18:06:14 -0400 Subject: [PATCH 1/6] rsclientmixin: make use of edited menuentryclicked event variables --- .../src/main/java/net/runelite/mixins/RSClientMixin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 069c9a99d4..a08bcaf36a 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1264,7 +1264,8 @@ public abstract class RSClientMixin implements RSClient return; } - rs$menuAction(actionParam, widgetId, menuAction, id, menuOption, menuTarget, var6, var7); + rs$menuAction(menuOptionClicked.getActionParam0(), menuOptionClicked.getActionParam1(), menuOptionClicked.getType(), + menuOptionClicked.getIdentifier(), menuOptionClicked.getOption(), menuOptionClicked.getTarget(), var6, var7); } @FieldHook("Login_username") From 32a95a679859bb6ee5d6224ecb2f681b29518cd0 Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sat, 29 Jun 2019 18:13:44 -0400 Subject: [PATCH 2/6] menumanager: fix priority entry and performance improvements --- .../runelite/client/menus/MenuManager.java | 242 ++++++++---------- 1 file changed, 106 insertions(+), 136 deletions(-) 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 6c674c1d14..58200d407e 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 @@ -27,10 +27,12 @@ package net.runelite.client.menus; import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -39,12 +41,10 @@ import java.util.Set; import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import static net.runelite.api.MenuAction.GAME_OBJECT_FIRST_OPTION; -import static net.runelite.api.MenuAction.WIDGET_DEFAULT; +import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import net.runelite.api.MenuEntry; import net.runelite.api.NPCDefinition; import net.runelite.api.events.ClientTick; @@ -97,7 +97,7 @@ public class MenuManager private final Set hiddenEntries = new HashSet<>(); private final Map swaps = new HashMap<>(); - private EntryTypeMapping originalType; + private MenuEntry leftClickEntry; @Inject private MenuManager(Client client, EventBus eventBus) @@ -170,109 +170,128 @@ public class MenuManager @Subscribe private void onClientTick(ClientTick event) { - originalType = null; + leftClickEntry = null; + + if (client.isMenuOpen()) + { + return; + } + currentPriorityEntries.clear(); client.sortMenuEntries(); MenuEntry[] oldEntries = client.getMenuEntries(); List newEntries = Lists.newArrayList(oldEntries); - for (MenuEntry entry : oldEntries) + boolean shouldDeprioritize = false; + boolean modified = false; + + + prioritizer: for (MenuEntry entry : oldEntries) { - for (ComparableEntry p : priorityEntries) - { - if (p.matches(entry)) - { - currentPriorityEntries.add(entry); - } - } - - // If there are entries we want to prioritize, we have to remove the rest - if (!currentPriorityEntries.isEmpty() && !client.isMenuOpen()) - { - newEntries.retainAll(currentPriorityEntries); - - // This is because players existing changes walk-here target - // so without this we lose track of em - if (newEntries.size() != currentPriorityEntries.size()) - { - for (MenuEntry e : currentPriorityEntries) - { - if (newEntries.contains(e)) - { - continue; - } - - for (MenuEntry e2 : client.getMenuEntries()) - { - if (e.getType() == e2.getType()) - { - e.setTarget(e2.getTarget()); - newEntries.add(e); - } - } - } - } - } - - boolean isHidden = false; + // Remove hidden entries from menus for (ComparableEntry p : hiddenEntries) { if (p.matches(entry)) { - isHidden = true; - break; + newEntries.remove(entry); + continue prioritizer; } } - if (isHidden) + for (ComparableEntry p : priorityEntries) { - newEntries.remove(entry); - } - } - - if (!currentPriorityEntries.isEmpty() && !client.isMenuOpen()) - { - newEntries.add(0, CANCEL()); - } - - MenuEntry leftClickEntry = newEntries.get(newEntries.size() - 1); - - for (ComparableEntry src : swaps.keySet()) - { - if (!src.matches(leftClickEntry)) - { - continue; - } - - ComparableEntry tgt = swaps.get(src); - - for (int i = newEntries.size() - 2; i > 0; i--) - { - MenuEntry e = newEntries.get(i); - - if (tgt.matches(e)) + // Create list of priority entries, and remove from menus + if (p.matches(entry)) { - newEntries.set(newEntries.size() - 1, e); - newEntries.set(i, leftClickEntry); - - int type = e.getType(); - - if (type >= 1000) + // Other entries need to be deprioritized if their types are lower than 1000 + if (entry.getType() >= 1000 && !shouldDeprioritize) { - int newType = getLeftClickType(type); - if (newType != -1 && newType != type) - { - MenuEntry original = MenuEntry.copy(e); - e.setType(newType); - originalType = new EntryTypeMapping(new ComparableEntry(leftClickEntry), original); - } + shouldDeprioritize = true; + } + currentPriorityEntries.add(entry); + newEntries.remove(entry); + continue prioritizer; + } + } + } + + if (newEntries.size() > 0) + { + MenuEntry entry = Iterables.getLast(newEntries); + + // Swap first matching entry to top + for (ComparableEntry src : swaps.keySet()) + { + if (!src.matches(entry)) + { + continue; + } + + MenuEntry swapFrom = null; + + ComparableEntry from = swaps.get(src); + + for (MenuEntry e : newEntries) + { + if (from.matches(e)) + { + swapFrom = e; + break; + } + } + + // Do not need to swap with itself + if (swapFrom != null && swapFrom != entry) + { + // Deprioritize entries if the swaps are not in similar type groups + if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) + { + shouldDeprioritize = true; } + int indexFrom = newEntries.indexOf(swapFrom); + int indexTo = newEntries.indexOf(entry); + + Collections.swap(newEntries, indexFrom, indexTo); + + // Set force left click if entry was moved to first entry + if (indexTo == newEntries.size() - 1) + { + swapFrom.setForceLeftClick(true); + entry.setForceLeftClick(false); + } + + modified = true; + + // If this loop is placed in the 'prioritizer' block and the following break is removed, + // all swaps will be applied instead of only swapping the first one found to the first entry break; } } } + + if (shouldDeprioritize) + { + for (MenuEntry entry : newEntries) + { + if (entry.getType() <= MENU_ACTION_DEPRIORITIZE_OFFSET) + { + entry.setType(entry.getType() + MENU_ACTION_DEPRIORITIZE_OFFSET); + } + } + } + + if (!priorityEntries.isEmpty()) + { + newEntries.addAll(currentPriorityEntries); + modified = true; + } + + if (modified) + { + leftClickEntry = newEntries.get(newEntries.size() - 1); + } client.setMenuEntries(newEntries.toArray(new MenuEntry[0])); } @@ -338,24 +357,6 @@ public class MenuManager } } - private int getLeftClickType(int oldType) - { - if (oldType > 2000) - { - oldType -= 2000; - } - - switch (MenuAction.of(oldType)) - { - case GAME_OBJECT_FIFTH_OPTION: - return GAME_OBJECT_FIRST_OPTION.getId(); - case EXAMINE_ITEM_BANK_EQ: - return WIDGET_DEFAULT.getId(); - default: - return oldType; - } - } - private void addNpcOption(NPCDefinition composition, String npcOption) { String[] actions = composition.getActions(); @@ -399,21 +400,10 @@ public class MenuManager @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - // Type is changed in check - if (originalType != null && originalType.check(event)) + if (leftClickEntry != null) { - event.consume(); - - client.invokeMenuAction( - event.getActionParam0(), - event.getActionParam1(), - event.getType(), - event.getIdentifier(), - "do not edit", - event.getTarget(), - client.getMouseCanvasPosition().getX(), - client.getMouseCanvasPosition().getY() - ); + event.setMenuEntry(leftClickEntry); + leftClickEntry = null; } if (event.getMenuAction() != MenuAction.RUNELITE) @@ -739,24 +729,4 @@ public class MenuManager { hiddenEntries.remove(entry); } - - @AllArgsConstructor - private class EntryTypeMapping - { - private final ComparableEntry comparable; - private final MenuEntry target; - - private boolean check(MenuOptionClicked event) - { - MenuEntry entry = event.getMenuEntry(); - - if (event.getTarget().equals("do not edit") || !comparable.matches(entry)) - { - return false; - } - - event.setMenuEntry(target); - return true; - } - } } From d2cd11a786d94b9de958167c386c3f78f6836ffb Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sun, 30 Jun 2019 16:06:20 -0400 Subject: [PATCH 3/6] rsclientmixin: make use of edited menuopened event variables --- .../src/main/java/net/runelite/mixins/RSClientMixin.java | 1 + 1 file changed, 1 insertion(+) 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 a08bcaf36a..ee569abca0 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1304,6 +1304,7 @@ public abstract class RSClientMixin implements RSClient final MenuOpened event = new MenuOpened(); event.setMenuEntries(getMenuEntries()); callbacks.post(event); + client.setMenuEntries(event.getMenuEntries()); } @Inject From 16c45f1020f82c9e554d55cc57952b737591deef Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sun, 30 Jun 2019 16:10:13 -0400 Subject: [PATCH 4/6] menumanager: moved back to menuentryadded, also using menuopened --- .../runelite/client/menus/MenuManager.java | 217 +++++++++++------- 1 file changed, 134 insertions(+), 83 deletions(-) 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 58200d407e..ddc0a5fe5d 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 @@ -30,6 +30,8 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; + +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -47,8 +49,8 @@ import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import net.runelite.api.MenuEntry; import net.runelite.api.NPCDefinition; -import net.runelite.api.events.ClientTick; import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcActionChanged; import net.runelite.api.events.PlayerMenuOptionClicked; @@ -58,6 +60,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; @Singleton @Slf4j @@ -97,7 +100,8 @@ public class MenuManager private final Set hiddenEntries = new HashSet<>(); private final Map swaps = new HashMap<>(); - private MenuEntry leftClickEntry; + private MenuEntry leftClickEntry = null; + private ComparableEntry comparableEntry = null; @Inject private MenuManager(Client client, EventBus eventBus) @@ -144,48 +148,18 @@ public class MenuManager } @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) - { - int widgetId = event.getActionParam1(); - Collection options = managedMenuOptions.get(widgetId); - MenuEntry[] menuEntries = client.getMenuEntries(); - - for (WidgetMenuOption currentMenu : options) - { - if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget - { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(currentMenu.getMenuOption()); - menuEntry.setParam1(widgetId); - menuEntry.setTarget(currentMenu.getMenuTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); - } - } - } - - @Subscribe - private void onClientTick(ClientTick event) + public void onMenuOpened(MenuOpened event) { leftClickEntry = null; - if (client.isMenuOpen()) - { - return; - } - currentPriorityEntries.clear(); - client.sortMenuEntries(); - MenuEntry[] oldEntries = client.getMenuEntries(); + MenuEntry[] entries = client.getMenuEntries(); + + ArrayList oldEntries = Lists.newArrayList(entries); List newEntries = Lists.newArrayList(oldEntries); boolean shouldDeprioritize = false; - boolean modified = false; - prioritizer: for (MenuEntry entry : oldEntries) { @@ -214,63 +188,50 @@ public class MenuManager continue prioritizer; } } - } - if (newEntries.size() > 0) - { - MenuEntry entry = Iterables.getLast(newEntries); - - // Swap first matching entry to top - for (ComparableEntry src : swaps.keySet()) + if (newEntries.size() > 0) { - if (!src.matches(entry)) + MenuEntry last = Iterables.getLast(newEntries); + + // Swap first matching entry to top + for (ComparableEntry src : swaps.keySet()) { - continue; - } - - MenuEntry swapFrom = null; - - ComparableEntry from = swaps.get(src); - - for (MenuEntry e : newEntries) - { - if (from.matches(e)) + if (!src.matches(last)) { - swapFrom = e; - break; - } - } - - // Do not need to swap with itself - if (swapFrom != null && swapFrom != entry) - { - // Deprioritize entries if the swaps are not in similar type groups - if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) - { - shouldDeprioritize = true; + continue; } - int indexFrom = newEntries.indexOf(swapFrom); - int indexTo = newEntries.indexOf(entry); + MenuEntry swapFrom = null; - Collections.swap(newEntries, indexFrom, indexTo); + ComparableEntry from = swaps.get(src); - // Set force left click if entry was moved to first entry - if (indexTo == newEntries.size() - 1) + for (MenuEntry e : newEntries) { - swapFrom.setForceLeftClick(true); - entry.setForceLeftClick(false); + if (from.matches(e)) + { + swapFrom = e; + break; + } } - modified = true; + // Do not need to swap with itself + if (swapFrom != null && swapFrom != last) + { + // Deprioritize entries if the swaps are not in similar type groups + if ((swapFrom.getType() >= 1000 && last.getType() < 1000) || (last.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) + { + shouldDeprioritize = true; + } - // If this loop is placed in the 'prioritizer' block and the following break is removed, - // all swaps will be applied instead of only swapping the first one found to the first entry - break; + int indexFrom = newEntries.indexOf(swapFrom); + int indexTo = newEntries.indexOf(last); + + Collections.swap(newEntries, indexFrom, indexTo); + } } } } - + if (shouldDeprioritize) { for (MenuEntry entry : newEntries) @@ -285,15 +246,106 @@ public class MenuManager if (!priorityEntries.isEmpty()) { newEntries.addAll(currentPriorityEntries); - modified = true; } - if (modified) + event.setMenuEntries(newEntries.toArray(new MenuEntry[0])); + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + int widgetId = event.getActionParam1(); + Collection options = managedMenuOptions.get(widgetId); + MenuEntry[] menuEntries = client.getMenuEntries(); + + for (WidgetMenuOption currentMenu : options) { - leftClickEntry = newEntries.get(newEntries.size() - 1); + if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget + { + menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + + MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); + menuEntry.setOption(currentMenu.getMenuOption()); + menuEntry.setParam1(widgetId); + menuEntry.setTarget(currentMenu.getMenuTarget()); + menuEntry.setType(MenuAction.RUNELITE.getId()); + + client.setMenuEntries(menuEntries); + } } - client.setMenuEntries(newEntries.toArray(new MenuEntry[0])); + final MenuEntry entry = menuEntries[menuEntries.length - 1]; + + // Reset tracked entries + if (entry.getOption().equals("Cancel")) + { + comparableEntry = null; + leftClickEntry = null; + } + + if (leftClickEntry == null) + { + for (ComparableEntry p : priorityEntries) + { + if (p.matches(entry)) + { + leftClickEntry = entry; + comparableEntry = new ComparableEntry(entry); + return; + } + } + + for (ComparableEntry p : swaps.values()) + { + if (p.matches(entry)) + { + leftClickEntry = entry; + comparableEntry = new ComparableEntry(entry); + return; + } + } + } + + if (leftClickEntry != null && menuEntries.length > 1) + { + // No need to move the entry if it is already the first option + if (comparableEntry.matches(menuEntries[menuEntries.length - 1])) + { + return; + } + + // If the entry is not the second to last, we can't do a normal swap + if (!comparableEntry.matches(menuEntries[menuEntries.length - 2])) + { + int position = 0; + MenuEntry foundEntry = null; + + for (MenuEntry e : menuEntries) + { + if (e.getOption().equals(leftClickEntry.getOption()) + && e.getTarget().equals(leftClickEntry.getTarget())) + { + foundEntry = menuEntries[position]; + break; + } + position++; + } + + if (foundEntry != null) + { + menuEntries = ArrayUtils.remove(menuEntries, position); + menuEntries = ArrayUtils.insert(menuEntries.length, menuEntries, foundEntry); + } + } + else + { + ArrayUtils.swap(menuEntries, menuEntries.length - 2, menuEntries.length - 1); + } + + menuEntries[menuEntries.length - 1].setType(MenuAction.WIDGET_DEFAULT.getId()); + + client.setMenuEntries(menuEntries); + } } public void addPlayerMenuItem(String menuText) @@ -403,7 +455,6 @@ public class MenuManager if (leftClickEntry != null) { event.setMenuEntry(leftClickEntry); - leftClickEntry = null; } if (event.getMenuAction() != MenuAction.RUNELITE) From 77c78aa9707482638207fd0b243a79ec2f6b706e Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Mon, 1 Jul 2019 13:15:04 -0400 Subject: [PATCH 5/6] menumanager: utilize beforerender, make use of additional threads --- .../runelite/client/menus/MenuManager.java | 272 +++++++++++++----- 1 file changed, 201 insertions(+), 71 deletions(-) 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 ddc0a5fe5d..2fb5700fb3 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 @@ -31,24 +31,28 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; + +import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import net.runelite.api.MenuEntry; import net.runelite.api.NPCDefinition; +import net.runelite.api.events.BeforeRender; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; @@ -60,7 +64,6 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; @Singleton @Slf4j @@ -88,6 +91,7 @@ public class MenuManager private final Client client; private final EventBus eventBus; + private final Prioritizer prioritizer; //Maps the indexes that are being used to the menu option. private final Map playerMenuIndexMap = new HashMap<>(); @@ -98,16 +102,21 @@ public class MenuManager private final Set priorityEntries = new HashSet<>(); private final Set currentPriorityEntries = new HashSet<>(); private final Set hiddenEntries = new HashSet<>(); - + private final Set currentHiddenEntries = new HashSet<>(); private final Map swaps = new HashMap<>(); + private final Map currentSwaps = new HashMap<>(); + + private final LinkedHashSet entries = Sets.newLinkedHashSet(); + private final Map originalTypes = new HashMap<>(); + private MenuEntry leftClickEntry = null; - private ComparableEntry comparableEntry = null; @Inject private MenuManager(Client client, EventBus eventBus) { this.client = client; this.eventBus = eventBus; + this.prioritizer = new Prioritizer(); } /** @@ -153,10 +162,21 @@ public class MenuManager leftClickEntry = null; currentPriorityEntries.clear(); + currentHiddenEntries.clear(); - MenuEntry[] entries = client.getMenuEntries(); + // Need to reorder the list to normal, then rebuild with swaps + MenuEntry[] oldEntries = event.getMenuEntries(); + + for (MenuEntry entry : oldEntries) + { + if (originalTypes.containsKey(entry)) + { + entry.setType(originalTypes.get(entry)); + } + } + + client.sortMenuEntries(); - ArrayList oldEntries = Lists.newArrayList(entries); List newEntries = Lists.newArrayList(oldEntries); boolean shouldDeprioritize = false; @@ -191,12 +211,10 @@ public class MenuManager if (newEntries.size() > 0) { - MenuEntry last = Iterables.getLast(newEntries); - // Swap first matching entry to top for (ComparableEntry src : swaps.keySet()) { - if (!src.matches(last)) + if (!src.matches(entry)) { continue; } @@ -215,16 +233,16 @@ public class MenuManager } // Do not need to swap with itself - if (swapFrom != null && swapFrom != last) + if (swapFrom != null && swapFrom != entry) { // Deprioritize entries if the swaps are not in similar type groups - if ((swapFrom.getType() >= 1000 && last.getType() < 1000) || (last.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) + if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) { shouldDeprioritize = true; } int indexFrom = newEntries.indexOf(swapFrom); - int indexTo = newEntries.indexOf(last); + int indexTo = newEntries.indexOf(entry); Collections.swap(newEntries, indexFrom, indexTo); } @@ -273,81 +291,80 @@ public class MenuManager client.setMenuEntries(menuEntries); } } + } - final MenuEntry entry = menuEntries[menuEntries.length - 1]; - // Reset tracked entries - if (entry.getOption().equals("Cancel")) + + @Subscribe + public void onBeforeRender(BeforeRender event) + { + leftClickEntry = null; + + if (client.isMenuOpen()) { - comparableEntry = null; - leftClickEntry = null; + return; } + entries.clear(); + + entries.addAll(Arrays.asList(client.getMenuEntries())); + + if (entries.size() < 2) + { + return; + } + + currentPriorityEntries.clear(); + currentHiddenEntries.clear(); + currentSwaps.clear(); + originalTypes.clear(); + + prioritizer.prioritize(); + + while (prioritizer.isRunning()) + { + // wait + } + + entries.removeAll(currentHiddenEntries); + + + for (MenuEntry entry : currentPriorityEntries) + { + if (entries.contains(entry)) + { + leftClickEntry = entry; + originalTypes.put(leftClickEntry, leftClickEntry.getType()); + entries.remove(leftClickEntry); + entries.add(leftClickEntry); + Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); + break; + } + } + + if (leftClickEntry == null) { - for (ComparableEntry p : priorityEntries) - { - if (p.matches(entry)) - { - leftClickEntry = entry; - comparableEntry = new ComparableEntry(entry); - return; - } - } + MenuEntry first = Iterables.getLast(entries); - for (ComparableEntry p : swaps.values()) + for (ComparableEntry swap : currentSwaps.keySet()) { - if (p.matches(entry)) + if (swap.matches(first)) { - leftClickEntry = entry; - comparableEntry = new ComparableEntry(entry); - return; + leftClickEntry = currentSwaps.get(swap); + originalTypes.put(leftClickEntry, leftClickEntry.getType()); + entries.remove(leftClickEntry); + entries.add(leftClickEntry); + Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); + break; } } } - if (leftClickEntry != null && menuEntries.length > 1) - { - // No need to move the entry if it is already the first option - if (comparableEntry.matches(menuEntries[menuEntries.length - 1])) - { - return; - } - - // If the entry is not the second to last, we can't do a normal swap - if (!comparableEntry.matches(menuEntries[menuEntries.length - 2])) - { - int position = 0; - MenuEntry foundEntry = null; - - for (MenuEntry e : menuEntries) - { - if (e.getOption().equals(leftClickEntry.getOption()) - && e.getTarget().equals(leftClickEntry.getTarget())) - { - foundEntry = menuEntries[position]; - break; - } - position++; - } - - if (foundEntry != null) - { - menuEntries = ArrayUtils.remove(menuEntries, position); - menuEntries = ArrayUtils.insert(menuEntries.length, menuEntries, foundEntry); - } - } - else - { - ArrayUtils.swap(menuEntries, menuEntries.length - 2, menuEntries.length - 1); - } - - menuEntries[menuEntries.length - 1].setType(MenuAction.WIDGET_DEFAULT.getId()); - - client.setMenuEntries(menuEntries); - } + client.setMenuEntries(entries.toArray(new MenuEntry[0])); } + public void addPlayerMenuItem(String menuText) { Preconditions.checkNotNull(menuText); @@ -455,6 +472,7 @@ public class MenuManager if (leftClickEntry != null) { event.setMenuEntry(leftClickEntry); + leftClickEntry = null; } if (event.getMenuAction() != MenuAction.RUNELITE) @@ -780,4 +798,116 @@ public class MenuManager { hiddenEntries.remove(entry); } + + private class Prioritizer + { + private MenuEntry[] entries; + private AtomicInteger state = new AtomicInteger(0); + + boolean isRunning() + { + return state.get() != 0; + } + + void prioritize() + { + if (state.get() != 0) + { + return; + } + + entries = client.getMenuEntries(); + + state.set(3); + + if (!hiddenEntries.isEmpty()) + { + hiddenFinder.run(); + } + else + { + state.decrementAndGet(); + } + + if (!priorityEntries.isEmpty()) + { + priorityFinder.run(); + } + else + { + state.decrementAndGet(); + } + + if (!swaps.isEmpty()) + { + swapFinder.run(); + } + else + { + state.decrementAndGet(); + } + } + + private Thread hiddenFinder = new Thread() + { + @Override + public void run() + { + Arrays.stream(entries).parallel().forEach(entry -> + { + for (ComparableEntry p : hiddenEntries) + { + if (p.matches(entry)) + { + currentHiddenEntries.add(entry); + return; + } + } + }); + state.decrementAndGet(); + } + }; + + private Thread priorityFinder = new Thread() + { + @Override + public void run() + { + Arrays.stream(entries).parallel().forEach(entry -> + { + for (ComparableEntry p : priorityEntries) + { + if (p.matches(entry)) + { + currentPriorityEntries.add(entry); + return; + } + } + }); + + state.decrementAndGet(); + } + }; + + private Thread swapFinder = new Thread() + { + @Override + public void run() + { + Arrays.stream(entries).parallel().forEach(entry -> + { + for (Map.Entry p : swaps.entrySet()) + { + if (p.getValue().matches(entry)) + { + currentSwaps.put(p.getKey(), entry); + return; + } + } + }); + + state.decrementAndGet(); + } + }; + } } From fa30bcd48f13f0edf81f980713f2fcfd86fc8c7a Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Mon, 1 Jul 2019 14:35:15 -0400 Subject: [PATCH 6/6] menumanager: cleanup --- .../runelite/client/menus/MenuManager.java | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) 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 2fb5700fb3..4e4f9fb847 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 @@ -76,19 +76,6 @@ public class MenuManager private static final int IDX_UPPER = 8; static final Pattern LEVEL_PATTERN = Pattern.compile("\\(level-[0-9]*\\)"); - private static MenuEntry CANCEL() - { - MenuEntry cancel = new MenuEntry(); - cancel.setOption("Cancel"); - cancel.setTarget(""); - cancel.setIdentifier(0); - cancel.setType(MenuAction.CANCEL.getId()); - cancel.setParam0(0); - cancel.setParam1(0); - - return cancel; - } - private final Client client; private final EventBus eventBus; private final Prioritizer prioritizer; @@ -107,9 +94,9 @@ public class MenuManager private final Map currentSwaps = new HashMap<>(); private final LinkedHashSet entries = Sets.newLinkedHashSet(); - private final Map originalTypes = new HashMap<>(); private MenuEntry leftClickEntry = null; + private int leftClickType = -1; @Inject private MenuManager(Client client, EventBus eventBus) @@ -159,8 +146,6 @@ public class MenuManager @Subscribe public void onMenuOpened(MenuOpened event) { - leftClickEntry = null; - currentPriorityEntries.clear(); currentHiddenEntries.clear(); @@ -169,12 +154,16 @@ public class MenuManager for (MenuEntry entry : oldEntries) { - if (originalTypes.containsKey(entry)) + if (entry == leftClickEntry) { - entry.setType(originalTypes.get(entry)); + entry.setType(leftClickType); + break; } } + leftClickEntry = null; + leftClickType = -1; + client.sortMenuEntries(); List newEntries = Lists.newArrayList(oldEntries); @@ -299,6 +288,7 @@ public class MenuManager public void onBeforeRender(BeforeRender event) { leftClickEntry = null; + leftClickType = -1; if (client.isMenuOpen()) { @@ -317,7 +307,6 @@ public class MenuManager currentPriorityEntries.clear(); currentHiddenEntries.clear(); currentSwaps.clear(); - originalTypes.clear(); prioritizer.prioritize(); @@ -334,10 +323,10 @@ public class MenuManager if (entries.contains(entry)) { leftClickEntry = entry; - originalTypes.put(leftClickEntry, leftClickEntry.getType()); + leftClickType = entry.getType(); entries.remove(leftClickEntry); + leftClickEntry.setType(MenuAction.WIDGET_DEFAULT.getId()); entries.add(leftClickEntry); - Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); break; } } @@ -352,10 +341,10 @@ public class MenuManager if (swap.matches(first)) { leftClickEntry = currentSwaps.get(swap); - originalTypes.put(leftClickEntry, leftClickEntry.getType()); + leftClickType = leftClickEntry.getType(); entries.remove(leftClickEntry); + leftClickEntry.setType(MenuAction.WIDGET_DEFAULT.getId()); entries.add(leftClickEntry); - Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); break; } } @@ -469,8 +458,9 @@ public class MenuManager @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (leftClickEntry != null) + if (leftClickEntry != null && leftClickType != -1) { + leftClickEntry.setType(leftClickType); event.setMenuEntry(leftClickEntry); leftClickEntry = null; }