diff --git a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java index 998e70de6a..d631395b89 100644 --- a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java +++ b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java @@ -179,6 +179,8 @@ public enum ChatMessageType CLAN_GIM_FORM_GROUP(111), CLAN_GIM_GROUP_WITH(112), + CLAN_GIM_CHAT(-1), + CLAN_GIM_MESSAGE(-1), /** * An unknown message type. */ @@ -192,7 +194,10 @@ public enum ChatMessageType { for (ChatMessageType chatMessageType : values()) { - CHAT_MESSAGE_TYPES.put(chatMessageType.type, chatMessageType); + if (chatMessageType.type != -1) + { + CHAT_MESSAGE_TYPES.put(chatMessageType.type, chatMessageType); + } } } diff --git a/runelite-api/src/main/java/net/runelite/api/MenuAction.java b/runelite-api/src/main/java/net/runelite/api/MenuAction.java index c441e25b03..e8b70c4b07 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuAction.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuAction.java @@ -233,6 +233,11 @@ public enum MenuAction */ SPELL_CAST_ON_WIDGET(58), + /** + * Menu action for high priority runelite options + */ + RUNELITE_HIGH_PRIORITY(999), + /** * Sub 1000 so it doesn't get sorted down in the list */ diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java index ff4d8481d9..25404b6040 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java @@ -100,6 +100,7 @@ public class ChatCommandManager implements ChatboxInputListener case PRIVATECHATOUT: case CLAN_CHAT: case CLAN_GUEST_CHAT: + case CLAN_GIM_CHAT: break; default: return; diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java index 9012aa8227..f673ea0e60 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java @@ -24,6 +24,7 @@ */ package net.runelite.client.chat; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import com.google.common.collect.HashMultimap; @@ -44,7 +45,6 @@ import net.runelite.api.Client; import net.runelite.api.MessageNode; import net.runelite.api.Player; import net.runelite.api.Varbits; -import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ResizeableChanged; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.VarbitChanged; @@ -111,15 +111,23 @@ public class ChatMessageManager } } - @Subscribe(priority = -1) // run after all plugins - public void onChatMessage(ChatMessage chatMessage) + @VisibleForTesting + void colorChatMessage() { - MessageNode messageNode = chatMessage.getMessageNode(); - ChatMessageType chatMessageType = chatMessage.getType(); + final String[] stringStack = client.getStringStack(); + final int size = client.getStringStackSize(); + final int uid = client.getIntStack()[client.getIntStackSize() - 1]; - boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1; + final MessageNode messageNode = client.getMessages().get(uid); + assert messageNode != null : "chat message build for unknown message"; + + final String username = stringStack[size - 3]; + final String channel = stringStack[size - 4]; + final ChatMessageType chatMessageType = messageNode.getType(); + + final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1; Color usernameColor = null; - Color senderColor = null; + Color channelColor = null; switch (chatMessageType) { @@ -130,7 +138,7 @@ public class ChatMessageManager case PUBLICCHAT: case MODCHAT: { - String sanitizedUsername = Text.removeTags(chatMessage.getName()).replace('\u00A0', ' '); + String sanitizedUsername = Text.removeTags(username).replace('\u00A0', ' '); if (client.getLocalPlayer().getName().equals(sanitizedUsername)) { @@ -149,29 +157,30 @@ public class ChatMessageManager case FRIENDSCHAT: case FRIENDSCHATNOTIFICATION: usernameColor = isChatboxTransparent ? chatColorConfig.transparentFriendsChatUsernames() : chatColorConfig.opaqueFriendsChatUsernames(); - senderColor = isChatboxTransparent ? chatColorConfig.transparentFriendsChatChannelName() : chatColorConfig.opaqueFriendsChatChannelName(); + channelColor = isChatboxTransparent ? chatColorConfig.transparentFriendsChatChannelName() : chatColorConfig.opaqueFriendsChatChannelName(); break; case CLAN_CHAT: case CLAN_MESSAGE: + case CLAN_GIM_CHAT: + case CLAN_GIM_MESSAGE: usernameColor = isChatboxTransparent ? chatColorConfig.transparentClanChatUsernames() : chatColorConfig.opaqueClanChatUsernames(); - senderColor = isChatboxTransparent ? chatColorConfig.transparentClanChannelName() : chatColorConfig.opaqueClanChannelName(); + channelColor = isChatboxTransparent ? chatColorConfig.transparentClanChannelName() : chatColorConfig.opaqueClanChannelName(); break; case CLAN_GUEST_CHAT: case CLAN_GUEST_MESSAGE: usernameColor = isChatboxTransparent ? chatColorConfig.transparentClanChatGuestUsernames() : chatColorConfig.opaqueClanChatGuestUsernames(); - senderColor = isChatboxTransparent ? chatColorConfig.transparentClanChannelGuestName() : chatColorConfig.opaqueClanGuestChatChannelName(); + channelColor = isChatboxTransparent ? chatColorConfig.transparentClanChannelGuestName() : chatColorConfig.opaqueClanGuestChatChannelName(); break; } if (usernameColor != null) { - messageNode.setName(ColorUtil.wrapWithColorTag(messageNode.getName(), usernameColor)); + stringStack[size - 3] = ColorUtil.wrapWithColorTag(username, usernameColor); } - String sender = messageNode.getSender(); - if (senderColor != null && !Strings.isNullOrEmpty(sender)) + if (channelColor != null && !Strings.isNullOrEmpty(channel)) { - messageNode.setSender(ColorUtil.wrapWithColorTag(sender, senderColor)); + stringStack[size - 4] = ColorUtil.wrapWithColorTag(channel, channelColor); } final Collection chatColors = colorCache.get(chatMessageType); @@ -184,9 +193,9 @@ public class ChatMessageManager // Replace tags in the message with the new color so embedded won't reset the color final Color color = chatColor.getColor(); - messageNode.setValue(ColorUtil.wrapWithColorTag( - messageNode.getValue().replace(ColorUtil.CLOSING_COLOR_TAG, ColorUtil.colorTag(color)), - color)); + stringStack[size - 2] = ColorUtil.wrapWithColorTag( + stringStack[size - 2].replace(ColorUtil.CLOSING_COLOR_TAG, ColorUtil.colorTag(color)), + color); break; } } @@ -205,6 +214,9 @@ public class ChatMessageManager case "privChatUsername": wrap = true; break; + case "chatMessageBuilding": + colorChatMessage(); + return; default: return; } @@ -247,6 +259,7 @@ public class ChatMessageManager case FRIENDSCHAT: case CLAN_CHAT: case CLAN_GUEST_CHAT: + case CLAN_GIM_CHAT: return JagexColors.CHAT_FC_TEXT_OPAQUE_BACKGROUND; case ITEM_EXAMINE: case OBJECT_EXAMINE: @@ -255,6 +268,7 @@ public class ChatMessageManager case FRIENDSCHATNOTIFICATION: case CLAN_MESSAGE: case CLAN_GUEST_MESSAGE: + case CLAN_GIM_MESSAGE: return JagexColors.CHAT_GAME_EXAMINE_TEXT_OPAQUE_BACKGROUND; } } @@ -272,6 +286,7 @@ public class ChatMessageManager case FRIENDSCHAT: case CLAN_CHAT: case CLAN_GUEST_CHAT: + case CLAN_GIM_CHAT: return JagexColors.CHAT_FC_TEXT_TRANSPARENT_BACKGROUND; case ITEM_EXAMINE: case OBJECT_EXAMINE: @@ -280,6 +295,7 @@ public class ChatMessageManager case FRIENDSCHATNOTIFICATION: case CLAN_MESSAGE: case CLAN_GUEST_MESSAGE: + case CLAN_GIM_MESSAGE: return JagexColors.CHAT_GAME_EXAMINE_TEXT_TRANSPARENT_BACKGROUND; } } @@ -373,21 +389,29 @@ public class ChatMessageManager { cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.opaqueClanChatInfo(), false), ChatMessageType.CLAN_MESSAGE); + cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.opaqueClanChatInfo(), false), + ChatMessageType.CLAN_GIM_MESSAGE); } if (chatColorConfig.opaqueClanChatInfoHighlight() != null) { cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.opaqueClanChatInfoHighlight(), false), ChatMessageType.CLAN_MESSAGE); + cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.opaqueClanChatInfoHighlight(), false), + ChatMessageType.CLAN_GIM_MESSAGE); } if (chatColorConfig.opaqueClanChatMessage() != null) { cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.opaqueClanChatMessage(), false), ChatMessageType.CLAN_CHAT); + cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.opaqueClanChatMessage(), false), + ChatMessageType.CLAN_GIM_CHAT); } if (chatColorConfig.opaqueClanChatMessageHighlight() != null) { cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.opaqueClanChatMessageHighlight(), false), ChatMessageType.CLAN_CHAT); + cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.opaqueClanChatMessageHighlight(), false), + ChatMessageType.CLAN_GIM_CHAT); } if (chatColorConfig.opaqueClanChatGuestInfo() != null) @@ -555,21 +579,29 @@ public class ChatMessageManager { cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.transparentClanChatInfo(), true), ChatMessageType.CLAN_MESSAGE); + cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.transparentClanChatInfo(), true), + ChatMessageType.CLAN_GIM_MESSAGE); } if (chatColorConfig.transparentClanChatInfoHighlight() != null) { cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.transparentClanChatInfoHighlight(), true), ChatMessageType.CLAN_MESSAGE); + cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.transparentClanChatInfoHighlight(), true), + ChatMessageType.CLAN_GIM_MESSAGE); } if (chatColorConfig.transparentClanChatMessage() != null) { cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.transparentClanChatMessage(), true), ChatMessageType.CLAN_CHAT); + cacheColor(new ChatColor(ChatColorType.NORMAL, chatColorConfig.transparentClanChatMessage(), true), + ChatMessageType.CLAN_GIM_CHAT); } if (chatColorConfig.transparentClanChatMessageHighlight() != null) { cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.transparentClanChatMessageHighlight(), true), ChatMessageType.CLAN_CHAT); + cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, chatColorConfig.transparentClanChatMessageHighlight(), true), + ChatMessageType.CLAN_GIM_CHAT); } if (chatColorConfig.transparentClanChatGuestInfo() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java index 30087bb33a..1553bc904a 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java @@ -99,11 +99,9 @@ class ConfigInvocationHandler implements InvocationHandler } // Convert value to return type - Class returnType = method.getReturnType(); - try { - Object objectValue = ConfigManager.stringToObject(value, returnType); + Object objectValue = manager.stringToObject(value, method.getGenericReturnType()); cache.put(method, objectValue == null ? NULL : objectValue); return objectValue; } @@ -155,7 +153,7 @@ class ConfigInvocationHandler implements InvocationHandler } else { - String newValueStr = ConfigManager.objectToString(newValue); + String newValueStr = manager.objectToString(newValue); manager.setConfiguration(group.value(), item.keyName(), newValueStr); } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java index d6ced58e18..922fb531a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java @@ -24,13 +24,14 @@ */ package net.runelite.client.config; +import java.lang.reflect.Type; import lombok.Value; @Value public class ConfigItemDescriptor implements ConfigObject { private final ConfigItem item; - private final Class type; + private final Type type; private final Range range; private final Alpha alpha; private final Units units; diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index c6d10f171a..0e6d051a0d 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -30,6 +30,7 @@ import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableSet; import com.google.common.hash.Hasher; import com.google.common.hash.Hashing; +import com.google.gson.Gson; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; @@ -44,7 +45,9 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Proxy; +import java.lang.reflect.Type; import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.nio.file.AtomicMoveNotSupportedException; @@ -128,6 +131,7 @@ public class ConfigManager private final File settingsFileInput; private final EventBus eventBus; private final OkHttpClient okHttpClient; + private final Gson gson; private AccountSession session; private ConfigClient configClient; @@ -152,13 +156,15 @@ public class ConfigManager ScheduledExecutorService scheduledExecutorService, EventBus eventBus, OkHttpClient okHttpClient, - @Nullable Client client) + @Nullable Client client, + Gson gson) { this.settingsFileInput = config; this.eventBus = eventBus; this.okHttpClient = okHttpClient; this.client = client; this.propertiesFile = getPropertiesFile(); + this.gson = gson; scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS); } @@ -412,12 +418,12 @@ public class ConfigManager return properties.getProperty(getWholeKey(groupName, profile, key)); } - public T getConfiguration(String groupName, String key, Class clazz) + public T getConfiguration(String groupName, String key, Type clazz) { return getConfiguration(groupName, null, key, clazz); } - public T getRSProfileConfiguration(String groupName, String key, Class clazz) + public T getRSProfileConfiguration(String groupName, String key, Type clazz) { String rsProfileKey = this.rsProfileKey; if (rsProfileKey == null) @@ -428,14 +434,14 @@ public class ConfigManager return getConfiguration(groupName, rsProfileKey, key, clazz); } - public T getConfiguration(String groupName, String profile, String key, Class clazz) + public T getConfiguration(String groupName, String profile, String key, Type type) { String value = getConfiguration(groupName, profile, key); if (!Strings.isNullOrEmpty(value)) { try { - return (T) stringToObject(value, clazz); + return (T) stringToObject(value, type); } catch (Exception e) { @@ -488,12 +494,12 @@ public class ConfigManager eventBus.post(configChanged); } - public void setConfiguration(String groupName, String profile, String key, Object value) + public void setConfiguration(String groupName, String profile, String key, T value) { setConfiguration(groupName, profile, key, objectToString(value)); } - public void setConfiguration(String groupName, String key, Object value) + public void setConfiguration(String groupName, String key, T value) { // do not save consumers for buttons, they cannot be changed anyway if (value instanceof Consumer) @@ -504,7 +510,7 @@ public class ConfigManager setConfiguration(groupName, null, key, value); } - public void setRSProfileConfiguration(String groupName, String key, Object value) + public void setRSProfileConfiguration(String groupName, String key, T value) { String rsProfileKey = this.rsProfileKey; if (rsProfileKey == null) @@ -650,7 +656,7 @@ public class ConfigManager .filter(m -> m.getParameterCount() == 0 && m.isAnnotationPresent(ConfigItem.class)) .map(m -> new ConfigItemDescriptor( m.getDeclaredAnnotation(ConfigItem.class), - m.getReturnType(), + m.getGenericReturnType(), m.getDeclaredAnnotation(Range.class), m.getDeclaredAnnotation(Alpha.class), m.getDeclaredAnnotation(Units.class) @@ -721,16 +727,16 @@ public class ConfigManager continue; } - if (!override) + if (!override) + { + // This checks if it is set and is also unmarshallable to the correct type; so + // we will overwrite invalid config values with the default + Object current = getConfiguration(group.value(), item.keyName(), method.getGenericReturnType()); + if (current != null) { - // This checks if it is set and is also unmarshallable to the correct type; so - // we will overwrite invalid config values with the default - Object current = getConfiguration(group.value(), item.keyName(), method.getReturnType()); - if (current != null) - { - continue; // something else is already set - } + continue; // something else is already set } + } Object defaultValue; try @@ -760,7 +766,7 @@ public class ConfigManager } } - static Object stringToObject(String str, Class type) + Object stringToObject(String str, Type type) { if (type == boolean.class || type == Boolean.class) { @@ -801,7 +807,7 @@ public class ConfigManager int height = Integer.parseInt(splitStr[3]); return new Rectangle(x, y, width, height); } - if (type.isEnum()) + if (type instanceof Class && ((Class) type).isEnum()) { return Enum.valueOf((Class) type, str); } @@ -836,6 +842,14 @@ public class ConfigManager { return Base64.getUrlDecoder().decode(str); } + if (type instanceof ParameterizedType) + { + ParameterizedType parameterizedType = (ParameterizedType) type; + if (parameterizedType.getRawType() == Set.class) + { + return gson.fromJson(str, parameterizedType); + } + } if (type == EnumSet.class) { try @@ -875,7 +889,7 @@ public class ConfigManager } @Nullable - static String objectToString(Object object) + String objectToString(Object object) { if (object instanceof Color) { @@ -922,6 +936,10 @@ public class ConfigManager { return Base64.getUrlEncoder().encodeToString((byte[]) object); } + if (object instanceof Set) + { + return gson.toJson(object, Set.class); + } if (object instanceof EnumSet) { if (((EnumSet) object).size() == 0) 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 ab0e0e7149..39d736d4c5 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 @@ -188,6 +188,7 @@ public class ChatFilterPlugin extends Plugin case FRIENDSCHAT: case CLAN_CHAT: case CLAN_GUEST_CHAT: + case CLAN_GIM_CHAT: if (shouldFilterPlayerMessage(Text.removeTags(name))) { message = censorMessage(name, message); 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 cc7903f0b4..ad6530a2e7 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 @@ -28,7 +28,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.Color; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.awt.event.KeyEvent; @@ -63,7 +62,6 @@ import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.util.ColorUtil; import net.runelite.client.util.Text; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -176,7 +174,11 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener case MODCHAT: case FRIENDSCHAT: case CLAN_GUEST_CHAT: + case CLAN_GUEST_MESSAGE: case CLAN_CHAT: + case CLAN_MESSAGE: + case CLAN_GIM_CHAT: + case CLAN_GIM_MESSAGE: case CONSOLE: messageQueue.offer(chatMessage.getMessageNode()); } @@ -266,35 +268,37 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener @Subscribe public void onMenuEntryAdded(MenuEntryAdded entry) { - final ChatboxTab tab = ChatboxTab.of(entry.getParam1()); + if (entry.getType() != MenuAction.CC_OP.getId()) + { + return; + } - if (tab == null || tab.getAfter() == null || !config.clearHistory() || !Text.removeTags(entry.getOption()).equals(tab.getAfter())) + ChatboxTab tab = ChatboxTab.of(entry.getActionParam1()); + if (tab == null || tab.getAfter() == null || !config.clearHistory() || !entry.getOption().endsWith(tab.getAfter())) { return; } final MenuEntry clearEntry = new MenuEntry(); clearEntry.setTarget(""); - clearEntry.setType(MenuAction.RUNELITE.getId()); + clearEntry.setType(MenuAction.RUNELITE_HIGH_PRIORITY.getId()); clearEntry.setParam0(entry.getActionParam0()); - clearEntry.setParam1(entry.getParam1()); - - if (tab == ChatboxTab.GAME) - { - // keep type as the original CC_OP to correctly group "Game: Clear history" with - // other tab "Game: *" options. - clearEntry.setType(entry.getType()); - } - - final StringBuilder messageBuilder = new StringBuilder(); + clearEntry.setParam1(entry.getActionParam1()); + final StringBuilder optionBuilder = new StringBuilder(); if (tab != ChatboxTab.ALL) { - messageBuilder.append(ColorUtil.wrapWithColorTag(tab.getName() + ": ", Color.YELLOW)); + // Pull tab name from menu since Trade/Group is variable + String option = entry.getOption(); + int idx = option.indexOf(':'); + if (idx != -1) + { + optionBuilder.append(option, 0, idx).append(": "); + } } - messageBuilder.append(CLEAR_HISTORY); - clearEntry.setOption(messageBuilder.toString()); + optionBuilder.append(CLEAR_HISTORY); + clearEntry.setOption(optionBuilder.toString()); final MenuEntry[] menuEntries = client.getMenuEntries(); client.setMenuEntries(ArrayUtils.insert(menuEntries.length - 1, menuEntries, clearEntry)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatboxTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatboxTab.java index a0ad48f287..82c04c82e4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatboxTab.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatboxTab.java @@ -35,46 +35,47 @@ import net.runelite.api.widgets.WidgetInfo; enum ChatboxTab { - ALL("All", "Switch tab", WidgetInfo.CHATBOX_TAB_ALL, + ALL("Switch tab", WidgetInfo.CHATBOX_TAB_ALL, ChatMessageType.values()), // null 'after' var since we're not adding to menu - PRIVATE("Private", null, WidgetInfo.CHATBOX_TAB_PRIVATE, + PRIVATE(null, WidgetInfo.CHATBOX_TAB_PRIVATE, ChatMessageType.PRIVATECHAT, ChatMessageType.PRIVATECHATOUT, ChatMessageType.MODPRIVATECHAT, ChatMessageType.LOGINLOGOUTNOTIFICATION), // null 'after' var since we're not adding to menu - PUBLIC("Public", null, WidgetInfo.CHATBOX_TAB_PUBLIC, + PUBLIC(null, WidgetInfo.CHATBOX_TAB_PUBLIC, ChatMessageType.PUBLICCHAT, ChatMessageType.AUTOTYPER, ChatMessageType.MODCHAT, ChatMessageType.MODAUTOTYPER), - GAME("Game", "Game: Filter", WidgetInfo.CHATBOX_TAB_GAME, + GAME("Filter", WidgetInfo.CHATBOX_TAB_GAME, ChatMessageType.GAMEMESSAGE, ChatMessageType.ENGINE, ChatMessageType.BROADCAST, ChatMessageType.SNAPSHOTFEEDBACK, ChatMessageType.ITEM_EXAMINE, ChatMessageType.NPC_EXAMINE, ChatMessageType.OBJECT_EXAMINE, ChatMessageType.FRIENDNOTIFICATION, ChatMessageType.IGNORENOTIFICATION, ChatMessageType.CONSOLE, ChatMessageType.SPAM, ChatMessageType.PLAYERRELATED, ChatMessageType.TENSECTIMEOUT, ChatMessageType.WELCOME, ChatMessageType.UNKNOWN), - CHANNEL("Channel", null, WidgetInfo.CHATBOX_TAB_CHANNEL, + CHANNEL(null, WidgetInfo.CHATBOX_TAB_CHANNEL, ChatMessageType.FRIENDSCHATNOTIFICATION, ChatMessageType.FRIENDSCHAT, ChatMessageType.CHALREQ_FRIENDSCHAT), - CLAN("Clan", null, WidgetInfo.CHATBOX_TAB_CLAN, - ChatMessageType.CLAN_CHAT, ChatMessageType.CLAN_MESSAGE, ChatMessageType.CLAN_GUEST_CHAT, ChatMessageType.CLAN_GUEST_MESSAGE), + CLAN(null, WidgetInfo.CHATBOX_TAB_CLAN, + ChatMessageType.CLAN_CHAT, ChatMessageType.CLAN_MESSAGE, + ChatMessageType.CLAN_GUEST_CHAT, ChatMessageType.CLAN_GUEST_MESSAGE), - TRADE("Trade", "Trade: Show none", WidgetInfo.CHATBOX_TAB_TRADE, - ChatMessageType.TRADE_SENT, ChatMessageType.TRADEREQ, ChatMessageType.TRADE, ChatMessageType.CHALREQ_TRADE), + // Group has its own Clear option, but Trade does not + TRADE_GROUP("Trade: Show none", WidgetInfo.CHATBOX_TAB_TRADE, + ChatMessageType.TRADE_SENT, ChatMessageType.TRADEREQ, ChatMessageType.TRADE, ChatMessageType.CHALREQ_TRADE, + ChatMessageType.CLAN_GIM_CHAT, ChatMessageType.CLAN_GIM_MESSAGE), ; private static final Map TAB_MESSAGE_TYPES; - private final String name; @Nullable private final String after; private final int widgetId; private final ChatMessageType[] messageTypes; - ChatboxTab(String name, String after, WidgetInfo widgetId, ChatMessageType... messageTypes) + ChatboxTab(String after, WidgetInfo widgetId, ChatMessageType... messageTypes) { - this.name = name; this.after = after; this.widgetId = widgetId.getId(); this.messageTypes = messageTypes; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java index c13e87c38b..9f74205102 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java @@ -211,6 +211,7 @@ public class ChatNotificationsPlugin extends Plugin case FRIENDSCHAT: case CLAN_CHAT: case CLAN_GUEST_CHAT: + case CLAN_GIM_CHAT: case AUTOTYPER: case MODAUTOTYPER: if (client.getLocalPlayer() != null && Text.toJagexName(Text.removeTags(chatMessage.getName())).equals(client.getLocalPlayer().getName())) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 0fa33cf1f5..685bd16b1f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -25,8 +25,10 @@ package net.runelite.client.plugins.config; import com.google.common.base.Splitter; +import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import com.google.common.collect.ComparisonChain; +import com.google.common.collect.Sets; import com.google.common.primitives.Ints; import java.awt.BasicStroke; import java.awt.BorderLayout; @@ -48,9 +50,12 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.EnumSet; +import java.lang.reflect.ParameterizedType; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import java.util.function.Consumer; import javax.inject.Inject; @@ -62,6 +67,7 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFormattedTextField; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -72,6 +78,8 @@ import javax.swing.JSlider; import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.JTextField; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; @@ -124,6 +132,7 @@ import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.SwingUtil; import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; @Slf4j class ConfigPanel extends PluginPanel @@ -464,434 +473,55 @@ class ConfigPanel extends PluginPanel item.add(configEntryName, BorderLayout.CENTER); item.setName(cid.getItem().keyName()); - if (cid.getType() == Button.class) - { - try - { - ConfigItem cidItem = cid.getItem(); - JButton button = new JButton(cidItem.name()); - button.addActionListener((e) -> - { - ConfigButtonClicked event = new ConfigButtonClicked(); - event.setGroup(cd.getGroup().value()); - event.setKey(cid.getItem().keyName()); - eventBus.post(event); - }); - item.add(button); - } - catch (Exception ex) - { - log.error("Adding action listener failed: {}", ex.getMessage()); - ex.printStackTrace(); - } - } - if (cid.getType() == boolean.class) { - JCheckBox checkbox = new ToggleButton(); - checkbox.setPreferredSize(new Dimension(26, 25)); - checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()))); - checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid)); - - item.add(checkbox, BorderLayout.EAST); + item.add(createCheckbox(cd, cid), BorderLayout.EAST); } - - if (cid.getType().isAssignableFrom(Consumer.class)) + else if (cid.getType() == int.class) { - item.remove(configEntryName); - - JButton button = new JButton(cid.getItem().name()); - button.addActionListener((e) -> - { - log.debug("Running consumer: {}.{}", cd.getGroup().value(), cid.getItem().keyName()); - configManager.getConsumer(cd.getGroup().value(), cid.getItem().keyName()).accept(pluginConfig.getPlugin()); - }); - - item.add(button, BorderLayout.CENTER); + item.add(createIntSpinner(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == int.class) - { - int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - - Units units = cid.getUnits(); - Range range = cid.getRange(); - int min = 0, max = Integer.MAX_VALUE; - if (range != null) - { - min = range.min(); - max = range.max(); - } - - // Config may previously have been out of range - value = Ints.constrainToRange(value, min, max); - - if (max < Integer.MAX_VALUE) - { - JLabel sliderValueLabel = new JLabel(); - JSlider slider = new JSlider(min, max, value); - slider.setBackground(ColorScheme.DARK_GRAY_COLOR); - if (units != null) - { - sliderValueLabel.setText(slider.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(slider.getValue())); - } - slider.setPreferredSize(new Dimension(80, 25)); - slider.addChangeListener((l) -> - { - if (units != null) - { - sliderValueLabel.setText(slider.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(slider.getValue())); - } - - if (!slider.getValueIsAdjusting()) - { - changeConfiguration(slider, cd, cid); - } - } - ); - - SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.setUI(new BasicSpinnerUI() - { - protected Component createNextButton() - { - return null; - } - - protected Component createPreviousButton() - { - return null; - } - }); - - JPanel subPanel = new JPanel(); - subPanel.setPreferredSize(new Dimension(110, 25)); - subPanel.setLayout(new BorderLayout()); - - spinner.addChangeListener((ce) -> - { - changeConfiguration(spinner, cd, cid); - - if (units != null) - { - sliderValueLabel.setText(spinner.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(spinner.getValue())); - } - slider.setValue((Integer) spinner.getValue()); - - subPanel.add(sliderValueLabel, BorderLayout.WEST); - subPanel.add(slider, BorderLayout.EAST); - subPanel.remove(spinner); - - validate(); - repaint(); - }); - - sliderValueLabel.addMouseListener(new MouseAdapter() - { - public void mouseClicked(MouseEvent e) - { - spinner.setValue(slider.getValue()); - - subPanel.remove(sliderValueLabel); - subPanel.remove(slider); - subPanel.add(spinner, BorderLayout.EAST); - - validate(); - repaint(); - - final JTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField(); - tf.requestFocusInWindow(); - SwingUtilities.invokeLater(tf::selectAll); - } - }); - - subPanel.add(sliderValueLabel, BorderLayout.WEST); - subPanel.add(slider, BorderLayout.EAST); - - item.add(subPanel, BorderLayout.EAST); - } - else - { - SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); - - if (units != null) - { - spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); - } - - item.add(spinner, BorderLayout.EAST); - } - } - else if (cid.getType() == double.class) { - double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class); - - SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); - - item.add(spinner, BorderLayout.EAST); + item.add(createDoubleSpinner(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == String.class) + else if (cid.getType() == String.class) { - JTextComponent textField; - - if (cid.getItem().secret()) - { - textField = new JPasswordField(); - } - else - { - final JTextArea textArea = new JTextArea(); - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - textField = textArea; - } - - textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - - textField.addFocusListener(new FocusAdapter() - { - @Override - public void focusLost(FocusEvent e) - { - changeConfiguration(textField, cd, cid); - } - }); - - if (cid.getItem().parse()) - { - JLabel parsingLabel = new JLabel(); - parsingLabel.setHorizontalAlignment(SwingConstants.CENTER); - parsingLabel.setPreferredSize(new Dimension(PANEL_WIDTH, 15)); - - DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener(); - listener.addChangeListener(e -> - { - if (cid.getItem().parse()) - { - parseLabel(cid.getItem(), parsingLabel, textField.getText()); - } - }); - textField.getDocument().addDocumentListener(listener); - - item.add(configEntryName, BorderLayout.NORTH); - item.add(textField, BorderLayout.CENTER); - - - parseLabel(cid.getItem(), parsingLabel, textField.getText()); - item.add(parsingLabel, BorderLayout.SOUTH); - } - else - { - item.add(textField, BorderLayout.SOUTH); - } + item.add(createTextField(cd, cid), BorderLayout.SOUTH); } - - if (cid.getType() == Color.class) + else if (cid.getType() == Color.class) { - Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class); - - ColorJButton colorPickerBtn; - - boolean alphaHidden = cid.getAlpha() == null; - - if (existing == null) - { - colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK); - } - else - { - String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase(); - colorPickerBtn = new ColorJButton(colorHex, existing); - } - - colorPickerBtn.setFocusable(false); - colorPickerBtn.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - RuneliteColorPicker colorPicker = colorPickerManager.create( - SwingUtilities.windowForComponent(ConfigPanel.this), - colorPickerBtn.getColor(), - cid.getItem().name(), - alphaHidden); - colorPicker.setLocation(getLocationOnScreen()); - colorPicker.setOnColorChange(c -> - { - colorPickerBtn.setColor(c); - colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase()); - }); - colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid)); - colorPicker.setVisible(true); - } - }); - - item.add(colorPickerBtn, BorderLayout.EAST); + item.add(createColorPicker(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == Dimension.class) + else if (cid.getType() == Dimension.class) { - JPanel dimensionPanel = new JPanel(); - dimensionPanel.setLayout(new BorderLayout()); - - String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()); - String[] splitStr = str.split("x"); - int width = Integer.parseInt(splitStr[0]); - int height = Integer.parseInt(splitStr[1]); - - SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1); - JSpinner widthSpinner = new JSpinner(widthModel); - Component widthEditor = widthSpinner.getEditor(); - JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField(); - widthSpinnerTextField.setColumns(4); - - SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1); - JSpinner heightSpinner = new JSpinner(heightModel); - Component heightEditor = heightSpinner.getEditor(); - JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField(); - heightSpinnerTextField.setColumns(4); - - ChangeListener listener = e -> - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); - - widthSpinner.addChangeListener(listener); - heightSpinner.addChangeListener(listener); - - dimensionPanel.add(widthSpinner, BorderLayout.WEST); - dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER); - dimensionPanel.add(heightSpinner, BorderLayout.EAST); - - item.add(dimensionPanel, BorderLayout.EAST); + item.add(createDimension(cd, cid), BorderLayout.EAST); } - - if (cid.getType().isEnum()) + else if (cid.getType() instanceof Class && ((Class) cid.getType()).isEnum()) { - Class type = (Class) cid.getType(); - - JComboBox> box = new JComboBox>(type.getEnumConstants()); // NOPMD: UseDiamondOperator - // set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer - // to build components for each combobox element in order to compute the display size of the - // combobox - box.setRenderer(new ComboBoxListRenderer<>()); - box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25)); - box.setForeground(Color.WHITE); - box.setFocusable(false); - - try - { - Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - box.setSelectedItem(selectedItem); - box.setToolTipText(Text.titleCase(selectedItem)); - } - catch (IllegalArgumentException ex) - { - log.debug("invalid seleced item", ex); - } - box.addItemListener(e -> - { - if (e.getStateChange() == ItemEvent.SELECTED) - { - changeConfiguration(box, cd, cid); - box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem())); - } - }); - item.add(box, BorderLayout.EAST); + item.add(createComboBox(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class) + else if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class) { - Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), - (Class) cid.getType()); - - HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); - - button.addFocusListener(new FocusAdapter() - { - @Override - public void focusLost(FocusEvent e) - { - changeConfiguration(button, cd, cid); - } - }); - - item.add(button, BorderLayout.EAST); + item.add(createKeybind(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == EnumSet.class) + else if (cid.getType() instanceof ParameterizedType) { - Class enumType = cid.getItem().enumClass(); - - EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), EnumSet.class); - if (enumSet == null || enumSet.contains(null)) + ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); + if (parameterizedType.getRawType() == Set.class) { - enumSet = EnumSet.noneOf(enumType); + item.add(createList(cd, cid), BorderLayout.EAST); } - - JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); - List jcheckboxes = new ArrayList<>(); - - for (Object obj : enumType.getEnumConstants()) - { - String option = String.valueOf(obj).toLowerCase().replace("_", " "); - - JCheckBox checkbox = new ToggleButton(option); - checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); - checkbox.setSelected(enumSet.contains(obj)); - jcheckboxes.add(checkbox); - - enumsetLayout.add(checkbox); - } - - jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid))); - - item.add(enumsetLayout, BorderLayout.SOUTH); } JPanel section = sectionWidgets.get(cid.getItem().section()); - JPanel title = titleWidgets.get(cid.getItem().title()); - - if (section != null) + if (section == null) { - section.add(item); - } - else if (title != null) - { - title.add(item); + topLevelPanels.put(cid, item); } else { - topLevelPanels.put(cid, item); + section.add(item); } } @@ -927,6 +557,251 @@ class ConfigPanel extends PluginPanel revalidate(); } + private JCheckBox createCheckbox(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JCheckBox checkbox = new JCheckBox(); + checkbox.setBackground(ColorScheme.LIGHT_GRAY_COLOR); + checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()))); + checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid)); + return checkbox; + } + + private JSpinner createIntSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + + Range range = cid.getRange(); + int min = 0, max = Integer.MAX_VALUE; + if (range != null) + { + min = range.min(); + max = range.max(); + } + + // Config may previously have been out of range + value = Ints.constrainToRange(value, min, max); + + SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + + Units units = cid.getUnits(); + if (units != null) + { + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); + } + + return spinner; + } + + private JSpinner createDoubleSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class); + + SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + return spinner; + } + + private JTextComponent createTextField(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JTextComponent textField; + + if (cid.getItem().secret()) + { + textField = new JPasswordField(); + } + else + { + final JTextArea textArea = new JTextArea(); + textArea.setLineWrap(true); + textArea.setWrapStyleWord(true); + textField = textArea; + } + + textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + + textField.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + changeConfiguration(textField, cd, cid); + } + }); + + return textField; + } + + private ColorJButton createColorPicker(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class); + + ColorJButton colorPickerBtn; + + boolean alphaHidden = cid.getAlpha() == null; + + if (existing == null) + { + colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK); + } + else + { + String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase(); + colorPickerBtn = new ColorJButton(colorHex, existing); + } + + colorPickerBtn.setFocusable(false); + colorPickerBtn.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + RuneliteColorPicker colorPicker = colorPickerManager.create( + SwingUtilities.windowForComponent(ConfigPanel.this), + colorPickerBtn.getColor(), + cid.getItem().name(), + alphaHidden); + colorPicker.setLocation(getLocationOnScreen()); + colorPicker.setOnColorChange(c -> + { + colorPickerBtn.setColor(c); + colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase()); + }); + colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid)); + colorPicker.setVisible(true); + } + }); + + return colorPickerBtn; + } + + private JPanel createDimension(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JPanel dimensionPanel = new JPanel(); + dimensionPanel.setLayout(new BorderLayout()); + + String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()); + String[] splitStr = str.split("x"); + int width = Integer.parseInt(splitStr[0]); + int height = Integer.parseInt(splitStr[1]); + + SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1); + JSpinner widthSpinner = new JSpinner(widthModel); + Component widthEditor = widthSpinner.getEditor(); + JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField(); + widthSpinnerTextField.setColumns(4); + + SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1); + JSpinner heightSpinner = new JSpinner(heightModel); + Component heightEditor = heightSpinner.getEditor(); + JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField(); + heightSpinnerTextField.setColumns(4); + + ChangeListener listener = e -> + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); + + widthSpinner.addChangeListener(listener); + heightSpinner.addChangeListener(listener); + + dimensionPanel.add(widthSpinner, BorderLayout.WEST); + dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER); + dimensionPanel.add(heightSpinner, BorderLayout.EAST); + + return dimensionPanel; + } + + private JComboBox> createComboBox(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Class type = (Class) cid.getType(); + + JComboBox> box = new JComboBox>(type.getEnumConstants()); // NOPMD: UseDiamondOperator + // set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer + // to build components for each combobox element in order to compute the display size of the + // combobox + box.setRenderer(listCellRenderer); + box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25)); + box.setForeground(Color.WHITE); + box.setFocusable(false); + + try + { + Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + box.setSelectedItem(selectedItem); + box.setToolTipText(Text.titleCase(selectedItem)); + } + catch (IllegalArgumentException ex) + { + log.debug("invalid selected item", ex); + } + box.addItemListener(e -> + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + changeConfiguration(box, cd, cid); + box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem())); + } + }); + + return box; + } + + private HotkeyButton createKeybind(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), + cid.getItem().keyName(), + (Class) cid.getType()); + + HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); + + button.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + changeConfiguration(button, cd, cid); + } + }); + + return button; + } + + private JList> createList(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); + Class type = (Class) parameterizedType.getActualTypeArguments()[0]; + Set set = configManager.getConfiguration(cd.getGroup().value(), null, + cid.getItem().keyName(), parameterizedType); + + JList> list = new JList>(type.getEnumConstants()); // NOPMD: UseDiamondOperator + list.setCellRenderer(listCellRenderer); + list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + list.setLayoutOrientation(JList.VERTICAL); + list.setSelectedIndices( + MoreObjects.firstNonNull(set, Collections.emptySet()) + .stream() + .mapToInt(e -> ArrayUtils.indexOf(type.getEnumConstants(), e)) + .toArray()); + list.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + changeConfiguration(list, cd, cid); + } + }); + + return list; + } + private Boolean parse(ConfigItem item, String value) { try @@ -1044,6 +919,13 @@ class ConfigPanel extends PluginPanel HotkeyButton hotkeyButton = (HotkeyButton) component; configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), hotkeyButton.getValue()); } + else if (component instanceof JList) + { + JList list = (JList) component; + List selectedValues = list.getSelectedValuesList(); + + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Sets.newHashSet(selectedValues)); + } enableDisable(component, cid); rebuild(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java index 03866ee5c3..39d022c3e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java @@ -126,6 +126,7 @@ public class EmojiPlugin extends Plugin case FRIENDSCHAT: case CLAN_CHAT: case CLAN_GUEST_CHAT: + case CLAN_GIM_CHAT: case PRIVATECHAT: case PRIVATECHATOUT: case MODPRIVATECHAT: 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 25ae9a55b3..56673629e4 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 @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; @@ -145,10 +146,7 @@ public class HiscorePanel extends PluginPanel this.nameAutocompleter = nameAutocompleter; this.hiscoreClient = new HiscoreClient(okHttpClient); - // The layout seems to be ignoring the top margin and only gives it - // a 2-3 pixel margin, so I set the value to 18 to compensate - // TODO: Figure out why this layout is ignoring most of the top margin - setBorder(new EmptyBorder(18, 10, 0, 10)); + setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); setBackground(ColorScheme.DARK_GRAY_COLOR); setLayout(new GridBagLayout()); 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 f245c9b2d5..95f12ec821 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 @@ -188,7 +188,7 @@ public class HiscorePlugin extends Plugin && event.getMenuOption().equals(LOOKUP)) { final String target; - HiscoreEndpoint endpoint = HiscoreEndpoint.NORMAL; + 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, @@ -199,6 +199,7 @@ public class HiscorePlugin extends Plugin return; } + endpoint = getWorldEndpoint(); target = player.getName(); } else diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java index 5714ff9f8a..0551258282 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java @@ -32,7 +32,7 @@ import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import javax.inject.Inject; -import static net.runelite.api.widgets.WidgetID.GRAVESTONE_GROUP_ID; +import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.WidgetItemOverlay; @@ -54,7 +54,12 @@ public class InventoryTagsOverlay extends WidgetItemOverlay this.config = config; showOnEquipment(); showOnInventory(); - showOnInterfaces(GRAVESTONE_GROUP_ID); + showOnInterfaces( + WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_INVENTORY_GROUP_ID, + WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_PRIVATE_GROUP_ID, + WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_SHARED_GROUP_ID, + WidgetID.GRAVESTONE_GROUP_ID + ); fillCache = CacheBuilder.newBuilder() .concurrencyLevel(1) .maximumSize(32) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index f234f1b045..98c2302fcd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -113,6 +113,18 @@ public interface MenuEntrySwapperConfig extends Config KALPHITE_CAVE, } + @ConfigItem( + position = -3, + keyName = "leftClickCustomization", + name = "Customizable left-click", + description = "Allows customization of left-clicks on items", + section = itemSection + ) + default boolean leftClickCustomization() + { + return true; + } + @ConfigItem( position = -2, keyName = "shiftClickCustomization", 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 14cfb0bf75..6a457ce2b7 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 @@ -29,6 +29,7 @@ package net.runelite.client.plugins.menuentryswapper; import com.google.common.annotations.VisibleForTesting; import static com.google.common.base.Predicates.alwaysTrue; import static com.google.common.base.Predicates.equalTo; +import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.LinkedHashMultimap; @@ -43,7 +44,6 @@ import java.util.Set; import java.util.function.Predicate; import java.util.function.Supplier; import javax.inject.Inject; -import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.ItemComposition; @@ -88,28 +88,43 @@ public class MenuEntrySwapperPlugin extends Plugin private static final String CONFIGURE = "Configure"; private static final String SAVE = "Save"; private static final String RESET = "Reset"; - private static final String MENU_TARGET = "Shift-click"; + private static final String LEFT_CLICK_MENU_TARGET = "Left-click"; + private static final String SHIFT_CLICK_MENU_TARGET = "Shift-click"; private static final String SHIFTCLICK_CONFIG_GROUP = "shiftclick"; private static final String ITEM_KEY_PREFIX = "item_"; - private static final WidgetMenuOption FIXED_INVENTORY_TAB_CONFIGURE = new WidgetMenuOption(CONFIGURE, - MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); + // Shift click + private static final WidgetMenuOption FIXED_INVENTORY_TAB_CONFIGURE_SC = new WidgetMenuOption(CONFIGURE, + SHIFT_CLICK_MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); + private static final WidgetMenuOption FIXED_INVENTORY_TAB_SAVE_SC = new WidgetMenuOption(SAVE, + SHIFT_CLICK_MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); - private static final WidgetMenuOption FIXED_INVENTORY_TAB_SAVE = new WidgetMenuOption(SAVE, - MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_INVENTORY_TAB_CONFIGURE_SC = new WidgetMenuOption(CONFIGURE, + SHIFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_INVENTORY_TAB_SAVE_SC = new WidgetMenuOption(SAVE, + SHIFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB); - private static final WidgetMenuOption RESIZABLE_INVENTORY_TAB_CONFIGURE = new WidgetMenuOption(CONFIGURE, - MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC = new WidgetMenuOption(CONFIGURE, + SHIFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC = new WidgetMenuOption(SAVE, + SHIFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB); - private static final WidgetMenuOption RESIZABLE_INVENTORY_TAB_SAVE = new WidgetMenuOption(SAVE, - MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB); + // Left click + private static final WidgetMenuOption FIXED_INVENTORY_TAB_CONFIGURE_LC = new WidgetMenuOption(CONFIGURE, + LEFT_CLICK_MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); + private static final WidgetMenuOption FIXED_INVENTORY_TAB_SAVE_LC = new WidgetMenuOption(SAVE, + LEFT_CLICK_MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); - private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE = new WidgetMenuOption(CONFIGURE, - MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_INVENTORY_TAB_CONFIGURE_LC = new WidgetMenuOption(CONFIGURE, + LEFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_INVENTORY_TAB_SAVE_LC = new WidgetMenuOption(SAVE, + LEFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB); - private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE = new WidgetMenuOption(SAVE, - MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC = new WidgetMenuOption(CONFIGURE, + LEFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB); + private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC = new WidgetMenuOption(SAVE, + LEFT_CLICK_MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB); private static final Set ITEM_MENU_TYPES = ImmutableSet.of( MenuAction.ITEM_FIRST_OPTION, @@ -162,8 +177,8 @@ public class MenuEntrySwapperPlugin extends Plugin @Inject private ItemManager itemManager; - @Getter private boolean configuringShiftClick = false; + private boolean configuringLeftClick = false; private final Multimap swaps = Multimaps.synchronizedSetMultimap(LinkedHashMultimap.create()); private final ArrayListMultimap optionIndexes = ArrayListMultimap.create(); @@ -177,11 +192,7 @@ public class MenuEntrySwapperPlugin extends Plugin @Override public void startUp() { - if (config.shiftClickCustomization()) - { - enableCustomization(); - } - + enableCustomization(); setupSwaps(); } @@ -450,16 +461,10 @@ public class MenuEntrySwapperPlugin extends Plugin @Subscribe public void onConfigChanged(ConfigChanged event) { - if (event.getGroup().equals(MenuEntrySwapperConfig.GROUP) && event.getKey().equals("shiftClickCustomization")) + if (event.getGroup().equals(MenuEntrySwapperConfig.GROUP) + && (event.getKey().equals("shiftClickCustomization") || event.getKey().equals("leftClickCustomization"))) { - if (config.shiftClickCustomization()) - { - enableCustomization(); - } - else - { - disableCustomization(); - } + enableCustomization(); } else if (event.getGroup().equals(SHIFTCLICK_CONFIG_GROUP) && event.getKey().startsWith(ITEM_KEY_PREFIX)) { @@ -472,10 +477,10 @@ public class MenuEntrySwapperPlugin extends Plugin client.getItemCompositionCache().reset(); } - private Integer getSwapConfig(int itemId) + private Integer getSwapConfig(boolean shift, int itemId) { itemId = ItemVariationMapping.map(itemId); - String config = configManager.getConfiguration(SHIFTCLICK_CONFIG_GROUP, ITEM_KEY_PREFIX + itemId); + String config = configManager.getConfiguration(shift ? SHIFTCLICK_CONFIG_GROUP : MenuEntrySwapperConfig.GROUP, ITEM_KEY_PREFIX + itemId); if (config == null || config.isEmpty()) { return null; @@ -484,29 +489,29 @@ public class MenuEntrySwapperPlugin extends Plugin return Integer.parseInt(config); } - private void setSwapConfig(int itemId, int index) + private void setSwapConfig(boolean shift, int itemId, int index) { itemId = ItemVariationMapping.map(itemId); - configManager.setConfiguration(SHIFTCLICK_CONFIG_GROUP, ITEM_KEY_PREFIX + itemId, index); + configManager.setConfiguration(shift ? SHIFTCLICK_CONFIG_GROUP : MenuEntrySwapperConfig.GROUP, ITEM_KEY_PREFIX + itemId, index); } - private void unsetSwapConfig(int itemId) + private void unsetSwapConfig(boolean shift, int itemId) { itemId = ItemVariationMapping.map(itemId); - configManager.unsetConfiguration(SHIFTCLICK_CONFIG_GROUP, ITEM_KEY_PREFIX + itemId); + configManager.unsetConfiguration(shift ? SHIFTCLICK_CONFIG_GROUP : MenuEntrySwapperConfig.GROUP, ITEM_KEY_PREFIX + itemId); } private void enableCustomization() { - refreshShiftClickCustomizationMenus(); + rebuildCustomizationMenus(); // set shift click action index on the item compositions clientThread.invoke(this::resetItemCompositionCache); } private void disableCustomization() { - removeShiftClickCustomizationMenus(); - configuringShiftClick = false; + removeCusomizationMenus(); + configuringShiftClick = configuringLeftClick = false; // flush item compositions to reset the shift click action index clientThread.invoke(this::resetItemCompositionCache); } @@ -518,15 +523,21 @@ public class MenuEntrySwapperPlugin extends Plugin || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) { - configuringShiftClick = event.getMenuOption().equals(CONFIGURE) && Text.removeTags(event.getMenuTarget()).equals(MENU_TARGET); - refreshShiftClickCustomizationMenus(); + 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) { - if (!configuringShiftClick) + if (!configuringShiftClick && !configuringLeftClick) { return; } @@ -549,13 +560,41 @@ public class MenuEntrySwapperPlugin extends Plugin return; } - ItemComposition itemComposition = itemManager.getItemComposition(itemId); - MenuAction shiftClickAction = MenuAction.ITEM_USE; - final int shiftClickActionIndex = itemComposition.getShiftClickActionIndex(); + MenuAction activeAction = MenuAction.ITEM_USE; + final ItemComposition itemComposition = itemManager.getItemComposition(itemId); - if (shiftClickActionIndex >= 0) + if (configuringShiftClick) { - shiftClickAction = MenuAction.of(MenuAction.ITEM_FIRST_OPTION.getId() + shiftClickActionIndex); + // For shift-click read the active action off of the item composition, since it may be set by + // that even if we have no existing config for it + final int shiftClickActionIndex = itemComposition.getShiftClickActionIndex(); + + if (shiftClickActionIndex >= 0) + { + activeAction = MenuAction.of(MenuAction.ITEM_FIRST_OPTION.getId() + shiftClickActionIndex); + } + } + else + { + // The default left click on items is the highest priority action 0-2, and otherwise is use. + final String[] actions = itemComposition.getInventoryActions(); + for (int i = 0; i <= 2; ++i) + { + if (!Strings.isNullOrEmpty(actions[i])) + { + activeAction = MenuAction.of(MenuAction.ITEM_FIRST_OPTION.getId() + i); + break; + } + } + + // Apply left click action from configuration + Integer config = getSwapConfig(false, itemId); + if (config != null) + { + activeAction = config >= 0 + ? MenuAction.of(MenuAction.ITEM_FIRST_OPTION.getId() + config) + : MenuAction.ITEM_USE; + } } MenuEntry[] entries = event.getMenuEntries(); @@ -568,7 +607,7 @@ public class MenuEntrySwapperPlugin extends Plugin { entry.setType(MenuAction.RUNELITE.getId()); - if (shiftClickAction == menuAction) + if (activeAction == menuAction) { entry.setOption("* " + entry.getOption()); } @@ -577,7 +616,7 @@ public class MenuEntrySwapperPlugin extends Plugin final MenuEntry resetShiftClickEntry = new MenuEntry(); resetShiftClickEntry.setOption(RESET); - resetShiftClickEntry.setTarget(MENU_TARGET); + resetShiftClickEntry.setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET); resetShiftClickEntry.setIdentifier(itemId); resetShiftClickEntry.setParam1(widgetId); resetShiftClickEntry.setType(MenuAction.RUNELITE.getId()); @@ -674,9 +713,14 @@ public class MenuEntrySwapperPlugin extends Plugin String target = event.getMenuTarget(); ItemComposition itemComposition = itemManager.getItemComposition(itemId); - if (option.equals(RESET) && target.equals(MENU_TARGET)) + if (option.equals(RESET) && target.equals(SHIFT_CLICK_MENU_TARGET)) { - unsetSwapConfig(itemId); + unsetSwapConfig(true, itemId); + return; + } + if (option.equals(RESET) && target.equals(LEFT_CLICK_MENU_TARGET)) + { + unsetSwapConfig(false, itemId); return; } @@ -687,7 +731,7 @@ public class MenuEntrySwapperPlugin extends Plugin if (option.equals("Use")) //because "Use" is not in inventoryActions { - setSwapConfig(itemId, -1); + setSwapConfig(configuringShiftClick, itemId, -1); } else { @@ -697,14 +741,14 @@ public class MenuEntrySwapperPlugin extends Plugin { if (option.equals(inventoryActions[index])) { - setSwapConfig(itemId, index); + setSwapConfig(configuringShiftClick, itemId, index); break; } } } } - private void swapMenuEntry(int index, MenuEntry menuEntry) + private void swapMenuEntry(MenuEntry[] menuEntries, int index, MenuEntry menuEntry) { final int eventId = menuEntry.getIdentifier(); final MenuAction menuAction = MenuAction.of(menuEntry.getType()); @@ -712,6 +756,7 @@ public class MenuEntrySwapperPlugin extends Plugin final String target = Text.removeTags(menuEntry.getTarget()).toLowerCase(); final NPC hintArrowNpc = client.getHintArrowNpc(); + // Don't swap on hint arrow npcs, usually they need "Talk-to" for clues. if (hintArrowNpc != null && hintArrowNpc.getIndex() == eventId && NPC_MENU_TYPES.contains(menuAction)) @@ -719,22 +764,23 @@ public class MenuEntrySwapperPlugin extends Plugin return; } - if (shiftModifier() && (menuAction == MenuAction.ITEM_FIRST_OPTION + final boolean itemOp = menuAction == MenuAction.ITEM_FIRST_OPTION || menuAction == MenuAction.ITEM_SECOND_OPTION || menuAction == MenuAction.ITEM_THIRD_OPTION || menuAction == MenuAction.ITEM_FOURTH_OPTION || menuAction == MenuAction.ITEM_FIFTH_OPTION - || menuAction == MenuAction.ITEM_USE)) + || menuAction == MenuAction.ITEM_USE; + if (shiftModifier() && itemOp) { // Special case use shift click due to items not actually containing a "Use" option, making // the client unable to perform the swap itself. if (config.shiftClickCustomization() && !option.equals("use")) { - Integer customOption = getSwapConfig(eventId); + Integer customOption = getSwapConfig(true, eventId); if (customOption != null && customOption == -1) { - swap("use", target, index, true); + swap(menuEntries, "use", target, index, true); } } @@ -743,12 +789,31 @@ public class MenuEntrySwapperPlugin extends Plugin return; } + // Custom left-click item swap + if (itemOp) + { + Integer swapIndex = getSwapConfig(false, eventId); + if (swapIndex != null && index < menuEntries.length - 1) + { + MenuAction swapAction = swapIndex >= 0 + ? MenuAction.of(MenuAction.ITEM_FIRST_OPTION.getId() + swapIndex) + : MenuAction.ITEM_USE; + + if (menuAction == swapAction) + { + swap(optionIndexes, menuEntries, index, menuEntries.length - 1); + return; + } + } + } + + // Built-in swaps Collection swaps = this.swaps.get(option); for (Swap swap : swaps) { if (swap.getTargetPredicate().test(target) && swap.getEnabled().get()) { - if (swap(swap.getSwappedOption(), target, index, swap.isStrict())) + if (swap(menuEntries, swap.getSwappedOption(), target, index, swap.isStrict())) { break; } @@ -781,7 +846,7 @@ public class MenuEntrySwapperPlugin extends Plugin idx = 0; for (MenuEntry entry : menuEntries) { - swapMenuEntry(idx++, entry); + swapMenuEntry(menuEntries, idx++, entry); } } @@ -796,7 +861,7 @@ public class MenuEntrySwapperPlugin extends Plugin } ItemComposition itemComposition = event.getItemComposition(); - Integer option = getSwapConfig(itemComposition.getId()); + Integer option = getSwapConfig(true, itemComposition.getId()); if (option != null) { @@ -804,10 +869,8 @@ public class MenuEntrySwapperPlugin extends Plugin } } - private boolean swap(String option, String target, int index, boolean strict) + private boolean swap(MenuEntry[] menuEntries, String option, String target, int index, boolean strict) { - MenuEntry[] menuEntries = client.getMenuEntries(); - // find option to swap with int optionIdx = findIndex(menuEntries, index, option, target, strict); @@ -892,30 +955,55 @@ public class MenuEntrySwapperPlugin extends Plugin list.add(idx < 0 ? -idx - 1 : idx, value); } - private void removeShiftClickCustomizationMenus() + private void removeCusomizationMenus() { - menuManager.removeManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE); - menuManager.removeManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE); - menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE); - menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE); - menuManager.removeManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE); - menuManager.removeManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE); + // Shift click + menuManager.removeManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC); + menuManager.removeManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC); + menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC); + menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC); + menuManager.removeManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC); + menuManager.removeManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC); + // Left click + menuManager.removeManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC); + menuManager.removeManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC); + menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC); + menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC); + menuManager.removeManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC); + menuManager.removeManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC); } - private void refreshShiftClickCustomizationMenus() + private void rebuildCustomizationMenus() { - removeShiftClickCustomizationMenus(); - if (configuringShiftClick) + removeCusomizationMenus(); + if (configuringLeftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC); + } + 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); } else { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE); + // 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); + } + // 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); + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java index 2a1a244b89..0b88556032 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java @@ -24,16 +24,13 @@ */ package net.runelite.client.plugins.worldhopper; -import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import net.runelite.http.api.worlds.WorldRegion; -@NoArgsConstructor -@AllArgsConstructor -public enum RegionFilterMode +@RequiredArgsConstructor +enum RegionFilterMode { - NONE, AUSTRALIA(WorldRegion.AUSTRALIA), GERMANY(WorldRegion.GERMANY), UNITED_KINGDOM(WorldRegion.UNITED_KINGDOM) @@ -54,5 +51,22 @@ public enum RegionFilterMode }; @Getter - private WorldRegion region; + private final WorldRegion region; + + static RegionFilterMode of(WorldRegion region) + { + switch (region) + { + case UNITED_STATES_OF_AMERICA: + return UNITED_STATES; + case UNITED_KINGDOM: + return UNITED_KINGDOM; + case AUSTRALIA: + return AUSTRALIA; + case GERMANY: + return GERMANY; + default: + throw new IllegalStateException(); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java index 44c33c22ab..8996dd12f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java @@ -27,6 +27,8 @@ package net.runelite.client.plugins.worldhopper; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.util.Collections; +import java.util.Set; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -76,9 +78,9 @@ public interface WorldHopperConfig extends Config description = "Limit quick-hopping to worlds of a specific region", position = 3 ) - default RegionFilterMode quickHopRegionFilter() + default Set quickHopRegionFilter() { - return RegionFilterMode.NONE; + return Collections.emptySet(); } @ConfigItem( @@ -142,9 +144,9 @@ public interface WorldHopperConfig extends Config description = "Restrict sidebar worlds to one region", position = 8 ) - default RegionFilterMode regionFilter() + default Set regionFilter() { - return RegionFilterMode.NONE; + return Collections.emptySet(); } @ConfigItem( 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 dbe2fba12b..f0abbfb07b 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 @@ -36,6 +36,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -533,6 +534,8 @@ public class WorldHopperPlugin extends Plugin int worldIdx = worlds.indexOf(currentWorld); int totalLevel = client.getTotalLevel(); + final Set regionFilter = config.quickHopRegionFilter(); + World world; do { @@ -564,7 +567,7 @@ public class WorldHopperPlugin extends Plugin world = worlds.get(worldIdx); // Check world region if filter is enabled - if (config.quickHopRegionFilter() != RegionFilterMode.NONE && world.getRegion() != config.quickHopRegionFilter().getRegion()) + if (!regionFilter.isEmpty() && !regionFilter.contains(RegionFilterMode.of(world.getRegion()))) { continue; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java index 6f62551cc9..2878a36ca3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java @@ -34,6 +34,7 @@ import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; import javax.swing.JPanel; import javax.swing.SwingUtilities; @@ -68,7 +69,7 @@ class WorldSwitcherPanel extends PluginPanel @Setter(AccessLevel.PACKAGE) private SubscriptionFilterMode subscriptionFilterMode; @Setter(AccessLevel.PACKAGE) - private RegionFilterMode regionFilterMode; + private Set regionFilterMode; WorldSwitcherPanel(WorldHopperPlugin plugin) { @@ -249,7 +250,7 @@ class WorldSwitcherPanel extends PluginPanel break; } - if (regionFilterMode.getRegion() != null && !regionFilterMode.getRegion().equals(world.getRegion())) + if (!regionFilterMode.isEmpty() && !regionFilterMode.contains(RegionFilterMode.of(world.getRegion()))) { continue; } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java index b73700134c..7cb057f8e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java @@ -59,9 +59,9 @@ public final class ComboBoxListRenderer extends JLabel implements ListCellRen setBorder(new EmptyBorder(5, 5, 5, 0)); String text; - if (o instanceof Enum) + if (o instanceof Enum) { - text = Text.titleCase((Enum) o); + text = Text.titleCase((Enum) o); } else { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/skin/ObsidianSkin.java b/runelite-client/src/main/java/net/runelite/client/ui/skin/ObsidianSkin.java index 92620713fc..ecdf500957 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/skin/ObsidianSkin.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/skin/ObsidianSkin.java @@ -67,6 +67,10 @@ public class ObsidianSkin extends SubstanceSkin activeScheme, enabledScheme, enabledScheme); + // Selected and rollover + defaultSchemeBundle.registerHighlightColorScheme(schemes.get("RuneLite Highlight"), + ComponentState.SELECTED, ComponentState.ROLLOVER_SELECTED, ComponentState.ROLLOVER_UNSELECTED); + // borders final SubstanceColorScheme borderDisabledSelectedScheme = schemes .get("RuneLite Selected Disabled Border"); diff --git a/runelite-client/src/main/resources/net/runelite/client/ui/skin/RuneLite.colorschemes b/runelite-client/src/main/resources/net/runelite/client/ui/skin/RuneLite.colorschemes index 1d9ffee41b..271125ea94 100644 --- a/runelite-client/src/main/resources/net/runelite/client/ui/skin/RuneLite.colorschemes +++ b/runelite-client/src/main/resources/net/runelite/client/ui/skin/RuneLite.colorschemes @@ -89,14 +89,14 @@ RuneLite Mark Active { } RuneLite Highlight { - kind=Light - colorUltraLight=#C6C6C6 - colorExtraLight=#C6C6C6 - colorLight=#C6C6C6 - colorMid=#C6C6C6 - colorDark=#C6C6C6 - colorUltraDark=#C6C6C6 - colorForeground=#191919 + kind=Dark + colorUltraLight=#525252 + colorExtraLight=#525252 + colorLight=#525252 + colorMid=#525252 + colorDark=#525252 + colorUltraDark=#525252 + colorForeground=#FFFFFF } RuneLite Watermark { diff --git a/runelite-client/src/main/scripts/ChatBuilder.rs2asm b/runelite-client/src/main/scripts/ChatBuilder.rs2asm index 89e852e785..59c9b36675 100644 --- a/runelite-client/src/main/scripts/ChatBuilder.rs2asm +++ b/runelite-client/src/main/scripts/ChatBuilder.rs2asm @@ -440,11 +440,17 @@ LABEL391: jump LABEL1721 LABEL405: iload 10 ; message uid + sload 17 ; message channel + sload 16 ; message name + sload 18 ; message sload 21 ; message timestamp sconst "chatMessageBuilding" runelite_callback pop_int ; pop uid sstore 21 ; message timestamp + sstore 18 ; message + sstore 16 ; message name + sstore 17 ; message channel iload 11 switch 1: LABEL408 diff --git a/runelite-client/src/main/scripts/ChatSend.hash b/runelite-client/src/main/scripts/ChatSend.hash index 402d756ff5..9c54adf40e 100644 --- a/runelite-client/src/main/scripts/ChatSend.hash +++ b/runelite-client/src/main/scripts/ChatSend.hash @@ -1 +1 @@ -BF6EEA4353A596E6389BC0CCDB654CC28D11E809F92A59C0301557F6185690CD \ No newline at end of file +6FB26238E2041A40DE52A7E797AD54BF8633BE93FD3B0C244F1313B53CC0A922 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatSend.rs2asm b/runelite-client/src/main/scripts/ChatSend.rs2asm index 5e79e5baa8..7ce4fa5d9a 100644 --- a/runelite-client/src/main/scripts/ChatSend.rs2asm +++ b/runelite-client/src/main/scripts/ChatSend.rs2asm @@ -33,71 +33,101 @@ LABEL23: iload 3 iconst -1 if_icmpne LABEL27 - jump LABEL33 + jump LABEL60 LABEL27: iload 3 iconst 4 if_icmple LABEL31 - jump LABEL33 + jump LABEL60 LABEL31: + iload 3 + get_varc_int 945 + if_icmpne LABEL35 + jump LABEL60 +LABEL35: iload 3 set_varc_int 945 -LABEL33: + iload 3 + iconst 0 + if_icmpne LABEL41 + jump LABEL51 +LABEL41: + sconst "Your chatbox mode is now set to " + iconst 105 + iconst 115 + iconst 4070 + iload 3 + enum + sconst " chat, to reset your mode type /@p" + join_string 3 + mes + jump LABEL60 +LABEL51: + sconst "Your chatbox mode has been reset to " + iconst 105 + iconst 115 + iconst 4070 + iload 3 + enum + sconst " chat." + join_string 3 + mes +LABEL60: iload 2 iconst 1 - if_icmpeq LABEL37 - jump LABEL75 -LABEL37: + if_icmpeq LABEL64 + jump LABEL102 +LABEL64: get_varc_int 945 switch - 1: LABEL40 - 2: LABEL61 - 3: LABEL66 - 4: LABEL71 - jump LABEL75 -LABEL40: + 1: LABEL67 + 2: LABEL88 + 3: LABEL93 + 4: LABEL98 + jump LABEL102 +LABEL67: iconst 2 istore 0 sload 0 string_length iconst 0 - if_icmpgt LABEL47 - jump LABEL60 -LABEL47: + if_icmpgt LABEL74 + jump LABEL87 +LABEL74: sload 0 iconst 0 iconst 1 substring sconst "/" compare - iconst 1 - if_icmpeq LABEL56 - jump LABEL60 -LABEL56: + iconst 0 ; + if_icmpne LABEL83 + jump LABEL87 +LABEL83: sconst "/" sload 0 append sstore 0 -LABEL60: - jump LABEL75 -LABEL61: +LABEL87: + jump LABEL102 +LABEL88: iconst 3 iconst 0 istore 1 istore 0 - jump LABEL75 -LABEL66: + jump LABEL102 +LABEL93: iconst 4 iconst 0 istore 1 istore 0 - jump LABEL75 -LABEL71: + jump LABEL102 +LABEL98: iconst 3 iconst 1 istore 1 istore 0 -LABEL75: +LABEL102: sload 0 ; load input iload 0 ; load chat type iload 1 ; load clan target @@ -114,46 +144,74 @@ CONTINUE: sstore 1 iload 0 iconst 2 - if_icmpeq LABEL87 + if_icmpeq LABEL114 iload 0 iconst 3 - if_icmpeq LABEL87 + if_icmpeq LABEL114 iload 0 iconst 4 - if_icmpeq LABEL87 - jump LABEL109 -LABEL87: + if_icmpeq LABEL114 + jump LABEL154 +LABEL114: sload 0 invoke 5501 iconst 1 - if_icmpeq LABEL92 - jump LABEL96 -LABEL92: + if_icmpeq LABEL119 + jump LABEL123 +LABEL119: sload 0 invoke 632 sstore 0 sstore 1 -LABEL96: +LABEL123: iload 1 iconst 1 - if_icmpeq LABEL100 - jump LABEL104 -LABEL100: + if_icmpeq LABEL127 + jump LABEL143 +LABEL127: + sload 0 + iconst 0 + iconst 1 + substring + 4122 + sload 0 + iconst 1 + sload 0 + string_length + substring + append + sstore 0 sconst "|" sload 0 append sstore 0 -LABEL104: +LABEL143: + sload 0 + string_length + iconst 0 + if_icmple LABEL148 + jump LABEL149 +LABEL148: + return +LABEL149: sload 0 iload 0 iload 1 chat_sendclan - jump LABEL112 -LABEL109: + jump LABEL163 +LABEL154: + sload 0 + string_length + iconst 0 + if_icmple LABEL159 + jump LABEL160 +LABEL159: + return +LABEL160: sload 0 iload 0 chat_sendpublic -LABEL112: +LABEL163: clientclock set_varc_int 61 return diff --git a/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm b/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm index 53a08ad34f..80cdf54e09 100644 --- a/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm +++ b/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm @@ -413,11 +413,17 @@ CHAT_FILTER: jump LABEL562 LABEL368: iload 12 ; message uid - sload 2 ; message timestamp + sconst "" ; message channel + sload 1 ; message name + sload 0 ; message + sload 2 ; message timestamp sconst "chatMessageBuilding" runelite_callback - pop_int + pop_int ; uid sstore 2 ; message timestamp + sstore 0 ; message + sstore 1 ; message name + pop_string ; message channel iload 18 switch 3: LABEL371 diff --git a/runelite-client/src/main/scripts/CommandScript.hash b/runelite-client/src/main/scripts/CommandScript.hash index 47fe097eda..3e4753a0fe 100644 --- a/runelite-client/src/main/scripts/CommandScript.hash +++ b/runelite-client/src/main/scripts/CommandScript.hash @@ -1 +1 @@ -725BA34A3D0891309D6CC3A6E7AD9AEAB331BC08E1E312606E846C607F820519 \ No newline at end of file +690BCC4CE42FE670B31A14E214FECD3B27CEB013D6413713DB4A587D1CC38974 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/CommandScript.rs2asm b/runelite-client/src/main/scripts/CommandScript.rs2asm index e29269053e..15da445c03 100644 --- a/runelite-client/src/main/scripts/CommandScript.rs2asm +++ b/runelite-client/src/main/scripts/CommandScript.rs2asm @@ -90,13 +90,13 @@ LABEL60: iload 0 iconst 84 if_icmpeq LABEL76 - jump LABEL740 + jump LABEL815 LABEL76: invoke 1984 iload 2 iconst 0 if_icmpgt LABEL81 - jump LABEL739 + jump LABEL814 LABEL81: iload 3 iconst 1 @@ -192,7 +192,7 @@ LABEL152: LABEL159: iconst 1 istore 4 - jump LABEL175 + jump LABEL188 LABEL162: get_varc_int 41 iconst 5 @@ -201,29 +201,45 @@ LABEL162: LABEL166: iconst 41 istore 5 - jump LABEL175 + jump LABEL188 LABEL169: get_varc_int 41 iconst 4 if_icmpeq LABEL173 - jump LABEL175 + jump LABEL176 LABEL173: iconst 9 istore 5 -LABEL175: + jump LABEL188 +LABEL176: + get_varc_int 41 + iconst 6 + if_icmpeq LABEL180 + jump LABEL188 +LABEL180: + invoke 5262 + iconst 1 + if_icmpeq LABEL184 + jump LABEL188 +LABEL184: + iconst 41 + iconst 1 + istore 8 + istore 5 +LABEL188: get_varc_string 335 sconst "////" iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL182 - jump LABEL210 -LABEL182: + if_icmpeq LABEL195 + jump LABEL223 +LABEL195: invoke 5262 iconst 1 - if_icmpeq LABEL186 - jump LABEL210 -LABEL186: + if_icmpeq LABEL199 + jump LABEL223 +LABEL199: iconst 4 iconst 41 iconst 1 @@ -235,46 +251,32 @@ LABEL186: iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL199 - jump LABEL203 -LABEL199: + if_icmpeq LABEL212 + jump LABEL216 +LABEL212: iconst 4 istore 9 iconst 5 istore 6 -LABEL203: +LABEL216: get_varbit 13120 iconst 1 - if_icmpeq LABEL207 - jump LABEL209 -LABEL207: + if_icmpeq LABEL220 + jump LABEL222 +LABEL220: iconst 4 istore 9 -LABEL209: - jump LABEL458 -LABEL210: +LABEL222: + jump LABEL558 +LABEL223: get_varc_string 335 sconst "///" iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL231 - get_varc_string 335 - lowercase - sconst "/g " - iconst 0 - string_indexof_string - iconst 0 - if_icmpeq LABEL231 - get_varc_string 335 - lowercase - sconst "/@g " - iconst 0 - string_indexof_string - iconst 0 - if_icmpeq LABEL231 - jump LABEL260 -LABEL231: + if_icmpeq LABEL230 + jump LABEL252 +LABEL230: iconst 3 iconst 44 istore 5 @@ -284,39 +286,32 @@ LABEL231: iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL249 - get_varc_string 335 - lowercase - sconst "/@g " - iconst 0 - string_indexof_string - iconst 0 - if_icmpeq LABEL249 - jump LABEL253 -LABEL249: + if_icmpeq LABEL241 + jump LABEL245 +LABEL241: iconst 3 istore 9 iconst 4 istore 6 -LABEL253: +LABEL245: get_varbit 13120 iconst 1 - if_icmpeq LABEL257 - jump LABEL259 -LABEL257: + if_icmpeq LABEL249 + jump LABEL251 +LABEL249: iconst 3 istore 9 -LABEL259: - jump LABEL458 -LABEL260: +LABEL251: + jump LABEL558 +LABEL252: get_varc_string 335 sconst "//" iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL267 - jump LABEL289 -LABEL267: + if_icmpeq LABEL259 + jump LABEL281 +LABEL259: iconst 2 iconst 41 istore 5 @@ -326,40 +321,84 @@ LABEL267: iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL278 - jump LABEL282 -LABEL278: + if_icmpeq LABEL270 + jump LABEL274 +LABEL270: iconst 2 istore 9 iconst 3 istore 6 -LABEL282: +LABEL274: get_varbit 13120 iconst 1 - if_icmpeq LABEL286 - jump LABEL288 -LABEL286: + if_icmpeq LABEL278 + jump LABEL280 +LABEL278: iconst 2 istore 9 -LABEL288: - jump LABEL458 -LABEL289: +LABEL280: + jump LABEL558 +LABEL281: + get_varc_string 335 + lowercase + sconst "/gc " + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL296 + get_varc_string 335 + lowercase + sconst "/@gc " + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL296 + jump LABEL319 +LABEL296: + iconst 4 + iconst 44 + istore 5 + istore 6 + get_varc_string 335 + lowercase + sconst "/@gc " + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL308 + jump LABEL312 +LABEL308: + iconst 3 + istore 9 + iconst 5 + istore 6 +LABEL312: + get_varbit 13120 + iconst 1 + if_icmpeq LABEL316 + jump LABEL318 +LABEL316: + iconst 3 + istore 9 +LABEL318: + jump LABEL558 +LABEL319: get_varc_string 335 lowercase sconst "/c " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL304 + if_icmpeq LABEL334 get_varc_string 335 lowercase sconst "/@c " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL304 - jump LABEL326 -LABEL304: + if_icmpeq LABEL334 + jump LABEL356 +LABEL334: iconst 3 iconst 41 istore 5 @@ -369,45 +408,45 @@ LABEL304: iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL315 - jump LABEL319 -LABEL315: + if_icmpeq LABEL345 + jump LABEL349 +LABEL345: iconst 2 istore 9 iconst 4 istore 6 -LABEL319: +LABEL349: get_varbit 13120 iconst 1 - if_icmpeq LABEL323 - jump LABEL325 -LABEL323: + if_icmpeq LABEL353 + jump LABEL355 +LABEL353: iconst 2 istore 9 -LABEL325: - jump LABEL458 -LABEL326: +LABEL355: + jump LABEL558 +LABEL356: invoke 5262 iconst 1 - if_icmpeq LABEL330 - jump LABEL369 -LABEL330: + if_icmpeq LABEL360 + jump LABEL399 +LABEL360: get_varc_string 335 lowercase - sconst "/i " + sconst "/g " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL345 + if_icmpeq LABEL375 get_varc_string 335 lowercase - sconst "/@i " + sconst "/@g " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL345 - jump LABEL369 -LABEL345: + if_icmpeq LABEL375 + jump LABEL399 +LABEL375: iconst 3 iconst 41 iconst 1 @@ -415,43 +454,43 @@ LABEL345: istore 5 istore 6 get_varc_string 335 - sconst "/@i " + sconst "/@g " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL358 - jump LABEL362 -LABEL358: + if_icmpeq LABEL388 + jump LABEL392 +LABEL388: iconst 4 istore 9 iconst 4 istore 6 -LABEL362: +LABEL392: get_varbit 13120 iconst 1 - if_icmpeq LABEL366 - jump LABEL368 -LABEL366: + if_icmpeq LABEL396 + jump LABEL398 +LABEL396: iconst 4 istore 9 -LABEL368: - jump LABEL458 -LABEL369: +LABEL398: + jump LABEL558 +LABEL399: get_varc_string 335 lowercase sconst "/f " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL383 + if_icmpeq LABEL413 get_varc_string 335 sconst "/@f " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL383 - jump LABEL405 -LABEL383: + if_icmpeq LABEL413 + jump LABEL435 +LABEL413: iconst 3 iconst 9 istore 5 @@ -461,39 +500,39 @@ LABEL383: iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL394 - jump LABEL398 -LABEL394: + if_icmpeq LABEL424 + jump LABEL428 +LABEL424: iconst 1 istore 9 iconst 4 istore 6 -LABEL398: +LABEL428: get_varbit 13120 iconst 1 - if_icmpeq LABEL402 - jump LABEL404 -LABEL402: + if_icmpeq LABEL432 + jump LABEL434 +LABEL432: iconst 1 istore 9 -LABEL404: - jump LABEL458 -LABEL405: +LABEL434: + jump LABEL558 +LABEL435: get_varc_string 335 lowercase sconst "/p " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL419 + if_icmpeq LABEL449 get_varc_string 335 sconst "/@p " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL419 - jump LABEL441 -LABEL419: + if_icmpeq LABEL449 + jump LABEL471 +LABEL449: iconst 3 iconst 2 istore 5 @@ -503,71 +542,144 @@ LABEL419: iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL430 - jump LABEL434 -LABEL430: + if_icmpeq LABEL460 + jump LABEL464 +LABEL460: iconst 0 istore 9 iconst 4 istore 6 -LABEL434: +LABEL464: get_varbit 13120 iconst 1 - if_icmpeq LABEL438 - jump LABEL440 -LABEL438: + if_icmpeq LABEL468 + jump LABEL470 +LABEL468: iconst 0 istore 9 -LABEL440: - jump LABEL458 -LABEL441: +LABEL470: + jump LABEL558 +LABEL471: get_varc_string 335 sconst "/" iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL448 - jump LABEL458 -LABEL448: + if_icmpeq LABEL478 + jump LABEL558 +LABEL478: + get_varc_string 335 + sconst "/@p" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL485 + jump LABEL492 +LABEL485: + iconst 0 + iconst 2 + iconst 3 + istore 6 + istore 5 + istore 9 + jump LABEL558 +LABEL492: + get_varc_string 335 + sconst "/@f" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL499 + jump LABEL506 +LABEL499: + iconst 1 + iconst 9 + iconst 3 + istore 6 + istore 5 + istore 9 + jump LABEL558 +LABEL506: + get_varc_string 335 + sconst "/@c" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL513 + jump LABEL520 +LABEL513: + iconst 2 + iconst 41 + iconst 3 + istore 6 + istore 5 + istore 9 + jump LABEL558 +LABEL520: + get_varc_string 335 + sconst "/@gc" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL527 + jump LABEL534 +LABEL527: + iconst 3 + iconst 44 + iconst 4 + istore 6 + istore 5 + istore 9 + jump LABEL558 +LABEL534: + get_varc_string 335 + sconst "/@g" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL541 + jump LABEL548 +LABEL541: + iconst 4 + iconst 41 + iconst 3 + istore 6 + istore 5 + istore 9 + jump LABEL558 +LABEL548: iconst 1 iconst 9 istore 5 istore 6 get_varbit 13120 iconst 1 - if_icmpeq LABEL456 - jump LABEL458 -LABEL456: + if_icmpeq LABEL556 + jump LABEL558 +LABEL556: iconst 1 istore 9 -LABEL458: +LABEL558: iload 5 iconst 44 - if_icmpeq LABEL462 - jump LABEL495 -LABEL462: + if_icmpeq LABEL562 + jump LABEL590 +LABEL562: activeclansettings_find_listened iconst 1 - if_icmpeq LABEL466 - jump LABEL492 -LABEL466: + if_icmpeq LABEL566 + jump LABEL587 +LABEL566: activeclanchannel_find_listened iconst 1 - if_icmpeq LABEL470 - jump LABEL492 -LABEL470: - iload 2 - iload 6 - if_icmple LABEL474 - jump LABEL475 -LABEL474: - return -LABEL475: + if_icmpeq LABEL570 + jump LABEL587 +LABEL570: activeclansettings_getallowunaffined iconst 1 - if_icmpeq LABEL479 - jump LABEL489 -LABEL479: + if_icmpeq LABEL574 + jump LABEL584 +LABEL574: get_varc_string 335 iload 6 iload 2 @@ -577,61 +689,54 @@ LABEL479: iconst 0 iload 9 invoke 5517 - jump LABEL491 -LABEL489: + jump LABEL586 +LABEL584: sconst "Guests are not invited to speak in this clan's channel." mes -LABEL491: - jump LABEL494 -LABEL492: +LABEL586: + jump LABEL589 +LABEL587: sconst "You are not chatting as a guest in a clan channel at the moment." mes -LABEL494: - jump LABEL735 -LABEL495: +LABEL589: + jump LABEL810 +LABEL590: iload 5 iconst 41 - if_icmpeq LABEL499 - jump LABEL580 -LABEL499: + if_icmpeq LABEL594 + jump LABEL665 +LABEL594: iload 8 iconst 0 - if_icmpeq LABEL503 - jump LABEL546 -LABEL503: + if_icmpeq LABEL598 + jump LABEL636 +LABEL598: iconst 0 activeclanchannel_find_affined iconst 1 - if_icmpeq LABEL508 - jump LABEL546 -LABEL508: + if_icmpeq LABEL603 + jump LABEL636 +LABEL603: get_varbit 931 iconst 0 - if_icmpeq LABEL512 - jump LABEL543 -LABEL512: - iload 2 - iload 6 - if_icmple LABEL516 - jump LABEL517 -LABEL516: - return -LABEL517: + if_icmpeq LABEL607 + jump LABEL633 +LABEL607: chat_playername removetags activeclanchannel_getuserslot istore 7 iload 7 iconst -1 - if_icmpne LABEL525 - jump LABEL540 -LABEL525: + if_icmpne LABEL615 + jump LABEL630 +LABEL615: iload 7 activeclanchannel_getuserrank activeclanchannel_getranktalk - if_icmpge LABEL530 - jump LABEL540 -LABEL530: + if_icmpge LABEL620 + jump LABEL630 +LABEL620: get_varc_string 335 iload 6 iload 2 @@ -641,36 +746,29 @@ LABEL530: iconst 0 iload 9 invoke 5517 - jump LABEL542 -LABEL540: + jump LABEL632 +LABEL630: sconst "You do not have the required rank to talk in the clan's channel." mes -LABEL542: - jump LABEL545 -LABEL543: +LABEL632: + jump LABEL635 +LABEL633: sconst "You have muted your clan's channel. Unmute it if you wish to talk in it." mes -LABEL545: - jump LABEL579 -LABEL546: +LABEL635: + jump LABEL664 +LABEL636: iload 8 iconst 1 - if_icmpeq LABEL550 - jump LABEL570 -LABEL550: + if_icmpeq LABEL640 + jump LABEL655 +LABEL640: iconst 1 activeclanchannel_find_affined iconst 1 - if_icmpeq LABEL555 - jump LABEL570 -LABEL555: - iload 2 - iload 6 - if_icmple LABEL559 - jump LABEL560 -LABEL559: - return -LABEL560: + if_icmpeq LABEL645 + jump LABEL655 +LABEL645: get_varc_string 335 iload 6 iload 2 @@ -680,63 +778,56 @@ LABEL560: iconst 0 iload 9 invoke 5517 - jump LABEL579 -LABEL570: + jump LABEL664 +LABEL655: iload 8 iconst 1 - if_icmpeq LABEL574 - jump LABEL577 -LABEL574: + if_icmpeq LABEL659 + jump LABEL662 +LABEL659: sconst "You are not chatting in the channel of your Iron Group at the moment." mes - jump LABEL579 -LABEL577: + jump LABEL664 +LABEL662: sconst "You are not chatting in the channel of your own clan at the moment." mes -LABEL579: - jump LABEL735 -LABEL580: +LABEL664: + jump LABEL810 +LABEL665: iload 5 iconst 9 - if_icmpeq LABEL584 - jump LABEL633 -LABEL584: + if_icmpeq LABEL669 + jump LABEL713 +LABEL669: clan_getchatcount iconst 0 - if_icmpgt LABEL588 - jump LABEL626 -LABEL588: - iload 2 - iload 6 - if_icmple LABEL592 - jump LABEL593 -LABEL592: - return -LABEL593: + if_icmpgt LABEL673 + jump LABEL706 +LABEL673: get_varbit 4394 iconst 1 - if_icmpeq LABEL597 - jump LABEL599 -LABEL597: + if_icmpeq LABEL677 + jump LABEL679 +LABEL677: clan_leavechat - jump LABEL625 -LABEL599: + jump LABEL705 +LABEL679: iload 6 iconst 1 - if_icmplt LABEL603 - jump LABEL608 -LABEL603: + if_icmplt LABEL683 + jump LABEL688 +LABEL683: sconst "/" get_varc_string 335 append set_varc_string 335 - jump LABEL619 -LABEL608: + jump LABEL699 +LABEL688: iload 6 iconst 3 - if_icmpge LABEL612 - jump LABEL619 -LABEL612: + if_icmpge LABEL692 + jump LABEL699 +LABEL692: sconst "/" get_varc_string 335 iload 6 @@ -744,37 +835,30 @@ LABEL612: substring append set_varc_string 335 -LABEL619: +LABEL699: get_varc_string 335 iconst 2 iconst -1 iconst 0 iload 9 invoke 5517 -LABEL625: - jump LABEL632 -LABEL626: +LABEL705: + jump LABEL712 +LABEL706: get_varc_string 335 iconst 0 iconst -1 iconst 0 iconst -1 invoke 5517 -LABEL632: - jump LABEL735 -LABEL633: +LABEL712: + jump LABEL810 +LABEL713: iload 5 iconst 2 - if_icmpeq LABEL637 - jump LABEL652 -LABEL637: - iload 2 - iload 6 - if_icmple LABEL641 - jump LABEL642 -LABEL641: - return -LABEL642: + if_icmpeq LABEL717 + jump LABEL727 +LABEL717: get_varc_string 335 iload 6 iload 2 @@ -784,79 +868,79 @@ LABEL642: iconst 0 iload 9 invoke 5517 - jump LABEL735 -LABEL652: + jump LABEL810 +LABEL727: iload 4 iconst 1 - if_icmpeq LABEL656 - jump LABEL729 -LABEL656: + if_icmpeq LABEL731 + jump LABEL804 +LABEL731: iload 2 iconst 2 - if_icmpgt LABEL660 - jump LABEL722 -LABEL660: + if_icmpgt LABEL735 + jump LABEL797 +LABEL735: get_varc_string 335 sconst "::toggleroof" iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL667 - jump LABEL681 -LABEL667: + if_icmpeq LABEL742 + jump LABEL756 +LABEL742: getremoveroofs iconst 1 - if_icmpeq LABEL671 - jump LABEL676 -LABEL671: + if_icmpeq LABEL746 + jump LABEL751 +LABEL746: iconst 0 setremoveroofs sconst "Roofs will only be removed selectively." mes - jump LABEL680 -LABEL676: + jump LABEL755 +LABEL751: iconst 1 setremoveroofs sconst "Roofs are now all hidden." mes -LABEL680: - jump LABEL721 -LABEL681: +LABEL755: + jump LABEL796 +LABEL756: get_varc_string 335 sconst "::wiki " iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL693 + if_icmpeq LABEL768 get_varc_string 335 sconst "::wiki" compare iconst 0 - if_icmpeq LABEL693 + if_icmpeq LABEL768 sconst "runeliteCommand" ; load callback name runelite_callback ; invoke callback - jump LABEL696 -LABEL693: + jump LABEL771 +LABEL768: get_varc_string 335 invoke 3299 - jump LABEL721 -LABEL696: + jump LABEL796 +LABEL771: get_varc_string 335 sconst "::bank" iconst 0 string_indexof_string iconst 0 - if_icmpeq LABEL703 - jump LABEL710 -LABEL703: + if_icmpeq LABEL778 + jump LABEL785 +LABEL778: sconst "Hey, everyone, I just tried to do something very silly!" iconst 0 iconst -1 iconst 0 iconst -1 invoke 5517 - jump LABEL721 -LABEL710: + jump LABEL796 +LABEL785: get_varc_string 335 invoke 224 set_varc_string 335 @@ -868,97 +952,97 @@ LABEL710: iload 2 substring docheat -LABEL721: - jump LABEL728 -LABEL722: +LABEL796: + jump LABEL803 +LABEL797: get_varc_string 335 iconst 0 iconst -1 iconst 0 iconst -1 invoke 5517 -LABEL728: - jump LABEL735 -LABEL729: +LABEL803: + jump LABEL810 +LABEL804: get_varc_string 335 iconst 0 iconst -1 iconst 1 iload 9 invoke 5517 -LABEL735: +LABEL810: get_varc_string 335 invoke 77 sconst "" set_varc_string 335 -LABEL739: - jump LABEL815 -LABEL740: +LABEL814: + jump LABEL890 +LABEL815: iload 0 iconst 104 - if_icmpeq LABEL744 - jump LABEL750 -LABEL744: + if_icmpeq LABEL819 + jump LABEL825 +LABEL819: iload 3 iconst 1 - if_icmpeq LABEL748 - jump LABEL749 -LABEL748: + if_icmpeq LABEL823 + jump LABEL824 +LABEL823: invoke 75 -LABEL749: - jump LABEL815 -LABEL750: +LABEL824: + jump LABEL890 +LABEL825: iload 0 iconst 105 - if_icmpeq LABEL754 - jump LABEL760 -LABEL754: + if_icmpeq LABEL829 + jump LABEL835 +LABEL829: iload 3 iconst 1 - if_icmpeq LABEL758 - jump LABEL759 -LABEL758: + if_icmpeq LABEL833 + jump LABEL834 +LABEL833: invoke 76 -LABEL759: - jump LABEL815 -LABEL760: +LABEL834: + jump LABEL890 +LABEL835: iload 0 iconst 80 - if_icmpeq LABEL764 - jump LABEL809 -LABEL764: + if_icmpeq LABEL839 + jump LABEL884 +LABEL839: iconst 40697936 iconst 1 cc_find iconst 1 - if_icmpeq LABEL770 - jump LABEL771 -LABEL770: + if_icmpeq LABEL845 + jump LABEL846 +LABEL845: return -LABEL771: +LABEL846: get_varc_string 356 string_length iconst 0 - if_icmpgt LABEL776 - jump LABEL796 -LABEL776: + if_icmpgt LABEL851 + jump LABEL871 +LABEL851: get_varc_string 356 friend_test iconst 1 - if_icmpeq LABEL781 - jump LABEL784 -LABEL781: + if_icmpeq LABEL856 + jump LABEL859 +LABEL856: get_varc_string 356 invoke 107 return -LABEL784: +LABEL859: get_varc_int 60 clientclock - if_icmpgt LABEL788 - jump LABEL789 -LABEL788: + if_icmpgt LABEL863 + jump LABEL864 +LABEL863: return -LABEL789: +LABEL864: clientclock iconst 50 add @@ -966,14 +1050,14 @@ LABEL789: sconst "That player was not found on your Friends list." mes return -LABEL796: +LABEL871: get_varc_int 60 clientclock - if_icmpgt LABEL800 - jump LABEL801 -LABEL800: + if_icmpgt LABEL875 + jump LABEL876 +LABEL875: return -LABEL801: +LABEL876: clientclock iconst 50 add @@ -981,8 +1065,8 @@ LABEL801: sconst "You haven't received any messages to which you can reply." mes return - jump LABEL815 -LABEL809: + jump LABEL890 +LABEL884: get_varc_string 335 iconst 0 iload 0 @@ -994,9 +1078,9 @@ LABEL809: runelite_callback ; if_icmpeq SKIPSETVARC ; skip setting varc with input set_varc_string 335 - jump LABEL815 ; jump over SKIPSETVARC + jump LABEL890 ; jump over SKIPSETVARC SKIPSETVARC: pop_string ; pop message -LABEL815: +LABEL890: invoke 223 return diff --git a/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java b/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java index 97b2caaef0..f389702dce 100644 --- a/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java @@ -31,14 +31,16 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import java.awt.Color; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.IterableHashTable; import net.runelite.api.MessageNode; import net.runelite.api.Player; -import net.runelite.api.events.ChatMessage; import net.runelite.client.config.ChatColorConfig; import net.runelite.client.events.ConfigChanged; +import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import static org.mockito.ArgumentMatchers.anyLong; import org.mockito.Mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -59,12 +61,39 @@ public class ChatMessageManagerTest @Inject private ChatMessageManager chatMessageManager; + private String[] sstack; + private int[] istack; + @Before public void before() { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); } + private void setupVm(ChatMessageType type, String name, String message) + { + MessageNode messageNode = mock(MessageNode.class); + when(messageNode.getType()).thenReturn(type); + + IterableHashTable tbl = mock(IterableHashTable.class); + when(tbl.get(anyLong())).thenReturn(messageNode); + when(client.getMessages()).thenReturn(tbl); + + sstack = new String[]{ + "", + name, + message, + "" + }; + istack = new int[]{ + 1 + }; + when(client.getStringStack()).thenReturn(sstack); + when(client.getStringStackSize()).thenReturn(sstack.length); + when(client.getIntStack()).thenReturn(istack); + when(client.getIntStackSize()).thenReturn(istack.length); + } + @Test public void testMessageRecoloring() { @@ -75,16 +104,10 @@ public class ChatMessageManagerTest configChanged.setGroup("textrecolor"); chatMessageManager.onConfigChanged(configChanged); - ChatMessage chatMessage = new ChatMessage(); - chatMessage.setType(ChatMessageType.GAMEMESSAGE); + setupVm(ChatMessageType.GAMEMESSAGE, "", "Your dodgy necklace protects you. It has 1 charge left."); + chatMessageManager.colorChatMessage(); - MessageNode messageNode = mock(MessageNode.class); - chatMessage.setMessageNode(messageNode); - - when(messageNode.getValue()).thenReturn("Your dodgy necklace protects you. It has 1 charge left."); - chatMessageManager.onChatMessage(chatMessage); - - verify(messageNode).setValue("Your dodgy necklace protects you. It has 1 charge left."); + assertEquals("Your dodgy necklace protects you. It has 1 charge left.", sstack[2]); } @Test @@ -95,14 +118,7 @@ public class ChatMessageManagerTest when(chatColorConfig.opaquePublicFriendUsernames()).thenReturn(Color.decode("#b20000")); - // Setup message - ChatMessage chatMessage = new ChatMessage(); - chatMessage.setType(ChatMessageType.PUBLICCHAT); - chatMessage.setName(friendName); - - MessageNode messageNode = mock(MessageNode.class); - chatMessage.setMessageNode(messageNode); - when(messageNode.getName()).thenReturn(friendName); + setupVm(ChatMessageType.PUBLICCHAT, friendName, ""); // Setup friend checking Player localPlayer = mock(Player.class); @@ -111,9 +127,9 @@ public class ChatMessageManagerTest when(client.getLocalPlayer()).thenReturn(localPlayer); when(localPlayer.getName()).thenReturn(localPlayerName); - chatMessageManager.onChatMessage(chatMessage); + chatMessageManager.colorChatMessage(); - verify(messageNode).setName("" + friendName + ""); + assertEquals("" + friendName + "", sstack[1]); } @Test @@ -125,14 +141,7 @@ public class ChatMessageManagerTest when(chatColorConfig.opaquePublicFriendUsernames()).thenReturn(Color.decode("#b20000")); - // Setup message - ChatMessage chatMessage = new ChatMessage(); - chatMessage.setType(ChatMessageType.PUBLICCHAT); - chatMessage.setName(friendName); - - MessageNode messageNode = mock(MessageNode.class); - chatMessage.setMessageNode(messageNode); - when(messageNode.getName()).thenReturn(friendName); + setupVm(ChatMessageType.PUBLICCHAT, friendName, ""); // Setup friend checking Player localPlayer = mock(Player.class); @@ -141,9 +150,9 @@ public class ChatMessageManagerTest when(client.getLocalPlayer()).thenReturn(localPlayer); when(localPlayer.getName()).thenReturn(localPlayerName); - chatMessageManager.onChatMessage(chatMessage); + chatMessageManager.colorChatMessage(); - verify(messageNode).setName("" + friendName + ""); + assertEquals("" + friendName + "", sstack[1]); } @Test