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] 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();
+ }
}