From 1fd617c35977e58a292ec65856cf80a4f47077d4 Mon Sep 17 00:00:00 2001
From: TheStonedTurtle <29030969+TheStonedTurtle@users.noreply.github.com>
Date: Mon, 18 Feb 2019 07:13:40 -0800
Subject: [PATCH 1/2] Add PM Target Cycling to Chat History plugin
---
.../main/java/net/runelite/api/ScriptID.java | 18 +++
.../java/net/runelite/api/VarClientStr.java | 1 +
.../java/net/runelite/api/vars/InputType.java | 1 +
.../chathistory/ChatHistoryPlugin.java | 143 ++++++++++++++----
4 files changed, 137 insertions(+), 26 deletions(-)
diff --git a/runelite-api/src/main/java/net/runelite/api/ScriptID.java b/runelite-api/src/main/java/net/runelite/api/ScriptID.java
index 778b271036..05c057a38d 100644
--- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java
+++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java
@@ -45,6 +45,24 @@ public final class ScriptID
*/
public static final int CHATBOX_INPUT = 96;
+ /**
+ * Opens the Private Message chat interface
+ *
+ * Jagex refers to this script as {@code meslayer_mode6}
+ *
+ * - String Player to send private message to
+ *
+ */
+ public static final int OPEN_PRIVATE_MESSAGE_INTERFACE = 107;
+
+ /**
+ * Rebuilds the text input widget inside the chat interface
+ *
+ * - String Message Prefix. Only used inside the GE search interfaces
+ *
+ */
+ public static final int CHAT_TEXT_INPUT_REBUILD = 222;
+
/**
* Layouts the bank widgets
*
diff --git a/runelite-api/src/main/java/net/runelite/api/VarClientStr.java b/runelite-api/src/main/java/net/runelite/api/VarClientStr.java
index b3bf1b09b6..72f4ee0303 100644
--- a/runelite-api/src/main/java/net/runelite/api/VarClientStr.java
+++ b/runelite-api/src/main/java/net/runelite/api/VarClientStr.java
@@ -36,6 +36,7 @@ public enum VarClientStr
{
CHATBOX_TYPED_TEXT(1),
INPUT_TEXT(22),
+ PRIVATE_MESSAGE_TARGET(23),
RECENT_CLAN_CHAT(129);
private final int index;
diff --git a/runelite-api/src/main/java/net/runelite/api/vars/InputType.java b/runelite-api/src/main/java/net/runelite/api/vars/InputType.java
index db1301b281..c94ccd79ef 100644
--- a/runelite-api/src/main/java/net/runelite/api/vars/InputType.java
+++ b/runelite-api/src/main/java/net/runelite/api/vars/InputType.java
@@ -38,6 +38,7 @@ public enum InputType
RUNELITE_CHATBOX_PANEL(-3),
RUNELITE(-2),
NONE(0),
+ PRIVATE_MESSAGE(6),
SEARCH(11);
private final int type;
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 6ac89bf605..77fcb70df0 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java
@@ -25,39 +25,53 @@
package net.runelite.client.plugins.chathistory;
import com.google.common.collect.EvictingQueue;
-import com.google.common.collect.Sets;
+import java.awt.event.KeyEvent;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
import java.util.Queue;
-import java.util.Set;
import javax.inject.Inject;
import net.runelite.api.ChatMessageType;
+import net.runelite.api.Client;
+import net.runelite.api.ScriptID;
+import net.runelite.api.VarClientInt;
+import net.runelite.api.VarClientStr;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.MenuOptionClicked;
+import net.runelite.api.vars.InputType;
+import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.eventbus.Subscribe;
+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.Text;
@PluginDescriptor(
name = "Chat History",
- description = "Retain your chat history when logging in/out or world hopping"
+ description = "Retain your chat history when logging in/out or world hopping",
+ tags = {"chat", "history", "retain", "cycle", "pm"}
)
-public class ChatHistoryPlugin extends Plugin
+public class ChatHistoryPlugin extends Plugin implements KeyListener
{
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape.";
private static final String CLEAR_HISTORY = "Clear history";
private static final String CLEAR_PRIVATE = "Private:";
- private static final Set ALLOWED_HISTORY = Sets.newHashSet(
- ChatMessageType.PUBLIC,
- ChatMessageType.PUBLIC_MOD,
- ChatMessageType.CLANCHAT,
- ChatMessageType.PRIVATE_MESSAGE_RECEIVED,
- ChatMessageType.PRIVATE_MESSAGE_SENT,
- ChatMessageType.PRIVATE_MESSAGE_RECEIVED_MOD,
- ChatMessageType.GAME
- );
+ private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
private Queue messageQueue;
+ private Deque friends;
+
+ @Inject
+ private Client client;
+
+ @Inject
+ private ClientThread clientThread;
+
+ @Inject
+ private KeyManager keyManager;
@Inject
private ChatMessageManager chatMessageManager;
@@ -66,6 +80,8 @@ public class ChatHistoryPlugin extends Plugin
protected void startUp()
{
messageQueue = EvictingQueue.create(100);
+ friends = new ArrayDeque<>(5);
+ keyManager.registerKeyListener(this);
}
@Override
@@ -73,6 +89,9 @@ public class ChatHistoryPlugin extends Plugin
{
messageQueue.clear();
messageQueue = null;
+ friends.clear();
+ friends = null;
+ keyManager.unregisterKeyListener(this);
}
@Subscribe
@@ -92,21 +111,33 @@ public class ChatHistoryPlugin extends Plugin
return;
}
- if (ALLOWED_HISTORY.contains(chatMessage.getType()))
+ switch (chatMessage.getType())
{
- final QueuedMessage queuedMessage = QueuedMessage.builder()
- .type(chatMessage.getType())
- .name(chatMessage.getName())
- .sender(chatMessage.getSender())
- .value(nbsp(chatMessage.getMessage()))
- .runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage()))
- .timestamp(chatMessage.getTimestamp())
- .build();
+ case PRIVATE_MESSAGE_SENT:
+ case PRIVATE_MESSAGE_RECEIVED:
+ case PRIVATE_MESSAGE_RECEIVED_MOD:
+ final String name = Text.removeTags(chatMessage.getName());
+ // Remove to ensure uniqueness & its place in history
+ friends.remove(name);
+ friends.add(name);
+ // intentional fall-through
+ case PUBLIC:
+ case PUBLIC_MOD:
+ case CLANCHAT:
+ case GAME:
+ final QueuedMessage queuedMessage = QueuedMessage.builder()
+ .type(chatMessage.getType())
+ .name(chatMessage.getName())
+ .sender(chatMessage.getSender())
+ .value(nbsp(chatMessage.getMessage()))
+ .runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage()))
+ .timestamp(chatMessage.getTimestamp())
+ .build();
- if (!messageQueue.contains(queuedMessage))
- {
- messageQueue.offer(queuedMessage);
- }
+ if (!messageQueue.contains(queuedMessage))
+ {
+ messageQueue.offer(queuedMessage);
+ }
}
}
@@ -143,4 +174,64 @@ public class ChatHistoryPlugin extends Plugin
return null;
}
+
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ if (e.getKeyCode() != CYCLE_HOTKEY)
+ {
+ return;
+ }
+
+ if (client.getVar(VarClientInt.INPUT_TYPE) != InputType.PRIVATE_MESSAGE.getType())
+ {
+ return;
+ }
+
+ clientThread.invoke(() ->
+ {
+ final String target = findPreviousFriend();
+ if (target == null)
+ {
+ return;
+ }
+
+ final String currentMessage = client.getVar(VarClientStr.INPUT_TEXT);
+
+ client.runScript(ScriptID.OPEN_PRIVATE_MESSAGE_INTERFACE, target);
+
+ client.setVar(VarClientStr.INPUT_TEXT, currentMessage);
+ client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, "");
+ });
+ }
+
+ @Override
+ public void keyTyped(KeyEvent e)
+ {
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e)
+ {
+ }
+
+ private String findPreviousFriend()
+ {
+ final String currentTarget = client.getVar(VarClientStr.PRIVATE_MESSAGE_TARGET);
+ if (currentTarget == null || friends.isEmpty())
+ {
+ return null;
+ }
+
+ for (Iterator it = friends.descendingIterator(); it.hasNext(); )
+ {
+ String friend = it.next();
+ if (friend.equals(currentTarget))
+ {
+ return it.hasNext() ? it.next() : friends.getLast();
+ }
+ }
+
+ return friends.getLast();
+ }
}
From c3bbd4934817d741c4d9ce8f59c6dc95dd42b7e5 Mon Sep 17 00:00:00 2001
From: TheStonedTurtle <29030969+TheStonedTurtle@users.noreply.github.com>
Date: Mon, 18 Feb 2019 07:14:21 -0800
Subject: [PATCH 2/2] Add Chat History config options
---
.../chathistory/ChatHistoryConfig.java | 55 +++++++++++++++++++
.../chathistory/ChatHistoryPlugin.java | 18 +++++-
2 files changed, 72 insertions(+), 1 deletion(-)
create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryConfig.java
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryConfig.java
new file mode 100644
index 0000000000..e30629c742
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryConfig.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018, TheStonedTurtle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.runelite.client.plugins.chathistory;
+
+import net.runelite.client.config.Config;
+import net.runelite.client.config.ConfigGroup;
+import net.runelite.client.config.ConfigItem;
+
+@ConfigGroup("chathistory")
+public interface ChatHistoryConfig extends Config
+{
+ @ConfigItem(
+ keyName = "retainChatHistory",
+ name = "Retain Chat History",
+ description = "Retains chat history when logging in/out or world hopping",
+ position = 0
+ )
+ default boolean retainChatHistory()
+ {
+ return true;
+ }
+
+ @ConfigItem(
+ keyName = "pmTargetCycling",
+ name = "PM Target Cycling",
+ description = "Pressing Tab while sending a PM will cycle the target username based on PM history",
+ position = 1
+ )
+ default boolean pmTargetCycling()
+ {
+ return true;
+ }
+}
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 77fcb70df0..43919214ea 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java
@@ -25,6 +25,7 @@
package net.runelite.client.plugins.chathistory;
import com.google.common.collect.EvictingQueue;
+import com.google.inject.Provides;
import java.awt.event.KeyEvent;
import java.util.ArrayDeque;
import java.util.Deque;
@@ -42,6 +43,7 @@ import net.runelite.api.vars.InputType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
+import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
@@ -70,11 +72,20 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
@Inject
private ClientThread clientThread;
+ @Inject
+ private ChatHistoryConfig config;
+
@Inject
private KeyManager keyManager;
@Inject
private ChatMessageManager chatMessageManager;
+
+ @Provides
+ ChatHistoryConfig getConfig(ConfigManager configManager)
+ {
+ return configManager.getConfig(ChatHistoryConfig.class);
+ }
@Override
protected void startUp()
@@ -101,6 +112,11 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
// of information that chat history was reset
if (chatMessage.getMessage().equals(WELCOME_MESSAGE))
{
+ if (!config.retainChatHistory())
+ {
+ return;
+ }
+
QueuedMessage queuedMessage;
while ((queuedMessage = messageQueue.poll()) != null)
@@ -178,7 +194,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
@Override
public void keyPressed(KeyEvent e)
{
- if (e.getKeyCode() != CYCLE_HOTKEY)
+ if (e.getKeyCode() != CYCLE_HOTKEY || !config.pmTargetCycling())
{
return;
}