From c6ed38afb2dd50497ab4c093626e3209c7b608ed Mon Sep 17 00:00:00 2001 From: Dennis Date: Thu, 29 Mar 2018 00:34:54 +0200 Subject: [PATCH] add bank tags plugin --- .../plugins/banktags/BankTagsPlugin.java | 251 ++++++++++++++++++ .../scripts/BankSearchFilter.hash | 1 + .../scripts/BankSearchFilter.rs2asm | 69 +++++ .../scripts/OpenBankSearchInput.hash | 1 + .../scripts/OpenBankSearchInput.rs2asm | 43 +++ runelite-scripts/scripts/SetBankItemMenu.hash | 1 + .../scripts/SetBankItemMenu.rs2asm | 170 ++++++++++++ 7 files changed, 536 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java create mode 100644 runelite-scripts/scripts/BankSearchFilter.hash create mode 100644 runelite-scripts/scripts/BankSearchFilter.rs2asm create mode 100644 runelite-scripts/scripts/OpenBankSearchInput.hash create mode 100644 runelite-scripts/scripts/OpenBankSearchInput.rs2asm create mode 100644 runelite-scripts/scripts/SetBankItemMenu.hash create mode 100644 runelite-scripts/scripts/SetBankItemMenu.rs2asm 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 new file mode 100644 index 0000000000..2d505829a1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2018, 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.plugins.banktags; + +import com.google.common.eventbus.Subscribe; +import java.util.Arrays; +import java.util.List; +import javax.inject.Inject; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.IntegerNode; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.MenuAction; +import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.ScriptEvent; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetConfig; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "Bank Tags" +) +@Slf4j +public class BankTagsPlugin extends Plugin +{ + private static final String CONFIG_GROUP = "banktags"; + + private static final String ITEM_KEY_PREFIX = "item_"; + + private static final String SEARCH_BANK_INPUT_TEXT = + "Show items whose names or tags contain the following text:
" + + "(To show only tagged items, start your search with 'tag:')"; + + private static final String TAG_SEARCH = "tag:"; + + private static final String EDIT_TAGS_MENU_OPTION = "Edit-tags"; + + private static final int EDIT_TAGS_MENU_INDEX = 9; + + @Inject + private Client client; + + @Inject + private ItemManager itemManager; + + @Inject + private ConfigManager configManager; + + private String getTags(int itemId) + { + String config = configManager.getConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId); + if (config == null) + { + return ""; + } + return config; + } + + private void setTags(int itemId, String tags) + { + if (tags == null || tags.isEmpty()) + { + configManager.unsetConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId); + } + else + { + configManager.setConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId, tags); + } + } + + private int getTagCount(int itemId) + { + String tags = getTags(itemId); + if (tags.length() > 0) + { + return tags.split(",").length; + } + return 0; + } + + @Subscribe + public void onScriptEvent(ScriptEvent event) + { + String eventName = event.getEventName(); + + int[] intStack = client.getIntStack(); + String[] stringStack = client.getStringStack(); + int intStackSize = client.getIntStackSize(); + int stringStackSize = client.getStringStackSize(); + + switch (eventName) + { + case "bankTagsActive": + // tell the script the bank tag plugin is active + intStack[intStackSize - 1] = 1; + break; + case "setSearchBankInputText": + stringStack[stringStackSize - 1] = SEARCH_BANK_INPUT_TEXT; + break; + case "setBankItemMenu": + { + // set menu action index so the edit tags option will not be overridden + intStack[intStackSize - 3] = EDIT_TAGS_MENU_INDEX; + + int itemId = intStack[intStackSize - 2]; + int tagCount = getTagCount(itemId); + if (tagCount > 0) + { + stringStack[stringStackSize - 1] += " (" + tagCount + ")"; + } + + int index = intStack[intStackSize - 1]; + long key = (long) index + ((long) WidgetInfo.BANK_ITEM_CONTAINER.getId() << 32); + IntegerNode flagNode = (IntegerNode) client.getWidgetFlags().get(key); + if (flagNode != null && flagNode.getValue() != 0) + { + flagNode.setValue(flagNode.getValue() | WidgetConfig.SHOW_MENU_OPTION_NINE); + } + break; + } + case "bankSearchFilter": + int itemId = intStack[intStackSize - 1]; + String itemName = stringStack[stringStackSize - 2]; + String searchInput = stringStack[stringStackSize - 1]; + + String tagsConfig = configManager.getConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId); + if (tagsConfig == null || tagsConfig.length() == 0) + { + intStack[intStackSize - 2] = itemName.contains(searchInput) ? 1 : 0; + return; + } + + boolean tagSearch = searchInput.startsWith(TAG_SEARCH); + String search; + if (tagSearch) + { + search = searchInput.substring(TAG_SEARCH.length()).trim(); + } + else + { + search = searchInput; + } + + List tags = Arrays.asList(tagsConfig.split(",")); + + if (tags.stream().anyMatch(tag -> tag.contains(search))) + { + // return true + intStack[intStackSize - 2] = 1; + } + else if (!tagSearch) + { + intStack[intStackSize - 2] = itemName.contains(search) ? 1 : 0; + } + break; + } + } + + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) + { + if (event.getWidgetId() == WidgetInfo.BANK_ITEM_CONTAINER.getId() + && event.getMenuAction() == MenuAction.EXAMINE_ITEM_BANK_EQ + && event.getId() == EDIT_TAGS_MENU_INDEX) + { + int inventoryIndex = event.getActionParam(); + 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(); + String itemName = itemManager.getItemComposition(itemId).getName(); + String initialValue = getTags(itemId); + SwingUtilities.invokeLater(() -> + { + String newTags = (String) JOptionPane.showInputDialog(client.getCanvas(), null, + "Edit " + itemName + " Tags", JOptionPane.PLAIN_MESSAGE, null, null, + initialValue); + if (newTags == null) + { + return; + } + setTags(itemId, newTags); + Widget bankContainerWidget = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER); + if (bankContainerWidget == null) + { + return; + } + Widget[] bankItemWidgets = bankContainerWidget.getDynamicChildren(); + if (bankItemWidgets == null || inventoryIndex >= bankItemWidgets.length) + { + return; + } + Widget bankItemWidget = bankItemWidgets[inventoryIndex]; + String[] actions = bankItemWidget.getActions(); + if (actions == null || EDIT_TAGS_MENU_INDEX - 1 >= actions.length) + { + return; + } + int tagCount = getTagCount(itemId); + actions[EDIT_TAGS_MENU_INDEX - 1] = EDIT_TAGS_MENU_OPTION; + if (tagCount > 0) + { + actions[EDIT_TAGS_MENU_INDEX - 1] += " (" + tagCount + ")"; + } + }); + } + } + +} diff --git a/runelite-scripts/scripts/BankSearchFilter.hash b/runelite-scripts/scripts/BankSearchFilter.hash new file mode 100644 index 0000000000..7a7a40a9f5 --- /dev/null +++ b/runelite-scripts/scripts/BankSearchFilter.hash @@ -0,0 +1 @@ +FD851583852C34596F250D63AEDB0A13B294129108A9DB52B6BDF2D51EDA0BFC \ No newline at end of file diff --git a/runelite-scripts/scripts/BankSearchFilter.rs2asm b/runelite-scripts/scripts/BankSearchFilter.rs2asm new file mode 100644 index 0000000000..3a1ab14e56 --- /dev/null +++ b/runelite-scripts/scripts/BankSearchFilter.rs2asm @@ -0,0 +1,69 @@ +.id 279 +.int_stack_count 1 +.string_stack_count 0 +.int_var_count 1 +.string_var_count 2 + load_string "" + sstore 0 + load_string "" + sstore 1 + invoke 514 + load_int 1 + if_icmpeq LABEL8 + jump LABEL34 +LABEL8: + invoke 280 + sstore 1 + sload 1 + string_length + load_int 0 + if_icmpgt LABEL15 + jump LABEL34 +LABEL15: + iload 0 + load_int -1 + if_icmpne LABEL19 + jump LABEL23 +LABEL19: + iload 0 + get_item_name + tolowercase + sstore 0 +LABEL1337: ; check if the bank tags plugin is active + load_int 1 ; true + load_int 0 ; load active boolean + load_string "bankTagsActive" ; push event name + runelite_callback ; invoke callback + if_icmpeq LABEL1338 ; if the plugin is active then jump to the label that decides if the + ; item should be shown + jump LABEL23 ; if the plugin is not active then jump to the normal label +LABEL1338: ; let the bank tag plugin decide if the item should be shown + load_int 0 ; load return value + iload 0 ; load item id + sload 0 ; load item name + sload 1 ; load search string + load_string "bankSearchFilter" ; push event name + runelite_callback ; invoke callback + pop_int ; pop item id + pop_string ; pop search string + pop_string ; pop item name + return ; return value +LABEL23: + sload 0 + sload 1 + load_int 0 + string_indexof_from + load_int -1 + if_icmpne LABEL30 + jump LABEL32 +LABEL30: + load_int 1 + return +LABEL32: + load_int 0 + return +LABEL34: + load_int 1 + return + load_int -1 + return \ No newline at end of file diff --git a/runelite-scripts/scripts/OpenBankSearchInput.hash b/runelite-scripts/scripts/OpenBankSearchInput.hash new file mode 100644 index 0000000000..3416b75f62 --- /dev/null +++ b/runelite-scripts/scripts/OpenBankSearchInput.hash @@ -0,0 +1 @@ +27446C2A53527645827D4EDE100B50607D0D2177947649C7E9BEA155FDF78BBC \ No newline at end of file diff --git a/runelite-scripts/scripts/OpenBankSearchInput.rs2asm b/runelite-scripts/scripts/OpenBankSearchInput.rs2asm new file mode 100644 index 0000000000..c307dc8cde --- /dev/null +++ b/runelite-scripts/scripts/OpenBankSearchInput.rs2asm @@ -0,0 +1,43 @@ +.id 300 +.int_stack_count 0 +.string_stack_count 0 +.int_var_count 0 +.string_var_count 1 + get_varc 11 + load_int 1 + if_icmpeq LABEL4 + jump LABEL5 +LABEL4: + close_window +LABEL5: + invoke 677 + load_string "Show items whose names contain the following text:" + load_string "setSearchBankInputText" ; load event name + runelite_callback ; invoke callback + load_int 10616867 + widget_put_text_widget + load_int 11 + put_varc 5 + load_string "" + invoke 222 + load_string "" + sstore 0 + load_int 112 + load_int -2147483640 + load_int -2147483639 + sload 0 + load_string "izs" + load_int 10616868 + widget_put_key_listener_widget + load_int 138 + load_string "" + load_int 10616868 + widget_put_dialog_abort_listener_widget + invoke 1972 + load_int 1 + if_icmpeq LABEL30 + jump LABEL31 +LABEL30: + invoke 1983 +LABEL31: + return \ No newline at end of file diff --git a/runelite-scripts/scripts/SetBankItemMenu.hash b/runelite-scripts/scripts/SetBankItemMenu.hash new file mode 100644 index 0000000000..29780b20ad --- /dev/null +++ b/runelite-scripts/scripts/SetBankItemMenu.hash @@ -0,0 +1 @@ +BD8E0D58CD175BCE02F9A63A35E5F025E87A3A31C4DFAA8282926B69CD5FD60B \ No newline at end of file diff --git a/runelite-scripts/scripts/SetBankItemMenu.rs2asm b/runelite-scripts/scripts/SetBankItemMenu.rs2asm new file mode 100644 index 0000000000..3e34685e63 --- /dev/null +++ b/runelite-scripts/scripts/SetBankItemMenu.rs2asm @@ -0,0 +1,170 @@ +.id 278 +.int_stack_count 7 +.string_stack_count 0 +.int_var_count 7 +.string_var_count 0 + iload 0 + load_int -1 + if_icmpne LABEL4 + jump LABEL130 +LABEL4: + widget_put_actions_null + iload 0 + load_int 20594 + if_icmpeq LABEL9 + jump LABEL33 +LABEL9: + iload 0 + load_int -1 + 1200 + load_int 7 + load_string "Clear-All" + widget_put_action + load_int 8 + load_string "Clear" + widget_put_action + load_int 0 + widget_put_opacity + load_int 285 + load_int -2147483645 + load_int -2147483643 + load_int -2147483642 + load_int -2147483641 + load_int 0 + iload 3 + iload 4 + iload 5 + iload 6 + load_string "IiIiiIIII" + widget_put_drag_release_listener + jump LABEL111 +LABEL33: + iload 0 + 4209 + iload 0 + if_icmpne LABEL38 + jump LABEL59 +LABEL38: + iload 0 + load_int 0 + 1200 + load_int 8 + load_string "Release" + widget_put_action + load_int 120 + widget_put_opacity + load_int 285 + load_int -2147483645 + load_int -2147483643 + load_int -2147483642 + load_int -2147483641 + load_int 120 + iload 3 + iload 4 + iload 5 + iload 6 + load_string "IiIiiIIII" + widget_put_drag_release_listener + jump LABEL111 +LABEL59: + iload 0 + iload 1 + 1200 + load_int 1 ; if the bank tags plugin is not active this will not get changed and thus + ; overridden by the Withdraw-1 option + load_string "Edit-tags" ; push menu action name + iload 0 ; push item id + widget_get_index ; push the item index for setting the widget flag + load_string "setBankItemMenu" ; push event name + runelite_callback ; invoke callback + pop_int ; pop widget index + pop_int ; pop item id + widget_put_action ; add edit tags menu action + load_int 1 + load_string "Withdraw-1" + widget_put_action + load_int 2 + load_string "Withdraw-5" + widget_put_action + load_int 3 + load_string "Withdraw-10" + widget_put_action + get_varbit 3960 + load_int 0 + if_icmpgt LABEL75 + jump LABEL81 +LABEL75: + load_int 4 + load_string "Withdraw-" + get_varbit 3960 + int_to_string + string_append 2 + widget_put_action +LABEL81: + load_int 5 + load_string "Withdraw-X" + widget_put_action + load_int 6 + load_string "Withdraw-All" + widget_put_action + load_int 7 + load_string "Withdraw-All-but-1" + widget_put_action + get_varbit 3755 + load_int 0 + if_icmpeq LABEL94 + jump LABEL97 +LABEL94: + load_int 8 + load_string "Placeholder" + widget_put_action +LABEL97: + load_int 0 + widget_put_opacity + load_int 285 + load_int -2147483645 + load_int -2147483643 + load_int -2147483642 + load_int -2147483641 + load_int 0 + iload 3 + iload 4 + iload 5 + iload 6 + load_string "IiIiiIIII" + widget_put_drag_release_listener +LABEL111: + load_int 10 + load_string "Examine" + widget_put_action + load_string "" + iload 0 + get_item_name + load_string "" + string_append 3 + widget_put_name + load_int 284 + load_int -2147483645 + load_int -2147483643 + load_int -2147483647 + load_int -2147483646 + iload 3 + load_int 0 + load_string "IiiiIi" + widget_put_drag_start_listener + jump LABEL142 +LABEL130: + load_int 255 + widget_put_opacity + load_int 6512 + load_int 1 + 1200 + widget_put_actions_null + load_int -1 + load_string "" + widget_put_drag_start_listener + load_int -1 + load_string "" + widget_put_drag_release_listener +LABEL142: + return \ No newline at end of file