diff --git a/runelite-api/src/main/java/net/runelite/api/EnumID.java b/runelite-api/src/main/java/net/runelite/api/EnumID.java index 7d836dc613..2c2fcecb87 100644 --- a/runelite-api/src/main/java/net/runelite/api/EnumID.java +++ b/runelite-api/src/main/java/net/runelite/api/EnumID.java @@ -34,4 +34,5 @@ public final class EnumID public static final int MUSIC_TRACK_NAMES = 812; public static final int MUSIC_TRACK_IDS = 819; public static final int XPDROP_COLORS = 1169; + public static final int FRIENDS_CHAT_RANK_ICONS = 1543; } diff --git a/runelite-client/src/main/java/net/runelite/client/game/FriendChatManager.java b/runelite-client/src/main/java/net/runelite/client/game/ChatIconManager.java similarity index 52% rename from runelite-client/src/main/java/net/runelite/client/game/FriendChatManager.java rename to runelite-client/src/main/java/net/runelite/client/game/ChatIconManager.java index f27eb6f312..6e80237e96 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/FriendChatManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ChatIconManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Adam + * Copyright (c) 2021, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,94 +24,45 @@ */ package net.runelite.client.game; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; import java.awt.Color; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.util.Arrays; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import net.runelite.api.FriendsChatMember; -import net.runelite.api.FriendsChatManager; -import net.runelite.api.FriendsChatRank; import net.runelite.api.Client; +import net.runelite.api.EnumComposition; +import net.runelite.api.EnumID; +import net.runelite.api.FriendsChatRank; import net.runelite.api.GameState; import net.runelite.api.IndexedSprite; -import net.runelite.api.SpriteID; -import net.runelite.api.events.FriendsChatChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.util.ImageUtil; -import net.runelite.client.util.Text; @Singleton -public class FriendChatManager +public class ChatIconManager { - private static final int[] RANK_IMAGES = - { - SpriteID.FRIENDS_CHAT_RANK_SMILEY_FRIEND, - SpriteID.FRIENDS_CHAT_RANK_SINGLE_CHEVRON_RECRUIT, - SpriteID.FRIENDS_CHAT_RANK_DOUBLE_CHEVRON_CORPORAL, - SpriteID.FRIENDS_CHAT_RANK_TRIPLE_CHEVRON_SERGEANT, - SpriteID.FRIENDS_CHAT_RANK_BRONZE_STAR_LIEUTENANT, - SpriteID.FRIENDS_CHAT_RANK_SILVER_STAR_CAPTAIN, - SpriteID.FRIENDS_CHAT_RANK_GOLD_STAR_GENERAL, - SpriteID.FRIENDS_CHAT_RANK_KEY_CHANNEL_OWNER, - SpriteID.FRIENDS_CHAT_RANK_CROWN_JAGEX_MODERATOR, - }; private static final Dimension IMAGE_DIMENSION = new Dimension(11, 11); private static final Color IMAGE_OUTLINE_COLOR = new Color(33, 33, 33); private final Client client; private final SpriteManager spriteManager; - private final BufferedImage[] rankImages = new BufferedImage[RANK_IMAGES.length]; - private final LoadingCache ranksCache = CacheBuilder.newBuilder() - .maximumSize(100) - .expireAfterWrite(1, TimeUnit.MINUTES) - .build(new CacheLoader() - { - @Override - public FriendsChatRank load(@Nonnull String key) - { - final FriendsChatManager friendsChatManager = client.getFriendsChatManager(); - if (friendsChatManager == null) - { - return FriendsChatRank.UNRANKED; - } + private BufferedImage[] friendsChatRankImages; - FriendsChatMember friendsChatMember = friendsChatManager.findByName(sanitize(key)); - return friendsChatMember != null ? friendsChatMember.getRank() : FriendsChatRank.UNRANKED; - } - }); - - private int offset; + private int friendsChatOffset; @Inject - private FriendChatManager(Client client, SpriteManager spriteManager, EventBus eventBus) + private ChatIconManager(Client client, SpriteManager spriteManager, EventBus eventBus) { this.client = client; this.spriteManager = spriteManager; eventBus.register(this); } - public boolean isMember(String name) - { - FriendsChatManager friendsChatManager = client.getFriendsChatManager(); - return friendsChatManager != null && friendsChatManager.findByName(name) != null; - } - - public FriendsChatRank getRank(String playerName) - { - return ranksCache.getUnchecked(playerName); - } - @Nullable public BufferedImage getRankImage(final FriendsChatRank friendsChatRank) { @@ -120,64 +71,57 @@ public class FriendChatManager return null; } - return rankImages[friendsChatRank.ordinal() - 1]; + return friendsChatRankImages[friendsChatRank.ordinal() - 1]; } public int getIconNumber(final FriendsChatRank friendsChatRank) { - return offset + friendsChatRank.ordinal() - 1; + return friendsChatOffset + friendsChatRank.ordinal() - 1; } @Subscribe public void onGameStateChanged(GameStateChanged gameStateChanged) { - if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN && offset == 0) + if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN && friendsChatOffset == 0) { loadRankIcons(); } } - @Subscribe - public void onFriendsChatChanged(FriendsChatChanged friendsChatChanged) - { - ranksCache.invalidateAll(); - } - private void loadRankIcons() { + final EnumComposition friendsChatIcons = client.getEnum(EnumID.FRIENDS_CHAT_RANK_ICONS); + { IndexedSprite[] modIcons = client.getModIcons(); - offset = modIcons.length; + friendsChatOffset = modIcons.length; IndexedSprite blank = ImageUtil.getImageIndexedSprite( new BufferedImage(modIcons[0].getWidth(), modIcons[0].getHeight(), BufferedImage.TYPE_INT_ARGB), client); - modIcons = Arrays.copyOf(modIcons, offset + RANK_IMAGES.length); - Arrays.fill(modIcons, offset, modIcons.length, blank); + modIcons = Arrays.copyOf(modIcons, friendsChatOffset + friendsChatIcons.size()); + Arrays.fill(modIcons, friendsChatOffset, modIcons.length, blank); client.setModIcons(modIcons); } - for (int i = 0; i < RANK_IMAGES.length; i++) + friendsChatRankImages = new BufferedImage[friendsChatIcons.size()]; + + final IndexedSprite[] modIcons = client.getModIcons(); + + for (int i = 0; i < friendsChatIcons.size(); i++) { final int fi = i; - spriteManager.getSpriteAsync(RANK_IMAGES[i], 0, sprite -> + spriteManager.getSpriteAsync(friendsChatIcons.getIntValue(friendsChatIcons.getKeys()[i]), 0, sprite -> { - IndexedSprite[] modIcons = client.getModIcons(); - rankImages[fi] = friendsChatImageFromSprite(sprite); - modIcons[offset + fi] = ImageUtil.getImageIndexedSprite(rankImages[fi], client); + friendsChatRankImages[fi] = friendsChatImageFromSprite(sprite); + modIcons[friendsChatOffset + fi] = ImageUtil.getImageIndexedSprite(friendsChatRankImages[fi], client); }); } } - private static String sanitize(String lookup) - { - final String cleaned = Text.removeTags(lookup); - return cleaned.replace('\u00A0', ' '); - } - private static BufferedImage friendsChatImageFromSprite(final BufferedImage sprite) { final BufferedImage canvas = ImageUtil.resizeCanvas(sprite, IMAGE_DIMENSION.width, IMAGE_DIMENSION.height); 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 5340be1df0..c7252a46b3 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 @@ -50,6 +50,7 @@ import static net.runelite.api.ChatMessageType.OBJECT_EXAMINE; import static net.runelite.api.ChatMessageType.PUBLICCHAT; import static net.runelite.api.ChatMessageType.SPAM; import net.runelite.api.Client; +import net.runelite.api.FriendsChatManager; import net.runelite.api.MessageNode; import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; @@ -58,7 +59,6 @@ import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.game.FriendChatManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.Text; @@ -117,9 +117,6 @@ public class ChatFilterPlugin extends Plugin @Inject private ChatFilterConfig config; - @Inject - private FriendChatManager friendChatManager; - @Provides ChatFilterConfig provideConfig(ConfigManager configManager) { @@ -274,7 +271,13 @@ public class ChatFilterPlugin extends Plugin boolean isMessageFromSelf = playerName.equals(client.getLocalPlayer().getName()); return !isMessageFromSelf && (config.filterFriends() || !client.isFriended(playerName, false)) && - (config.filterFriendsChat() || !friendChatManager.isMember(playerName)); + (config.filterFriendsChat() || !isFriendsChatMember(playerName)); + } + + private boolean isFriendsChatMember(String name) + { + FriendsChatManager friendsChatManager = client.getFriendsChatManager(); + return friendsChatManager != null && friendsChatManager.findByName(name) != null; } String censorMessage(final String username, final String message) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java index 2f6eb086a3..c7dc727b33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java @@ -76,7 +76,7 @@ import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.game.FriendChatManager; +import net.runelite.client.game.ChatIconManager; import net.runelite.client.game.SpriteManager; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.plugins.Plugin; @@ -103,7 +103,7 @@ public class FriendsChatPlugin extends Plugin private Client client; @Inject - private FriendChatManager friendChatManager; + private ChatIconManager chatIconManager; @Inject private FriendsChatConfig config; @@ -398,7 +398,7 @@ public class FriendsChatPlugin extends Plugin if (config.chatIcons() && rank != null && rank != FriendsChatRank.UNRANKED) { - rankIcon = friendChatManager.getIconNumber(rank); + rankIcon = chatIconManager.getIconNumber(rank); } ChatMessageBuilder message = new ChatMessageBuilder() @@ -580,11 +580,11 @@ public class FriendsChatPlugin extends Plugin private void insertRankIcon(final ChatMessage message) { - final FriendsChatRank rank = friendChatManager.getRank(message.getName()); + final FriendsChatRank rank = getRank(message.getName()); if (rank != null && rank != FriendsChatRank.UNRANKED) { - int iconNumber = friendChatManager.getIconNumber(rank); + int iconNumber = chatIconManager.getIconNumber(rank); final String img = ""; if (message.getType() == ChatMessageType.FRIENDSCHAT) { @@ -600,6 +600,18 @@ public class FriendsChatPlugin extends Plugin } } + private FriendsChatRank getRank(String playerName) + { + final FriendsChatManager friendsChatManager = client.getFriendsChatManager(); + if (friendsChatManager == null) + { + return FriendsChatRank.UNRANKED; + } + + FriendsChatMember friendsChatMember = friendsChatManager.findByName(playerName); + return friendsChatMember != null ? friendsChatMember.getRank() : FriendsChatRank.UNRANKED; + } + private void rebuildFriendsChat() { Widget chat = client.getWidget(WidgetInfo.FRIENDS_CHAT_ROOT); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java index 5ca263a64c..063a3cd488 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java @@ -34,7 +34,7 @@ import javax.inject.Singleton; import net.runelite.api.FriendsChatRank; import net.runelite.api.Player; import net.runelite.api.Point; -import net.runelite.client.game.FriendChatManager; +import net.runelite.client.game.ChatIconManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; @@ -49,15 +49,15 @@ public class PlayerIndicatorsOverlay extends Overlay private final PlayerIndicatorsService playerIndicatorsService; private final PlayerIndicatorsConfig config; - private final FriendChatManager friendChatManager; + private final ChatIconManager chatIconManager; @Inject private PlayerIndicatorsOverlay(PlayerIndicatorsConfig config, PlayerIndicatorsService playerIndicatorsService, - FriendChatManager friendChatManager) + ChatIconManager chatIconManager) { this.config = config; this.playerIndicatorsService = playerIndicatorsService; - this.friendChatManager = friendChatManager; + this.chatIconManager = chatIconManager; setPosition(OverlayPosition.DYNAMIC); setPriority(OverlayPriority.MED); } @@ -108,13 +108,13 @@ public class PlayerIndicatorsOverlay extends Overlay return; } - if (config.showFriendsChatRanks() && actor.isFriendsChatMember()) + if (actor.isFriendsChatMember() && config.showFriendsChatRanks()) { - final FriendsChatRank rank = friendChatManager.getRank(name); + final FriendsChatRank rank = playerIndicatorsService.getFriendsChatRank(actor); if (rank != FriendsChatRank.UNRANKED) { - final BufferedImage rankImage = friendChatManager.getRankImage(rank); + final BufferedImage rankImage = chatIconManager.getRankImage(rank); if (rankImage != null) { @@ -145,4 +145,4 @@ public class PlayerIndicatorsOverlay extends Overlay OverlayUtil.renderTextLocation(graphics, textLocation, name, color); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java index ef3863225d..b7c5d28471 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java @@ -28,16 +28,28 @@ import com.google.inject.Provides; import java.awt.Color; import javax.inject.Inject; import lombok.Value; +import net.runelite.api.Client; import net.runelite.api.FriendsChatRank; import static net.runelite.api.FriendsChatRank.UNRANKED; -import net.runelite.api.Client; -import static net.runelite.api.MenuAction.*; +import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; +import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; +import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FOURTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SECOND_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SEVENTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SIXTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_THIRD_OPTION; +import static net.runelite.api.MenuAction.RUNELITE_PLAYER; +import static net.runelite.api.MenuAction.SPELL_CAST_ON_PLAYER; +import static net.runelite.api.MenuAction.WALK; import net.runelite.api.MenuEntry; import net.runelite.api.Player; import net.runelite.api.events.ClientTick; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.FriendChatManager; +import net.runelite.client.game.ChatIconManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -65,11 +77,14 @@ public class PlayerIndicatorsPlugin extends Plugin @Inject private PlayerIndicatorsMinimapOverlay playerIndicatorsMinimapOverlay; + @Inject + private PlayerIndicatorsService playerIndicatorsService; + @Inject private Client client; @Inject - private FriendChatManager friendChatManager; + private ChatIconManager chatIconManager; @Provides PlayerIndicatorsConfig provideConfig(ConfigManager configManager) @@ -182,10 +197,13 @@ public class PlayerIndicatorsPlugin extends Plugin { color = config.getFriendsChatMemberColor(); - FriendsChatRank rank = friendChatManager.getRank(player.getName()); - if (rank != UNRANKED) + if (config.showFriendsChatRanks()) { - image = friendChatManager.getIconNumber(rank); + FriendsChatRank rank = playerIndicatorsService.getFriendsChatRank(player); + if (rank != UNRANKED) + { + image = chatIconManager.getIconNumber(rank); + } } } else if (config.highlightTeamMembers() @@ -222,7 +240,7 @@ public class PlayerIndicatorsPlugin extends Plugin newTarget = ColorUtil.prependColorTag(newTarget, decorations.getColor()); } - if (decorations.getImage() != -1 && config.showFriendsChatRanks()) + if (decorations.getImage() != -1) { newTarget = "" + newTarget; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java index 8c9823f5c3..c0af49d7cb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java @@ -29,6 +29,9 @@ import java.util.function.BiConsumer; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; +import net.runelite.api.FriendsChatManager; +import net.runelite.api.FriendsChatMember; +import net.runelite.api.FriendsChatRank; import net.runelite.api.Player; @Singleton @@ -88,4 +91,16 @@ public class PlayerIndicatorsService } } } + + FriendsChatRank getFriendsChatRank(Player player) + { + final FriendsChatManager friendsChatManager = client.getFriendsChatManager(); + if (friendsChatManager == null) + { + return FriendsChatRank.UNRANKED; + } + + FriendsChatMember friendsChatMember = friendsChatManager.findByName(player.getName()); + return friendsChatMember != null ? friendsChatMember.getRank() : FriendsChatRank.UNRANKED; + } } 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 f12ae93e4a..501787576a 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 @@ -31,12 +31,13 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import javax.inject.Inject; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.FriendsChatManager; +import net.runelite.api.FriendsChatMember; import net.runelite.api.IterableHashTable; import net.runelite.api.MessageNode; import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ScriptCallbackEvent; -import net.runelite.client.game.FriendChatManager; import static net.runelite.client.plugins.chatfilter.ChatFilterPlugin.CENSOR_MESSAGE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -59,12 +60,11 @@ public class ChatFilterPluginTest private Client client; @Mock - @Bind - private ChatFilterConfig chatFilterConfig; + private FriendsChatManager friendsChatManager; @Mock @Bind - private FriendChatManager friendChatManager; + private ChatFilterConfig chatFilterConfig; @Mock private Player localPlayer; @@ -81,7 +81,9 @@ public class ChatFilterPluginTest when(chatFilterConfig.filteredWords()).thenReturn(""); when(chatFilterConfig.filteredRegex()).thenReturn(""); when(chatFilterConfig.filteredNames()).thenReturn(""); + when(client.getLocalPlayer()).thenReturn(localPlayer); + when(client.getFriendsChatManager()).thenReturn(friendsChatManager); } private ScriptCallbackEvent createCallbackEvent(final String sender, final String chatMessage, final ChatMessageType messageType) @@ -187,7 +189,6 @@ public class ChatFilterPluginTest @Test public void testMessageFromFriendIsFiltered() { - when(friendChatManager.isMember("Iron Mammal")).thenReturn(false); when(chatFilterConfig.filterFriends()).thenReturn(true); assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal")); } @@ -211,7 +212,7 @@ public class ChatFilterPluginTest @Test public void testMessageFromFriendsChatIsNotFiltered() { - when(friendChatManager.isMember("B0aty")).thenReturn(true); + when(friendsChatManager.findByName("B0aty")).thenReturn(mock(FriendsChatMember.class)); when(chatFilterConfig.filterFriendsChat()).thenReturn(false); assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("B0aty")); } @@ -227,7 +228,6 @@ public class ChatFilterPluginTest public void testMessageFromNonFriendNonFCIsFiltered() { when(client.isFriended("Woox", false)).thenReturn(false); - when(friendChatManager.isMember("Woox")).thenReturn(false); assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Woox")); } @@ -414,7 +414,7 @@ public class ChatFilterPluginTest when(chatFilterConfig.filteredWords()).thenReturn("test"); // if this test is broken, this stubbing is required to trip the assert lenient().when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE); - when(friendChatManager.isMember("Lazark")).thenReturn(true); + when(friendsChatManager.findByName("Lazark")).thenReturn(mock(FriendsChatMember.class)); chatFilterPlugin.updateFilteredPatterns(); ScriptCallbackEvent event = createCallbackEvent("Lazark", "test", ChatMessageType.PUBLICCHAT);