chat notifications: add regex highlights
Co-authored-by: Adam <Adam@sigterm.info>
This commit is contained in:
@@ -28,12 +28,44 @@ package net.runelite.client.plugins.chatnotifications;
|
|||||||
import net.runelite.client.config.Config;
|
import net.runelite.client.config.Config;
|
||||||
import net.runelite.client.config.ConfigGroup;
|
import net.runelite.client.config.ConfigGroup;
|
||||||
import net.runelite.client.config.ConfigItem;
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
import net.runelite.client.config.ConfigSection;
|
||||||
|
|
||||||
@ConfigGroup("chatnotification")
|
@ConfigGroup("chatnotification")
|
||||||
public interface ChatNotificationsConfig extends Config
|
public interface ChatNotificationsConfig extends Config
|
||||||
{
|
{
|
||||||
|
@ConfigSection(
|
||||||
|
name = "Highlight Lists",
|
||||||
|
description = "Custom single word and regex filter lists",
|
||||||
|
position = 0
|
||||||
|
)
|
||||||
|
String highlightLists = "highlightLists";
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
position = 0,
|
position = 1,
|
||||||
|
keyName = "highlightWordsString",
|
||||||
|
name = "Highlight words",
|
||||||
|
description = "Highlights the following words in chat",
|
||||||
|
section = highlightLists
|
||||||
|
)
|
||||||
|
default String highlightWordsString()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 2,
|
||||||
|
keyName = "highlightRegexString",
|
||||||
|
name = "Highlight Regex",
|
||||||
|
description = "Highlights the following regular expressions in chat, one per line",
|
||||||
|
section = highlightLists
|
||||||
|
)
|
||||||
|
default String highlightRegexString()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 1,
|
||||||
keyName = "highlightOwnName",
|
keyName = "highlightOwnName",
|
||||||
name = "Highlight own name",
|
name = "Highlight own name",
|
||||||
description = "Highlights any instance of your username in chat"
|
description = "Highlights any instance of your username in chat"
|
||||||
@@ -43,17 +75,6 @@ public interface ChatNotificationsConfig extends Config
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
|
||||||
position = 1,
|
|
||||||
keyName = "highlightWordsString",
|
|
||||||
name = "Highlight words",
|
|
||||||
description = "Highlights the following words in chat"
|
|
||||||
)
|
|
||||||
default String highlightWordsString()
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
position = 2,
|
position = 2,
|
||||||
keyName = "notifyOnOwnName",
|
keyName = "notifyOnOwnName",
|
||||||
|
|||||||
@@ -27,12 +27,16 @@ package net.runelite.client.plugins.chatnotifications;
|
|||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.PatternSyntaxException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
@@ -77,7 +81,7 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
|
|
||||||
//Custom Highlights
|
//Custom Highlights
|
||||||
private Pattern usernameMatcher = null;
|
private Pattern usernameMatcher = null;
|
||||||
private Pattern highlightMatcher = null;
|
private final List<Pattern> highlightPatterns = new ArrayList<>();
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
ChatNotificationsConfig provideConfig(ConfigManager configManager)
|
ChatNotificationsConfig provideConfig(ConfigManager configManager)
|
||||||
@@ -91,6 +95,13 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
updateHighlights();
|
updateHighlights();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown()
|
||||||
|
{
|
||||||
|
usernameMatcher = null;
|
||||||
|
highlightPatterns.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onGameStateChanged(GameStateChanged event)
|
public void onGameStateChanged(GameStateChanged event)
|
||||||
{
|
{
|
||||||
@@ -114,7 +125,7 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
|
|
||||||
private void updateHighlights()
|
private void updateHighlights()
|
||||||
{
|
{
|
||||||
highlightMatcher = null;
|
highlightPatterns.clear();
|
||||||
|
|
||||||
if (!config.highlightWordsString().trim().equals(""))
|
if (!config.highlightWordsString().trim().equals(""))
|
||||||
{
|
{
|
||||||
@@ -125,7 +136,28 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
.collect(Collectors.joining("|"));
|
.collect(Collectors.joining("|"));
|
||||||
// To match <word> \b doesn't work due to <> not being in \w,
|
// To match <word> \b doesn't work due to <> not being in \w,
|
||||||
// so match \b or \s, as well as \A and \z for beginning and end of input respectively
|
// so match \b or \s, as well as \A and \z for beginning and end of input respectively
|
||||||
highlightMatcher = Pattern.compile("(?:\\b|(?<=\\s)|\\A)(?:" + joined + ")(?:\\b|(?=\\s)|\\z)", Pattern.CASE_INSENSITIVE);
|
highlightPatterns.add(Pattern.compile("(?:\\b|(?<=\\s)|\\A)(?:" + joined + ")(?:\\b|(?=\\s)|\\z)", Pattern.CASE_INSENSITIVE));
|
||||||
|
}
|
||||||
|
|
||||||
|
Splitter
|
||||||
|
.on("\n")
|
||||||
|
.omitEmptyStrings()
|
||||||
|
.trimResults()
|
||||||
|
.splitToList(config.highlightRegexString()).stream()
|
||||||
|
.map(ChatNotificationsPlugin::compilePattern)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(highlightPatterns::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pattern compilePattern(String pattern)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
|
||||||
|
}
|
||||||
|
catch (PatternSyntaxException ex)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,14 +257,22 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highlightMatcher != null)
|
boolean matchesHighlight = false;
|
||||||
|
// Get nodeValue to store and update in between the different pattern passes
|
||||||
|
// The messageNode value is only set after all patterns have been processed
|
||||||
|
String nodeValue = messageNode.getValue();
|
||||||
|
|
||||||
|
for (Pattern pattern : highlightPatterns)
|
||||||
{
|
{
|
||||||
String nodeValue = messageNode.getValue();
|
Matcher matcher = pattern.matcher(nodeValue);
|
||||||
Matcher matcher = highlightMatcher.matcher(nodeValue);
|
if (!matcher.find())
|
||||||
boolean found = false;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuffer stringBuffer = new StringBuffer();
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
|
|
||||||
while (matcher.find())
|
do
|
||||||
{
|
{
|
||||||
String value = matcher.group();
|
String value = matcher.group();
|
||||||
|
|
||||||
@@ -256,18 +296,21 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
stringBuffer.append(endColor == null ? "<col" + ChatColorType.NORMAL + ">" : endColor);
|
stringBuffer.append(endColor == null ? "<col" + ChatColorType.NORMAL + ">" : endColor);
|
||||||
|
|
||||||
update = true;
|
update = true;
|
||||||
found = true;
|
matchesHighlight = true;
|
||||||
}
|
}
|
||||||
|
while (matcher.find());
|
||||||
|
|
||||||
if (found)
|
// Append stringBuffer with remainder of message and update nodeValue
|
||||||
|
matcher.appendTail(stringBuffer);
|
||||||
|
nodeValue = stringBuffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchesHighlight)
|
||||||
|
{
|
||||||
|
messageNode.setValue(nodeValue);
|
||||||
|
if (config.notifyOnHighlight())
|
||||||
{
|
{
|
||||||
matcher.appendTail(stringBuffer);
|
sendNotification(chatMessage);
|
||||||
messageNode.setValue(stringBuffer.toString());
|
|
||||||
|
|
||||||
if (config.notifyOnHighlight())
|
|
||||||
{
|
|
||||||
sendNotification(chatMessage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ public class ChatNotificationsPluginTest
|
|||||||
public void before()
|
public void before()
|
||||||
{
|
{
|
||||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||||
|
when(config.highlightRegexString()).thenReturn("");
|
||||||
|
when(config.highlightWordsString()).thenReturn("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -102,6 +104,42 @@ public class ChatNotificationsPluginTest
|
|||||||
verify(messageNode).setValue("<colHIGHLIGHT>Deathbeam<colNORMAL>, <colHIGHLIGHT>Deathbeam<colNORMAL> OSRS");
|
verify(messageNode).setValue("<colHIGHLIGHT>Deathbeam<colNORMAL>, <colHIGHLIGHT>Deathbeam<colNORMAL> OSRS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegexMultiplePatternsMessage()
|
||||||
|
{
|
||||||
|
when(config.highlightRegexString()).thenReturn("brandie+\ntest");
|
||||||
|
|
||||||
|
MessageNode messageNode = mock(MessageNode.class);
|
||||||
|
when(messageNode.getValue()).thenReturn("brandieeee testing");
|
||||||
|
|
||||||
|
ChatMessage chatMessage = new ChatMessage();
|
||||||
|
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||||
|
chatMessage.setMessageNode(messageNode);
|
||||||
|
|
||||||
|
chatNotificationsPlugin.startUp();
|
||||||
|
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||||
|
|
||||||
|
verify(messageNode).setValue("<colHIGHLIGHT>brandieeee<colNORMAL> <colHIGHLIGHT>test<colNORMAL>ing");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegexMultiplePatternsWithOnlyOneMatch()
|
||||||
|
{
|
||||||
|
when(config.highlightRegexString()).thenReturn("brandie+\nwillNotMatch");
|
||||||
|
|
||||||
|
MessageNode messageNode = mock(MessageNode.class);
|
||||||
|
when(messageNode.getValue()).thenReturn("brandieeee testing");
|
||||||
|
|
||||||
|
ChatMessage chatMessage = new ChatMessage();
|
||||||
|
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||||
|
chatMessage.setMessageNode(messageNode);
|
||||||
|
|
||||||
|
chatNotificationsPlugin.startUp();
|
||||||
|
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||||
|
|
||||||
|
verify(messageNode).setValue("<colHIGHLIGHT>brandieeee<colNORMAL> testing");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLtGt()
|
public void testLtGt()
|
||||||
{
|
{
|
||||||
@@ -179,7 +217,7 @@ public class ChatNotificationsPluginTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPreceedingColor()
|
public void testPrecedingColor()
|
||||||
{
|
{
|
||||||
when(config.highlightWordsString()).thenReturn("you. It");
|
when(config.highlightWordsString()).thenReturn("you. It");
|
||||||
|
|
||||||
@@ -239,10 +277,10 @@ public class ChatNotificationsPluginTest
|
|||||||
public void highlightListTest()
|
public void highlightListTest()
|
||||||
{
|
{
|
||||||
when(config.highlightWordsString()).thenReturn("this,is, a , test, ");
|
when(config.highlightWordsString()).thenReturn("this,is, a , test, ");
|
||||||
final List<String> higlights = Text.fromCSV(config.highlightWordsString());
|
final List<String> highlights = Text.fromCSV(config.highlightWordsString());
|
||||||
assertEquals(4, higlights.size());
|
assertEquals(4, highlights.size());
|
||||||
|
|
||||||
final Iterator<String> iterator = higlights.iterator();
|
final Iterator<String> iterator = highlights.iterator();
|
||||||
assertEquals("this", iterator.next());
|
assertEquals("this", iterator.next());
|
||||||
assertEquals("is", iterator.next());
|
assertEquals("is", iterator.next());
|
||||||
assertEquals("a", iterator.next());
|
assertEquals("a", iterator.next());
|
||||||
|
|||||||
Reference in New Issue
Block a user