friendchatmanager: rename to chaticonmanager

FriendsChatManager predates the api having an ability to look up clan
members by name, without doing string matching, hence the caching. This
is no longer necessary as we can do efficient lookups of players by name
now.

Also remove the old isMember utility function which is just duplicated
from the friends chat manager.
This commit is contained in:
Adam
2021-05-24 23:26:37 -04:00
parent c72a571837
commit a781efc73a
8 changed files with 107 additions and 114 deletions

View File

@@ -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;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2021, Adam <Adam@sigterm.info>
* 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<String, FriendsChatRank> ranksCache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(1, TimeUnit.MINUTES)
.build(new CacheLoader<String, FriendsChatRank>()
{
@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);

View File

@@ -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)

View File

@@ -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 = "<img=" + iconNumber + ">";
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);

View File

@@ -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);
}
}
}

View File

@@ -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 = "<img=" + decorations.getImage() + ">" + newTarget;
}

View File

@@ -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;
}
}

View File

@@ -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("<img=22>Lazark", "test", ChatMessageType.PUBLICCHAT);