feat: player tracker
This commit is contained in:
@@ -6,6 +6,7 @@ import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.time.Instant;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -17,15 +18,18 @@ import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOpened;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.gameval.InterfaceID;
|
||||
import net.runelite.api.widgets.ComponentID;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetUtil;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
@@ -183,10 +187,17 @@ public class ChatHelper
|
||||
|
||||
if (removedAny)
|
||||
{
|
||||
client.runScript(83);
|
||||
refreshChat();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshChat()
|
||||
{
|
||||
// Invalidate the cached chat before rebuilding the chatbox and split PMs.
|
||||
client.refreshChat();
|
||||
client.runScript(ScriptID.SPLITPM_CHANGED);
|
||||
}
|
||||
|
||||
private boolean shouldClearType(ChatMessageType type)
|
||||
{
|
||||
if (type == null)
|
||||
@@ -204,13 +215,22 @@ public class ChatHelper
|
||||
case SPAM:
|
||||
case BROADCAST:
|
||||
case CONSOLE:
|
||||
case WELCOME:
|
||||
case PLAYERRELATED:
|
||||
case TENSECTIMEOUT:
|
||||
case SNAPSHOTFEEDBACK:
|
||||
case FRIENDNOTIFICATION:
|
||||
case IGNORENOTIFICATION:
|
||||
return config.chatClearGame();
|
||||
|
||||
case PUBLICCHAT:
|
||||
case MODCHAT:
|
||||
case AUTOTYPER:
|
||||
case MODAUTOTYPER:
|
||||
case TRADEREQ:
|
||||
case TRADE:
|
||||
case TRADE_SENT:
|
||||
case CHALREQ_TRADE:
|
||||
return config.chatClearPublic();
|
||||
|
||||
case PRIVATECHAT:
|
||||
@@ -222,6 +242,8 @@ public class ChatHelper
|
||||
case CLAN_GUEST_CHAT:
|
||||
case FRIENDSCHAT:
|
||||
case CLAN_MESSAGE:
|
||||
case CLAN_GUEST_MESSAGE:
|
||||
case FRIENDSCHATNOTIFICATION:
|
||||
case CLAN_GIM_CHAT:
|
||||
case CLAN_GIM_MESSAGE:
|
||||
return config.chatClearClan();
|
||||
@@ -349,7 +371,16 @@ public class ChatHelper
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Highlight own name
|
||||
// 3. Recolor clan chat text without changing public, private, or game messages.
|
||||
if (isClanChatType(ChatMessageType.of(messageTypeVal)))
|
||||
{
|
||||
Color clanColor = config.chatClanMessageColor();
|
||||
String hex = ColorUtil.colorToHexCode(clanColor != null ? clanColor : new Color(0x66FFFF));
|
||||
message = "<col=" + hex + ">" + message + "</col>";
|
||||
objectStack[objectStackSize - 1] = message;
|
||||
}
|
||||
|
||||
// 4. Highlight own name
|
||||
if (config.chatHighlightName() && isPlayerSpeechType(messageTypeVal))
|
||||
{
|
||||
String highlighted = highlightPlayerName(message);
|
||||
@@ -360,6 +391,13 @@ public class ChatHelper
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isClanChatType(ChatMessageType type)
|
||||
{
|
||||
return type == ChatMessageType.CLAN_CHAT
|
||||
|| type == ChatMessageType.CLAN_GUEST_CHAT
|
||||
|| type == ChatMessageType.CLAN_GIM_CHAT;
|
||||
}
|
||||
|
||||
private boolean isCollapsible(ChatMessageType type)
|
||||
{
|
||||
if (type == null)
|
||||
@@ -495,18 +533,17 @@ public class ChatHelper
|
||||
if (config.chatCopyToClipboard() && "Report".equals(event.getOption()))
|
||||
{
|
||||
Widget lineWidget = client.getWidget(interfaceId, childId);
|
||||
if (lineWidget != null && lineWidget.getParent() != null && lineWidget.getParent().getId() == ComponentID.CHATBOX_MESSAGE_LINES)
|
||||
if (lineWidget != null && lineWidget.getParent() != null && lineWidget.getParent().getId() == InterfaceID.Chatbox.SCROLLAREA)
|
||||
{
|
||||
int lineIndex = (childId - WidgetUtil.componentToId(ComponentID.CHATBOX_FRAME)) * 4 + 1;
|
||||
int lineIndex = (childId - WidgetUtil.componentToId(InterfaceID.Chatbox.LINE0)) * 4 + 1;
|
||||
if (lineIndex < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Widget textWidget = lineWidget.getParent().getChild(lineIndex);
|
||||
if (textWidget != null && textWidget.getText() != null)
|
||||
{
|
||||
String fullText = textWidget.getText();
|
||||
client.createMenuEntry(1)
|
||||
.setOption("Copy message")
|
||||
.setTarget(event.getTarget())
|
||||
.setType(MenuAction.RUNELITE)
|
||||
.onClick(e -> copyToClipboard(fullText));
|
||||
addCopyEntry(textWidget.getText(), event.getTarget());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -522,7 +559,73 @@ public class ChatHelper
|
||||
}
|
||||
}
|
||||
|
||||
private void copyToClipboard(String text)
|
||||
/** Game messages and transparent chat text do not necessarily have a Report action. */
|
||||
@Subscribe(priority = -1)
|
||||
public void onMenuOpened(MenuOpened event)
|
||||
{
|
||||
if (!config.chatHelper() || !config.chatCopyToClipboard())
|
||||
{
|
||||
return;
|
||||
}
|
||||
MenuEntry[] entries = client.getMenu().getMenuEntries();
|
||||
if (Arrays.stream(entries).anyMatch(e -> "Copy message".equals(e.getOption())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Do not intercept another interface or an overlay covering the chat.
|
||||
if (Arrays.stream(entries).anyMatch(e -> e.getWidget() != null
|
||||
&& WidgetUtil.componentToInterface(e.getWidget().getId()) != InterfaceID.CHATBOX))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Widget scroll = client.getWidget(InterfaceID.Chatbox.SCROLLAREA);
|
||||
Point mouse = client.getMouseCanvasPosition();
|
||||
if (scroll == null || scroll.isHidden() || mouse == null
|
||||
|| !scroll.getBounds().contains(mouse.getX(), mouse.getY()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Widget[] children = scroll.getDynamicChildren();
|
||||
if (children == null || children.length == 0)
|
||||
{
|
||||
children = scroll.getChildren();
|
||||
}
|
||||
if (children == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 1; i < children.length; i += 4)
|
||||
{
|
||||
Widget message = children[i];
|
||||
if (message != null && !message.isHidden() && message.getText() != null
|
||||
&& !Text.removeTags(message.getText()).trim().isEmpty()
|
||||
&& message.getBounds().contains(mouse.getX(), mouse.getY()))
|
||||
{
|
||||
// A world-only menu here is click-through from transparent chat.
|
||||
boolean hasChatAction = Arrays.stream(entries).anyMatch(e ->
|
||||
WidgetUtil.componentToInterface(e.getParam1()) == InterfaceID.CHATBOX);
|
||||
if (!hasChatAction)
|
||||
{
|
||||
client.getMenu().setMenuEntries(Arrays.stream(entries)
|
||||
.filter(e -> e.getType() == MenuAction.CANCEL).toArray(MenuEntry[]::new));
|
||||
}
|
||||
addCopyEntry(message.getText(), "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addCopyEntry(String text, String target)
|
||||
{
|
||||
// Capture the displayed text now: new messages can arrive while the menu is open.
|
||||
client.createMenuEntry(Math.min(1, client.getMenu().getMenuEntries().length))
|
||||
.setOption("Copy message")
|
||||
.setTarget(target)
|
||||
.setType(MenuAction.RUNELITE)
|
||||
.onClick(e -> copyToClipboard(text));
|
||||
}
|
||||
|
||||
void copyToClipboard(String text)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -572,7 +675,8 @@ public class ChatHelper
|
||||
}
|
||||
}
|
||||
|
||||
client.runScript(83);
|
||||
reset();
|
||||
refreshChat();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user