From 757b392bb936e05cb3d923faf8581895240b826a Mon Sep 17 00:00:00 2001 From: Maciej Lewicki Date: Mon, 25 Jan 2021 01:55:31 +0100 Subject: [PATCH] friendlist: add option to show world in login notifications Co-authored-by: Adam --- .../plugins/friendlist/FriendListConfig.java | 43 +++++++++ .../plugins/friendlist/FriendListPlugin.java | 47 ++++++++++ .../friendlist/FriendListPluginTest.java | 89 +++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java new file mode 100644 index 0000000000..441820c465 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021, Maciej + * 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.friendlist; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("friendlist") +public interface FriendListConfig extends Config +{ + @ConfigItem( + keyName = "showWorldOnLogin", + name = "Show world on login", + description = "Shows world number on friend login notifications" + ) + default boolean showWorldOnLogin() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index da491c4c76..da5ebda38b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -25,19 +25,26 @@ */ package net.runelite.client.plugins.friendlist; +import com.google.inject.Provides; import javax.inject.Inject; +import net.runelite.api.ChatMessageType; +import net.runelite.api.ChatPlayer; import net.runelite.api.Client; import net.runelite.api.Friend; import net.runelite.api.Ignore; +import net.runelite.api.MessageNode; import net.runelite.api.NameableContainer; import net.runelite.api.ScriptID; import net.runelite.api.VarPlayer; +import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ScriptPostFired; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.Text; @PluginDescriptor( name = "Friend List", @@ -54,6 +61,15 @@ public class FriendListPlugin extends Plugin @Inject private Client client; + @Inject + private FriendListConfig config; + + @Provides + FriendListConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(FriendListConfig.class); + } + @Override protected void shutDown() { @@ -109,6 +125,25 @@ public class FriendListPlugin extends Plugin } } + @Subscribe + public void onChatMessage(ChatMessage message) + { + if (message.getType() == ChatMessageType.LOGINLOGOUTNOTIFICATION && config.showWorldOnLogin()) + { + MessageNode messageNode = message.getMessageNode(); + // get the player name out of the notification + String name = messageNode.getValue() + .substring(0, messageNode.getValue().indexOf(" ")); + ChatPlayer player = findFriend(name); + + if (player != null && player.getWorld() > 0) + { + messageNode + .setValue(messageNode.getValue() + String.format(" (World %d)", player.getWorld())); + } + } + } + private void setFriendsListTitle(final String title) { Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE); @@ -126,4 +161,16 @@ public class FriendListPlugin extends Plugin ignoreTitleWidget.setText(title); } } + + private ChatPlayer findFriend(String name) + { + NameableContainer friendContainer = client.getFriendContainer(); + if (friendContainer != null) + { + String cleanName = Text.removeTags(name); + return friendContainer.findByName(cleanName); + } + + return null; + } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java new file mode 100644 index 0000000000..4b3fd12f32 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021, Maciej + * 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.friendlist; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.Friend; +import net.runelite.api.MessageNode; +import net.runelite.api.NameableContainer; +import net.runelite.api.events.ChatMessage; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class FriendListPluginTest +{ + @Mock + @Bind + private Client client; + + @Mock + @Bind + private FriendListConfig config; + + @Inject + private FriendListPlugin friendListPlugin; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void onChatMessage() + { + when(config.showWorldOnLogin()).thenReturn(true); + + MessageNode messageNode = mock(MessageNode.class); + when(messageNode.getValue()).thenReturn("test\u00a0rsn has logged in."); + + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.LOGINLOGOUTNOTIFICATION); + chatMessage.setMessageNode(messageNode); + + Friend friend = mock(Friend.class); + when(friend.getWorld()).thenReturn(311); + + NameableContainer friendContainer = mock(NameableContainer.class); + when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend); + when(client.getFriendContainer()).thenReturn(friendContainer); + + friendListPlugin.onChatMessage(chatMessage); + + verify(messageNode).setValue("test\u00a0rsn has logged in. (World 311)"); + } +}