From 409d0dda7661468d0cc3c664894421bc7e17f1b2 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 4 Dec 2021 15:28:27 -0500 Subject: [PATCH 01/17] api: make MenuEntry an interface This adds a new createMenuEntry api method to make MenuEntries instead. Menu entries now have an associated callback called when they are clicked on, avoiding most plugins from having to hook separately to detect the menu click. Additionally get/set type has changed to take a MenuAction. --- .../main/java/net/runelite/api/Client.java | 7 + .../main/java/net/runelite/api/MenuEntry.java | 48 +++-- .../api/events/WidgetMenuOptionClicked.java | 54 ------ .../java/net/runelite/client/RuneLite.java | 1 - .../runelite/client/menus/MenuManager.java | 55 ++---- .../client/menus/WidgetMenuOption.java | 4 + .../plugins/banktags/BankTagsPlugin.java | 141 +++++++-------- .../plugins/banktags/tabs/TabInterface.java | 36 ++-- .../client/plugins/camera/CameraPlugin.java | 2 +- .../chathistory/ChatHistoryPlugin.java | 39 ++--- .../plugins/devtools/DevToolsPlugin.java | 1 - .../plugins/devtools/WidgetInspector.java | 14 +- .../friendnotes/FriendNotesPlugin.java | 76 +++----- .../grandexchange/GrandExchangePlugin.java | 3 +- .../grounditems/GroundItemsPlugin.java | 21 +-- .../groundmarkers/GroundMarkerPlugin.java | 65 +++---- .../GroundMarkerSharingManager.java | 44 +---- .../client/plugins/hiscore/HiscorePlugin.java | 64 +++---- .../instancemap/InstanceMapPlugin.java | 39 ++--- .../InteractHighlightOverlay.java | 2 +- .../inventorytags/InventoryTagsPlugin.java | 97 +++++------ .../plugins/itemprices/ItemPricesOverlay.java | 2 +- .../MenuEntrySwapperPlugin.java | 106 +++++------ .../mousehighlight/MouseHighlightOverlay.java | 2 +- .../npchighlight/NpcIndicatorsPlugin.java | 54 ++---- .../ObjectIndicatorsPlugin.java | 35 ++-- .../opponentinfo/OpponentInfoPlugin.java | 1 - .../PlayerIndicatorsPlugin.java | 42 ++--- .../client/plugins/wiki/WikiPlugin.java | 42 ++--- .../worldhopper/WorldHopperPlugin.java | 52 ++---- .../plugins/xptracker/XpTrackerPlugin.java | 60 ++----- .../client/ui/overlay/OverlayManager.java | 34 +--- .../client/ui/overlay/OverlayRenderer.java | 66 +++---- .../ui/overlay/worldmap/WorldMapOverlay.java | 56 ++---- .../client/menus/MenuManagerTest.java | 76 ++++---- .../runelite/client/menus/TestMenuEntry.java | 164 ++++++++++++++++++ .../MenuEntrySwapperPluginTest.java | 10 +- .../npchighlight/NpcIndicatorsPluginTest.java | 16 +- 38 files changed, 665 insertions(+), 966 deletions(-) delete mode 100644 runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java create mode 100644 runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java 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 5f1175fcdd..e53d03ec7f 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -593,6 +593,13 @@ public interface Client extends GameEngine */ World[] getWorldList(); + /** + * Create a new menu entry + * @param idx the index to create the menu entry at. Accepts negative indexes eg. -1 inserts at the end. + * @return the newly created menu entry + */ + MenuEntry createMenuEntry(int idx); + /** * Gets an array of currently open right-click menu entries that can be * clicked and activated. 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 e28165e603..6891927c4b 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -24,46 +24,72 @@ */ package net.runelite.api; -import lombok.Data; +import java.util.function.Consumer; /** * A menu entry in a right-click menu. */ -@Data -public class MenuEntry +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. */ - private int type; + 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; + boolean isForceLeftClick(); + MenuEntry setForceLeftClick(boolean forceLeftClick); + + /** + * Deprioritized menus are sorted in the menu to be below the other menu entries. + * @return + */ + boolean isDeprioritized(); + void setDeprioritized(boolean deprioritized); + + /** + * Set a callback to be called when this menu option is clicked + * @param callback + * @return + */ + MenuEntry onClick(Consumer callback); } diff --git a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java deleted file mode 100644 index d3a4dda748..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.api.events; - -import javax.annotation.Nullable; -import lombok.Data; -import net.runelite.api.widgets.WidgetInfo; - -/** - * A MenuManager widget menu was clicked. This event is fired only for MenuManager managed custom menus. - */ -@Data -public class WidgetMenuOptionClicked -{ - /** - * The clicked menu option. - */ - private String menuOption; - /** - * The clicked menu target. - */ - private String menuTarget; - /** - * The WidgetInfo of the widget that was clicked, if available. - */ - @Nullable - private WidgetInfo widget; - /** - * The widget id of the widget that was clicked. - */ - private int widgetId; -} diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index dde04da268..142c4570c3 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -326,7 +326,6 @@ public class RuneLite // Add core overlays WidgetOverlay.createOverlays(overlayManager, client).forEach(overlayManager::add); overlayManager.add(worldMapOverlay.get()); - eventBus.register(worldMapOverlay.get()); overlayManager.add(tooltipOverlay.get()); } 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 c6a952239a..2b77f99e13 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,10 @@ package net.runelite.client.menus; import com.google.common.base.Preconditions; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -38,9 +38,7 @@ import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.PlayerMenuOptionsChanged; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; @@ -55,7 +53,6 @@ public class MenuManager private static final int IDX_UPPER = 8; private final Client client; - private final EventBus eventBus; //Maps the indexes that are being used to the menu option. private final Map playerMenuIndexMap = new HashMap<>(); @@ -66,7 +63,6 @@ public class MenuManager private MenuManager(Client client, EventBus eventBus) { this.client = client; - this.eventBus = eventBus; eventBus.register(this); } @@ -74,10 +70,12 @@ public class MenuManager * Adds a CustomMenuOption to the list of managed menu options. * * @param customMenuOption The custom menu to add + * @param callback callback to be called when the menu is clicked */ - public void addManagedCustomMenu(WidgetMenuOption customMenuOption) + public void addManagedCustomMenu(WidgetMenuOption customMenuOption, Consumer callback) { managedMenuOptions.put(customMenuOption.getWidgetId(), customMenuOption); + customMenuOption.callback = callback; } /** @@ -122,11 +120,10 @@ public class MenuManager MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry[] newMenuEntries = Arrays.copyOf(menuEntries, menuEntries.length + options.size()); // Menu entries are sorted with higher-index entries appearing toward the top of the minimenu, so insert older // managed menu entries at higher indices and work backward for newer entries so newly-added entries appear at // the bottom - int insertIdx = newMenuEntries.length - 1; + int insertIdx = -1; for (WidgetMenuOption currentMenu : options) { // Exit if we've inserted the managed menu entries already @@ -135,16 +132,13 @@ public class MenuManager return; } - MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(currentMenu.getMenuOption()); - menuEntry.setParam1(widgetId); - menuEntry.setTarget(currentMenu.getMenuTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - newMenuEntries[insertIdx--] = menuEntry; + client.createMenuEntry(insertIdx--) + .setOption(currentMenu.getMenuOption()) + .setTarget(currentMenu.getMenuTarget()) + .setType(MenuAction.RUNELITE) + .setParam1(widgetId) + .onClick(currentMenu.callback); } - - client.setMenuEntries(newMenuEntries); } public void addPlayerMenuItem(String menuText) @@ -198,33 +192,6 @@ public class MenuManager addPlayerMenuItem(newIdx, menuText); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - int widgetId = event.getParam1(); - Collection options = managedMenuOptions.get(widgetId); - - for (WidgetMenuOption curMenuOption : options) - { - if (curMenuOption.getMenuTarget().equals(event.getMenuTarget()) - && curMenuOption.getMenuOption().equals(event.getMenuOption())) - { - WidgetMenuOptionClicked customMenu = new WidgetMenuOptionClicked(); - customMenu.setMenuOption(event.getMenuOption()); - customMenu.setMenuTarget(event.getMenuTarget()); - customMenu.setWidget(curMenuOption.getWidget()); - customMenu.setWidgetId(curMenuOption.getWidgetId()); - eventBus.post(customMenu); - return; - } - } - } - private void addPlayerMenuItem(int playerOptionIndex, String menuText) { client.getPlayerOptions()[playerOptionIndex] = menuText; diff --git a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java index 1f1a74606b..7727897f3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java @@ -25,9 +25,11 @@ package net.runelite.client.menus; import java.awt.Color; +import java.util.function.Consumer; import javax.annotation.Nullable; import lombok.Getter; import lombok.Setter; +import net.runelite.api.MenuEntry; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; @@ -65,6 +67,8 @@ public final class WidgetMenuOption @Getter private final int widgetId; + Consumer callback; + /** * Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options * 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 70088692c8..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 @@ -341,8 +341,6 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - MenuEntry[] entries = client.getMenuEntries(); - if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { @@ -357,87 +355,80 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener text += " (" + tagCount + ")"; } - MenuEntry editTags = new MenuEntry(); - editTags.setParam0(event.getActionParam0()); - editTags.setParam1(event.getActionParam1()); - editTags.setTarget(event.getTarget()); - editTags.setOption(text); - editTags.setType(MenuAction.RUNELITE.getId()); - editTags.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = editTags; - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(event.getTarget()) + .setOption(text) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(this::editTags); } tabInterface.handleAdd(event); } + private void editTags(MenuEntry entry) + { + int inventoryIndex = entry.getParam0(); + ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); + if (bankContainer == null) + { + return; + } + Item[] items = bankContainer.getItems(); + if (inventoryIndex < 0 || inventoryIndex >= items.length) + { + return; + } + Item item = bankContainer.getItems()[inventoryIndex]; + if (item == null) + { + return; + } + + int itemId = item.getId(); + ItemComposition itemComposition = itemManager.getItemComposition(itemId); + String name = itemComposition.getName(); + + // Get both tags and vartags and append * to end of vartags name + Collection tags = tagManager.getTags(itemId, false); + tagManager.getTags(itemId, true).stream() + .map(i -> i + "*") + .forEach(tags::add); + + String initialValue = Text.toCSV(tags); + + chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") + .addCharValidator(FILTERED_CHARS) + .value(initialValue) + .onDone((Consumer) (newValue) -> + clientThread.invoke(() -> + { + // Split inputted tags to vartags (ending with *) and regular tags + final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); + final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> + { + newTags.remove(s); + return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); + }).collect(Collectors.toList()); + + // And save them + tagManager.setTagString(itemId, Text.toCSV(newTags), false); + tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); + + // Check both previous and current tags in case the tag got removed in new tags or in case + // the tag got added in new tags + tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + })) + .build(); + } + @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() - && event.getMenuAction() == MenuAction.RUNELITE - && event.getMenuOption().startsWith(EDIT_TAGS_MENU_OPTION)) - { - event.consume(); - int inventoryIndex = event.getParam0(); - ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); - if (bankContainer == null) - { - return; - } - Item[] items = bankContainer.getItems(); - if (inventoryIndex < 0 || inventoryIndex >= items.length) - { - return; - } - Item item = bankContainer.getItems()[inventoryIndex]; - if (item == null) - { - return; - } - - int itemId = item.getId(); - ItemComposition itemComposition = itemManager.getItemComposition(itemId); - String name = itemComposition.getName(); - - // Get both tags and vartags and append * to end of vartags name - Collection tags = tagManager.getTags(itemId, false); - tagManager.getTags(itemId, true).stream() - .map(i -> i + "*") - .forEach(tags::add); - - String initialValue = Text.toCSV(tags); - - chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") - .addCharValidator(FILTERED_CHARS) - .value(initialValue) - .onDone((Consumer) (newValue) -> - clientThread.invoke(() -> - { - // Split inputted tags to vartags (ending with *) and regular tags - final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); - final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> - { - newTags.remove(s); - return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); - }).collect(Collectors.toList()); - - // And save them - tagManager.setTagString(itemId, Text.toCSV(newTags), false); - tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); - - // Check both previous and current tags in case the tag got removed in new tags or in case - // the tag got added in new tags - tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - })) - .build(); - } - else - { - tabInterface.handleClick(event); - } + tabInterface.handleClick(event); } @Subscribe 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 04c41c9d1b..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 @@ -618,38 +618,32 @@ public class TabInterface return; } - MenuEntry[] entries = client.getMenuEntries(); if (activeTab != null && event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { - entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries); - client.setMenuEntries(entries); + createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget()); } else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() && event.getOption().equals("Deposit inventory")) { - entries = createMenuEntry(event, TAG_INVENTORY, event.getTarget(), entries); + createMenuEntry(event, TAG_INVENTORY, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() && event.getOption().equals("Deposit worn items")) { - entries = createMenuEntry(event, TAG_GEAR, event.getTarget(), entries); + createMenuEntry(event, TAG_GEAR, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } } @@ -773,7 +767,6 @@ public class TabInterface { entry.setOption(TAG_SEARCH + Text.removeTags(entry.getTarget()) + (shiftDown ? VAR_TAG_SUFFIX : "")); entry.setTarget(draggedWidget.getName()); - client.setMenuEntries(entries); } if (entry.getOption().equals(SCROLL_UP)) @@ -1195,17 +1188,14 @@ public class TabInterface searchButtonBackground.setSpriteId(SpriteID.EQUIPMENT_SLOT_TILE); } - private static MenuEntry[] createMenuEntry(MenuEntryAdded event, String option, String target, MenuEntry[] entries) + private void createMenuEntry(MenuEntryAdded event, String option, String target) { - final MenuEntry entry = new MenuEntry(); - entry.setParam0(event.getActionParam0()); - entry.setParam1(event.getActionParam1()); - entry.setTarget(target); - entry.setOption(option); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = entry; - return entries; + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(target) + .setOption(option) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java index dfb29e8950..21c495b603 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java @@ -294,7 +294,7 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener { for (MenuEntry menuEntry : menuEntries) { - MenuAction action = MenuAction.of(menuEntry.getType()); + MenuAction action = menuEntry.getType(); switch (action) { case CANCEL: 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 ad6530a2e7..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 @@ -25,7 +25,6 @@ */ package net.runelite.client.plugins.chathistory; -import com.google.common.base.Strings; import com.google.common.collect.EvictingQueue; import com.google.inject.Provides; import java.awt.Toolkit; @@ -83,8 +82,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener private Queue messageQueue; private Deque friends; - private String currentMessage = null; - @Inject private Client client; @@ -121,7 +118,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener messageQueue = null; friends.clear(); friends = null; - currentMessage = null; keyManager.unregisterKeyListener(this); } @@ -195,7 +191,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener // Use second entry as first one can be walk here with transparent chatbox final MenuEntry entry = event.getMenuEntries()[event.getMenuEntries().length - 2]; - if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY.getId() && entry.getType() != MenuAction.RUNELITE.getId()) + if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY && entry.getType() != MenuAction.RUNELITE) { return; } @@ -236,16 +232,17 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - currentMessage = messageContents.getText(); + String currentMessage = messageContents.getText(); - final MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(COPY_TO_CLIPBOARD); - menuEntry.setTarget(entry.getTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - menuEntry.setParam0(entry.getParam0()); - menuEntry.setParam1(entry.getParam1()); - menuEntry.setIdentifier(entry.getIdentifier()); - client.setMenuEntries(ArrayUtils.insert(1, client.getMenuEntries(), menuEntry)); + client.createMenuEntry(1) + .setOption(COPY_TO_CLIPBOARD) + .setTarget(entry.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); + }); } @Subscribe @@ -258,11 +255,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener { clearChatboxHistory(ChatboxTab.of(event.getParam1())); } - else if (COPY_TO_CLIPBOARD.equals(menuOption) && !Strings.isNullOrEmpty(currentMessage)) - { - final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); - } } @Subscribe @@ -279,10 +271,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - final MenuEntry clearEntry = new MenuEntry(); - clearEntry.setTarget(""); - clearEntry.setType(MenuAction.RUNELITE_HIGH_PRIORITY.getId()); - clearEntry.setParam0(entry.getActionParam0()); + final MenuEntry clearEntry = client.createMenuEntry(-2) + .setType(MenuAction.RUNELITE_HIGH_PRIORITY); clearEntry.setParam1(entry.getActionParam1()); final StringBuilder optionBuilder = new StringBuilder(); @@ -299,9 +289,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener optionBuilder.append(CLEAR_HISTORY); clearEntry.setOption(optionBuilder.toString()); - - final MenuEntry[] menuEntries = client.getMenuEntries(); - client.setMenuEntries(ArrayUtils.insert(menuEntries.length - 1, menuEntries, clearEntry)); } private void clearMessageQueue(ChatboxTab tab) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index b9cc30c8dd..a1588594ab 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -488,7 +488,6 @@ public class DevToolsPlugin extends Plugin } entry.setTarget(entry.getTarget() + " " + ColorUtil.prependColorTag("(" + info + ")", JagexColors.MENU_TARGET)); - client.setMenuEntries(entries); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java index 2f361bc99b..6e27c99a35 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java @@ -487,7 +487,7 @@ class WidgetInspector extends DevToolsFrame client.setSpellSelected(false); ev.consume(); - Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction().getId(), ev.getParam0(), ev.getParam1()); + Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction(), ev.getParam0(), ev.getParam1()); if (target == null) { return; @@ -516,8 +516,8 @@ class WidgetInspector extends DevToolsFrame for (int i = 0; i < menuEntries.length; i++) { MenuEntry entry = menuEntries[i]; - if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET.getId() - && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET + && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET) { continue; } @@ -532,8 +532,6 @@ class WidgetInspector extends DevToolsFrame entry.setTarget(ColorUtil.wrapWithColorTag(name, color)); } - - client.setMenuEntries(menuEntries); } Color colorForWidget(int index, int length) @@ -543,9 +541,9 @@ class WidgetInspector extends DevToolsFrame return Color.getHSBColor(h, 1, 1); } - Object getWidgetOrWidgetItemForMenuOption(int type, int param0, int param1) + Object getWidgetOrWidgetItemForMenuOption(MenuAction type, int param0, int param1) { - if (type == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (type == MenuAction.SPELL_CAST_ON_WIDGET) { Widget w = client.getWidget(param1); if (param0 != -1) @@ -555,7 +553,7 @@ class WidgetInspector extends DevToolsFrame return w; } - else if (type == MenuAction.ITEM_USE_ON_WIDGET.getId()) + else if (type == MenuAction.ITEM_USE_ON_WIDGET) { Widget w = client.getWidget(param1); return w.getWidgetItem(param0); 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 db87e799a0..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 @@ -28,7 +28,6 @@ package net.runelite.client.plugins.friendnotes; import com.google.common.base.Strings; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.Color; import java.awt.image.BufferedImage; @@ -43,12 +42,10 @@ import net.runelite.api.GameState; import net.runelite.api.Ignore; import net.runelite.api.IndexedSprite; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Nameable; import net.runelite.api.ScriptID; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NameableNameChanged; import net.runelite.api.events.RemovedFriend; import net.runelite.api.events.ScriptCallbackEvent; @@ -245,16 +242,31 @@ public class FriendNotesPlugin extends Plugin setHoveredFriend(Text.toJagexName(Text.removeTags(event.getTarget()))); // Build "Add Note" or "Edit Note" menu entry - final MenuEntry addNote = new MenuEntry(); - addNote.setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE); - addNote.setType(MenuAction.RUNELITE.getId()); - addNote.setTarget(event.getTarget()); //Preserve color codes here - addNote.setParam0(event.getActionParam0()); - addNote.setParam1(event.getActionParam1()); + client.createMenuEntry(-1) + .setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + //Friends have color tags + final String sanitizedTarget = Text.toJagexName(Text.removeTags(e.getTarget())); + final String note = getFriendNote(sanitizedTarget); - // Add menu entry - final MenuEntry[] menuEntries = ObjectArrays.concat(client.getMenuEntries(), addNote); - client.setMenuEntries(menuEntries); + // Open the new chatbox input dialog + chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) + .value(Strings.nullToEmpty(note)) + .onDone((content) -> + { + if (content == null) + { + return; + } + + content = Text.removeTags(content).trim(); + log.debug("Set note for '{}': '{}'", sanitizedTarget, content); + setFriendNote(sanitizedTarget, content); + }).build(); + }); } else if (hoveredFriend != null) { @@ -262,46 +274,6 @@ public class FriendNotesPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - final int groupId = WidgetInfo.TO_GROUP(event.getParam1()); - - if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() || groupId == WidgetInfo.IGNORE_LIST.getGroupId()) - { - if (Strings.isNullOrEmpty(event.getMenuTarget())) - { - return; - } - - // Handle clicks on "Add Note" or "Edit Note" - if (event.getMenuOption().equals(ADD_NOTE) || event.getMenuOption().equals(EDIT_NOTE)) - { - event.consume(); - - //Friends have color tags - final String sanitizedTarget = Text.toJagexName(Text.removeTags(event.getMenuTarget())); - final String note = getFriendNote(sanitizedTarget); - - // Open the new chatbox input dialog - chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) - .value(Strings.nullToEmpty(note)) - .onDone((content) -> - { - if (content == null) - { - return; - } - - content = Text.removeTags(content).trim(); - log.debug("Set note for '{}': '{}'", sanitizedTarget, content); - setFriendNote(sanitizedTarget, content); - }).build(); - } - } - - } - @Subscribe public void onNameableNameChanged(NameableNameChanged event) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index 6075b23e11..697bf0d43b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -574,8 +574,7 @@ public class GrandExchangePlugin extends Plugin case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID: case WidgetID.SHOP_INVENTORY_GROUP_ID: menuEntry.setOption(SEARCH_GRAND_EXCHANGE); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(entries); + menuEntry.setType(MenuAction.RUNELITE); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 655ae55fc7..6490f4d8d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -115,14 +115,6 @@ public class GroundItemsPlugin extends Plugin static final int MAX_QUANTITY = 65535; // ItemID for coins private static final int COINS = ItemID.COINS_995; - // Ground item menu options - private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId(); - private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId(); - private static final int THIRD_OPTION = MenuAction.GROUND_ITEM_THIRD_OPTION.getId(); // this is Take - private static final int FOURTH_OPTION = MenuAction.GROUND_ITEM_FOURTH_OPTION.getId(); - private static final int FIFTH_OPTION = MenuAction.GROUND_ITEM_FIFTH_OPTION.getId(); - private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId(); - private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE); @@ -344,9 +336,10 @@ public class GroundItemsPlugin extends Plugin { MenuEntry menuEntry = menuEntries[i]; - int menuType = menuEntry.getType(); - if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION - || menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM) + MenuAction menuType = menuEntry.getType(); + if (menuType == MenuAction.GROUND_ITEM_FIRST_OPTION || menuType == MenuAction.GROUND_ITEM_SECOND_OPTION + || menuType == MenuAction.GROUND_ITEM_THIRD_OPTION || menuType == MenuAction.GROUND_ITEM_FOURTH_OPTION + || menuType == MenuAction.GROUND_ITEM_FIFTH_OPTION || menuType == MenuAction.SPELL_CAST_ON_GROUND_ITEM) { for (MenuEntryWithCount entryWCount : newEntries) { @@ -490,8 +483,8 @@ public class GroundItemsPlugin extends Plugin { if (config.itemHighlightMode() == ItemHighlightMode.MENU || config.itemHighlightMode() == ItemHighlightMode.BOTH) { - final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == CAST_ON_ITEM; - if (!(event.getOption().equals("Take") && event.getType() == THIRD_OPTION) && !telegrabEntry) + final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); + if (!(event.getOption().equals("Take") && event.getType() == MenuAction.GROUND_ITEM_THIRD_OPTION.getId()) && !telegrabEntry) { return; } @@ -548,8 +541,6 @@ public class GroundItemsPlugin extends Plugin { lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")"); } - - client.setMenuEntries(menuEntries); } } 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 850f383439..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 @@ -30,7 +30,6 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -44,13 +43,11 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Tile; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; @@ -243,48 +240,34 @@ public class GroundMarkerPlugin extends Plugin final GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getRegionX(), worldPoint.getRegionY(), client.getPlane(), null, null); final boolean exists = getPoints(regionId).contains(point); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + (exists ? 2 : 1)); - - MenuEntry mark = menuEntries[menuEntries.length - 1] = new MenuEntry(); - mark.setOption(exists ? UNMARK : MARK); - mark.setTarget(event.getTarget()); - mark.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-1) + .setOption(exists ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + markTile(target.getLocalLocation()); + } + }); if (exists) { - MenuEntry label = menuEntries[menuEntries.length - 2] = new MenuEntry(); - label.setOption(LABEL); - label.setTarget(event.getTarget()); - label.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-2) + .setOption(LABEL) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + labelTile(target); + } + }); } - - client.setMenuEntries(menuEntries); - } - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId()) - { - return; - } - - Tile target = client.getSelectedSceneTile(); - if (target == null) - { - return; - } - - final String option = event.getMenuOption(); - if (option.equals(MARK) || option.equals(UNMARK)) - { - markTile(target.getLocalLocation()); - } - else if (option.equals(LABEL)) - { - labelTile(target); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java index d311a51319..a7661ff202 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -45,11 +45,10 @@ import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; -import net.runelite.api.events.WidgetMenuOptionClicked; +import net.runelite.api.MenuEntry; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; @@ -82,13 +81,13 @@ class GroundMarkerSharingManager void addImportExportMenuOptions() { - menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION); - menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION); + menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION, this::exportGroundMarkers); + menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION, this::promptForImport); } void addClearMenuOption() { - menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION); + menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION, this::promptForClear); } void removeMenuOptions() @@ -98,36 +97,7 @@ class GroundMarkerSharingManager menuManager.removeManagedCustomMenu(CLEAR_MARKERS_OPTION); } - private boolean widgetMenuClickedEquals(final WidgetMenuOptionClicked event, final WidgetMenuOption target) - { - return event.getMenuTarget().equals(target.getMenuTarget()) && - event.getMenuOption().equals(target.getMenuOption()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - // ensure that the option clicked is the export markers option - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (widgetMenuClickedEquals(event, EXPORT_MARKERS_OPTION)) - { - exportGroundMarkers(); - } - else if (widgetMenuClickedEquals(event, IMPORT_MARKERS_OPTION)) - { - promptForImport(); - } - else if (widgetMenuClickedEquals(event, CLEAR_MARKERS_OPTION)) - { - promptForClear(); - } - } - - private void exportGroundMarkers() + private void exportGroundMarkers(MenuEntry menuEntry) { int[] regions = client.getMapRegions(); if (regions == null) @@ -156,7 +126,7 @@ class GroundMarkerSharingManager sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard."); } - private void promptForImport() + private void promptForImport(MenuEntry menuEntry) { final String clipboardText; try @@ -244,7 +214,7 @@ class GroundMarkerSharingManager sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard."); } - private void promptForClear() + private void promptForClear(MenuEntry entry) { int[] regions = client.getMapRegions(); if (regions == null) 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 95f12ec821..6123055d1c 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 @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.hiscore; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.util.EnumSet; @@ -39,7 +38,6 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.IconID; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Player; import net.runelite.api.WorldType; import net.runelite.api.events.ChatMessage; @@ -59,7 +57,6 @@ import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; import net.runelite.http.api.hiscore.HiscoreEndpoint; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "HiScore", @@ -169,46 +166,37 @@ public class HiscorePlugin extends Plugin || groupId == WidgetID.GROUP_IRON_GROUP_ID && (option.equals("Add friend") || option.equals("Remove friend") || option.equals("Remove ignore")) ) { - final MenuEntry lookup = new MenuEntry(); - lookup.setOption(LOOKUP); - lookup.setTarget(event.getTarget()); - lookup.setType(MenuAction.RUNELITE.getId()); - lookup.setParam0(event.getActionParam0()); - lookup.setParam1(event.getActionParam1()); - lookup.setIdentifier(event.getIdentifier()); - - insertMenuEntry(lookup, client.getMenuEntries()); + client.createMenuEntry(-2) + .setOption(LOOKUP) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(e -> + { + // Determine proper endpoint from player name. + // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. + HiscoreEndpoint endpoint = findHiscoreEndpointFromPlayerName(e.getTarget()); + String target = Text.removeTags(e.getTarget()); + lookupPlayer(target, endpoint); + }); } } @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER) - && event.getMenuOption().equals(LOOKUP)) + if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER && event.getMenuOption().equals(LOOKUP)) { - final String target; - HiscoreEndpoint endpoint; - if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + // The player id is included in the event, so we can use that to get the player name, + // which avoids having to parse out the combat level and any icons preceding the name. + Player player = client.getCachedPlayers()[event.getId()]; + if (player == null) { - // The player id is included in the event, so we can use that to get the player name, - // which avoids having to parse out the combat level and any icons preceding the name. - Player player = client.getCachedPlayers()[event.getId()]; - if (player == null) - { - return; - } + return; + } - endpoint = getWorldEndpoint(); - target = player.getName(); - } - else - { - // Determine proper endpoint from player name. - // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. - endpoint = findHiscoreEndpointFromPlayerName(event.getMenuTarget()); - target = Text.removeTags(event.getMenuTarget()); - } + String target = player.getName(); + HiscoreEndpoint endpoint = getWorldEndpoint(); lookupPlayer(target, endpoint); } @@ -236,14 +224,6 @@ public class HiscorePlugin extends Plugin localHiscoreEndpoint = findHiscoreEndpointFromLocalPlayer(); } - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - client.setMenuEntries(newMenu); - } - private void lookupPlayer(String playerName, HiscoreEndpoint endpoint) { SwingUtilities.invokeLater(() -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java index f5cc4b6a51..8ed901350a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.instancemap; import com.google.inject.Binder; import javax.inject.Inject; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.WidgetMenuOptionClicked; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyManager; @@ -72,7 +71,17 @@ public class InstanceMapPlugin extends Plugin private void addCustomOptions() { - menuManager.addManagedCustomMenu(openMapOption); + menuManager.addManagedCustomMenu(openMapOption, entry -> + { + if (overlay.isMapShown()) + { + closeMap(); + } + else + { + showMap(); + } + }); } private void removeCustomOptions() @@ -107,32 +116,6 @@ public class InstanceMapPlugin extends Plugin overlay.onGameStateChange(event); } - private boolean clickedOptionEquals(WidgetMenuOptionClicked event, WidgetMenuOption widgetMenuOption) - { - return event.getMenuOption().equals(widgetMenuOption.getMenuOption()) && event.getMenuTarget().equals(widgetMenuOption.getMenuTarget()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (clickedOptionEquals(event, openMapOption)) - { - if (overlay.isMapShown()) - { - closeMap(); - } - else - { - showMap(); - } - } - } - public void showMap() { overlay.setShowMap(true); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java index a5dd9c95da..0a14053e36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java @@ -79,7 +79,7 @@ class InteractHighlightOverlay extends Overlay } MenuEntry top = menuEntries[menuEntries.length - 1]; - MenuAction menuAction = MenuAction.of(top.getType()); + MenuAction menuAction = top.getType(); switch (menuAction) { 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 cdbf26a845..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 @@ -28,14 +28,13 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.inject.Provides; import java.awt.Color; +import java.util.Arrays; import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.events.MenuOpened; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -46,7 +45,6 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; -import net.runelite.client.util.Text; @PluginDescriptor( name = "Inventory Tags", @@ -157,44 +155,11 @@ public class InventoryTagsPlugin extends Plugin } } - @Subscribe - public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - editorMode = event.getMenuOption().equals(CONFIGURE) && Text.removeTags(event.getMenuTarget()).equals(MENU_TARGET); - refreshInventoryMenuOptions(); - } - } - - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - final String selectedMenu = Text.removeTags(event.getMenuTarget()); - - if (event.getMenuOption().equals(MENU_SET)) - { - setTag(event.getId(), selectedMenu); - } - else if (event.getMenuOption().equals(MENU_REMOVE)) - { - unsetTag(event.getId()); - } - } - @Subscribe public void onMenuOpened(final MenuOpened event) { final MenuEntry firstEntry = event.getFirstEntry(); - - if (firstEntry == null) + if (firstEntry == null || !editorMode) { return; } @@ -202,7 +167,7 @@ public class InventoryTagsPlugin extends Plugin final int widgetId = firstEntry.getParam1(); // Inventory item menu - if (widgetId == WidgetInfo.INVENTORY.getId() && editorMode) + if (widgetId == WidgetInfo.INVENTORY.getId()) { int itemId = firstEntry.getIdentifier(); @@ -211,26 +176,30 @@ public class InventoryTagsPlugin extends Plugin return; } - MenuEntry[] menuList = new MenuEntry[GROUPS.size() + 1]; - int num = 0; - - // preserve the 'Cancel' option as the client will reuse the first entry for Cancel and only resets option/action - menuList[num++] = event.getMenuEntries()[0]; + // Set menu to only be Cancel + client.setMenuEntries(Arrays.copyOf(client.getMenuEntries(), 1)); for (final String groupName : GROUPS) { final String group = getTag(itemId); - final MenuEntry newMenu = new MenuEntry(); final Color color = getGroupNameColor(groupName); - newMenu.setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET); - newMenu.setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))); - newMenu.setIdentifier(itemId); - newMenu.setParam1(widgetId); - newMenu.setType(MenuAction.RUNELITE.getId()); - menuList[num++] = newMenu; - } - client.setMenuEntries(menuList); + client.createMenuEntry(-1) + .setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET) + .setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (e.getOption().equals(MENU_SET)) + { + setTag(itemId, groupName); + } + else + { + unsetTag(itemId); + } + }); + } } } @@ -270,15 +239,27 @@ public class InventoryTagsPlugin extends Plugin removeInventoryMenuOptions(); if (editorMode) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE, this::save); } else { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE, this::configure); } } + + private void save(MenuEntry menuEntry) + { + editorMode = false; + refreshInventoryMenuOptions(); + } + + private void configure(MenuEntry menuEntry) + { + editorMode = true; + refreshInventoryMenuOptions(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java index ea33e614f8..bea5de5af5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java @@ -90,7 +90,7 @@ class ItemPricesOverlay extends Overlay } final MenuEntry menuEntry = menuEntries[last]; - final MenuAction action = MenuAction.of(menuEntry.getType()); + final MenuAction action = menuEntry.getType(); final int widgetId = menuEntry.getParam1(); final int groupId = WidgetInfo.TO_GROUP(widgetId); final boolean isAlching = menuEntry.getOption().equals("Cast") && menuEntry.getTarget().contains("High Level Alchemy"); 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 56cb315caf..68ecf39f3b 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 @@ -55,7 +55,6 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.PostItemComposition; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; @@ -74,7 +73,6 @@ import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfi import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.MorytaniaLegsMode; import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.RadasBlessingMode; import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "Menu Entry Swapper", @@ -506,24 +504,6 @@ public class MenuEntrySwapperPlugin extends Plugin clientThread.invoke(this::resetItemCompositionCache); } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - String option = event.getMenuOption(); - String target = Text.removeTags(event.getMenuTarget()); - if ((option.equals(CONFIGURE) || option.equals(SAVE)) && (target.equals(LEFT_CLICK_MENU_TARGET) || target.equals(SHIFT_CLICK_MENU_TARGET))) - { - configuringShiftClick = option.equals(CONFIGURE) && target.equals(SHIFT_CLICK_MENU_TARGET); - configuringLeftClick = option.equals(CONFIGURE) && target.equals(LEFT_CLICK_MENU_TARGET); - rebuildCustomizationMenus(); - } - } - } - @Subscribe public void onMenuOpened(MenuOpened event) { @@ -591,11 +571,11 @@ public class MenuEntrySwapperPlugin extends Plugin for (MenuEntry entry : entries) { - final MenuAction menuAction = MenuAction.of(entry.getType()); + final MenuAction menuAction = entry.getType(); if (ITEM_MENU_TYPES.contains(menuAction) && entry.getIdentifier() == itemId) { - entry.setType(MenuAction.RUNELITE.getId()); + entry.setType(MenuAction.RUNELITE); if (activeAction == menuAction) { @@ -604,13 +584,11 @@ public class MenuEntrySwapperPlugin extends Plugin } } - final MenuEntry resetShiftClickEntry = new MenuEntry(); - resetShiftClickEntry.setOption(RESET); - resetShiftClickEntry.setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET); - resetShiftClickEntry.setIdentifier(itemId); - resetShiftClickEntry.setParam1(widgetId); - resetShiftClickEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(ArrayUtils.addAll(entries, resetShiftClickEntry)); + client.createMenuEntry(-1) + .setOption(RESET) + .setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET) + .setType(MenuAction.RUNELITE) + .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)); } @Subscribe @@ -636,8 +614,8 @@ public class MenuEntrySwapperPlugin extends Plugin final int opId = isDepositBoxPlayerInventory ? shiftDepositMode.getIdentifierDepositBox() : isChambersOfXericStorageUnitPlayerInventory ? shiftDepositMode.getIdentifierChambersStorageUnit() : shiftDepositMode.getIdentifier(); - final int actionId = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY.getId() : MenuAction.CC_OP.getId(); - bankModeSwap(actionId, opId); + final MenuAction action = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY : MenuAction.CC_OP; + bankModeSwap(action, opId); } // Swap to shift-click withdraw behavior @@ -647,22 +625,23 @@ public class MenuEntrySwapperPlugin extends Plugin && menuEntryAdded.getOption().startsWith("Withdraw")) { ShiftWithdrawMode shiftWithdrawMode = config.bankWithdrawShiftClick(); - final int actionId, opId; + final MenuAction action; + final int opId; if (widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_PRIVATE_GROUP_ID || widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_SHARED_GROUP_ID) { - actionId = MenuAction.CC_OP.getId(); + action = MenuAction.CC_OP; opId = shiftWithdrawMode.getIdentifierChambersStorageUnit(); } else { - actionId = shiftWithdrawMode.getMenuAction().getId(); + action = shiftWithdrawMode.getMenuAction(); opId = shiftWithdrawMode.getIdentifier(); } - bankModeSwap(actionId, opId); + bankModeSwap(action, opId); } } - private void bankModeSwap(int entryTypeId, int entryIdentifier) + private void bankModeSwap(MenuAction entryType, int entryIdentifier) { MenuEntry[] menuEntries = client.getMenuEntries(); @@ -670,10 +649,10 @@ public class MenuEntrySwapperPlugin extends Plugin { MenuEntry entry = menuEntries[i]; - if (entry.getType() == entryTypeId && entry.getIdentifier() == entryIdentifier) + if (entry.getType() == entryType && entry.getIdentifier() == entryIdentifier) { // Raise the priority of the op so it doesn't get sorted later - entry.setType(MenuAction.CC_OP.getId()); + entry.setType(MenuAction.CC_OP); menuEntries[i] = menuEntries[menuEntries.length - 1]; menuEntries[menuEntries.length - 1] = entry; @@ -703,17 +682,6 @@ public class MenuEntrySwapperPlugin extends Plugin String target = event.getMenuTarget(); ItemComposition itemComposition = itemManager.getItemComposition(itemId); - if (option.equals(RESET) && target.equals(SHIFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(true, itemId); - return; - } - if (option.equals(RESET) && target.equals(LEFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(false, itemId); - return; - } - if (!itemComposition.getName().equals(Text.removeTags(target))) { return; @@ -741,7 +709,7 @@ public class MenuEntrySwapperPlugin extends Plugin private void swapMenuEntry(MenuEntry[] menuEntries, int index, MenuEntry menuEntry) { final int eventId = menuEntry.getIdentifier(); - final MenuAction menuAction = MenuAction.of(menuEntry.getType()); + final MenuAction menuAction = menuEntry.getType(); final String option = Text.removeTags(menuEntry.getOption()).toLowerCase(); final String target = Text.removeTags(menuEntry.getTarget()).toLowerCase(); final NPC hintArrowNpc = client.getHintArrowNpc(); @@ -968,31 +936,31 @@ public class MenuEntrySwapperPlugin extends Plugin removeCusomizationMenus(); if (configuringLeftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC, this::save); } else if (configuringShiftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC, this::save); } else { // Left click if (config.leftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC, this::configure); } // Shift click if (config.shiftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC, this::configure); } } } @@ -1001,4 +969,18 @@ public class MenuEntrySwapperPlugin extends Plugin { return client.isKeyPressed(KeyCode.KC_SHIFT); } + + private void save(MenuEntry menuEntry) + { + configuringLeftClick = configuringShiftClick = false; + rebuildCustomizationMenus(); + } + + private void configure(MenuEntry menuEntry) + { + String target = Text.removeTags(menuEntry.getTarget()); + configuringShiftClick = target.equals(SHIFT_CLICK_MENU_TARGET); + configuringLeftClick = target.equals(LEFT_CLICK_MENU_TARGET); + rebuildCustomizationMenus(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java index 1e56b743eb..f9355f0aa5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java @@ -108,7 +108,7 @@ class MouseHighlightOverlay extends Overlay MenuEntry menuEntry = menuEntries[last]; String target = menuEntry.getTarget(); String option = menuEntry.getOption(); - MenuAction type = MenuAction.of(menuEntry.getType()); + MenuAction type = menuEntry.getType(); if (type == MenuAction.RUNELITE_OVERLAY || type == MenuAction.CC_OP_LOW_PRIORITY) { 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 c2fb671c10..ed736f728a 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 @@ -31,7 +31,6 @@ import com.google.inject.Provides; import java.awt.Color; import java.time.Instant; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -57,7 +56,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.GraphicsObjectCreated; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; @@ -271,7 +269,6 @@ public class NpcIndicatorsPlugin extends Plugin final MenuEntry menuEntry = menuEntries[menuEntries.length - 1]; final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color); menuEntry.setTarget(target); - client.setMenuEntries(menuEntries); } } else if (menuAction == MenuAction.EXAMINE_NPC && client.isKeyPressed(KeyCode.KC_SHIFT)) @@ -291,48 +288,29 @@ public class NpcIndicatorsPlugin extends Plugin .filter(highlight -> !highlight.equalsIgnoreCase(npcName)) .anyMatch(highlight -> WildcardMatcher.matches(highlight, npcName)); - MenuEntry[] menuEntries = client.getMenuEntries(); - // Only add Untag-All option to npcs not highlighted by a wildcard entry, because untag-all will not remove wildcards if (!matchesList) { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 2); - final MenuEntry tagAllEntry = menuEntries[menuEntries.length - 2] = new MenuEntry(); - tagAllEntry.setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL); - tagAllEntry.setTarget(event.getTarget()); - tagAllEntry.setParam0(event.getActionParam0()); - tagAllEntry.setParam1(event.getActionParam1()); - tagAllEntry.setIdentifier(event.getIdentifier()); - tagAllEntry.setType(MenuAction.RUNELITE.getId()); - } - else - { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + client.createMenuEntry(-1) + .setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag); } - final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - tagEntry.setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG); - tagEntry.setTarget(event.getTarget()); - tagEntry.setParam0(event.getActionParam0()); - tagEntry.setParam1(event.getActionParam1()); - tagEntry.setIdentifier(event.getIdentifier()); - tagEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag); } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked click) + private void tag(MenuEntry entry) { - if (click.getMenuAction() != MenuAction.RUNELITE || - !(click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG) || - click.getMenuOption().equals(TAG_ALL) || click.getMenuOption().equals(UNTAG_ALL))) - { - return; - } - - final int id = click.getId(); + final int id = entry.getIdentifier(); final NPC[] cachedNPCs = client.getCachedNPCs(); final NPC npc = cachedNPCs[id]; @@ -341,7 +319,7 @@ public class NpcIndicatorsPlugin extends Plugin return; } - if (click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG)) + if (entry.getOption().equals(TAG) || entry.getOption().equals(UNTAG)) { final boolean removed = npcTags.remove(id); @@ -371,8 +349,6 @@ public class NpcIndicatorsPlugin extends Plugin // this trips a config change which triggers the overlay rebuild updateNpcsToHighlight(name); } - - click.consume(); } @Subscribe 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 826eb725da..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 @@ -31,7 +31,6 @@ import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.awt.Color; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -65,7 +64,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; @@ -230,35 +228,26 @@ public class ObjectIndicatorsPlugin extends Plugin return; } - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK); - menuEntry.setTarget(event.getTarget()); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(event.getActionParam1()); - menuEntry.setIdentifier(event.getIdentifier()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::markObject); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void markObject(MenuEntry entry) { - if (event.getMenuAction() != MenuAction.RUNELITE - || !(event.getMenuOption().equals(MARK) || event.getMenuOption().equals(UNMARK))) - { - return; - } - Scene scene = client.getScene(); Tile[][][] tiles = scene.getTiles(); - final int x = event.getParam0(); - final int y = event.getParam1(); + final int x = entry.getParam0(); + final int y = entry.getParam1(); final int z = client.getPlane(); final Tile tile = tiles[z][x][y]; - TileObject object = findTileObject(tile, event.getId()); + TileObject object = findTileObject(tile, entry.getIdentifier()); if (object == null) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index 4d58b924d1..330f4dfb42 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -184,7 +184,6 @@ public class OpponentInfoPlugin extends Plugin { MenuEntry[] menuEntries = client.getMenuEntries(); menuEntries[menuEntries.length - 1].setTarget("*" + menuEntries[menuEntries.length - 1].getTarget()); - client.setMenuEntries(menuEntries); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java index df72925bb8..eaa841a620 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java @@ -31,8 +31,8 @@ import lombok.Value; import net.runelite.api.Client; import net.runelite.api.FriendsChatRank; import static net.runelite.api.FriendsChatRank.UNRANKED; +import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; -import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; @@ -118,29 +118,23 @@ public class PlayerIndicatorsPlugin extends Plugin } MenuEntry[] menuEntries = client.getMenuEntries(); - boolean modified = false; for (MenuEntry entry : menuEntries) { - int type = entry.getType(); + MenuAction type = entry.getType(); - if (type >= MENU_ACTION_DEPRIORITIZE_OFFSET) - { - type -= MENU_ACTION_DEPRIORITIZE_OFFSET; - } - - if (type == WALK.getId() - || type == SPELL_CAST_ON_PLAYER.getId() - || type == ITEM_USE_ON_PLAYER.getId() - || type == PLAYER_FIRST_OPTION.getId() - || type == PLAYER_SECOND_OPTION.getId() - || type == PLAYER_THIRD_OPTION.getId() - || type == PLAYER_FOURTH_OPTION.getId() - || type == PLAYER_FIFTH_OPTION.getId() - || type == PLAYER_SIXTH_OPTION.getId() - || type == PLAYER_SEVENTH_OPTION.getId() - || type == PLAYER_EIGTH_OPTION.getId() - || type == RUNELITE_PLAYER.getId()) + if (type == WALK + || type == SPELL_CAST_ON_PLAYER + || type == ITEM_USE_ON_PLAYER + || type == PLAYER_FIRST_OPTION + || type == PLAYER_SECOND_OPTION + || type == PLAYER_THIRD_OPTION + || type == PLAYER_FOURTH_OPTION + || type == PLAYER_FIFTH_OPTION + || type == PLAYER_SIXTH_OPTION + || type == PLAYER_SEVENTH_OPTION + || type == PLAYER_EIGTH_OPTION + || type == RUNELITE_PLAYER) { Player[] players = client.getCachedPlayers(); Player player = null; @@ -149,7 +143,7 @@ public class PlayerIndicatorsPlugin extends Plugin // 'Walk here' identifiers are offset by 1 because the default // identifier for this option is 0, which is also a player index. - if (type == WALK.getId()) + if (type == WALK) { identifier--; } @@ -175,14 +169,8 @@ public class PlayerIndicatorsPlugin extends Plugin String newTarget = decorateTarget(oldTarget, decorations); entry.setTarget(newTarget); - modified = true; } } - - if (modified) - { - client.setMenuEntries(menuEntries); - } } private Decorations getDecorations(Player player) 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 241ebc9809..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 @@ -70,7 +70,7 @@ import okhttp3.HttpUrl; ) public class WikiPlugin extends Plugin { - static final HttpUrl WIKI_BASE = HttpUrl.parse("https://oldschool.runescape.wiki"); + static final HttpUrl WIKI_BASE = HttpUrl.get("https://oldschool.runescape.wiki"); static final HttpUrl WIKI_API = WIKI_BASE.newBuilder().addPathSegments("api.php").build(); static final String UTM_SORUCE_KEY = "utm_source"; static final String UTM_SORUCE_VALUE = "runelite"; @@ -335,20 +335,6 @@ public class WikiPlugin extends Plugin LinkBrowser.browse(url.toString()); return; } - - if (ev.getMenuAction() == MenuAction.RUNELITE) - { - switch (ev.getMenuOption()) - { - case MENUOP_WIKI: - LinkBrowser.browse(WIKI_BASE.newBuilder() - .addPathSegment("w") - .addPathSegment(Text.removeTags(ev.getMenuTarget())) - .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) - .build().toString()); - - } - } } private void openSearchInput() @@ -372,17 +358,17 @@ public class WikiPlugin extends Plugin { int widgetIndex = event.getActionParam0(); int widgetID = event.getActionParam1(); - MenuEntry[] menuEntries = client.getMenuEntries(); if (wikiSelected && event.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) { + MenuEntry[] menuEntries = client.getMenuEntries(); Widget w = getWidget(widgetID, widgetIndex); if (w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1) { for (int ourEntry = menuEntries.length - 1;ourEntry >= 0; ourEntry--) { MenuEntry entry = menuEntries[ourEntry]; - if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET) { int id = itemManager.canonicalize(w.getItemId()); String name = itemManager.getItemComposition(id).getName(); @@ -390,7 +376,6 @@ public class WikiPlugin extends Plugin break; } } - client.setMenuEntries(menuEntries); } else { @@ -400,7 +385,7 @@ public class WikiPlugin extends Plugin MenuEntry[] oldEntries = menuEntries; menuEntries = Arrays.copyOf(menuEntries, menuEntries.length - 1); for (int ourEntry = oldEntries.length - 1; - ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId(); + ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET; ourEntry--) { menuEntries[ourEntry - 1] = oldEntries[ourEntry]; @@ -425,16 +410,15 @@ public class WikiPlugin extends Plugin return; } - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(action.replace("View ", "").replace(" guide", "")); - menuEntry.setOption(MENUOP_WIKI); - menuEntry.setParam0(widgetIndex); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setTarget(action.replace("View ", "").replace(" guide", "")) + .setOption(MENUOP_WIKI) + .setType(MenuAction.RUNELITE) + .onClick(ev -> LinkBrowser.browse(WIKI_BASE.newBuilder() + .addPathSegment("w") + .addPathSegment(Text.removeTags(ev.getTarget())) + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) + .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 ef3bcaf423..109095545b 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 @@ -28,7 +28,6 @@ package net.runelite.client.plugins.worldhopper; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.Instant; @@ -54,7 +53,6 @@ import net.runelite.api.FriendsChatManager; import net.runelite.api.FriendsChatMember; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NameableContainer; import net.runelite.api.Varbits; import net.runelite.api.clan.ClanChannel; @@ -63,7 +61,6 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WorldListLoad; import net.runelite.api.widgets.WidgetInfo; @@ -92,7 +89,6 @@ import net.runelite.client.util.WorldUtil; import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldType; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "World Hopper", @@ -397,43 +393,19 @@ public class WorldHopperPlugin extends Plugin return; } - final MenuEntry hopTo = new MenuEntry(); - hopTo.setOption(HOP_TO); - hopTo.setTarget(event.getTarget()); - hopTo.setType(MenuAction.RUNELITE.getId()); - hopTo.setParam0(event.getActionParam0()); - hopTo.setParam1(event.getActionParam1()); + client.createMenuEntry(after ? -2 : -1) + .setOption(HOP_TO) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + ChatPlayer p = getChatPlayerFromName(e.getTarget()); - insertMenuEntry(hopTo, client.getMenuEntries(), after); - } - } - - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries, boolean after) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - - if (after) - { - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - } - - client.setMenuEntries(newMenu); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE || !event.getMenuOption().equals(HOP_TO)) - { - return; - } - - ChatPlayer player = getChatPlayerFromName(event.getMenuTarget()); - - if (player != null) - { - hop(player.getWorld()); + if (p != null) + { + hop(p.getWorld()); + } + }); } } 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 7433a81323..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 @@ -32,7 +32,6 @@ import com.google.inject.Binder; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.temporal.ChronoUnit; -import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Objects; @@ -45,7 +44,6 @@ import net.runelite.api.Client; import net.runelite.api.Experience; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NPC; import net.runelite.api.Player; import net.runelite.api.Skill; @@ -54,7 +52,6 @@ import net.runelite.api.WorldType; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.StatChanged; import net.runelite.api.widgets.WidgetID; @@ -521,48 +518,21 @@ public class XpTrackerPlugin extends Plugin final String skillText = event.getOption().split(" ")[1]; final Skill skill = Skill.valueOf(Text.removeTags(skillText).toUpperCase()); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(skillText); - menuEntry.setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() - || TO_GROUP(event.getParam1()) != WidgetID.SKILLS_GROUP_ID) - { - return; - } - - final Skill skill; - try - { - skill = Skill.valueOf(Text.removeTags(event.getMenuTarget()).toUpperCase()); - } - catch (IllegalArgumentException ex) - { - log.debug(null, ex); - return; - } - - switch (event.getMenuOption()) - { - case MENUOP_ADD_CANVAS_TRACKER: - addOverlay(skill); - break; - case MENUOP_REMOVE_CANVAS_TRACKER: - removeOverlay(skill); - break; - } + client.createMenuEntry(-1) + .setTarget(skillText) + .setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (hasOverlay(skill)) + { + removeOverlay(skill); + } + else + { + addOverlay(skill); + } + }); } XpStateSingle getSkillState(Skill skill) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java index bea3f9d280..31d428ceed 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java @@ -40,17 +40,13 @@ import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; -import net.runelite.api.MenuAction; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PluginChanged; /** @@ -108,14 +104,12 @@ public class OverlayManager private ArrayListMultimap overlayMap = ArrayListMultimap.create(); private final ConfigManager configManager; - private final EventBus eventBus; private final RuneLiteConfig runeLiteConfig; @Inject - private OverlayManager(final ConfigManager configManager, final EventBus eventBus, final RuneLiteConfig runeLiteConfig) + private OverlayManager(final ConfigManager configManager, final RuneLiteConfig runeLiteConfig) { this.configManager = configManager; - this.eventBus = eventBus; this.runeLiteConfig = runeLiteConfig; } @@ -137,32 +131,6 @@ public class OverlayManager rebuildOverlayLayers(); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - MenuAction menuAction = event.getMenuAction(); - if (menuAction != MenuAction.RUNELITE_OVERLAY && menuAction != MenuAction.RUNELITE_OVERLAY_CONFIG) - { - return; - } - - event.consume(); - - Overlay overlay = overlays.get(event.getId()); - if (overlay != null) - { - List menuEntries = overlay.getMenuEntries(); - OverlayMenuEntry overlayMenuEntry = menuEntries.stream() - .filter(me -> me.getOption().equals(event.getMenuOption())) - .findAny() - .orElse(null); - if (overlayMenuEntry != null) - { - eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay)); - } - } - } - /** * Gets all of the overlays on a layer sorted by priority and position * 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 99b75c0255..d673faba77 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 @@ -49,7 +49,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; -import net.runelite.api.MenuEntry; import net.runelite.api.Varbits; import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ClientTick; @@ -60,6 +59,7 @@ import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseAdapter; @@ -86,10 +86,12 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private static final Color MOVING_OVERLAY_ACTIVE_COLOR = new Color(255, 255, 0, 200); private static final Color MOVING_OVERLAY_TARGET_COLOR = Color.RED; private static final Color MOVING_OVERLAY_RESIZING_COLOR = new Color(255, 0, 255, 200); + private final Client client; private final OverlayManager overlayManager; private final RuneLiteConfig runeLiteConfig; private final ClientUI clientUI; + private final EventBus eventBus; // Overlay movement variables private final Point overlayOffset = new Point(); @@ -101,7 +103,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private boolean inOverlayResizingMode; private boolean inOverlayDraggingMode; private boolean startedMovingOverlay; - private MenuEntry[] menuEntries; + private Overlay hoveredOverlay; // for building menu entries // Overlay state validation private Rectangle viewportBounds; @@ -124,6 +126,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener this.overlayManager = overlayManager; this.runeLiteConfig = runeLiteConfig; this.clientUI = clientUI; + this.eventBus = eventBus; keyManager.registerKeyListener(this); mouseManager.registerMouseListener(this); eventBus.register(this); @@ -140,14 +143,15 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener resetOverlayManagementMode(); } - menuEntries = null; + hoveredOverlay = null; } } @Subscribe protected void onClientTick(ClientTick t) { - if (menuEntries == null) + final Overlay overlay = hoveredOverlay; + if (overlay == null || client.isMenuOpen()) { return; } @@ -158,24 +162,29 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener return; } - if (client.isMenuOpen()) + List menuEntries = overlay.getMenuEntries(); + if (menuEntries.isEmpty()) { return; } - MenuEntry[] clientMenuEntries = client.getMenuEntries(); - MenuEntry[] newEntries = new MenuEntry[clientMenuEntries.length + menuEntries.length]; + // Add in reverse order so they display correctly in the right-click menu + for (int i = menuEntries.size() - 1; i >= 0; --i) + { + OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - newEntries[0] = clientMenuEntries[0]; // Keep cancel at 0 - System.arraycopy(menuEntries, 0, newEntries, 1, menuEntries.length); // Add overlay menu entries - System.arraycopy(clientMenuEntries, 1, newEntries, menuEntries.length + 1, clientMenuEntries.length - 1); // Add remaining menu entries - client.setMenuEntries(newEntries); + client.createMenuEntry(-1) + .setOption(overlayMenuEntry.getOption()) + .setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)) + .setType(overlayMenuEntry.getMenuAction()) + .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))); + } } @Subscribe public void onBeforeRender(BeforeRender event) { - menuEntries = null; + hoveredOverlay = null; if (client.getGameState() == GameState.LOGGED_IN) { @@ -349,11 +358,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener if (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse)) { - if (menuEntries == null) - { - menuEntries = createRightClickMenuEntries(overlay); - } - + hoveredOverlay = overlay; overlay.onMouseOver(); } } @@ -902,33 +907,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE)); } - private MenuEntry[] createRightClickMenuEntries(Overlay overlay) - { - List menuEntries = overlay.getMenuEntries(); - if (menuEntries.isEmpty()) - { - return null; - } - - final MenuEntry[] entries = new MenuEntry[menuEntries.size()]; - - // Add in reverse order so they display correctly in the right-click menu - for (int i = menuEntries.size() - 1; i >= 0; --i) - { - OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - - final MenuEntry entry = new MenuEntry(); - entry.setOption(overlayMenuEntry.getOption()); - entry.setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)); - entry.setType(overlayMenuEntry.getMenuAction().getId()); - entry.setIdentifier(overlayManager.getOverlays().indexOf(overlay)); // overlay id - - entries[i] = entry; - } - - return entries; - } - /** * Adjust the given overlay position to be within its parent's bounds. * 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 2f2beb0c62..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 @@ -24,6 +24,7 @@ */ package net.runelite.client.ui.overlay.worldmap; +import com.google.common.base.MoreObjects; import com.google.common.base.Splitter; import com.google.common.base.Strings; import java.awt.Dimension; @@ -32,23 +33,18 @@ import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Point; import net.runelite.api.RenderOverview; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.overlay.Overlay; @@ -73,7 +69,7 @@ public class WorldMapOverlay extends Overlay private final WorldMapPointManager worldMapPointManager; private final Client client; - private final List mapMenuEntries = new ArrayList<>(); + private WorldMapPoint hoveredPoint; @Inject private WorldMapOverlay( @@ -107,19 +103,18 @@ public class WorldMapOverlay extends Overlay bottomBar.setOnTimerListener((JavaScriptCallback) ev -> { - if (client.isMenuOpen() || mapMenuEntries.isEmpty()) + WorldMapPoint worldPoint = hoveredPoint; + if (client.isMenuOpen() || worldPoint == null) { return; } - MenuEntry[] entries = client.getMenuEntries(); - int end = entries.length; - entries = Arrays.copyOf(entries, end + mapMenuEntries.size()); - for (int i = 0; i < mapMenuEntries.size(); i++) - { - entries[end + i] = mapMenuEntries.get(i); - } - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)) + .setOption(FOCUS_ON) + .setType(MenuAction.RUNELITE) + .onClick(m -> client.getRenderOverview().setWorldMapPositionTarget( + MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))); }); bottomBar.setHasListener(true); @@ -135,7 +130,7 @@ public class WorldMapOverlay extends Overlay mousePos = null; } - mapMenuEntries.clear(); + hoveredPoint = null; WorldMapPoint tooltipPoint = null; @@ -227,19 +222,7 @@ public class WorldMapOverlay extends Overlay if (worldPoint.isJumpOnClick()) { assert worldPoint.getName() != null; - - WorldPoint target = worldPoint.getTarget(); - if (target == null) - { - target = worldPoint.getWorldPoint(); - } - - MenuEntry entry = new MenuEntry(); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setOption(FOCUS_ON); - entry.setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)); - entry.setIdentifier(target.getPlane() << 28 | target.getX() << 14 | target.getY()); - mapMenuEntries.add(entry); + hoveredPoint = worldPoint; } } } @@ -259,21 +242,6 @@ public class WorldMapOverlay extends Overlay return null; } - @Subscribe - private void onMenuOptionClicked(MenuOptionClicked ev) - { - if (ev.getMenuAction() == MenuAction.RUNELITE && FOCUS_ON.equals(ev.getMenuOption())) - { - int pxy = ev.getId(); - WorldPoint wp = new WorldPoint( - pxy >> 14 & 0x3fff, - pxy & 0x3fff, - pxy >> 28); - - client.getRenderOverview().setWorldMapPositionTarget(wp); - } - } - /** * Get the screen coordinates for a WorldPoint on the world map * diff --git a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java index 30ca3dfeda..cd33ded89b 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java @@ -24,9 +24,12 @@ */ package net.runelite.client.menus; +import com.google.common.collect.Lists; import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; @@ -38,24 +41,18 @@ import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.util.Text; import static org.junit.Assert.assertArrayEquals; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatchers; +import static org.mockito.ArgumentMatchers.anyInt; import org.mockito.Mock; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.class) public class MenuManagerTest { - private static final MenuEntry CANCEL = new MenuEntry(); - @Inject private MenuManager menuManager; @@ -63,14 +60,18 @@ public class MenuManagerTest @Bind private Client client; - private MenuEntry[] clientMenuEntries = {CANCEL}; + private final MenuEntry CANCEL = createMenuEntry("Cancel", "", MenuAction.CANCEL, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - @BeforeClass - public static void beforeClass() + private final List createdMenuEntries = new ArrayList<>(); + + private static MenuEntry createMenuEntry(String option, String target, MenuAction type, int param1) { - CANCEL.setOption("Cancel"); - CANCEL.setType(MenuAction.CANCEL.getId()); - CANCEL.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + MenuEntry menuEntry = new TestMenuEntry(); + menuEntry.setOption(option); + menuEntry.setTarget(target); + menuEntry.setType(type); + menuEntry.setParam1(param1); + return menuEntry; } @Before @@ -78,35 +79,25 @@ public class MenuManagerTest { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); - doAnswer((Answer) invocationOnMock -> - { - clientMenuEntries = invocationOnMock.getArgument(0, MenuEntry[].class); - return null; - }).when(client).setMenuEntries(ArgumentMatchers.any(MenuEntry[].class)); - when(client.getMenuEntries()).thenAnswer((Answer) invocationMock -> clientMenuEntries); + when(client.createMenuEntry(anyInt())) + .thenAnswer(a -> + { + MenuEntry e = new TestMenuEntry(); + createdMenuEntries.add(e); + return e; + }); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{CANCEL}); } @Test public void testManagedMenuOrder() { - final MenuEntry first = new MenuEntry(); - final MenuEntry second = new MenuEntry(); - final MenuEntry third = new MenuEntry(); - first.setOption("Test"); - first.setTarget("First Entry"); - first.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - first.setType(RUNELITE.getId()); - second.setOption("Test"); - second.setTarget("Second Entry"); - second.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - second.setType(RUNELITE.getId()); - third.setOption("Test"); - third.setTarget("Third Entry"); - third.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - third.setType(RUNELITE.getId()); - menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); + final MenuEntry first = createMenuEntry("Test", "First Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry second = createMenuEntry("Test", "Second Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry third = createMenuEntry("Test", "Third Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); menuManager.onMenuEntryAdded(new MenuEntryAdded( CANCEL.getOption(), @@ -116,12 +107,10 @@ public class MenuManagerTest CANCEL.getParam0(), CANCEL.getParam1())); - ArgumentCaptor captor = ArgumentCaptor.forClass(MenuEntry[].class); - verify(client, atLeastOnce()).setMenuEntries(captor.capture()); + verify(client, times(3)).createMenuEntry(anyInt()); - final MenuEntry[] resultMenuEntries = captor.getValue(); // Strip color tags from menu options before array comparison - for (MenuEntry resultEntry : resultMenuEntries) + for (MenuEntry resultEntry : createdMenuEntries) { final String resultTarget = resultEntry.getTarget(); if (resultTarget != null) @@ -130,6 +119,7 @@ public class MenuManagerTest } } - assertArrayEquals(new MenuEntry[]{CANCEL, third, second, first}, resultMenuEntries); + assertArrayEquals(new MenuEntry[]{third, second, first}, + Lists.reverse(createdMenuEntries).toArray(new MenuEntry[0])); } } 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 new file mode 100644 index 0000000000..35ca935676 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2021, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.menus; + +import java.util.function.Consumer; +import lombok.EqualsAndHashCode; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; + +@EqualsAndHashCode +public class TestMenuEntry implements MenuEntry +{ + private String option; + private String target; + private int identifier; + private int type; + private int param0; + private int param1; + private boolean forceLeftClick; + + @Override + public String getOption() + { + return option; + } + + @Override + public MenuEntry setOption(String option) + { + this.option = option; + return this; + } + + @Override + public String getTarget() + { + return target; + } + + @Override + public MenuEntry setTarget(String target) + { + this.target = target; + return this; + } + + @Override + public int getIdentifier() + { + return this.identifier; + } + + @Override + public MenuEntry setIdentifier(int identifier) + { + this.identifier = identifier; + return this; + } + + @Override + public MenuAction getType() + { + return MenuAction.of(this.type); + } + + @Override + public MenuEntry setType(MenuAction type) + { + this.type = type.getId(); + return this; + } + + @Override + public int getParam0() + { + return this.param0; + } + + @Override + public MenuEntry setParam0(int param0) + { + this.param0 = param0; + return this; + } + + @Override + public int getParam1() + { + return this.param1; + } + + @Override + public MenuEntry setParam1(int param1) + { + this.param1 = param1; + return this; + } + + @Override + public boolean isForceLeftClick() + { + return this.forceLeftClick; + } + + @Override + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + this.forceLeftClick = forceLeftClick; + return this; + } + + @Override + public boolean isDeprioritized() + { + return type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + + @Override + public void setDeprioritized(boolean deprioritized) + { + if (deprioritized) + { + if (type < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + else + { + if (type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + } + + @Override + public MenuEntry onClick(Consumer callback) + { + return this; + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java index cbe6cd34d6..4fa03023a1 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java @@ -28,6 +28,7 @@ import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.Arrays; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; @@ -37,6 +38,7 @@ import net.runelite.api.events.ClientTick; import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.config.ConfigManager; import net.runelite.client.game.ItemManager; +import net.runelite.client.menus.TestMenuEntry; import static org.junit.Assert.assertArrayEquals; import org.junit.Before; import org.junit.Test; @@ -88,9 +90,7 @@ public class MenuEntrySwapperPluginTest { // The menu implementation returns a copy of the array, which causes swap() to not // modify the same array being iterated in onClientTick - MenuEntry[] copy = new MenuEntry[entries.length]; - System.arraycopy(entries, 0, copy, 0, entries.length); - return copy; + return Arrays.copyOf(entries, entries.length); }); doAnswer((Answer) invocationOnMock -> { @@ -109,10 +109,10 @@ public class MenuEntrySwapperPluginTest private static MenuEntry menu(String option, String target, MenuAction menuAction, int identifier) { - MenuEntry menuEntry = new MenuEntry(); + MenuEntry menuEntry = new TestMenuEntry(); menuEntry.setOption(option); menuEntry.setTarget(target); - menuEntry.setType(menuAction.getId()); + menuEntry.setType(menuAction); menuEntry.setIdentifier(identifier); return menuEntry; } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java index 00d3bd2eaa..90d306a1cd 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java @@ -39,6 +39,7 @@ import net.runelite.api.NPC; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcSpawned; +import net.runelite.client.menus.TestMenuEntry; import net.runelite.client.ui.overlay.OverlayManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -48,7 +49,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -109,13 +109,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // red - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // red } @Test @@ -133,13 +132,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // blue - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // blue } @Test From 3ad7fc1aad05a9e65b23df8a3a31bc23d1948db7 Mon Sep 17 00:00:00 2001 From: Freeburn113 Date: Fri, 10 Dec 2021 05:39:04 +0100 Subject: [PATCH 02/17] woodcutting: update respawn times from wiki --- .../client/plugins/woodcutting/Tree.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java index f6cc53254f..f87bcaeef3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java @@ -53,26 +53,27 @@ import static net.runelite.api.ObjectID.WILLOW_10833; import static net.runelite.api.ObjectID.YEW; import static net.runelite.api.NullObjectID.NULL_10823; import static net.runelite.api.ObjectID.YEW_36683; +import static net.runelite.client.util.RSTimeUnit.GAME_TICKS; @Getter enum Tree { REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280), - OAK_TREE(Duration.ofMillis(8500), OAK_TREE_4540, OAK_10820), - WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), - MAPLE_TREE(Duration.ofSeconds(35), MAPLE_TREE_10832, MAPLE_TREE_36681) + OAK_TREE(Duration.of(14, GAME_TICKS), OAK_TREE_4540, OAK_10820), + WILLOW_TREE(Duration.of(14, GAME_TICKS), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), + MAPLE_TREE(Duration.of(59, GAME_TICKS), MAPLE_TREE_10832, MAPLE_TREE_36681) { @Override Duration getRespawnTime(int region) { - return region == MISCELLANIA_REGION ? Duration.ofMillis(8500) : super.respawnTime; + return region == MISCELLANIA_REGION ? Duration.of(14, GAME_TICKS) : super.respawnTime; } }, - TEAK_TREE(Duration.ofMillis(8500), TEAK, TEAK_36686), - MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688), - YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683), - MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835), - REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670); + TEAK_TREE(Duration.of(15, GAME_TICKS), TEAK, TEAK_36686), + MAHOGANY_TREE(Duration.of(14, GAME_TICKS), MAHOGANY, MAHOGANY_36688), + YEW_TREE(Duration.of(99, GAME_TICKS), YEW, NULL_10823, YEW_36683), + MAGIC_TREE(Duration.of(199, GAME_TICKS), MAGIC_TREE_10834, NULL_10835), + REDWOOD(Duration.of(199, GAME_TICKS), ObjectID.REDWOOD, REDWOOD_29670); @Nullable private final Duration respawnTime; From a585253d3628172ebbcdbedc655b9dc716365043 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Dec 2021 11:57:50 -0500 Subject: [PATCH 03/17] chatfilter: add clan message types --- .../runelite/client/plugins/chatfilter/ChatFilterPlugin.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java index 39d736d4c5..a529800017 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java @@ -201,6 +201,9 @@ public class ChatFilterPlugin extends Plugin case NPC_EXAMINE: case OBJECT_EXAMINE: case SPAM: + case CLAN_MESSAGE: + case CLAN_GUEST_MESSAGE: + case CLAN_GIM_MESSAGE: if (config.filterGameChat()) { message = censorMessage(null, message); From 4fe37f978cd72a4b31e3efaee73bbdf0fcae3b20 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 9 Dec 2021 18:55:07 -0500 Subject: [PATCH 04/17] friendslist: add option to hide per-friend login notifications --- .../main/java/net/runelite/api/Client.java | 2 +- .../net/runelite/api/FriendContainer.java | 37 +++++++++ .../java/net/runelite/api/PendingLogin.java | 45 +++++++++++ .../plugins/friendlist/FriendListConfig.java | 4 +- .../plugins/friendlist/FriendListPlugin.java | 76 +++++++++++++++++++ .../friendlist/FriendListPluginTest.java | 14 +++- 6 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/FriendContainer.java create mode 100644 runelite-api/src/main/java/net/runelite/api/PendingLogin.java 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 e53d03ec7f..91cf6a842c 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1276,7 +1276,7 @@ public interface Client extends GameEngine * * @return */ - NameableContainer getFriendContainer(); + FriendContainer getFriendContainer(); /** * Retrieve the nameable container containing ignores diff --git a/runelite-api/src/main/java/net/runelite/api/FriendContainer.java b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java new file mode 100644 index 0000000000..b288db028b --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +/** + * A nameable container of friends + */ +public interface FriendContainer extends NameableContainer +{ + /** + * Get the recent logins/logouts of friends from the last few seconds + * @return + */ + Deque getPendingLogins(); +} diff --git a/runelite-api/src/main/java/net/runelite/api/PendingLogin.java b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java new file mode 100644 index 0000000000..c7c3a1d1a3 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +/** + * A pending friend login/out. This is used to suppress world hop notifications + * by buffering the pending logins to try to match a pending logout with a pending + * login and cancel both. + */ +public interface PendingLogin +{ + /** + * The name of the player + * @return + */ + String getName(); + + /** + * The world the player logged into, or 0 if a logout. + * @return + */ + short getWorld(); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java index 441820c465..9c556c3dec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java @@ -28,9 +28,11 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup("friendlist") +@ConfigGroup(FriendListConfig.GROUP) public interface FriendListConfig extends Config { + String GROUP = "friendlist"; + @ConfigItem( keyName = "showWorldOnLogin", name = "Show world on login", 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 da5ebda38b..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 @@ -26,30 +26,40 @@ package net.runelite.client.plugins.friendlist; import com.google.inject.Provides; +import java.time.temporal.ChronoUnit; +import java.util.Iterator; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.ChatPlayer; import net.runelite.api.Client; import net.runelite.api.Friend; import net.runelite.api.Ignore; +import net.runelite.api.MenuAction; import net.runelite.api.MessageNode; import net.runelite.api.NameableContainer; +import net.runelite.api.PendingLogin; import net.runelite.api.ScriptID; import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptPostFired; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.task.Schedule; import net.runelite.client.util.Text; @PluginDescriptor( name = "Friend List", description = "Add extra information to the friend and ignore lists" ) +@Slf4j public class FriendListPlugin extends Plugin { private static final int MAX_FRIENDS_P2P = 400; @@ -58,12 +68,21 @@ public class FriendListPlugin extends Plugin private static final int MAX_IGNORES_P2P = 400; private static final int MAX_IGNORES_F2P = 100; + private static final String HIDE_NOTIFICATIONS = "Hide notifications"; + private static final String SHOW_NOTIFICATIONS = "Show notifications"; + @Inject private Client client; @Inject private FriendListConfig config; + @Inject + private ConfigManager configManager; + + @Inject + private ChatMessageManager chatMessageManager; + @Provides FriendListConfig getConfig(ConfigManager configManager) { @@ -144,6 +163,46 @@ public class FriendListPlugin extends Plugin } } + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); + + // Look for "Message" on friends list + if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) + { + String friend = Text.toJagexName(Text.removeTags(event.getTarget())); + + client.createMenuEntry(-1) + .setOption(isHideNotification(friend) ? SHOW_NOTIFICATIONS : HIDE_NOTIFICATIONS) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + boolean hidden = isHideNotification(friend); + setHideNotifications(friend, !hidden); + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .value("Login notifications for " + friend + " are now " + (hidden ? "shown." : "hidden.")) + .build()); + }); + } + } + + @Schedule(period = 5, unit = ChronoUnit.SECONDS) + public void setHideNotifications() + { + for (Iterator it = client.getFriendContainer().getPendingLogins().iterator(); it.hasNext(); ) + { + PendingLogin pendingLogin = it.next(); + if (isHideNotification(Text.toJagexName(pendingLogin.getName()))) + { + log.debug("Removing login notification for {}", pendingLogin.getName()); + it.remove(); + } + } + } + private void setFriendsListTitle(final String title) { Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE); @@ -173,4 +232,21 @@ public class FriendListPlugin extends Plugin return null; } + + private void setHideNotifications(String friend, boolean hide) + { + if (hide) + { + configManager.setConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, true); + } + else + { + configManager.unsetConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend); + } + } + + private boolean isHideNotification(String friend) + { + return configManager.getConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, Boolean.class) == Boolean.TRUE; + } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java index 4b3fd12f32..ee8b485b6a 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java @@ -31,9 +31,11 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Friend; +import net.runelite.api.FriendContainer; import net.runelite.api.MessageNode; -import net.runelite.api.NameableContainer; import net.runelite.api.events.ChatMessage; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.config.ConfigManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +56,14 @@ public class FriendListPluginTest @Bind private FriendListConfig config; + @Mock + @Bind + private ConfigManager configManager; + + @Mock + @Bind + private ChatMessageManager chatMessageManager; + @Inject private FriendListPlugin friendListPlugin; @@ -78,7 +88,7 @@ public class FriendListPluginTest Friend friend = mock(Friend.class); when(friend.getWorld()).thenReturn(311); - NameableContainer friendContainer = mock(NameableContainer.class); + FriendContainer friendContainer = mock(FriendContainer.class); when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend); when(client.getFriendContainer()).thenReturn(friendContainer); From 1d5c63bfacba94e6cf690f77451237fae01563ce Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 Dec 2021 15:10:23 -0500 Subject: [PATCH 05/17] rl-client: build test jar --- runelite-client/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 46bd34a2b2..9b282461bb 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -330,6 +330,13 @@ + + + + test-jar + + + org.apache.maven.plugins From a0c14cf06afcdd133599d5926ded9c791b541a53 Mon Sep 17 00:00:00 2001 From: Ron Young Date: Sat, 11 Dec 2021 16:25:54 -0600 Subject: [PATCH 06/17] api: MenuEntry::setDeprioritized return self --- runelite-api/src/main/java/net/runelite/api/MenuEntry.java | 2 +- .../test/java/net/runelite/client/menus/TestMenuEntry.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) 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 6891927c4b..5cdcfe3559 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -84,7 +84,7 @@ public interface MenuEntry * @return */ boolean isDeprioritized(); - void setDeprioritized(boolean deprioritized); + MenuEntry setDeprioritized(boolean deprioritized); /** * Set a callback to be called when this menu option is clicked 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 35ca935676..bdcf842040 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 @@ -138,7 +138,7 @@ public class TestMenuEntry implements MenuEntry } @Override - public void setDeprioritized(boolean deprioritized) + public MenuEntry setDeprioritized(boolean deprioritized) { if (deprioritized) { @@ -154,6 +154,8 @@ public class TestMenuEntry implements MenuEntry type -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; } } + + return this; } @Override From e956ed1ba7bb5ea8eeda7a8c21e7b782fc6d6b27 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 Dec 2021 21:12:51 -0500 Subject: [PATCH 07/17] ge plugin: compact buy offer examine text The examine text, buy limit, trade price, and fee info does not fit on the interface anymore since the addition of the fee info. This compacts the examine text as well as places the limit / trade price on the same line in order to prevent pushing the fee off of the bottom of the border. --- .../grandexchange/GrandExchangePlugin.java | 133 +++++++------- .../src/main/scripts/GeExamineInfoText.hash | 1 + .../src/main/scripts/GeExamineInfoText.rs2asm | 167 ++++++++++++++++++ 3 files changed, 233 insertions(+), 68 deletions(-) create mode 100644 runelite-client/src/main/scripts/GeExamineInfoText.hash create mode 100644 runelite-client/src/main/scripts/GeExamineInfoText.rs2asm diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index 697bf0d43b..f5458b9562 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -66,6 +66,7 @@ import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.ScriptID; import net.runelite.api.VarClientStr; +import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.FocusChanged; import net.runelite.api.events.GameStateChanged; @@ -74,7 +75,6 @@ import net.runelite.api.events.GrandExchangeSearched; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptPostFired; -import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; @@ -120,10 +120,9 @@ public class GrandExchangePlugin extends Plugin @VisibleForTesting static final int GE_SLOTS = 8; private static final int GE_LOGIN_BURST_WINDOW = 2; // ticks - private static final int OFFER_CONTAINER_ITEM = 21; - private static final int OFFER_DEFAULT_ITEM_ID = 6512; + private static final int GE_MAX_EXAMINE_LEN = 100; - private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; + private static final String BUY_LIMIT_GE_TEXT = "Buy limit: "; private static final String BUY_LIMIT_KEY = "buylimit"; private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4); @@ -182,9 +181,6 @@ public class GrandExchangePlugin extends Plugin @Inject private RuneLiteConfig runeLiteConfig; - private Widget grandExchangeText; - private String grandExchangeExamine; - @Inject private GrandExchangeClient grandExchangeClient; private int lastLoginTick; @@ -317,7 +313,6 @@ public class GrandExchangePlugin extends Plugin clientToolbar.removeNavigation(button); mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); - grandExchangeText = null; lastUsername = machineUuid = null; tradeSeq = 0; } @@ -587,31 +582,10 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - switch (event.getGroupId()) - { - // Grand exchange was opened. - case WidgetID.GRAND_EXCHANGE_GROUP_ID: - grandExchangeText = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_TEXT); - break; - // Grand exchange was closed (if it was open before). - case WidgetID.INVENTORY_GROUP_ID: - grandExchangeText = null; - break; - } - } - @Subscribe public void onScriptPostFired(ScriptPostFired event) { - // GE offers setup init - if (event.getScriptId() == ScriptID.GE_OFFERS_SETUP_BUILD) - { - rebuildGeText(); - } - else if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) + if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) { highlightSearchMatches(); } @@ -738,7 +712,30 @@ public class GrandExchangePlugin extends Plugin @Subscribe public void onScriptCallbackEvent(ScriptCallbackEvent event) { - if (!event.getEventName().equals("setGETitle") || !config.showTotal()) + switch (event.getEventName()) + { + case "setGETitle": + setGeTitle(); + break; + case "geExamineText": + { + String[] stack = client.getStringStack(); + int sz = client.getStringStackSize(); + String fee = stack[sz - 2]; + String examine = stack[sz - 3]; + String text = setExamineText(examine, fee); + if (text != null) + { + stack[sz - 1] = text; + } + break; + } + } + } + + private void setGeTitle() + { + if (!config.showTotal()) { return; } @@ -817,39 +814,10 @@ public class GrandExchangePlugin extends Plugin } } - private void rebuildGeText() + private String setExamineText(String examine, String fee) { - if (grandExchangeText == null) - { - return; - } - Widget grandExchangeOffer = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER); - if (grandExchangeOffer == null) - { - return; - } - Widget grandExchangeItem = grandExchangeOffer.getChild(OFFER_CONTAINER_ITEM); - if (grandExchangeItem == null || grandExchangeItem.isHidden()) - { - return; - } - - final Widget geText = grandExchangeText; - final int itemId = grandExchangeItem.getItemId(); - - if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1) - { - // This item is invalid/nothing has been searched for - return; - } - - if (geText.getText() == grandExchangeExamine) - { - // if we've already set the text, don't set it again - return; - } - - String text = geText.getText(); + final int itemId = client.getVar(VarPlayer.CURRENT_GE_ITEM); + StringBuilder sb = new StringBuilder(); if (config.enableGELimits()) { @@ -858,7 +826,7 @@ public class GrandExchangePlugin extends Plugin // If we have item buy limit, append it if (itemStats != null && itemStats.getGeLimit() > 0) { - text += BUY_LIMIT_GE_TEXT + QuantityFormatter.formatNumber(itemStats.getGeLimit()); + sb.append(BUY_LIMIT_GE_TEXT).append(QuantityFormatter.formatNumber(itemStats.getGeLimit())); } } @@ -868,7 +836,7 @@ public class GrandExchangePlugin extends Plugin if (resetTime != null) { Duration remaining = Duration.between(Instant.now(), resetTime); - text += " (" + DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm") + ")"; + sb.append(" (").append(DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm")).append(")"); } } @@ -877,12 +845,41 @@ public class GrandExchangePlugin extends Plugin final int price = itemManager.getItemPriceWithSource(itemId, true); if (price > 0) { - text += "
Actively traded price: " + QuantityFormatter.formatNumber(price); + if (sb.length() > 0) + { + sb.append(" / "); + } + sb.append("Actively traded price: ").append(QuantityFormatter.formatNumber(price)); } } - grandExchangeExamine = text; - geText.setText(text); + if (sb.length() == 0) + { + return null; + } + + return shortenExamine(examine) + "
" + sb + "
" + fee; + } + + private static String shortenExamine(String examine) + { + int from = 0; + int idx; + while (true) + { + idx = examine.indexOf(' ', from); + if (idx == -1) + { + return examine; + } + if (idx > GE_MAX_EXAMINE_LEN && from > 0) + { + break; // use from + } + from = idx + 1; + } + + return examine.substring(0, from - 1) + "..."; } void openGeLink(String name, int itemId) diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.hash b/runelite-client/src/main/scripts/GeExamineInfoText.hash new file mode 100644 index 0000000000..162121bd78 --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.hash @@ -0,0 +1 @@ +157D0FE4248A0C0CAC825733A8DE7B0FA5A93451A9FCE3A4B1D8BFD54038B970 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm new file mode 100644 index 0000000000..20c53ea902 --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm @@ -0,0 +1,167 @@ +; script used to position the ge buy offer "Convenience fee" info icon as well as set the +; examine text +; component0 = text component for the examine text +; component1 = parent of the info icon +; string0 = item examine +; string1 = Convenience fee text +.id 5730 +.int_stack_count 2 +.string_stack_count 2 +.int_var_count 5 +.string_var_count 3 + sconst "" + sstore 2 + iconst 0 + istore 2 + iconst 0 + istore 3 + iconst 0 + istore 4 + sload 1 + string_length + iconst 0 + if_icmpgt LABEL13 + jump LABEL118 +LABEL13: + sload 0 + sconst "
" + sconst "
" + sload 1 + join_string 4 + iload 0 + if_getwidth + istore 2 + sstore 2 + + sload 0 ; examine + sload 1 ; Convenience fee + sload 2 ; "<$string0>

