diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterConfig.java index abc1747b4a..264e5ae425 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterConfig.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Magic fTail + * Copyright (c) 2019, osrs-music-map * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,4 +64,26 @@ public interface ChatFilterConfig extends Config { return ""; } + + @ConfigItem( + keyName = "filterFriends", + name = "Filter Friends", + description = "Filter your friends' messages", + position = 4 + ) + default boolean filterFriends() + { + return false; + } + + @ConfigItem( + keyName = "filterClan", + name = "Filter Clan Chat Members", + description = "Filter your clan chat members' messages", + position = 5 + ) + default boolean filterClan() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java index 3f49a1f7e4..690669cc54 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Magic fTail + * Copyright (c) 2019, osrs-music-map * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +36,7 @@ import java.util.regex.PatternSyntaxException; import javax.inject.Inject; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.MessageNode; import net.runelite.api.Player; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.OverheadTextChanged; @@ -97,7 +99,10 @@ public class ChatFilterPlugin extends Plugin int[] intStack = client.getIntStack(); int intStackSize = client.getIntStackSize(); - ChatMessageType chatMessageType = ChatMessageType.of(intStack[intStackSize - 1]); + int messageType = intStack[intStackSize - 2]; + int messageId = intStack[intStackSize - 1]; + + ChatMessageType chatMessageType = ChatMessageType.of(messageType); // Only filter public chat and private messages switch (chatMessageType) @@ -113,6 +118,13 @@ public class ChatFilterPlugin extends Plugin return; } + MessageNode messageNode = (MessageNode) client.getMessages().get(messageId); + String name = messageNode.getName(); + if (!shouldFilterPlayerMessage(name)) + { + return; + } + String[] stringStack = client.getStringStack(); int stringStackSize = client.getStringStackSize(); @@ -122,7 +134,7 @@ public class ChatFilterPlugin extends Plugin if (censoredMessage == null) { // Block the message - intStack[intStackSize - 2] = 0; + intStack[intStackSize - 3] = 0; } else { @@ -134,7 +146,7 @@ public class ChatFilterPlugin extends Plugin @Subscribe public void onOverheadTextChanged(OverheadTextChanged event) { - if (!(event.getActor() instanceof Player)) + if (!(event.getActor() instanceof Player) || !shouldFilterPlayerMessage(event.getActor().getName())) { return; } @@ -149,6 +161,14 @@ public class ChatFilterPlugin extends Plugin event.getActor().setOverheadText(message); } + boolean shouldFilterPlayerMessage(String playerName) + { + boolean isMessageFromSelf = playerName.equals(client.getLocalPlayer().getName()); + return !isMessageFromSelf && + (config.filterFriends() || !client.isFriended(playerName, false)) && + (config.filterClan() || !client.isClanMember(playerName)); + } + String censorMessage(final String message) { String strippedMessage = jagexPrintableCharMatcher.retainFrom(message) diff --git a/runelite-client/src/main/scripts/ChatBuilder.rs2asm b/runelite-client/src/main/scripts/ChatBuilder.rs2asm index c30307da67..2e0bc1d37c 100644 --- a/runelite-client/src/main/scripts/ChatBuilder.rs2asm +++ b/runelite-client/src/main/scripts/ChatBuilder.rs2asm @@ -189,8 +189,10 @@ CHAT_FILTER: sload 11 ; Load the message iconst 1 ; Gets changed to 0 if message is blocked iload 10 ; Load the messageType + iload 9 ; Load the id of the messageNode sconst "chatFilterCheck" runelite_callback + pop_int ; Pop the id of the messageNode pop_int ; Pop the messageType iconst 1 ; 2nd half of conditional sstore 11 ; Override the message with our filtered message diff --git a/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm b/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm index 45b420248d..73badbb543 100644 --- a/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm +++ b/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm @@ -359,9 +359,11 @@ CHAT_FILTER: sload 0 ; Load the message iconst 1 ; Gets changed to 0 if message is blocked iload 15 ; Load the messageType + iload 12 ; Load the id of the messageNode sconst "chatFilterCheck" - runelite_callback - pop_int ; Pop the messageType + runelite_callback + pop_int ; Pop the id of the messageNode + pop_int ; Pop the messageType iconst 1 ; 2nd half of conditional sstore 0 ; Override the message with our filtered message if_icmpeq LABEL327 ; Check if we are building this message diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java index 2fe4d88e05..a12a8b257b 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, Adam + * Copyright (c) 2019, osrs-music-map * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,8 +30,11 @@ import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.Player; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -49,6 +53,10 @@ public class ChatFilterPluginTest @Bind private ChatFilterConfig chatFilterConfig; + @Mock + @Bind + private Player localPlayer; + @Inject private ChatFilterPlugin chatFilterPlugin; @@ -60,6 +68,7 @@ public class ChatFilterPluginTest when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS); when(chatFilterConfig.filteredWords()).thenReturn(""); when(chatFilterConfig.filteredRegex()).thenReturn(""); + when(client.getLocalPlayer()).thenReturn(localPlayer); } @Test @@ -110,4 +119,51 @@ public class ChatFilterPluginTest chatFilterPlugin.updateFilteredPatterns(); assertNull(chatFilterPlugin.censorMessage("te\u008Cst")); } + + @Test + public void testMessageFromFriendIsFiltered() + { + when(client.isFriended("Iron Mammal", false)).thenReturn(true); + when(chatFilterConfig.filterFriends()).thenReturn(true); + assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal")); + } + + @Test + public void testMessageFromFriendIsNotFiltered() + { + when(client.isFriended("Iron Mammal", false)).thenReturn(true); + when(chatFilterConfig.filterFriends()).thenReturn(false); + assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal")); + } + + @Test + public void testMessageFromClanIsFiltered() + { + when(client.isClanMember("B0aty")).thenReturn(true); + when(chatFilterConfig.filterClan()).thenReturn(true); + assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("B0aty")); + } + + @Test + public void testMessageFromClanIsNotFiltered() + { + when(client.isClanMember("B0aty")).thenReturn(true); + when(chatFilterConfig.filterClan()).thenReturn(false); + assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("B0aty")); + } + + @Test + public void testMessageFromSelfIsNotFiltered() + { + when(localPlayer.getName()).thenReturn("Swampletics"); + assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("Swampletics")); + } + + @Test + public void testMessageFromNonFriendNonClanIsFiltered() + { + when(client.isFriended("Woox", false)).thenReturn(false); + when(client.isClanMember("Woox")).thenReturn(false); + assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Woox")); + } } \ No newline at end of file