chat-history: add option to clear history for all chatbox tabs (#11543)

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
Co-authored-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
Anthony Alves
2020-05-22 15:48:12 -04:00
committed by GitHub
parent f7532b2e9c
commit d434e48d77
6 changed files with 214 additions and 15 deletions

View File

@@ -46,7 +46,11 @@ public interface ChatLineBuffer
int getLength();
/**
* Removes a message node
* Removes a message node.
*
* This method modifies the underlying MessageNode array. If removing multiple MessageNodes at a time,
* clone the original {@link #getLines()} array; as items in the array will get modified and be left in an
* inconsistent state.
*
* @param node the {@link MessageNode} to remove
*/

View File

@@ -466,6 +466,12 @@ public class WidgetID
{
static final int PARENT = 0;
static final int BUTTONS = 1;
static final int TAB_ALL = 4;
static final int TAB_GAME = 8;
static final int TAB_PUBLIC = 13;
static final int TAB_PRIVATE = 18;
static final int TAB_CLAN = 23;
static final int TAB_TRADE = 28;
static final int REPORT_TEXT = 36;
static final int FRAME = 37;
static final int TRANSPARENT_BACKGROUND = 38;

View File

@@ -365,6 +365,12 @@ public enum WidgetInfo
CHATBOX_TRANSPARENT_LINES(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TRANSPARENT_BACKGROUND_LINES),
CHATBOX_MESSAGE_LINES(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.MESSAGE_LINES),
CHATBOX_FIRST_MESSAGE(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.FIRST_MESSAGE),
CHATBOX_TAB_ALL(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TAB_ALL),
CHATBOX_TAB_GAME(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TAB_GAME),
CHATBOX_TAB_PUBLIC(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TAB_PUBLIC),
CHATBOX_TAB_PRIVATE(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TAB_PRIVATE),
CHATBOX_TAB_CLAN(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TAB_CLAN),
CHATBOX_TAB_TRADE(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TAB_TRADE),
BA_HEAL_WAVE_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.CURRENT_WAVE),
BA_HEAL_CALL_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.TO_CALL),

View File