<$string1>" + sconst "geExamineText" + runelite_callback + sstore 2 ; final text + pop_string ; Convenience fee + pop_string ; examine + + iload 0 + if_getx + sload 1 + iload 2 + iconst 494 + parawidth + add + iconst 5 + add + iload 0 + if_gety + sload 2 + iload 2 + iconst 494 + paraheight + iconst 15 + multiply + add + iconst 2 + add + istore 4 + istore 3 + iload 3 + iload 1 + if_getwidth + iconst 15 + sub + iconst 2 + div + sub + iload 4 + iconst 11 + iload 1 + if_getheight + iconst 2 + div + add + sub + istore 4 + istore 3 + iload 3 + iload 4 + iconst 0 + iconst 0 + iload 1 + if_setposition + iconst 0 + iload 1 + if_sethide + iload 1 + cc_deleteall + iload 1 + iconst 5 + iconst 0 + cc_create + iconst 15 + iconst 15 + iconst 0 + iconst 0 + cc_setsize + iconst 0 + iconst 0 + iconst 1 + iconst 1 + cc_setposition + iconst 1094 + cc_setgraphic + iconst 50 + cc_settrans + iconst 244 + iconst -2147483645 + cc_getid + iconst 0 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouserepeat + iconst 244 + iconst -2147483645 + cc_getid + iconst 50 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouseleave + iconst 489 + iconst -2147483644 + iconst 2 + sconst "ii" + iload 1 + if_setonop + iconst 1 + sconst "Info" + iload 1 + if_setop + jump LABEL139 +LABEL118: + sload 0 + sstore 2 + iconst 1 + iload 1 + if_sethide + iload 1 + cc_deleteall + iconst -1 + sconst "" + iload 1 + if_setonmouserepeat + iconst -1 + sconst "" + iload 1 + if_setonmouseleave + iconst -1 + sconst "" + iload 1 + if_setonop + iload 1 + if_clearops +LABEL139: + sload 2 + iload 0 + if_settext + return From 24d0127e3d6f1211c2ef4058a1f08b5679a44b19 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Fri, 10 Dec 2021 19:45:25 -0700 Subject: [PATCH 08/17] rl-api: use less confusing names for model indices --- .../api/{Sequence.java => Animation.java} | 2 +- .../main/java/net/runelite/api/Client.java | 2 +- .../src/main/java/net/runelite/api/Model.java | 10 +++---- .../java/net/runelite/api/Perspective.java | 10 +++---- .../java/net/runelite/api/RuneLiteObject.java | 2 +- .../client/plugins/gpu/GpuPlugin.java | 4 +-- .../client/plugins/gpu/SceneUploader.java | 30 +++++++++---------- .../overlay/outline/ModelOutlineRenderer.java | 10 +++---- 8 files changed, 35 insertions(+), 35 deletions(-) rename runelite-api/src/main/java/net/runelite/api/{Sequence.java => Animation.java} (98%) diff --git a/runelite-api/src/main/java/net/runelite/api/Sequence.java b/runelite-api/src/main/java/net/runelite/api/Animation.java similarity index 98% rename from runelite-api/src/main/java/net/runelite/api/Sequence.java rename to runelite-api/src/main/java/net/runelite/api/Animation.java index e7e1c8fcb9..77c8a8af2e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Sequence.java +++ b/runelite-api/src/main/java/net/runelite/api/Animation.java @@ -27,6 +27,6 @@ package net.runelite.api; /** * Represents an animation of a renderable */ -public interface Sequence +public interface Animation { } 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 91cf6a842c..1699b5637d 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1089,7 +1089,7 @@ public interface Client extends GameEngine * @param id the ID of the animation. Any int is allowed, but implementations in the client * should be defined in {@link AnimationID} */ - Sequence loadAnimation(int id); + Animation loadAnimation(int id); /** * Gets the music volume diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java index e923cbd3d4..d3756ea727 100644 --- a/runelite-api/src/main/java/net/runelite/api/Model.java +++ b/runelite-api/src/main/java/net/runelite/api/Model.java @@ -37,13 +37,13 @@ public interface Model extends Renderable int[] getVerticesZ(); - int getTrianglesCount(); + int getFaceCount(); - int[] getTrianglesX(); + int[] getFaceIndices1(); - int[] getTrianglesY(); + int[] getFaceIndices2(); - int[] getTrianglesZ(); + int[] getFaceIndices3(); int[] getFaceColors1(); @@ -51,7 +51,7 @@ public interface Model extends Renderable int[] getFaceColors3(); - byte[] getTriangleTransparencies(); + byte[] getFaceTransparencies(); int getSceneId(); void setSceneId(int sceneId); diff --git a/runelite-api/src/main/java/net/runelite/api/Perspective.java b/runelite-api/src/main/java/net/runelite/api/Perspective.java index 75963a2486..e5f2262965 100644 --- a/runelite-api/src/main/java/net/runelite/api/Perspective.java +++ b/runelite-api/src/main/java/net/runelite/api/Perspective.java @@ -781,9 +781,9 @@ public class Perspective final int radius = 5; int[][] tris = new int[][]{ - m.getTrianglesX(), - m.getTrianglesY(), - m.getTrianglesZ() + m.getFaceIndices1(), + m.getFaceIndices2(), + m.getFaceIndices3() }; int vpX1 = client.getViewportXOffset(); @@ -791,10 +791,10 @@ public class Perspective int vpX2 = vpX1 + client.getViewportWidth(); int vpY2 = vpY1 + client.getViewportHeight(); - List rects = new ArrayList<>(m.getTrianglesCount()); + List rects = new ArrayList<>(m.getFaceCount()); nextTri: - for (int tri = 0; tri < m.getTrianglesCount(); tri++) + for (int tri = 0; tri < m.getFaceCount(); tri++) { if (faceColors3[tri] == -2) { diff --git a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java index 20f2fb001e..5fcd50c3e3 100644 --- a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java +++ b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java @@ -41,7 +41,7 @@ public interface RuneLiteObject extends GraphicsObject * Sets the animation of the RuneLiteObject * If animation is null model will be static */ - void setAnimation(Sequence animation); + void setAnimation(Animation animation); /** * Sets whether the animation of the RuneLiteObject should loop when the animation ends. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index b275fd7d4e..062c810ffa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -1608,7 +1608,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks modelY = y + client.getCameraY2(); modelZ = z + client.getCameraZ2(); modelOrientation = orientation; - int triangleCount = model.getTrianglesCount(); + int triangleCount = model.getFaceCount(); vertexBuffer.ensureCapacity(12 * triangleCount); uvBuffer.ensureCapacity(12 * triangleCount); @@ -1632,7 +1632,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks model.calculateExtreme(orientation); client.checkClickbox(model, orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash); - int tc = Math.min(MAX_TRIANGLE, model.getTrianglesCount()); + int tc = Math.min(MAX_TRIANGLE, model.getFaceCount()); int uvOffset = model.getUvBufferOffset(); GpuIntBuffer b = bufferForTriangles(tc); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index 910f8b3147..1bf9dcce63 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -379,7 +379,7 @@ class SceneUploader public int pushModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) { - final int triangleCount = Math.min(model.getTrianglesCount(), GpuPlugin.MAX_TRIANGLE); + final int triangleCount = Math.min(model.getFaceCount(), GpuPlugin.MAX_TRIANGLE); vertexBuffer.ensureCapacity(triangleCount * 12); uvBuffer.ensureCapacity(triangleCount * 12); @@ -388,15 +388,15 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); @@ -432,9 +432,9 @@ class SceneUploader int packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + int triangleA = indices1[face]; + int triangleB = indices2[face]; + int triangleC = indices3[face]; vertexBuffer.put(vertexX[triangleA], vertexY[triangleA], vertexZ[triangleA], packAlphaPriority | color1); vertexBuffer.put(vertexX[triangleB], vertexY[triangleB], vertexZ[triangleB], packAlphaPriority | color2); @@ -458,21 +458,21 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + int triangleA = indices1[face]; + int triangleB = indices2[face]; + int triangleC = indices3[face]; int color1 = color1s[face]; int color2 = color2s[face]; diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java index e3528433cb..3047086dda 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java @@ -564,11 +564,11 @@ public class ModelOutlineRenderer */ private void simulateModelRasterizationForOutline(Model model) { - final int triangleCount = model.getTrianglesCount(); - final int[] indices1 = model.getTrianglesX(); - final int[] indices2 = model.getTrianglesY(); - final int[] indices3 = model.getTrianglesZ(); - final byte[] triangleTransparencies = model.getTriangleTransparencies(); + final int triangleCount = model.getFaceCount(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); + final byte[] triangleTransparencies = model.getFaceTransparencies(); for (int i = 0; i < triangleCount; i++) { From 02235d15846cb58a3a4cff347f14b4346904a2cd Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 8 Dec 2021 21:55:02 -0700 Subject: [PATCH 09/17] cache: add rev202 model formats --- .../cache/definitions/ModelDefinition.java | 179 +- .../definitions/loaders/ModelLoader.java | 1674 ++++++++++++----- .../cache/item/ItemSpriteFactory.java | 52 +- .../runelite/cache/models/ObjExporter.java | 16 +- 4 files changed, 1289 insertions(+), 632 deletions(-) diff --git a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java index 2259026a4d..939fdf90da 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java +++ b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java @@ -12,45 +12,40 @@ public class ModelDefinition public int id; public int vertexCount = 0; - public int[] vertexPositionsX; - public int[] vertexPositionsY; - public int[] vertexPositionsZ; + public int[] vertexX; + public int[] vertexY; + public int[] vertexZ; public transient VertexNormal[] vertexNormals; public int faceCount; - public int[] faceVertexIndices1; - public int[] faceVertexIndices2; - public int[] faceVertexIndices3; - public byte[] faceAlphas; + public int[] faceIndices1; + public int[] faceIndices2; + public int[] faceIndices3; + public byte[] faceTransparencies; public short[] faceColors; public byte[] faceRenderPriorities; public byte[] faceRenderTypes; public transient FaceNormal[] faceNormals; - public int textureTriangleCount; - public short[] textureTriangleVertexIndices1; - public short[] textureTriangleVertexIndices2; - public short[] textureTriangleVertexIndices3; + public int numTextureFaces; + public short[] texIndices1; + public short[] texIndices2; + public short[] texIndices3; public transient float[][] faceTextureUCoordinates; public transient float[][] faceTextureVCoordinates; public short[] texturePrimaryColors; public short[] faceTextures; - public byte[] textureCoordinates; + public byte[] textureCoords; public byte[] textureRenderTypes; - public int[] vertexSkins; - public int[] faceSkins; + public int[] packedVertexGroups; + public int[] packedTransparencyVertexGroups; public byte priority; - public short[] aShortArray2574; - public short[] aShortArray2575; - public short[] aShortArray2577; - public short[] aShortArray2578; - public byte[] aByteArray2580; - public short[] aShortArray2586; - private transient int[][] vertexGroups; + public int[][] animayaGroups; + public int[][] animayaScales; private transient int[] origVX; private transient int[] origVY; @@ -77,17 +72,17 @@ public class ModelDefinition for (var1 = 0; var1 < this.faceCount; ++var1) { - int vertexA = this.faceVertexIndices1[var1]; - int vertexB = this.faceVertexIndices2[var1]; - int vertexC = this.faceVertexIndices3[var1]; + int vertexA = this.faceIndices1[var1]; + int vertexB = this.faceIndices2[var1]; + int vertexC = this.faceIndices3[var1]; - int xA = this.vertexPositionsX[vertexB] - this.vertexPositionsX[vertexA]; - int yA = this.vertexPositionsY[vertexB] - this.vertexPositionsY[vertexA]; - int zA = this.vertexPositionsZ[vertexB] - this.vertexPositionsZ[vertexA]; + int xA = this.vertexX[vertexB] - this.vertexX[vertexA]; + int yA = this.vertexY[vertexB] - this.vertexY[vertexA]; + int zA = this.vertexZ[vertexB] - this.vertexZ[vertexA]; - int xB = this.vertexPositionsX[vertexC] - this.vertexPositionsX[vertexA]; - int yB = this.vertexPositionsY[vertexC] - this.vertexPositionsY[vertexA]; - int zB = this.vertexPositionsZ[vertexC] - this.vertexPositionsZ[vertexA]; + int xB = this.vertexX[vertexC] - this.vertexX[vertexA]; + int yB = this.vertexY[vertexC] - this.vertexY[vertexA]; + int zB = this.vertexZ[vertexC] - this.vertexZ[vertexA]; // Compute cross product int var11 = yA * zB - yB * zA; @@ -168,13 +163,13 @@ public class ModelDefinition for (int i = 0; i < faceCount; i++) { int textureCoordinate; - if (textureCoordinates == null) + if (textureCoords == null) { textureCoordinate = -1; } else { - textureCoordinate = textureCoordinates[i]; + textureCoordinate = textureCoords[i]; } int textureIdx; @@ -215,33 +210,33 @@ public class ModelDefinition if (textureRenderType == 0) { - int faceVertexIdx1 = faceVertexIndices1[i]; - int faceVertexIdx2 = faceVertexIndices2[i]; - int faceVertexIdx3 = faceVertexIndices3[i]; + int faceVertexIdx1 = faceIndices1[i]; + int faceVertexIdx2 = faceIndices2[i]; + int faceVertexIdx3 = faceIndices3[i]; - short triangleVertexIdx1 = textureTriangleVertexIndices1[textureCoordinate]; - short triangleVertexIdx2 = textureTriangleVertexIndices2[textureCoordinate]; - short triangleVertexIdx3 = textureTriangleVertexIndices3[textureCoordinate]; + short triangleVertexIdx1 = texIndices1[textureCoordinate]; + short triangleVertexIdx2 = texIndices2[textureCoordinate]; + short triangleVertexIdx3 = texIndices3[textureCoordinate]; - float triangleX = (float) vertexPositionsX[triangleVertexIdx1]; - float triangleY = (float) vertexPositionsY[triangleVertexIdx1]; - float triangleZ = (float) vertexPositionsZ[triangleVertexIdx1]; + float triangleX = (float) vertexX[triangleVertexIdx1]; + float triangleY = (float) vertexY[triangleVertexIdx1]; + float triangleZ = (float) vertexZ[triangleVertexIdx1]; - float f_882_ = (float) vertexPositionsX[triangleVertexIdx2] - triangleX; - float f_883_ = (float) vertexPositionsY[triangleVertexIdx2] - triangleY; - float f_884_ = (float) vertexPositionsZ[triangleVertexIdx2] - triangleZ; - float f_885_ = (float) vertexPositionsX[triangleVertexIdx3] - triangleX; - float f_886_ = (float) vertexPositionsY[triangleVertexIdx3] - triangleY; - float f_887_ = (float) vertexPositionsZ[triangleVertexIdx3] - triangleZ; - float f_888_ = (float) vertexPositionsX[faceVertexIdx1] - triangleX; - float f_889_ = (float) vertexPositionsY[faceVertexIdx1] - triangleY; - float f_890_ = (float) vertexPositionsZ[faceVertexIdx1] - triangleZ; - float f_891_ = (float) vertexPositionsX[faceVertexIdx2] - triangleX; - float f_892_ = (float) vertexPositionsY[faceVertexIdx2] - triangleY; - float f_893_ = (float) vertexPositionsZ[faceVertexIdx2] - triangleZ; - float f_894_ = (float) vertexPositionsX[faceVertexIdx3] - triangleX; - float f_895_ = (float) vertexPositionsY[faceVertexIdx3] - triangleY; - float f_896_ = (float) vertexPositionsZ[faceVertexIdx3] - triangleZ; + float f_882_ = (float) vertexX[triangleVertexIdx2] - triangleX; + float f_883_ = (float) vertexY[triangleVertexIdx2] - triangleY; + float f_884_ = (float) vertexZ[triangleVertexIdx2] - triangleZ; + float f_885_ = (float) vertexX[triangleVertexIdx3] - triangleX; + float f_886_ = (float) vertexY[triangleVertexIdx3] - triangleY; + float f_887_ = (float) vertexZ[triangleVertexIdx3] - triangleZ; + float f_888_ = (float) vertexX[faceVertexIdx1] - triangleX; + float f_889_ = (float) vertexY[faceVertexIdx1] - triangleY; + float f_890_ = (float) vertexZ[faceVertexIdx1] - triangleZ; + float f_891_ = (float) vertexX[faceVertexIdx2] - triangleX; + float f_892_ = (float) vertexY[faceVertexIdx2] - triangleY; + float f_893_ = (float) vertexZ[faceVertexIdx2] - triangleZ; + float f_894_ = (float) vertexX[faceVertexIdx3] - triangleX; + float f_895_ = (float) vertexY[faceVertexIdx3] - triangleY; + float f_896_ = (float) vertexZ[faceVertexIdx3] - triangleZ; float f_897_ = f_883_ * f_887_ - f_884_ * f_886_; float f_898_ = f_884_ * f_885_ - f_882_ * f_887_; @@ -274,7 +269,7 @@ public class ModelDefinition public void computeAnimationTables() { - if (this.vertexSkins != null) + if (this.packedVertexGroups != null) { int[] groupCounts = new int[256]; int numGroups = 0; @@ -282,7 +277,7 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; ++var3) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; ++groupCounts[var4]; if (var4 > numGroups) { @@ -300,10 +295,10 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; this.vertexGroups[var4][groupCounts[var4]++] = var3++) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; } - this.vertexSkins = null; + this.packedVertexGroups = null; } // triangleSkinValues is here @@ -314,13 +309,13 @@ public class ModelDefinition int sin = CircularAngle.SINE[orientation]; int cos = CircularAngle.COSINE[orientation]; - assert vertexPositionsX.length == vertexPositionsY.length; - assert vertexPositionsY.length == vertexPositionsZ.length; + assert vertexX.length == vertexY.length; + assert vertexY.length == vertexZ.length; - for (int i = 0; i < vertexPositionsX.length; ++i) + for (int i = 0; i < vertexX.length; ++i) { - vertexPositionsX[i] = vertexPositionsX[i] * cos + vertexPositionsZ[i] * sin >> 16; - vertexPositionsZ[i] = vertexPositionsZ[i] * cos - vertexPositionsX[i] * sin >> 16; + vertexX[i] = vertexX[i] * cos + vertexZ[i] * sin >> 16; + vertexZ[i] = vertexZ[i] * cos - vertexX[i] * sin >> 16; } reset(); @@ -333,23 +328,23 @@ public class ModelDefinition return; } - System.arraycopy(origVX, 0, vertexPositionsX, 0, origVX.length); - System.arraycopy(origVY, 0, vertexPositionsY, 0, origVY.length); - System.arraycopy(origVZ, 0, vertexPositionsZ, 0, origVZ.length); + System.arraycopy(origVX, 0, vertexX, 0, origVX.length); + System.arraycopy(origVY, 0, vertexY, 0, origVY.length); + System.arraycopy(origVZ, 0, vertexZ, 0, origVZ.length); } public void animate(int type, int[] frameMap, int dx, int dy, int dz) { if (origVX == null) { - origVX = Arrays.copyOf(vertexPositionsX, vertexPositionsX.length); - origVY = Arrays.copyOf(vertexPositionsY, vertexPositionsY.length); - origVZ = Arrays.copyOf(vertexPositionsZ, vertexPositionsZ.length); + origVX = Arrays.copyOf(vertexX, vertexX.length); + origVY = Arrays.copyOf(vertexY, vertexY.length); + origVZ = Arrays.copyOf(vertexZ, vertexZ.length); } - final int[] verticesX = vertexPositionsX; - final int[] verticesY = vertexPositionsY; - final int[] verticesZ = vertexPositionsZ; + final int[] verticesX = vertexX; + final int[] verticesY = vertexY; + final int[] verticesZ = vertexZ; int var6 = frameMap.length; int var7; int var8; @@ -512,14 +507,14 @@ public class ModelDefinition int var1; for (var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } for (var1 = 0; var1 < this.faceCount; ++var1) { - int var2 = this.faceVertexIndices1[var1]; - this.faceVertexIndices1[var1] = this.faceVertexIndices3[var1]; - this.faceVertexIndices3[var1] = var2; + int var2 = this.faceIndices1[var1]; + this.faceIndices1[var1] = this.faceIndices3[var1]; + this.faceIndices3[var1] = var2; } reset(); @@ -529,9 +524,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = -var2; + int var2 = this.vertexX[var1]; + this.vertexX[var1] = this.vertexZ[var1]; + this.vertexZ[var1] = -var2; } reset(); @@ -541,8 +536,8 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsX[var1] = -this.vertexPositionsX[var1]; - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexX[var1] = -this.vertexX[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } reset(); @@ -552,9 +547,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = -var2; + int var2 = this.vertexZ[var1]; + this.vertexZ[var1] = this.vertexX[var1]; + this.vertexX[var1] = -var2; } reset(); @@ -571,9 +566,9 @@ public class ModelDefinition { for (int var4 = 0; var4 < this.vertexCount; ++var4) { - this.vertexPositionsX[var4] = this.vertexPositionsX[var4] * var1 / 128; - this.vertexPositionsY[var4] = var2 * this.vertexPositionsY[var4] / 128; - this.vertexPositionsZ[var4] = var3 * this.vertexPositionsZ[var4] / 128; + this.vertexX[var4] = this.vertexX[var4] * var1 / 128; + this.vertexY[var4] = var2 * this.vertexY[var4] / 128; + this.vertexZ[var4] = var3 * this.vertexZ[var4] / 128; } reset(); @@ -610,9 +605,9 @@ public class ModelDefinition { for (int i = 0; i < this.vertexCount; i++) { - this.vertexPositionsX[i] += xOffset; - this.vertexPositionsY[i] += yOffset; - this.vertexPositionsZ[i] += zOffset; + this.vertexX[i] += xOffset; + this.vertexY[i] += yOffset; + this.vertexZ[i] += zOffset; } this.reset(); } diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java index 4529f8a069..22226c3d8a 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java @@ -10,13 +10,21 @@ public class ModelLoader ModelDefinition def = new ModelDefinition(); def.id = modelId; - if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + if (b[b.length - 1] == -3 && b[b.length - 2] == -1) { - this.load1(def, b); + decodeType3(def, b); + } + else if (b[b.length - 1] == -2 && b[b.length - 2] == -1) + { + decodeType2(def, b); + } + else if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + { + decodeType1(def, b); } else { - this.load2(def, b); + decodeOldFormat(def, b); } def.computeNormals(); @@ -26,702 +34,1356 @@ public class ModelLoader return def; } - private void load1(ModelDefinition model, byte[] var1) + void decodeType3(ModelDefinition def, byte[] var1) { InputStream var2 = new InputStream(var1); - InputStream var24 = new InputStream(var1); InputStream var3 = new InputStream(var1); - InputStream var28 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); InputStream var6 = new InputStream(var1); - InputStream var55 = new InputStream(var1); - InputStream var51 = new InputStream(var1); - var2.setOffset(var1.length - 23); - int verticeCount = var2.readUnsignedShort(); - int triangleCount = var2.readUnsignedShort(); - int textureTriangleCount = var2.readUnsignedByte(); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 26); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); int var13 = var2.readUnsignedByte(); - int modelPriority = var2.readUnsignedByte(); - int var50 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); int var17 = var2.readUnsignedByte(); - int modelTexture = var2.readUnsignedByte(); - int modelVertexSkins = var2.readUnsignedByte(); + int var18 = var2.readUnsignedByte(); + int var19 = var2.readUnsignedShort(); int var20 = var2.readUnsignedShort(); int var21 = var2.readUnsignedShort(); - int var42 = var2.readUnsignedShort(); int var22 = var2.readUnsignedShort(); - int var38 = var2.readUnsignedShort(); - int textureAmount = 0; - int var7 = 0; - int var29 = 0; - int position; - if (textureTriangleCount > 0) + int var23 = var2.readUnsignedShort(); + int var24 = var2.readUnsignedShort(); + int var25 = 0; + int var26 = 0; + int var27 = 0; + int var28; + if (var11 > 0) { - model.textureRenderTypes = new byte[textureTriangleCount]; + def.textureRenderTypes = new byte[var11]; var2.setOffset(0); - for (position = 0; position < textureTriangleCount; ++position) + for (var28 = 0; var28 < var11; ++var28) { - byte renderType = model.textureRenderTypes[position] = var2.readByte(); - if (renderType == 0) + byte var29 = def.textureRenderTypes[var28] = var2.readByte(); + if (var29 == 0) { - ++textureAmount; + ++var25; } - if (renderType >= 1 && renderType <= 3) + if (var29 >= 1 && var29 <= 3) { - ++var7; + ++var26; } - if (renderType == 2) + if (var29 == 2) { - ++var29; + ++var27; } } } - position = textureTriangleCount + verticeCount; - int renderTypePos = position; - if (var13 == 1) + var28 = var11 + var9; + int var58 = var28; + if (var12 == 1) { - position += triangleCount; + var28 += var10; } - int var49 = position; - position += triangleCount; - int priorityPos = position; - if (modelPriority == 255) + int var30 = var28; + var28 += var10; + int var31 = var28; + if (var13 == 255) { - position += triangleCount; + var28 += var10; } - int triangleSkinPos = position; + int var32 = var28; + if (var15 == 1) + { + var28 += var10; + } + + int var33 = var28; + var28 += var24; + int var34 = var28; + if (var14 == 1) + { + var28 += var10; + } + + int var35 = var28; + var28 += var22; + int var36 = var28; + if (var16 == 1) + { + var28 += var10 * 2; + } + + int var37 = var28; + var28 += var23; + int var38 = var28; + var28 += var10 * 2; + int var39 = var28; + var28 += var19; + int var40 = var28; + var28 += var20; + int var41 = var28; + var28 += var21; + int var42 = var28; + var28 += var25 * 6; + int var43 = var28; + var28 += var26 * 6; + int var44 = var28; + var28 += var26 * 6; + int var45 = var28; + var28 += var26 * 2; + int var46 = var28; + var28 += var26; + int var47 = var28; + var28 = var28 + var26 * 2 + var27 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; if (var17 == 1) { - position += triangleCount; + def.packedVertexGroups = new int[var9]; } - int var35 = position; - if (modelVertexSkins == 1) + if (var12 == 1) { - position += verticeCount; + def.faceRenderTypes = new byte[var10]; } - int alphaPos = position; - if (var50 == 1) + if (var13 == 255) { - position += triangleCount; - } - - int var11 = position; - position += var22; - int texturePos = position; - if (modelTexture == 1) - { - position += triangleCount * 2; - } - - int textureCoordPos = position; - position += var38; - int colorPos = position; - position += triangleCount * 2; - int var40 = position; - position += var20; - int var41 = position; - position += var21; - int var8 = position; - position += var42; - int var43 = position; - position += textureAmount * 6; - int var37 = position; - position += var7 * 6; - int var48 = position; - position += var7 * 6; - int var56 = position; - position += var7 * 2; - int var45 = position; - position += var7; - int var46 = position; - position += var7 * 2 + var29 * 2; - model.vertexCount = verticeCount; - model.faceCount = triangleCount; - model.textureTriangleCount = textureTriangleCount; - model.vertexPositionsX = new int[verticeCount]; - model.vertexPositionsY = new int[verticeCount]; - model.vertexPositionsZ = new int[verticeCount]; - model.faceVertexIndices1 = new int[triangleCount]; - model.faceVertexIndices2 = new int[triangleCount]; - model.faceVertexIndices3 = new int[triangleCount]; - if (modelVertexSkins == 1) - { - model.vertexSkins = new int[verticeCount]; - } - - if (var13 == 1) - { - model.faceRenderTypes = new byte[triangleCount]; - } - - if (modelPriority == 255) - { - model.faceRenderPriorities = new byte[triangleCount]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) modelPriority; + def.priority = (byte) var13; } - if (var50 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[triangleCount]; + def.faceTransparencies = new byte[var10]; } - if (var17 == 1) + if (var15 == 1) { - model.faceSkins = new int[triangleCount]; + def.packedTransparencyVertexGroups = new int[var10]; } - if (modelTexture == 1) + if (var16 == 1) { - model.faceTextures = new short[triangleCount]; + def.faceTextures = new short[var10]; } - if (modelTexture == 1 && textureTriangleCount > 0) + if (var16 == 1 && var11 > 0) { - model.textureCoordinates = new byte[triangleCount]; + def.textureCoords = new byte[var10]; } - model.faceColors = new short[triangleCount]; - if (textureTriangleCount > 0) + if (var18 == 1) { - model.textureTriangleVertexIndices1 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices2 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices3 = new short[textureTriangleCount]; - if (var7 > 0) - { - model.aShortArray2574 = new short[var7]; - model.aShortArray2575 = new short[var7]; - model.aShortArray2586 = new short[var7]; - model.aShortArray2577 = new short[var7]; - model.aByteArray2580 = new byte[var7]; - model.aShortArray2578 = new short[var7]; - } - - if (var29 > 0) - { - model.texturePrimaryColors = new short[var29]; - } + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; } - var2.setOffset(textureTriangleCount); - var24.setOffset(var40); - var3.setOffset(var41); - var28.setOffset(var8); - var6.setOffset(var35); - int vX = 0; - int vY = 0; - int vZ = 0; - - int vertexZOffset; - int var10; - int vertexYOffset; - int var15; - int point; - for (point = 0; point < verticeCount; ++point) + def.faceColors = new short[var10]; + if (var11 > 0) { - int vertexFlags = var2.readUnsignedByte(); - int vertexXOffset = 0; - if ((vertexFlags & 1) != 0) - { - vertexXOffset = var24.readShortSmart(); - } - - vertexYOffset = 0; - if ((vertexFlags & 2) != 0) - { - vertexYOffset = var3.readShortSmart(); - } - - vertexZOffset = 0; - if ((vertexFlags & 4) != 0) - { - vertexZOffset = var28.readShortSmart(); - } - - model.vertexPositionsX[point] = vX + vertexXOffset; - model.vertexPositionsY[point] = vY + vertexYOffset; - model.vertexPositionsZ[point] = vZ + vertexZOffset; - vX = model.vertexPositionsX[point]; - vY = model.vertexPositionsY[point]; - vZ = model.vertexPositionsZ[point]; - if (modelVertexSkins == 1) - { - model.vertexSkins[point] = var6.readUnsignedByte(); - } - } - - var2.setOffset(colorPos); - var24.setOffset(renderTypePos); - var3.setOffset(priorityPos); - var28.setOffset(alphaPos); - var6.setOffset(triangleSkinPos); - var55.setOffset(texturePos); - var51.setOffset(textureCoordPos); - - for (point = 0; point < triangleCount; ++point) - { - model.faceColors[point] = (short) var2.readUnsignedShort(); - if (var13 == 1) - { - model.faceRenderTypes[point] = var24.readByte(); - } - - if (modelPriority == 255) - { - model.faceRenderPriorities[point] = var3.readByte(); - } - - if (var50 == 1) - { - model.faceAlphas[point] = var28.readByte(); - } - - if (var17 == 1) - { - model.faceSkins[point] = var6.readUnsignedByte(); - } - - if (modelTexture == 1) - { - model.faceTextures[point] = (short) (var55.readUnsignedShort() - 1); - } - - if (model.textureCoordinates != null && model.faceTextures[point] != -1) - { - model.textureCoordinates[point] = (byte) (var51.readUnsignedByte() - 1); - } + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } var2.setOffset(var11); - var24.setOffset(var49); - int trianglePointX = 0; - int trianglePointY = 0; - int trianglePointZ = 0; - vertexYOffset = 0; + var3.setOffset(var39); + var4.setOffset(var40); + var5.setOffset(var41); + var6.setOffset(var33); + int var48 = 0; + int var49 = 0; + int var50 = 0; - int var16; - for (vertexZOffset = 0; vertexZOffset < triangleCount; ++vertexZOffset) + int var51; + int var52; + int var53; + int var54; + int var55; + for (var51 = 0; var51 < var9; ++var51) { - int numFaces = var24.readUnsignedByte(); - if (numFaces == 1) + var52 = var2.readUnsignedByte(); + var53 = 0; + if ((var52 & 1) != 0) { - trianglePointX = var2.readShortSmart() + vertexYOffset; - trianglePointY = var2.readShortSmart() + trianglePointX; - trianglePointZ = var2.readShortSmart() + trianglePointY; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var53 = var3.readShortSmart(); } - if (numFaces == 2) + var54 = 0; + if ((var52 & 2) != 0) { - trianglePointY = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var54 = var4.readShortSmart(); } - if (numFaces == 3) + var55 = 0; + if ((var52 & 4) != 0) { - trianglePointX = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var55 = var5.readShortSmart(); } - if (numFaces == 4) + def.vertexX[var51] = var48 + var53; + def.vertexY[var51] = var49 + var54; + def.vertexZ[var51] = var50 + var55; + var48 = def.vertexX[var51]; + var49 = def.vertexY[var51]; + var50 = def.vertexZ[var51]; + if (var17 == 1) { - int var57 = trianglePointX; - trianglePointX = trianglePointY; - trianglePointY = var57; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = var57; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + def.packedVertexGroups[var51] = var6.readUnsignedByte(); } } - var2.setOffset(var43); - var24.setOffset(var37); - var3.setOffset(var48); - var28.setOffset(var56); - var6.setOffset(var45); - var55.setOffset(var46); - - for (int texIndex = 0; texIndex < textureTriangleCount; ++texIndex) + if (var18 == 1) { - int type = model.textureRenderTypes[texIndex] & 255; - if (type == 0) + for (var51 = 0; var51 < var9; ++var51) { - model.textureTriangleVertexIndices1[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var2.readUnsignedShort(); - } + var52 = var6.readUnsignedByte(); + def.animayaGroups[var51] = new int[var52]; + def.animayaScales[var51] = new int[var52]; - if (type == 1) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 2) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - model.texturePrimaryColors[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 3) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); + for (var53 = 0; var53 < var52; ++var53) + { + def.animayaGroups[var51][var53] = var6.readUnsignedByte(); + def.animayaScales[var51][var53] = var6.readUnsignedByte(); + } } } - var2.setOffset(position); - vertexZOffset = var2.readUnsignedByte(); - if (vertexZOffset != 0) + var2.setOffset(var38); + var3.setOffset(var58); + var4.setOffset(var31); + var5.setOffset(var34); + var6.setOffset(var32); + var7.setOffset(var36); + var8.setOffset(var37); + + for (var51 = 0; var51 < var10; ++var51) + { + def.faceColors[var51] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var51] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var51] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var51] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var51] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var51] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var51] != -1) + { + def.textureCoords[var51] = (byte) (var8.readUnsignedByte() - 1); + } + } + + var2.setOffset(var35); + var3.setOffset(var30); + var51 = 0; + var52 = 0; + var53 = 0; + var54 = 0; + + int var56; + for (var55 = 0; var55 < var10; ++var55) + { + var56 = var3.readUnsignedByte(); + if (var56 == 1) + { + var51 = var2.readShortSmart() + var54; + var52 = var2.readShortSmart() + var51; + var53 = var2.readShortSmart() + var52; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 2) + { + var52 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 3) + { + var51 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 4) + { + int var57 = var51; + var51 = var52; + var52 = var57; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var57; + def.faceIndices3[var55] = var53; + } + } + + var2.setOffset(var42); + var3.setOffset(var43); + var4.setOffset(var44); + var5.setOffset(var45); + var6.setOffset(var46); + var7.setOffset(var47); + + for (var55 = 0; var55 < var11; ++var55) + { + var56 = def.textureRenderTypes[var55] & 255; + if (var56 == 0) + { + def.texIndices1[var55] = (short) var2.readUnsignedShort(); + def.texIndices2[var55] = (short) var2.readUnsignedShort(); + def.texIndices3[var55] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var28); + var55 = var2.readUnsignedByte(); + if (var55 != 0) { - //new Class41(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readInt(); } + } - private void load2(ModelDefinition model, byte[] var1) + void decodeType2(ModelDefinition def, byte[] var1) { boolean var2 = false; - boolean var43 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); InputStream var5 = new InputStream(var1); - InputStream var39 = new InputStream(var1); - InputStream var26 = new InputStream(var1); - InputStream var9 = new InputStream(var1); - InputStream var3 = new InputStream(var1); - var5.setOffset(var1.length - 18); - int var10 = var5.readUnsignedShort(); - int var11 = var5.readUnsignedShort(); - int var12 = var5.readUnsignedByte(); - int var13 = var5.readUnsignedByte(); - int var14 = var5.readUnsignedByte(); - int var30 = var5.readUnsignedByte(); - int var15 = var5.readUnsignedByte(); - int var28 = var5.readUnsignedByte(); - int var27 = var5.readUnsignedShort(); - int var20 = var5.readUnsignedShort(); - int var36 = var5.readUnsignedShort(); - int var23 = var5.readUnsignedShort(); - byte var16 = 0; - int var46 = var16 + var10; - int var24 = var46; - var46 += var11; - int var25 = var46; - if (var14 == 255) + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 23); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedByte(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + int var21 = var4.readUnsignedShort(); + int var22 = var4.readUnsignedShort(); + byte var23 = 0; + int var24 = var23 + var9; + int var25 = var24; + var24 += var10; + int var26 = var24; + if (var13 == 255) { - var46 += var11; + var24 += var10; } - int var4 = var46; + int var27 = var24; if (var15 == 1) { - var46 += var11; + var24 += var10; } - int var42 = var46; - if (var13 == 1) + int var28 = var24; + if (var12 == 1) { - var46 += var11; + var24 += var10; } - int var37 = var46; - if (var28 == 1) + int var29 = var24; + var24 += var22; + int var30 = var24; + if (var14 == 1) { - var46 += var10; + var24 += var10; } - int var29 = var46; - if (var30 == 1) + int var31 = var24; + var24 += var21; + int var32 = var24; + var24 += var10 * 2; + int var33 = var24; + var24 += var11 * 6; + int var34 = var24; + var24 += var18; + int var35 = var24; + var24 += var19; + int var10000 = var24 + var20; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) { - var46 += var11; + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } - int var44 = var46; - var46 += var23; - int var17 = var46; - var46 += var11 * 2; - int var32 = var46; - var46 += var12 * 6; - int var34 = var46; - var46 += var27; - int var35 = var46; - var46 += var20; - int var10000 = var46 + var36; - model.vertexCount = var10; - model.faceCount = var11; - model.textureTriangleCount = var12; - model.vertexPositionsX = new int[var10]; - model.vertexPositionsY = new int[var10]; - model.vertexPositionsZ = new int[var10]; - model.faceVertexIndices1 = new int[var11]; - model.faceVertexIndices2 = new int[var11]; - model.faceVertexIndices3 = new int[var11]; - if (var12 > 0) + if (var16 == 1) { - model.textureRenderTypes = new byte[var12]; - model.textureTriangleVertexIndices1 = new short[var12]; - model.textureTriangleVertexIndices2 = new short[var12]; - model.textureTriangleVertexIndices3 = new short[var12]; + def.packedVertexGroups = new int[var9]; } - if (var28 == 1) + if (var12 == 1) { - model.vertexSkins = new int[var10]; + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; } - if (var13 == 1) + if (var13 == 255) { - model.faceRenderTypes = new byte[var11]; - model.textureCoordinates = new byte[var11]; - model.faceTextures = new short[var11]; - } - - if (var14 == 255) - { - model.faceRenderPriorities = new byte[var11]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) var14; + def.priority = (byte) var13; } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[var11]; + def.faceTransparencies = new byte[var10]; } if (var15 == 1) { - model.faceSkins = new int[var11]; + def.packedTransparencyVertexGroups = new int[var10]; } - model.faceColors = new short[var11]; - var5.setOffset(var16); - var39.setOffset(var34); - var26.setOffset(var35); - var9.setOffset(var46); - var3.setOffset(var37); - int var41 = 0; - int var33 = 0; - int var19 = 0; - - int var6; - int var7; - int var8; - int var18; - int var31; - for (var18 = 0; var18 < var10; ++var18) + if (var17 == 1) { - var8 = var5.readUnsignedByte(); - var31 = 0; - if ((var8 & 1) != 0) + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var23); + var5.setOffset(var34); + var6.setOffset(var35); + var7.setOffset(var24); + var8.setOffset(var29); + int var37 = 0; + int var38 = 0; + int var39 = 0; + + int var40; + int var41; + int var42; + int var43; + int var44; + for (var40 = 0; var40 < var9; ++var40) + { + var41 = var4.readUnsignedByte(); + var42 = 0; + if ((var41 & 1) != 0) { - var31 = var39.readShortSmart(); + var42 = var5.readShortSmart(); } - var6 = 0; - if ((var8 & 2) != 0) + var43 = 0; + if ((var41 & 2) != 0) { - var6 = var26.readShortSmart(); + var43 = var6.readShortSmart(); } - var7 = 0; - if ((var8 & 4) != 0) + var44 = 0; + if ((var41 & 4) != 0) { - var7 = var9.readShortSmart(); + var44 = var7.readShortSmart(); } - model.vertexPositionsX[var18] = var41 + var31; - model.vertexPositionsY[var18] = var33 + var6; - model.vertexPositionsZ[var18] = var19 + var7; - var41 = model.vertexPositionsX[var18]; - var33 = model.vertexPositionsY[var18]; - var19 = model.vertexPositionsZ[var18]; - if (var28 == 1) + def.vertexX[var40] = var37 + var42; + def.vertexY[var40] = var38 + var43; + def.vertexZ[var40] = var39 + var44; + var37 = def.vertexX[var40]; + var38 = def.vertexY[var40]; + var39 = def.vertexZ[var40]; + if (var16 == 1) { - model.vertexSkins[var18] = var3.readUnsignedByte(); + def.packedVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var17); - var39.setOffset(var42); - var26.setOffset(var25); - var9.setOffset(var29); - var3.setOffset(var4); - - for (var18 = 0; var18 < var11; ++var18) + if (var17 == 1) { - model.faceColors[var18] = (short) var5.readUnsignedShort(); - if (var13 == 1) + for (var40 = 0; var40 < var9; ++var40) { - var8 = var39.readUnsignedByte(); - if ((var8 & 1) == 1) + var41 = var8.readUnsignedByte(); + def.animayaGroups[var40] = new int[var41]; + def.animayaScales[var40] = new int[var41]; + + for (var42 = 0; var42 < var41; ++var42) { - model.faceRenderTypes[var18] = 1; + def.animayaGroups[var40][var42] = var8.readUnsignedByte(); + def.animayaScales[var40][var42] = var8.readUnsignedByte(); + } + } + } + + var4.setOffset(var32); + var5.setOffset(var28); + var6.setOffset(var26); + var7.setOffset(var30); + var8.setOffset(var27); + + for (var40 = 0; var40 < var10; ++var40) + { + def.faceColors[var40] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var41 = var5.readUnsignedByte(); + if ((var41 & 1) == 1) + { + def.faceRenderTypes[var40] = 1; var2 = true; } else { - model.faceRenderTypes[var18] = 0; + def.faceRenderTypes[var40] = 0; } - if ((var8 & 2) == 2) + if ((var41 & 2) == 2) { - model.textureCoordinates[var18] = (byte) (var8 >> 2); - model.faceTextures[var18] = model.faceColors[var18]; - model.faceColors[var18] = 127; - if (model.faceTextures[var18] != -1) + def.textureCoords[var40] = (byte) (var41 >> 2); + def.faceTextures[var40] = def.faceColors[var40]; + def.faceColors[var40] = 127; + if (def.faceTextures[var40] != -1) { - var43 = true; + var3 = true; } } else { - model.textureCoordinates[var18] = -1; - model.faceTextures[var18] = -1; + def.textureCoords[var40] = -1; + def.faceTextures[var40] = -1; } } - if (var14 == 255) + if (var13 == 255) { - model.faceRenderPriorities[var18] = var26.readByte(); + def.faceRenderPriorities[var40] = var6.readByte(); } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas[var18] = var9.readByte(); + def.faceTransparencies[var40] = var7.readByte(); } if (var15 == 1) { - model.faceSkins[var18] = var3.readUnsignedByte(); + def.packedTransparencyVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var44); - var39.setOffset(var24); - var18 = 0; - var8 = 0; - var31 = 0; - var6 = 0; + var4.setOffset(var31); + var5.setOffset(var25); + var40 = 0; + var41 = 0; + var42 = 0; + var43 = 0; - int var21; - int var22; - for (var7 = 0; var7 < var11; ++var7) + int var45; + int var46; + for (var44 = 0; var44 < var10; ++var44) { - var22 = var39.readUnsignedByte(); - if (var22 == 1) + var45 = var5.readUnsignedByte(); + if (var45 == 1) { - var18 = var5.readShortSmart() + var6; - var8 = var5.readShortSmart() + var18; - var31 = var5.readShortSmart() + var8; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var4.readShortSmart() + var43; + var41 = var4.readShortSmart() + var40; + var42 = var4.readShortSmart() + var41; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 2) + if (var45 == 2) { - var8 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var41 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 3) + if (var45 == 3) { - var18 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 4) + if (var45 == 4) { - var21 = var18; - var18 = var8; - var8 = var21; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var21; - model.faceVertexIndices3[var7] = var31; + var46 = var40; + var40 = var41; + var41 = var46; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var46; + def.faceIndices3[var44] = var42; } } + var4.setOffset(var33); + + for (var44 = 0; var44 < var11; ++var44) + { + def.textureRenderTypes[var44] = 0; + def.texIndices1[var44] = (short) var4.readUnsignedShort(); + def.texIndices2[var44] = (short) var4.readUnsignedShort(); + def.texIndices3[var44] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) + { + boolean var47 = false; + + for (var45 = 0; var45 < var10; ++var45) + { + var46 = def.textureCoords[var45] & 255; + if (var46 != 255) + { + if (def.faceIndices1[var45] == (def.texIndices1[var46] & '\uffff') && def.faceIndices2[var45] == (def.texIndices2[var46] & '\uffff') && def.faceIndices3[var45] == (def.texIndices3[var46] & '\uffff')) + { + def.textureCoords[var45] = -1; + } + else + { + var47 = true; + } + } + } + + if (!var47) + { + def.textureCoords = null; + } + } + + if (!var3) + { + def.faceTextures = null; + } + + if (!var2) + { + def.faceRenderTypes = null; + } + + } + + void decodeType1(ModelDefinition def, byte[] var1) + { + InputStream var2 = new InputStream(var1); + InputStream var3 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 23); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); + int var13 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); + int var17 = var2.readUnsignedByte(); + int var18 = var2.readUnsignedShort(); + int var19 = var2.readUnsignedShort(); + int var20 = var2.readUnsignedShort(); + int var21 = var2.readUnsignedShort(); + int var22 = var2.readUnsignedShort(); + int var23 = 0; + int var24 = 0; + int var25 = 0; + int var26; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + var2.setOffset(0); + + for (var26 = 0; var26 < var11; ++var26) + { + byte var27 = def.textureRenderTypes[var26] = var2.readByte(); + if (var27 == 0) + { + ++var23; + } + + if (var27 >= 1 && var27 <= 3) + { + ++var24; + } + + if (var27 == 2) + { + ++var25; + } + } + } + + var26 = var11 + var9; + int var56 = var26; + if (var12 == 1) + { + var26 += var10; + } + + int var28 = var26; + var26 += var10; + int var29 = var26; + if (var13 == 255) + { + var26 += var10; + } + + int var30 = var26; + if (var15 == 1) + { + var26 += var10; + } + + int var31 = var26; + if (var17 == 1) + { + var26 += var9; + } + + int var32 = var26; + if (var14 == 1) + { + var26 += var10; + } + + int var33 = var26; + var26 += var21; + int var34 = var26; + if (var16 == 1) + { + var26 += var10 * 2; + } + + int var35 = var26; + var26 += var22; + int var36 = var26; + var26 += var10 * 2; + int var37 = var26; + var26 += var18; + int var38 = var26; + var26 += var19; + int var39 = var26; + var26 += var20; + int var40 = var26; + var26 += var23 * 6; + int var41 = var26; + var26 += var24 * 6; + int var42 = var26; + var26 += var24 * 6; + int var43 = var26; + var26 += var24 * 2; + int var44 = var26; + var26 += var24; + int var45 = var26; + var26 = var26 + var24 * 2 + var25 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var17 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + if (var16 == 1) + { + def.faceTextures = new short[var10]; + } + + if (var16 == 1 && var11 > 0) + { + def.textureCoords = new byte[var10]; + } + + def.faceColors = new short[var10]; + if (var11 > 0) + { + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + var2.setOffset(var11); + var3.setOffset(var37); + var4.setOffset(var38); + var5.setOffset(var39); + var6.setOffset(var31); + int var46 = 0; + int var47 = 0; + int var48 = 0; + + int var49; + int var50; + int var51; + int var52; + int var53; + for (var49 = 0; var49 < var9; ++var49) + { + var50 = var2.readUnsignedByte(); + var51 = 0; + if ((var50 & 1) != 0) + { + var51 = var3.readShortSmart(); + } + + var52 = 0; + if ((var50 & 2) != 0) + { + var52 = var4.readShortSmart(); + } + + var53 = 0; + if ((var50 & 4) != 0) + { + var53 = var5.readShortSmart(); + } + + def.vertexX[var49] = var46 + var51; + def.vertexY[var49] = var47 + var52; + def.vertexZ[var49] = var48 + var53; + var46 = def.vertexX[var49]; + var47 = def.vertexY[var49]; + var48 = def.vertexZ[var49]; + if (var17 == 1) + { + def.packedVertexGroups[var49] = var6.readUnsignedByte(); + } + } + + var2.setOffset(var36); + var3.setOffset(var56); + var4.setOffset(var29); var5.setOffset(var32); + var6.setOffset(var30); + var7.setOffset(var34); + var8.setOffset(var35); - for (var7 = 0; var7 < var12; ++var7) + for (var49 = 0; var49 < var10; ++var49) { - model.textureRenderTypes[var7] = 0; - model.textureTriangleVertexIndices1[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices2[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices3[var7] = (short) var5.readUnsignedShort(); + def.faceColors[var49] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var49] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var49] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var49] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var49] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var49] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var49] != -1) + { + def.textureCoords[var49] = (byte) (var8.readUnsignedByte() - 1); + } } - if (model.textureCoordinates != null) + var2.setOffset(var33); + var3.setOffset(var28); + var49 = 0; + var50 = 0; + var51 = 0; + var52 = 0; + + int var54; + for (var53 = 0; var53 < var10; ++var53) + { + var54 = var3.readUnsignedByte(); + if (var54 == 1) + { + var49 = var2.readShortSmart() + var52; + var50 = var2.readShortSmart() + var49; + var51 = var2.readShortSmart() + var50; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 2) + { + var50 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 3) + { + var49 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 4) + { + int var55 = var49; + var49 = var50; + var50 = var55; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var55; + def.faceIndices3[var53] = var51; + } + } + + var2.setOffset(var40); + var3.setOffset(var41); + var4.setOffset(var42); + var5.setOffset(var43); + var6.setOffset(var44); + var7.setOffset(var45); + + for (var53 = 0; var53 < var11; ++var53) + { + var54 = def.textureRenderTypes[var53] & 255; + if (var54 == 0) + { + def.texIndices1[var53] = (short) var2.readUnsignedShort(); + def.texIndices2[var53] = (short) var2.readUnsignedShort(); + def.texIndices3[var53] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var26); + var53 = var2.readUnsignedByte(); + if (var53 != 0) + { + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readInt(); + } + + } + + void decodeOldFormat(ModelDefinition def, byte[] var1) + { + boolean var2 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 18); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedShort(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + byte var21 = 0; + int var22 = var21 + var9; + int var23 = var22; + var22 += var10; + int var24 = var22; + if (var13 == 255) + { + var22 += var10; + } + + int var25 = var22; + if (var15 == 1) + { + var22 += var10; + } + + int var26 = var22; + if (var12 == 1) + { + var22 += var10; + } + + int var27 = var22; + if (var16 == 1) + { + var22 += var9; + } + + int var28 = var22; + if (var14 == 1) + { + var22 += var10; + } + + int var29 = var22; + var22 += var20; + int var30 = var22; + var22 += var10 * 2; + int var31 = var22; + var22 += var11 * 6; + int var32 = var22; + var22 += var17; + int var33 = var22; + var22 += var18; + int var10000 = var22 + var19; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + if (var16 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var21); + var5.setOffset(var32); + var6.setOffset(var33); + var7.setOffset(var22); + var8.setOffset(var27); + int var35 = 0; + int var36 = 0; + int var37 = 0; + + int var38; + int var39; + int var40; + int var41; + int var42; + for (var38 = 0; var38 < var9; ++var38) + { + var39 = var4.readUnsignedByte(); + var40 = 0; + if ((var39 & 1) != 0) + { + var40 = var5.readShortSmart(); + } + + var41 = 0; + if ((var39 & 2) != 0) + { + var41 = var6.readShortSmart(); + } + + var42 = 0; + if ((var39 & 4) != 0) + { + var42 = var7.readShortSmart(); + } + + def.vertexX[var38] = var35 + var40; + def.vertexY[var38] = var36 + var41; + def.vertexZ[var38] = var37 + var42; + var35 = def.vertexX[var38]; + var36 = def.vertexY[var38]; + var37 = def.vertexZ[var38]; + if (var16 == 1) + { + def.packedVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var30); + var5.setOffset(var26); + var6.setOffset(var24); + var7.setOffset(var28); + var8.setOffset(var25); + + for (var38 = 0; var38 < var10; ++var38) + { + def.faceColors[var38] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var39 = var5.readUnsignedByte(); + if ((var39 & 1) == 1) + { + def.faceRenderTypes[var38] = 1; + var2 = true; + } + else + { + def.faceRenderTypes[var38] = 0; + } + + if ((var39 & 2) == 2) + { + def.textureCoords[var38] = (byte) (var39 >> 2); + def.faceTextures[var38] = def.faceColors[var38]; + def.faceColors[var38] = 127; + if (def.faceTextures[var38] != -1) + { + var3 = true; + } + } + else + { + def.textureCoords[var38] = -1; + def.faceTextures[var38] = -1; + } + } + + if (var13 == 255) + { + def.faceRenderPriorities[var38] = var6.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var38] = var7.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var29); + var5.setOffset(var23); + var38 = 0; + var39 = 0; + var40 = 0; + var41 = 0; + + int var43; + int var44; + for (var42 = 0; var42 < var10; ++var42) + { + var43 = var5.readUnsignedByte(); + if (var43 == 1) + { + var38 = var4.readShortSmart() + var41; + var39 = var4.readShortSmart() + var38; + var40 = var4.readShortSmart() + var39; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 2) + { + var39 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 3) + { + var38 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 4) + { + var44 = var38; + var38 = var39; + var39 = var44; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var44; + def.faceIndices3[var42] = var40; + } + } + + var4.setOffset(var31); + + for (var42 = 0; var42 < var11; ++var42) + { + def.textureRenderTypes[var42] = 0; + def.texIndices1[var42] = (short) var4.readUnsignedShort(); + def.texIndices2[var42] = (short) var4.readUnsignedShort(); + def.texIndices3[var42] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) { boolean var45 = false; - for (var22 = 0; var22 < var11; ++var22) + for (var43 = 0; var43 < var10; ++var43) { - var21 = model.textureCoordinates[var22] & 255; - if (var21 != 255) + var44 = def.textureCoords[var43] & 255; + if (var44 != 255) { - if ((model.textureTriangleVertexIndices1[var21] & '\uffff') == model.faceVertexIndices1[var22] && (model.textureTriangleVertexIndices2[var21] & '\uffff') == model.faceVertexIndices2[var22] && (model.textureTriangleVertexIndices3[var21] & '\uffff') == model.faceVertexIndices3[var22]) + if (def.faceIndices1[var43] == (def.texIndices1[var44] & '\uffff') && def.faceIndices2[var43] == (def.texIndices2[var44] & '\uffff') && def.faceIndices3[var43] == (def.texIndices3[var44] & '\uffff')) { - model.textureCoordinates[var22] = -1; + def.textureCoords[var43] = -1; } else { @@ -732,19 +1394,19 @@ public class ModelLoader if (!var45) { - model.textureCoordinates = null; + def.textureCoords = null; } } - if (!var43) + if (!var3) { - model.faceTextures = null; + def.faceTextures = null; } if (!var2) { - model.faceRenderTypes = null; + def.faceRenderTypes = null; } - } + } } diff --git a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java index c93edf3611..cd70e9b218 100644 --- a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java +++ b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java @@ -227,22 +227,22 @@ public class ItemSpriteFactory litModel.field1856 = new int[def.faceCount]; litModel.field1854 = new int[def.faceCount]; litModel.field1823 = new int[def.faceCount]; - if (def.textureTriangleCount > 0 && def.textureCoordinates != null) + if (def.numTextureFaces > 0 && def.textureCoords != null) { - int[] var9 = new int[def.textureTriangleCount]; + int[] var9 = new int[def.numTextureFaces]; int var10; for (var10 = 0; var10 < def.faceCount; ++var10) { - if (def.textureCoordinates[var10] != -1) + if (def.textureCoords[var10] != -1) { - ++var9[def.textureCoordinates[var10] & 255]; + ++var9[def.textureCoords[var10] & 255]; } } litModel.field1852 = 0; - for (var10 = 0; var10 < def.textureTriangleCount; ++var10) + for (var10 = 0; var10 < def.numTextureFaces; ++var10) { if (var9[var10] > 0 && def.textureRenderTypes[var10] == 0) { @@ -256,13 +256,13 @@ public class ItemSpriteFactory var10 = 0; - for (int i = 0; i < def.textureTriangleCount; ++i) + for (int i = 0; i < def.numTextureFaces; ++i) { if (var9[i] > 0 && def.textureRenderTypes[i] == 0) { - litModel.field1844[var10] = def.textureTriangleVertexIndices1[i] & '\uffff'; - litModel.field1865[var10] = def.textureTriangleVertexIndices2[i] & '\uffff'; - litModel.field1846[var10] = def.textureTriangleVertexIndices3[i] & '\uffff'; + litModel.field1844[var10] = def.texIndices1[i] & '\uffff'; + litModel.field1865[var10] = def.texIndices2[i] & '\uffff'; + litModel.field1846[var10] = def.texIndices3[i] & '\uffff'; var9[i] = var10++; } else @@ -275,9 +275,9 @@ public class ItemSpriteFactory for (int i = 0; i < def.faceCount; ++i) { - if (def.textureCoordinates[i] != -1) + if (def.textureCoords[i] != -1) { - litModel.field1840[i] = (byte) var9[def.textureCoordinates[i] & 255]; + litModel.field1840[i] = (byte) var9[def.textureCoords[i] & 255]; } else { @@ -299,13 +299,13 @@ public class ItemSpriteFactory } byte faceAlpha; - if (def.faceAlphas == null) + if (def.faceTransparencies == null) { faceAlpha = 0; } else { - faceAlpha = def.faceAlphas[faceIdx]; + faceAlpha = def.faceTransparencies[faceIdx]; } short faceTexture; @@ -355,15 +355,15 @@ public class ItemSpriteFactory else { int var15 = def.faceColors[faceIdx] & '\uffff'; - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = method2608(var15, tmp); @@ -385,15 +385,15 @@ public class ItemSpriteFactory } else { - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = bound2to126(tmp); @@ -401,15 +401,15 @@ public class ItemSpriteFactory } litModel.verticesCount = def.vertexCount; - litModel.verticesX = def.vertexPositionsX; - litModel.verticesY = def.vertexPositionsY; - litModel.verticesZ = def.vertexPositionsZ; + litModel.verticesX = def.vertexX; + litModel.verticesY = def.vertexY; + litModel.verticesZ = def.vertexZ; litModel.indicesCount = def.faceCount; - litModel.indices1 = def.faceVertexIndices1; - litModel.indices2 = def.faceVertexIndices2; - litModel.indices3 = def.faceVertexIndices3; + litModel.indices1 = def.faceIndices1; + litModel.indices2 = def.faceIndices2; + litModel.indices3 = def.faceIndices3; litModel.field1838 = def.faceRenderPriorities; - litModel.field1882 = def.faceAlphas; + litModel.field1882 = def.faceTransparencies; litModel.field1842 = def.priority; litModel.field1841 = def.faceTextures; return litModel; diff --git a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java index fb65f99972..75b67f689f 100644 --- a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java +++ b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java @@ -53,9 +53,9 @@ public class ObjExporter for (int i = 0; i < model.vertexCount; ++i) { - objWriter.println("v " + model.vertexPositionsX[i] + " " - + model.vertexPositionsY[i] * -1 + " " - + model.vertexPositionsZ[i] * -1); + objWriter.println("v " + model.vertexX[i] + " " + + model.vertexY[i] * -1 + " " + + model.vertexZ[i] * -1); } if (model.faceTextures != null) @@ -78,9 +78,9 @@ public class ObjExporter for (int i = 0; i < model.faceCount; ++i) { - int x = model.faceVertexIndices1[i] + 1; - int y = model.faceVertexIndices2[i] + 1; - int z = model.faceVertexIndices3[i] + 1; + int x = model.faceIndices1[i] + 1; + int y = model.faceIndices2[i] + 1; + int z = model.faceIndices3[i] + 1; objWriter.println("usemtl m" + i); if (model.faceTextures != null) @@ -129,9 +129,9 @@ public class ObjExporter int alpha = 0; - if (model.faceAlphas != null) + if (model.faceTransparencies != null) { - alpha = model.faceAlphas[i] & 0xFF; + alpha = model.faceTransparencies[i] & 0xFF; } if (alpha != 0) From a3ed6c089f420642fe55e765b183cbe2be2dbc9a Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 12 Dec 2021 11:00:45 -0500 Subject: [PATCH 10/17] gpu: add model hsl override support --- .../src/main/java/net/runelite/api/Model.java | 5 ++ .../client/plugins/gpu/SceneUploader.java | 60 ++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java index d3756ea727..03045dac2c 100644 --- a/runelite-api/src/main/java/net/runelite/api/Model.java +++ b/runelite-api/src/main/java/net/runelite/api/Model.java @@ -89,4 +89,9 @@ public interface Model extends Renderable int[] getVertexNormalsX(); int[] getVertexNormalsY(); int[] getVertexNormalsZ(); + + byte getOverrideAmount(); + byte getOverrideHue(); + byte getOverrideSaturation(); + byte getOverrideLuminance(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index 1bf9dcce63..82f8676ce5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -402,6 +402,11 @@ class SceneUploader float[] uv = model.getFaceTextureUVCoordinates(); + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int len = 0; for (int face = 0; face < triangleCount; ++face) { @@ -429,6 +434,16 @@ class SceneUploader len += 3; continue; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); @@ -470,14 +485,19 @@ class SceneUploader final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); - int triangleA = indices1[face]; - int triangleB = indices2[face]; - int triangleC = indices3[face]; + final int triangleA = indices1[face]; + final int triangleB = indices2[face]; + final int triangleC = indices3[face]; int color1 = color1s[face]; int color2 = color2s[face]; int color3 = color3s[face]; + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int packedAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); int sin = 0, cos = 0; @@ -505,6 +525,16 @@ class SceneUploader } return 3; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int a, b, c; @@ -605,4 +635,28 @@ class SceneUploader uvBuffer.put(0, 0, 0, 0); } } + + private static int interpolateHSL(int hsl, byte hue2, byte sat2, byte lum2, byte lerp) + { + int hue = hsl >> 10 & 63; + int sat = hsl >> 7 & 7; + int lum = hsl & 127; + int var9 = lerp & 255; + if (hue2 != -1) + { + hue += var9 * (hue2 - hue) >> 7; + } + + if (sat2 != -1) + { + sat += var9 * (sat2 - sat) >> 7; + } + + if (lum2 != -1) + { + lum += var9 * (lum2 - lum) >> 7; + } + + return (hue << 10 | sat << 7 | lum) & 65535; + } } From 51cab2a3d80158fa0da57e6573b5c92f4762e2c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 12 Dec 2021 13:17:04 -0500 Subject: [PATCH 11/17] nmz: fix point overlay flickering with unlocked fps --- .../nightmarezone/NightmareZoneOverlay.java | 7 ------- .../nightmarezone/NightmareZonePlugin.java | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index 679f773913..4ad21005b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -91,13 +91,6 @@ class NightmareZoneOverlay extends OverlayPanel return null; } - Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); - - if (nmzWidget != null) - { - nmzWidget.setHidden(true); - } - renderAbsorptionCounter(); final int currentPoints = client.getVar(Varbits.NMZ_POINTS); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java index ccd2a775c0..f95e2ab8a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java @@ -33,6 +33,7 @@ import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Varbits; +import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ChatMessage; import net.runelite.client.events.ConfigChanged; import net.runelite.api.events.GameTick; @@ -121,6 +122,21 @@ public class NightmareZonePlugin extends Plugin return configManager.getConfig(NightmareZoneConfig.class); } + @Subscribe + public void onBeforeRender(BeforeRender beforeRender) + { + if (!isInNightmareZone() || !config.moveOverlay()) + { + return; + } + + Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); + if (nmzWidget != null) + { + nmzWidget.setHidden(true); + } + } + @Subscribe public void onGameTick(GameTick event) { From 0c76977381ade2a8d5d74a8fb593d51717461326 Mon Sep 17 00:00:00 2001 From: Wayne Li Date: Sun, 12 Dec 2021 17:26:49 -0800 Subject: [PATCH 12/17] hiscores: fix npe --- .../net/runelite/client/plugins/hiscore/NameAutocompleter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java index 00cadc1e22..3870803490 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java @@ -242,6 +242,7 @@ class NameAutocompleter implements KeyListener autocompleteName = Arrays.stream(cachedPlayers) .filter(Objects::nonNull) .map(Player::getName) + .filter(Objects::nonNull) .filter(n -> pattern.matcher(n).matches()) .findFirst(); } From 36e670112ee7fc8d808b17f46d9989dd0cc0851f Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 13 Dec 2021 17:35:39 -0500 Subject: [PATCH 13/17] widget inspector: add listeners --- .../plugins/devtools/WidgetInfoTableModel.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java index 5e5e9a6011..ed99e6ef70 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java @@ -48,16 +48,16 @@ public class WidgetInfoTableModel extends AbstractTableModel private static final int COL_FIELD = 0; private static final int COL_VALUE = 1; - private final List fields = populateWidgetFields(); + private final List> fields = populateWidgetFields(); private Widget widget = null; - private Map values = null; + private Map, Object> values = null; public void setWidget(Widget w) { clientThread.invoke(() -> { - Map newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( + Map, Object> newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( Function.identity(), i -> i.getValue(w) )); @@ -137,9 +137,9 @@ public class WidgetInfoTableModel extends AbstractTableModel }); } - private List populateWidgetFields() + private List> populateWidgetFields() { - List out = new ArrayList<>(); + List> out = new ArrayList<>(); out.add(new WidgetField<>("Id", Widget::getId)); out.add(new WidgetField<>("Type", Widget::getType, Widget::setType, Integer.class)); @@ -209,6 +209,11 @@ public class WidgetInfoTableModel extends AbstractTableModel } return null; })); + out.add(new WidgetField<>("OnOpListener", Widget::getOnOpListener)); + out.add(new WidgetField<>("OnKeyListener", Widget::getOnKeyListener)); + out.add(new WidgetField<>("OnLoadListener", Widget::getOnLoadListener)); + out.add(new WidgetField<>("OnInvTransmitListener", Widget::getOnInvTransmitListener)); + out.add(new WidgetField<>("OnVarTransmitListener", Widget::getOnVarTransmitListener)); return out; } From 62bb21a5169ebf38eb4691ff8187ae40a89f5a24 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 13 Dec 2021 17:38:30 -0500 Subject: [PATCH 14/17] chatchannels: display online member count Co-authored-by: Dasgust --- .../main/java/net/runelite/api/ScriptID.java | 6 +++ .../net/runelite/api/widgets/WidgetID.java | 4 ++ .../net/runelite/api/widgets/WidgetInfo.java | 5 ++ .../chatchannel/ChatChannelConfig.java | 24 ++++++++++ .../chatchannel/ChatChannelPlugin.java | 48 +++++++++++++++++++ 5 files changed, 87 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/ScriptID.java b/runelite-api/src/main/java/net/runelite/api/ScriptID.java index 099ebc1537..c2762be1a3 100644 --- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java +++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java @@ -199,6 +199,12 @@ public final class ScriptID @ScriptArguments(integer = 15) public static final int FRIENDS_CHAT_CHANNEL_REBUILD = 1658; + /** + * Builds the widget that holds all of the players inside a clan chat + */ + @ScriptArguments(integer = 7) + public static final int CLAN_SIDEPANEL_DRAW = 4396; + /** * Builds the widget for making an offer in Grand Exchange */ diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 7e4588ace8..0b69d793ab 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -921,11 +921,15 @@ public final class WidgetID static class Clan { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } static class ClanGuest { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 8e43b14e66..b5b91a7827 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -552,7 +552,12 @@ public enum WidgetInfo TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR), + CLAN_LAYER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.LAYER), + CLAN_HEADER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.HEADER), CLAN_MEMBER_LIST(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.MEMBERS), + + CLAN_GUEST_LAYER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.LAYER), + CLAN_GUEST_HEADER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.HEADER), CLAN_GUEST_MEMBER_LIST(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.MEMBERS), POH_TREASURE_CHEST_INVENTORY_CONTAINER(WidgetID.POH_TREASURE_CHEST_INVENTORY_GROUP_ID, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java index eeffc30f4d..66739bf5a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java @@ -206,6 +206,18 @@ public interface ChatChannelConfig extends Config return false; } + @ConfigItem( + keyName = "clanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online clan members at the end of the clan's name.", + position = 1, + section = clanChatSection + ) + default boolean clanChatShowOnlineMemberCount() + { + return false; + } + @ConfigItem( keyName = "guestClanChatShowJoinLeave", name = "Show Join/Leave", @@ -217,4 +229,16 @@ public interface ChatChannelConfig extends Config { return false; } + + @ConfigItem( + keyName = "guestClanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online guest clan members at the end of the clan's name.", + position = 1, + section = guestClanChatSection + ) + default boolean guestClanChatShowOnlineMemberCount() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java index 25ac07f449..d1277b981d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java @@ -145,6 +145,8 @@ public class ChatChannelPlugin extends Plugin { clientThread.invoke(() -> colorIgnoredPlayers(config.showIgnoresColor())); } + + rebuildClanTitle(); } @Override @@ -153,6 +155,7 @@ public class ChatChannelPlugin extends Plugin chats = null; clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE)); rebuildFriendsChat(); + rebuildClanTitle(); } @Subscribe @@ -167,6 +170,8 @@ public class ChatChannelPlugin extends Plugin Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE; clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor)); + + rebuildClanTitle(); } } @@ -606,6 +611,18 @@ public class ChatChannelPlugin extends Plugin chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)"); } } + else if (event.getScriptId() == ScriptID.CLAN_SIDEPANEL_DRAW) + { + if (config.clanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_HEADER, client.getClanChannel()); + } + + if (config.guestClanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_GUEST_HEADER, client.getGuestClanChannel()); + } + } } private void insertRankIcon(final ChatMessage message) @@ -740,4 +757,35 @@ public class ChatChannelPlugin extends Plugin listWidget.setTextColor(ignoreColor.getRGB()); } } + + private void rebuildClanTitle() + { + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_GUEST_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + } + + private void updateClanTitle(WidgetInfo widget, ClanChannel channel) + { + Widget header = client.getWidget(widget); + if (header != null && channel != null) + { + Widget title = header.getChild(0); + title.setText(title.getText() + " (" + channel.getMembers().size() + ")"); + } + } } From be56010800a12782b2a8308930e9d90cd4e2572e Mon Sep 17 00:00:00 2001 From: Alan Baumgartner Date: Wed, 13 Oct 2021 17:39:38 -0500 Subject: [PATCH 15/17] party: add option to join previous party and join party by id Co-authored-by: Adam --- .../client/plugins/party/PartyConfig.java | 19 ++++ .../client/plugins/party/PartyPanel.java | 103 +++++++++++++++++- .../client/plugins/party/PartyPlugin.java | 7 +- 3 files changed, 124 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java index 5d38da1b3d..4d484f4cdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java @@ -99,4 +99,23 @@ public interface PartyConfig extends Config { return false; } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + default String previousPartyId() + { + return ""; + } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + void setPreviousPartyId(String id); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java index 3c3c1bba95..52d4799e95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java @@ -26,6 +26,12 @@ package net.runelite.client.plugins.party; import com.google.inject.Inject; import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -55,6 +61,9 @@ class PartyPanel extends PluginPanel private final Map memberBoxes = new HashMap<>(); private final JButton startButton = new JButton(); + private final JButton joinPartyButton = new JButton(); + private final JButton rejoinPartyButton = new JButton(); + private final JButton copyPartyIdButton = new JButton(); private final PluginErrorPanel noPartyPanel = new PluginErrorPanel(); private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel(); @@ -79,10 +88,29 @@ class PartyPanel extends PluginPanel final JPanel topPanel = new JPanel(); - topPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); - topPanel.setLayout(new BorderLayout()); + topPanel.setBorder(new EmptyBorder(0, 0, 4, 0)); + topPanel.setLayout(new GridBagLayout()); - topPanel.add(startButton, BorderLayout.CENTER); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(0, 2, 4, 2); + + c.gridx = 0; + c.gridy = 0; + topPanel.add(startButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(joinPartyButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(copyPartyIdButton, c); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 2; + topPanel.add(rejoinPartyButton, c); layoutPanel.add(topPanel); layoutPanel.add(requestBoxPanel); @@ -91,7 +119,14 @@ class PartyPanel extends PluginPanel startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); startButton.setFocusable(false); - topPanel.add(startButton); + joinPartyButton.setText("Join party"); + joinPartyButton.setFocusable(false); + + rejoinPartyButton.setText("Join previous party"); + rejoinPartyButton.setFocusable(false); + + copyPartyIdButton.setText("Copy party id"); + copyPartyIdButton.setFocusable(false); startButton.addActionListener(e -> { @@ -115,6 +150,63 @@ class PartyPanel extends PluginPanel } }); + joinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + String s = (String) JOptionPane.showInputDialog( + joinPartyButton, + "Please enter the party id:", + "Party Id", + JOptionPane.PLAIN_MESSAGE, + null, + null, + ""); + + if (s == null) + { + return; + } + + try + { + party.changeParty(UUID.fromString(s)); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(joinPartyButton, "You have entered an invalid party id.", "Invalid Party Id", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + rejoinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + try + { + party.changeParty(UUID.fromString(config.previousPartyId())); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(rejoinPartyButton, + "Failed to join your previous party, create a new party or join a new one.", + "Failed to Join Party", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + copyPartyIdButton.addActionListener(e -> + { + if (party.isInParty()) + { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(String.valueOf(party.getPartyId())), null); + } + }); + noPartyPanel.setContent("Not in a party", "Create a party to begin."); partyEmptyPanel.setContent("Party created", "You can now invite friends!"); @@ -127,6 +219,9 @@ class PartyPanel extends PluginPanel remove(partyEmptyPanel); startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); + joinPartyButton.setVisible(!party.isInParty()); + rejoinPartyButton.setVisible(!party.isInParty()); + copyPartyIdButton.setVisible(party.isInParty()); if (!party.isInParty()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index e9287210a8..ae13a4a22f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -66,8 +66,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.discord.events.DiscordJoinRequest; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; import net.runelite.client.plugins.Plugin; @@ -585,6 +585,11 @@ public class PartyPlugin extends Plugin pendingTilePings.clear(); worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); + if (event.getPartyId() != null) + { + config.setPreviousPartyId(String.valueOf(event.getPartyId())); + } + SwingUtilities.invokeLater(() -> { panel.removeAllMembers(); From 9e06f8d5c2a36b819582214db38606e57008bc90 Mon Sep 17 00:00:00 2001 From: Logan Date: Mon, 13 Dec 2021 16:06:58 -0800 Subject: [PATCH 16/17] emoji: add rocketship emoji --- .../net/runelite/client/plugins/emojis/Emoji.java | 1 + .../runelite/client/plugins/emojis/rocketship.png | Bin 0 -> 789 bytes 2 files changed, 1 insertion(+) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java index 8eb163ba53..8d64881631 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java @@ -93,6 +93,7 @@ enum Emoji XD("Xd"), SPOON("--o"), WEARY_FACE("Dx"), + ROCKETSHIP("=="), // >==> ; private static final Map emojiMap; diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png new file mode 100644 index 0000000000000000000000000000000000000000..62bb05ace924be1046e3851718eab7c6a34e1d6b GIT binary patch literal 789 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uGBwbBK{D2fox}&cn1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKhU=$DV32_A~2wn3oY~9EC z?1~Fm?-L>bCqEn2hmX+7E3n6PigsgcNwDhT>b4k ztN%SuYhGS$&U9Kgpc<&3G0EHACFa!)hUq{Kdx@v7EBjL(R(4ji^B=u_1BEttx;Tb# zT-QB!RjkQD#Nnc~)ix!uGNrE0yM}BlJUV3m|CfIhHE;XhGKMn(PGa&;mowM1I6piw z=|aNM8)@l_HeRjT{I&V8q`ykA%apR;Cae~d&pzc}R5K-vRepo3tLm(}Nk=12FvYAq zBmKNvZ&HRpcptHiD0_Lb%CKn)C@u6{1- HoD!M Date: Sun, 12 Dec 2021 21:04:55 -0500 Subject: [PATCH 17/17] hiscore: add nex --- .../runelite/http/api/hiscore/HiscoreResult.java | 3 +++ .../http/api/hiscore/HiscoreResultBuilder.java | 4 ++++ .../runelite/http/api/hiscore/HiscoreSkill.java | 1 + .../http/service/hiscore/HiscoreServiceTest.java | 4 +++- .../client/plugins/hiscore/HiscorePanel.java | 14 +++++++------- .../client/plugins/hiscore/bosses/nex.png | Bin 0 -> 585 bytes 6 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java index de52f5c5aa..af6c461562 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java @@ -93,6 +93,7 @@ public class HiscoreResult private Skill kreearra; private Skill krilTsutsaroth; private Skill mimic; + private Skill nex; private Skill nightmare; private Skill phosanisNightmare; private Skill obor; @@ -244,6 +245,8 @@ public class HiscoreResult return krilTsutsaroth; case MIMIC: return mimic; + case NEX: + return nex; case NIGHTMARE: return nightmare; case PHOSANIS_NIGHTMARE: diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java index 6c88ebcd18..ee8504bc8a 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java @@ -118,6 +118,10 @@ class HiscoreResultBuilder hiscoreResult.setKreearra(skills.get(index++)); hiscoreResult.setKrilTsutsaroth(skills.get(index++)); hiscoreResult.setMimic(skills.get(index++)); + if (skills.size() > 83) + { + hiscoreResult.setNex(skills.get(index++)); + } hiscoreResult.setNightmare(skills.get(index++)); hiscoreResult.setPhosanisNightmare(skills.get(index++)); hiscoreResult.setObor(skills.get(index++)); diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java index 698bd34e8e..0856e9270a 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java @@ -97,6 +97,7 @@ public enum HiscoreSkill KREEARRA("Kree'Arra", BOSS), KRIL_TSUTSAROTH("K'ril Tsutsaroth", BOSS), MIMIC("Mimic", BOSS), + NEX("Nex", BOSS), NIGHTMARE("Nightmare", BOSS), PHOSANIS_NIGHTMARE("Phosani's Nightmare", BOSS), OBOR("Obor", BOSS), diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java index a301e694d9..798116e7ee 100644 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java +++ b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java @@ -98,7 +98,8 @@ public class HiscoreServiceTest + "702,6495\n" + "10170,184\n" + "8064,202\n" - + "6936,2\n" + + "6936,2\n" // Mimic + + "1,4920\n" // Nex + "2335,9\n" // Nightmare + "2336,10\n" // Phosanis Nightmare + "-1,-1\n" @@ -151,6 +152,7 @@ public class HiscoreServiceTest Assert.assertEquals(2460, result.getLeaguePoints().getLevel()); Assert.assertEquals(37, result.getAbyssalSire().getLevel()); Assert.assertEquals(92357, result.getCallisto().getRank()); + Assert.assertEquals(4920, result.getNex().getLevel()); Assert.assertEquals(2336, result.getPhosanisNightmare().getRank()); Assert.assertEquals(5678, result.getTempoross().getLevel()); Assert.assertEquals(42, result.getTheatreOfBloodHardMode().getLevel()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index 56673629e4..b823a57f62 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -105,13 +105,13 @@ public class HiscorePanel extends PluginPanel GIANT_MOLE, GROTESQUE_GUARDIANS, HESPORI, KALPHITE_QUEEN, KING_BLACK_DRAGON, KRAKEN, KREEARRA, KRIL_TSUTSAROTH, MIMIC, - NIGHTMARE, PHOSANIS_NIGHTMARE, OBOR, SARACHNIS, - SCORPIA, SKOTIZO, TEMPOROSS, - THE_GAUNTLET, THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, - THEATRE_OF_BLOOD_HARD_MODE, THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, - TZTOK_JAD, VENENATIS, VETION, - VORKATH, WINTERTODT, ZALCANO, - ZULRAH + NEX, NIGHTMARE, PHOSANIS_NIGHTMARE, + OBOR, SARACHNIS, SCORPIA, + SKOTIZO, TEMPOROSS, THE_GAUNTLET, + THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, THEATRE_OF_BLOOD_HARD_MODE, + THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, TZTOK_JAD, + VENENATIS, VETION, VORKATH, + WINTERTODT, ZALCANO, ZULRAH ); private static final HiscoreEndpoint[] ENDPOINTS = { diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png new file mode 100644 index 0000000000000000000000000000000000000000..eaaa147d0f4bb2ecba686578ed85a56723553de6 GIT binary patch literal 585 zcmV-P0=E5$P)FeMme`J~Ts&d7*S*e^W+V zg>8|CZ@EQEE9eL2zAqT}@^B`S|7H;7veN!L_ugqnb1R0d!JMQvg8b*k%9#0NP1JK~yNuwb5H! z0bvjaaQ~LbuB`NKn`Oz`RwtyQoXSh(oX8=i@BcCEg^SsTOZ~6rncp)PGvjjoM_^}r zcTdwOZu5}u2pIQxFbhTb(JsIUJe8mq%9U!`P=OkO=NHsD*A>ni zK$F1h8(>+Szqi^zhXA@jPwNjphMySG4KW7lU;W8+HpjPPb32R0&+l~kx8;oM?EarC Xzmpf%HB?FZ00000NkvXXu0mjfRDSB` literal 0 HcmV?d00001