Add PM Target Cycling to Chat History plugin

This commit is contained in:
TheStonedTurtle
2019-02-18 07:13:40 -08:00
parent c379e631d5
commit 1fd617c359
4 changed files with 137 additions and 26 deletions

View File

@@ -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}
* <ul>
* <li> String Player to send private message to</li>
* </ul>
*/
public static final int OPEN_PRIVATE_MESSAGE_INTERFACE = 107;
/**
* Rebuilds the text input widget inside the chat interface
* <ul>
* <li> String Message Prefix. Only used inside the GE search interfaces
* </ul>
*/
public static final int CHAT_TEXT_INPUT_REBUILD = 222;
/**
* Layouts the bank widgets
*

View File

@@ -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;

View File

@@ -38,6 +38,7 @@ public enum InputType
RUNELITE_CHATBOX_PANEL(-3),
RUNELITE(-2),
NONE(0),
PRIVATE_MESSAGE(6),
SEARCH(11);
private final int type;

View File

@@ -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 = "<col=ffff00>Private:";
private static final Set<ChatMessageType> 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<QueuedMessage> messageQueue;
private Deque<String> 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<String> it = friends.descendingIterator(); it.hasNext(); )
{
String friend = it.next();
if (friend.equals(currentTarget))
{
return it.hasNext() ? it.next() : friends.getLast();
}
}
return friends.getLast();
}
}