@@ -63,4 +63,15 @@ public interface ChatHistoryConfig extends Config
{
return true;
}
@ConfigItem(
keyName = "clearHistory",
name = "Clear history option for all tabs",
description = "Add 'Clear history' option chatbox tab buttons",
position = 3
)
default boolean clearHistory()
{
return true;
}
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* Copyright (c) 2020, Anthony <https://github.com/while-loop>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@ 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;
@@ -35,14 +37,17 @@ import java.util.Deque;
import java.util.Iterator;
import java.util.Queue;
import javax.inject.Inject;
import net.runelite.api.ChatLineBuffer;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.MessageNode;
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.MenuEntryAdded;
import net.runelite.api.events.MenuOpened;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.vars.InputType;
@@ -59,6 +64,7 @@ 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;
@@ -72,7 +78,6 @@ 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 String COPY_TO_CLIPBOARD = "Copy to clipboard";
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
private static final int FRIENDS_MAX_SIZE = 5;
@@ -102,7 +107,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
{
return configManager.getConfig(ChatHistoryConfig.class);
}
@Override
protected void startUp()
{
@@ -247,20 +252,11 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
String menuOption = event.getMenuOption();
final String menuOption = event.getMenuOption();
if (menuOption.contains(CLEAR_HISTORY))
if (CLEAR_HISTORY.equals(menuOption))
{
if (menuOption.startsWith(CLEAR_PRIVATE))
{
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PRIVATECHAT ||
e.getType() == ChatMessageType.PRIVATECHATOUT || e.getType() == ChatMessageType.MODPRIVATECHAT);
friends.clear();
}
else
{
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PUBLICCHAT || e.getType() == ChatMessageType.MODCHAT);
}
clearChatboxHistory(ChatboxTab.of(event.getWidgetId()));
}
else if (COPY_TO_CLIPBOARD.equals(menuOption) && !Strings.isNullOrEmpty(currentMessage))
{
@@ -269,6 +265,88 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
}
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded entry)
{
final String option = Text.removeTags(entry.getOption());
final ChatboxTab tab = ChatboxTab.of(entry.getActionParam1());
if (!config.clearHistory() || tab == null || !option.equals(tab.getAfter()))
{
return;
}
final MenuEntry clearEntry = new MenuEntry();
clearEntry.setTarget("");
clearEntry.setType(MenuAction.RUNELITE.getId());
clearEntry.setParam0(entry.getActionParam0());
clearEntry.setParam1(entry.getActionParam1());
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();
if (tab != ChatboxTab.ALL)
{
messageBuilder.append(ColorUtil.wrapWithColorTag(tab.getName() + ": ", Color.YELLOW));
}
messageBuilder.append(CLEAR_HISTORY);
clearEntry.setOption(messageBuilder.toString());
final MenuEntry[] menuEntries = client.getMenuEntries();
client.setMenuEntries(ArrayUtils.insert(menuEntries.length - 1, menuEntries, clearEntry));
}
private void clearMessageQueue(ChatboxTab tab)
{
if (tab == ChatboxTab.ALL || tab == ChatboxTab.PRIVATE)
{
friends.clear();
}
messageQueue.removeIf(e -> tab.getMessageTypes().contains(e.getType()));
}
private void clearChatboxHistory(ChatboxTab tab)
{
if (tab == null)
{
return;
}
boolean removed = false;
for (ChatMessageType msgType : tab.getMessageTypes())
{
final ChatLineBuffer lineBuffer = client.getChatLineMap().get(msgType.getType());
if (lineBuffer == null)
{
continue;
}
final MessageNode[] lines = lineBuffer.getLines().clone();
for (final MessageNode line : lines)
{
if (line != null)
{
lineBuffer.removeMessageNode(line);
removed = true;
}
}
}
if (removed)
{
clientThread.invoke(() -> client.runScript(ScriptID.BUILD_CHATBOX));
clearMessageQueue(tab);
}
}
/**
* Small hack to prevent plugins checking for specific messages to match
* @param message message

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2020, Anthony <https://github.com/while-loop>
* 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 com.google.common.collect.ImmutableList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import lombok.Getter;
import net.runelite.api.ChatMessageType;
import net.runelite.api.widgets.WidgetInfo;
@Getter
enum ChatboxTab
{
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,
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,
ChatMessageType.PUBLICCHAT, ChatMessageType.AUTOTYPER, ChatMessageType.MODCHAT, ChatMessageType.MODAUTOTYPER),
GAME("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),
CLAN("Clan", "Clan: Off", WidgetInfo.CHATBOX_TAB_CLAN,
ChatMessageType.FRIENDSCHATNOTIFICATION, ChatMessageType.FRIENDSCHAT, ChatMessageType.CHALREQ_FRIENDSCHAT),
TRADE("Trade", "Trade: Off", WidgetInfo.CHATBOX_TAB_TRADE,
ChatMessageType.TRADE_SENT, ChatMessageType.TRADEREQ, ChatMessageType.TRADE, ChatMessageType.CHALREQ_TRADE),
;
private static final Map<Integer, ChatboxTab> TAB_MESSAGE_TYPES = new HashMap<>();
@Nullable
private final String after;
private final String name;
private final int widgetId;
private final List<ChatMessageType> messageTypes;
ChatboxTab(String name, String after, WidgetInfo widgetId, ChatMessageType... messageTypes)
{
this.name = name;
this.after = after;
this.widgetId = widgetId.getId();
this.messageTypes = ImmutableList.copyOf(messageTypes);
}
static
{
for (ChatboxTab t : values())
{
TAB_MESSAGE_TYPES.put(t.widgetId, t);
}
}
static ChatboxTab of(int widgetId)
{
return TAB_MESSAGE_TYPES.get(widgetId);
}
}