From 0da4a65ce233f34eca74e8edbfbca8e3d506ee6e Mon Sep 17 00:00:00 2001 From: Zander Bolgar Date: Tue, 7 Jun 2022 22:53:54 -0400 Subject: [PATCH 01/21] mining: add gold vein respawn timer --- .../client/plugins/mining/MiningPlugin.java | 14 ++++++++++++++ .../net/runelite/client/plugins/mining/Rock.java | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java index 67edf4a1e5..8a55d92c67 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java @@ -41,11 +41,15 @@ import net.runelite.api.GameObject; import net.runelite.api.GameState; import static net.runelite.api.HintArrowType.WORLD_POSITION; import net.runelite.api.MenuAction; +import static net.runelite.api.ObjectID.DEPLETED_VEIN; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26665; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26666; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26667; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26668; import static net.runelite.api.ObjectID.EMPTY_WALL; +import static net.runelite.api.ObjectID.MINERAL_VEIN; +import static net.runelite.api.ObjectID.MINERAL_VEIN_5990; +import static net.runelite.api.ObjectID.MINERAL_VEIN_5991; import static net.runelite.api.ObjectID.ORE_VEIN_26661; import static net.runelite.api.ObjectID.ORE_VEIN_26662; import static net.runelite.api.ObjectID.ORE_VEIN_26663; @@ -355,12 +359,22 @@ public class MiningPlugin extends Plugin respawns.add(rockRespawn); break; } + case DEPLETED_VEIN: // Depleted gold vein + { + Rock rock = Rock.MINERAL_VEIN; + RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(region).toMillis(), rock.getZOffset()); + respawns.add(rockRespawn); + break; + } case ORE_VEIN_26661: // Motherlode vein case ORE_VEIN_26662: // Motherlode vein case ORE_VEIN_26663: // Motherlode vein case ORE_VEIN_26664: // Motherlode vein case ROCKS_41547: // Barronite vein case ROCKS_41548: // Barronite vein + case MINERAL_VEIN: // Arzinian gold vein + case MINERAL_VEIN_5990: // Gold vein + case MINERAL_VEIN_5991: // Gold vein { // If the vein respawns before the timer is up, remove it final WorldPoint point = object.getWorldLocation(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java index ac28366b8b..53535ac93d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java @@ -98,7 +98,8 @@ enum Rock TE_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33256), BASALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33257), DAEYALT_ESSENCE(Duration.of(MiningRocksOverlay.DAEYALT_MAX_RESPAWN_TIME, GAME_TICKS), 0, DAEYALT_ESSENCE_39095), - BARRONITE(Duration.of(89, GAME_TICKS), 140); + BARRONITE(Duration.of(89, GAME_TICKS), 140), + MINERAL_VEIN(Duration.of(100, GAME_TICKS), 150); private static final int WILDERNESS_RESOURCE_AREA = 12605; private static final int MISCELLANIA = 10044; From 8be3210b87b342238811f21e4cd4faeceb06d58f Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 6 Jun 2022 20:14:26 -0400 Subject: [PATCH 02/21] chatfilter: fix matching lt/gt These are encoded as and and so require the patterns to match those, which is unintuitive --- .../client/plugins/chatfilter/ChatFilterPlugin.java | 4 +++- .../plugins/chatfilter/ChatFilterPluginTest.java | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) 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 e5befde35f..8ed1c51fea 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 @@ -320,7 +320,9 @@ public class ChatFilterPlugin extends Plugin String censorMessage(final String username, final String message) { String strippedMessage = jagexPrintableCharMatcher.retainFrom(message) - .replace('\u00A0', ' '); + .replace('\u00A0', ' ') + .replaceAll("", "<") + .replaceAll("", ">"); String strippedAccents = stripAccents(strippedMessage); assert strippedMessage.length() == strippedAccents.length(); 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 324e3dacdf..318615fc43 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 @@ -453,4 +453,15 @@ public class ChatFilterPluginTest chatFilterPlugin.onScriptCallbackEvent(event); assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]); // not filtered } + + @Test + public void testLtGt() + { + when(chatFilterConfig.filteredWords()).thenReturn("fr"); + + chatFilterPlugin.updateFilteredPatterns(); + + String message = chatFilterPlugin.censorMessage("Adam", "start filter end"); + assertEquals("start ******** end", message); + } } \ No newline at end of file From 82d92b9953aae37d1e81dc1ff3815cd188f1a7a0 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 8 Jun 2022 14:19:22 -0400 Subject: [PATCH 03/21] Move entity hider logic to plugin --- .../main/java/net/runelite/api/Client.java | 113 +------- .../net/runelite/api/hooks/Callbacks.java | 9 + .../net/runelite/client/callback/Hooks.java | 33 +++ .../entityhider/EntityHiderPlugin.java | 151 ++++++++--- .../entityhider/EntityHiderPluginTest.java | 242 ++++++++++++++++++ 5 files changed, 411 insertions(+), 137 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/entityhider/EntityHiderPluginTest.java diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 3b0994fcd6..95785bea98 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -376,6 +376,13 @@ public interface Client extends OAuthApi, GameEngine */ Player getLocalPlayer(); + /** + * Get the local player's follower, such as a pet + * @return + */ + @Nullable + NPC getFollower(); + /** * Gets the item composition corresponding to an items ID. * @@ -1628,112 +1635,6 @@ public interface Client extends OAuthApi, GameEngine */ int getItemPressedDuration(); - /** - * Sets whether the client is hiding entities. - *

- * This method does not itself hide any entities. It behaves as a master - * switch for whether or not any of the related entities are hidden or - * shown. If this method is set to false, changing the configurations for - * specific entities will have no effect. - * - * @param state new entity hiding state - */ - void setIsHidingEntities(boolean state); - - /** - * Sets whether or not other players are hidden. - * - * @param state the new player hidden state - */ - void setOthersHidden(boolean state); - - /** - * Sets whether 2D sprites related to the other players are hidden. - * (ie. overhead prayers, PK skull) - * - * @param state the new player 2D hidden state - */ - void setOthersHidden2D(boolean state); - - /** - * Sets whether or not friends are hidden. - * - * @param state the new friends hidden state - */ - void setFriendsHidden(boolean state); - - /** - * Sets whether or not friends chat members are hidden. - * - * @param state the new friends chat member hidden state - */ - void setFriendsChatMembersHidden(boolean state); - - /** - * Sets whether or not clan members are hidden. - * - * @param state the new clan chat member hidden state - */ - void setClanChatMembersHidden(boolean state); - - /** - * Sets whether or not ignored players are hidden. - * - * @param state the new ignored player hidden state - */ - void setIgnoresHidden(boolean state); - - /** - * Sets whether the local player is hidden. - * - * @param state new local player hidden state - */ - void setLocalPlayerHidden(boolean state); - - /** - * Sets whether 2D sprites related to the local player are hidden. - * (ie. overhead prayers, PK skull) - * - * @param state new local player 2D hidden state - */ - void setLocalPlayerHidden2D(boolean state); - - /** - * Sets whether NPCs are hidden. - * - * @param state new NPC hidden state - */ - void setNPCsHidden(boolean state); - - /** - * Sets whether 2D sprites related to the NPCs are hidden. - * (ie. overhead prayers) - * - * @param state new NPC 2D hidden state - */ - void setNPCsHidden2D(boolean state); - - /** - * Sets whether Pets from other players are hidden. - * - * @param state new pet hidden state - */ - void setPetsHidden(boolean state); - - /** - * Sets whether attacking players or NPCs are hidden. - * - * @param state new attacker hidden state - */ - void setAttackersHidden(boolean state); - - /** - * Sets whether projectiles are hidden. - * - * @param state new projectile hidden state - */ - void setProjectilesHidden(boolean state); - /** * Gets an array of tile collision data. *

diff --git a/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java b/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java index 777f486e86..bf2c40b82b 100644 --- a/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java +++ b/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java @@ -30,6 +30,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.util.List; import net.runelite.api.MainBufferProvider; +import net.runelite.api.Renderable; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetItem; @@ -185,4 +186,12 @@ public interface Callbacks * @param keyEvent the key event */ void keyTyped(KeyEvent keyEvent); + + /** + * Called to test if a renderable should be drawn this frame + * @param renderable the renderable + * @param drawingUi if this is the 2d ui, such as hp bars or hitsplats + * @return false to prevent drawing + */ + boolean draw(Renderable renderable, boolean drawingUi); } diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 65c877184b..a208da0fa8 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -36,6 +36,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.image.BufferedImage; import java.awt.image.VolatileImage; +import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; @@ -43,6 +44,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.MainBufferProvider; import net.runelite.api.RenderOverview; +import net.runelite.api.Renderable; import net.runelite.api.Skill; import net.runelite.api.WorldMapManager; import net.runelite.api.events.BeforeRender; @@ -108,6 +110,14 @@ public class Hooks implements Callbacks private static MainBufferProvider lastMainBufferProvider; private static Graphics2D lastGraphics; + @FunctionalInterface + public interface RenderableDrawListener + { + boolean draw(Renderable renderable, boolean ui); + } + + private final List renderableDrawListeners = new ArrayList<>(); + /** * Get the Graphics2D for the MainBufferProvider image * This caches the Graphics2D instance so it can be reused @@ -544,4 +554,27 @@ public class Hooks implements Callbacks ); eventBus.post(fakeXpDrop); } + + public void registerRenderableDrawListener(RenderableDrawListener listener) + { + renderableDrawListeners.add(listener); + } + + public void unregisterRenderableDrawListener(RenderableDrawListener listener) + { + renderableDrawListeners.remove(listener); + } + + @Override + public boolean draw(Renderable renderable, boolean drawingUi) + { + for (RenderableDrawListener renderableDrawListener : renderableDrawListeners) + { + if (!renderableDrawListener.draw(renderable, drawingUi)) + { + return false; + } + } + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java index 2d34d5e813..a03d163fec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java @@ -25,9 +25,16 @@ */ package net.runelite.client.plugins.entityhider; +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Provides; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.api.Projectile; +import net.runelite.api.Renderable; +import net.runelite.api.Varbits; +import net.runelite.client.callback.Hooks; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; @@ -48,6 +55,25 @@ public class EntityHiderPlugin extends Plugin @Inject private EntityHiderConfig config; + @Inject + private Hooks hooks; + + private boolean hideOthers; + private boolean hideOthers2D; + private boolean hideFriends; + private boolean hideFriendsChatMembers; + private boolean hideClanMembers; + private boolean hideIgnoredPlayers; + private boolean hideLocalPlayer; + private boolean hideLocalPlayer2D; + private boolean hideNPCs; + private boolean hideNPCs2D; + private boolean hidePets; + private boolean hideAttackers; + private boolean hideProjectiles; + + private final Hooks.RenderableDrawListener drawListener = this::shouldDraw; + @Provides EntityHiderConfig provideConfig(ConfigManager configManager) { @@ -58,6 +84,14 @@ public class EntityHiderPlugin extends Plugin protected void startUp() { updateConfig(); + + hooks.registerRenderableDrawListener(drawListener); + } + + @Override + protected void shutDown() + { + hooks.unregisterRenderableDrawListener(drawListener); } @Subscribe @@ -71,52 +105,107 @@ public class EntityHiderPlugin extends Plugin private void updateConfig() { - client.setIsHidingEntities(true); + hideOthers = config.hideOthers(); + hideOthers2D = config.hideOthers2D(); - client.setOthersHidden(config.hideOthers()); - client.setOthersHidden2D(config.hideOthers2D()); + hideFriends = config.hideFriends(); + hideFriendsChatMembers = config.hideFriendsChatMembers(); + hideClanMembers = config.hideClanChatMembers(); + hideIgnoredPlayers = config.hideIgnores(); - client.setFriendsHidden(config.hideFriends()); - client.setFriendsChatMembersHidden(config.hideFriendsChatMembers()); - client.setClanChatMembersHidden(config.hideClanChatMembers()); - client.setIgnoresHidden(config.hideIgnores()); + hideLocalPlayer = config.hideLocalPlayer(); + hideLocalPlayer2D = config.hideLocalPlayer2D(); - client.setLocalPlayerHidden(config.hideLocalPlayer()); - client.setLocalPlayerHidden2D(config.hideLocalPlayer2D()); + hideNPCs = config.hideNPCs(); + hideNPCs2D = config.hideNPCs2D(); - client.setNPCsHidden(config.hideNPCs()); - client.setNPCsHidden2D(config.hideNPCs2D()); + hidePets = config.hidePets(); - client.setPetsHidden(config.hidePets()); + hideAttackers = config.hideAttackers(); - client.setAttackersHidden(config.hideAttackers()); - - client.setProjectilesHidden(config.hideProjectiles()); + hideProjectiles = config.hideProjectiles(); } - @Override - protected void shutDown() throws Exception + @VisibleForTesting + boolean shouldDraw(Renderable renderable, boolean drawingUI) { - client.setIsHidingEntities(false); + if (renderable instanceof Player) + { + Player player = (Player) renderable; + Player local = client.getLocalPlayer(); - client.setOthersHidden(false); - client.setOthersHidden2D(false); + if (player.getName() == null) + { + // player.isFriend() and player.isFriendsChatMember() npe when the player has a null name + return true; + } - client.setFriendsHidden(false); - client.setFriendsChatMembersHidden(false); - client.setClanChatMembersHidden(false); - client.setIgnoresHidden(false); + // Allow hiding local self in pvp, which is an established meta. + // It is more advantageous than renderself due to being able to still render local player 2d + if (player == local) + { + return !(drawingUI ? hideLocalPlayer2D : hideLocalPlayer); + } - client.setLocalPlayerHidden(false); - client.setLocalPlayerHidden2D(false); + final boolean inPvp = client.getVarbitValue(Varbits.PVP_SPEC_ORB) == 1; + if (inPvp) + { + // In PVP we only allow hiding everyone or no one + return !(drawingUI ? hideOthers2D : hideOthers); + } - client.setNPCsHidden(false); - client.setNPCsHidden2D(false); + if (hideAttackers && player.getInteracting() == local) + { + return false; // hide + } - client.setPetsHidden(false); + if (player.isFriend()) + { + return !hideFriends; + } + if (player.isFriendsChatMember()) + { + return !hideFriendsChatMembers; + } + if (player.isClanMember()) + { + return !hideClanMembers; + } + if (client.getIgnoreContainer().findByName(player.getName()) != null) + { + return !hideIgnoredPlayers; + } - client.setAttackersHidden(false); + return !(drawingUI ? hideOthers2D : hideOthers); + } + else if (renderable instanceof NPC) + { + NPC npc = (NPC) renderable; - client.setProjectilesHidden(false); + if (npc.getComposition().isFollower() && npc == client.getFollower()) + { + return !hidePets; + } + + if (npc.getInteracting() == client.getLocalPlayer()) + { + boolean b = hideAttackers; + // Kludge to make hide attackers only affect 2d or 3d if the 2d or 3d hide is on + // This allows hiding 2d for all npcs, including attackers. + if (hideNPCs2D || hideNPCs) + { + b &= drawingUI ? hideNPCs2D : hideNPCs; + } + return !b; + } + + return !(drawingUI ? hideNPCs2D : hideNPCs); + } + else if (renderable instanceof Projectile) + { + return !hideProjectiles; + } + + return true; } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/entityhider/EntityHiderPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/entityhider/EntityHiderPluginTest.java new file mode 100644 index 0000000000..834a296498 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/entityhider/EntityHiderPluginTest.java @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2022, Adam + * 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.entityhider; + +import com.google.inject.Guice; +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.Ignore; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.NameableContainer; +import net.runelite.api.Player; +import net.runelite.client.callback.Hooks; +import net.runelite.client.events.ConfigChanged; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +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.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class EntityHiderPluginTest +{ + @Inject + EntityHiderPlugin plugin; + + @Mock + @Bind + Client client; + + @Mock + @Bind + EntityHiderConfig config; + + @Mock + @Bind + Hooks hooks; + + @Mock + NameableContainer ignoreNameableContainer; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getIgnoreContainer()).thenReturn(ignoreNameableContainer); + } + + @Test + public void testHideFriendsPositive() + { + when(config.hideOthers()).thenReturn(true); + when(config.hideFriends()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(true); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + } + + @Test + public void testHideFriendsNegative() + { + when(config.hideOthers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(true); + + assertTrue(plugin.shouldDraw(player, false)); + } + + @Test + public void testHideClansPositivie() + { + when(config.hideOthers()).thenReturn(true); + when(config.hideFriendsChatMembers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(true); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + } + + @Test + public void testHideClansNegative() + { + when(config.hideOthers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(true); + + assertTrue(plugin.shouldDraw(player, false)); + } + + // hidenpc hideattacker hidden? + // t t t iif attacker would be hidden + // t f f + // f t t + // f f f + @Test + public void testHideAndAttacker() + { + when(config.hideNPCs2D()).thenReturn(true); + when(config.hideAttackers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + NPCComposition composition = mock(NPCComposition.class); + + NPC npc = mock(NPC.class); + when(npc.getComposition()).thenReturn(composition); + + Player player = mock(Player.class); + when(client.getLocalPlayer()).thenReturn(player); + + when(npc.getInteracting()).thenReturn(player); + + assertFalse(plugin.shouldDraw(npc, true)); + assertTrue(plugin.shouldDraw(npc, false)); + } + + @Test + public void testHideAndNoAttacker() + { + when(config.hideNPCs2D()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + NPCComposition composition = mock(NPCComposition.class); + + NPC npc = mock(NPC.class); + when(npc.getComposition()).thenReturn(composition); + + Player player = mock(Player.class); + when(client.getLocalPlayer()).thenReturn(player); + + when(npc.getInteracting()).thenReturn(player); + + assertTrue(plugin.shouldDraw(npc, true)); + assertTrue(plugin.shouldDraw(npc, false)); + } + + @Test + public void testHideAttacker() + { + when(config.hideAttackers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + NPCComposition composition = mock(NPCComposition.class); + + NPC npc = mock(NPC.class); + when(npc.getComposition()).thenReturn(composition); + + Player player = mock(Player.class); + when(client.getLocalPlayer()).thenReturn(player); + + when(npc.getInteracting()).thenReturn(player); + + assertFalse(plugin.shouldDraw(npc, true)); + assertFalse(plugin.shouldDraw(npc, false)); + } +} \ No newline at end of file From 5c319169d58088f9b3355f4d1f1a99264771c04c Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 8 Jun 2022 17:10:22 -0400 Subject: [PATCH 04/21] hooks: add exception handler for renderable draw listener --- .../java/net/runelite/client/callback/Hooks.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index a208da0fa8..41d7cd2faa 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -568,13 +568,20 @@ public class Hooks implements Callbacks @Override public boolean draw(Renderable renderable, boolean drawingUi) { - for (RenderableDrawListener renderableDrawListener : renderableDrawListeners) + try { - if (!renderableDrawListener.draw(renderable, drawingUi)) + for (RenderableDrawListener renderableDrawListener : renderableDrawListeners) { - return false; + if (!renderableDrawListener.draw(renderable, drawingUi)) + { + return false; + } } } + catch (Exception ex) + { + log.error("exception from renderable draw listener", ex); + } return true; } } From 4aa1a3f6e816df20cab630de92158150678d54f0 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 8 Jun 2022 17:13:34 -0400 Subject: [PATCH 05/21] hooks: raise exception logs to error level --- .../java/net/runelite/client/callback/Hooks.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 41d7cd2faa..7596799ad3 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -225,7 +225,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("error during main loop tasks", ex); + log.error("error during main loop tasks", ex); } } @@ -350,7 +350,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } notifier.processFlash(graphics2d); @@ -445,7 +445,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } @@ -461,7 +461,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } @@ -513,7 +513,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } @@ -529,7 +529,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } From b9d9cab69757e76dbd9e7c6cb22882f366e4f6df Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 29 May 2022 12:36:50 -0400 Subject: [PATCH 06/21] account: use http redirect for oauth login response --- .../client/account/AccountClient.java | 4 +- .../client/account/AccountSession.java | 2 +- .../client/account/SessionManager.java | 118 +++++++++++------- .../net/runelite/client/runelite.properties | 3 +- .../client/config/ConfigManagerTest.java | 15 --- 5 files changed, 79 insertions(+), 63 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java b/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java index 4c26a60170..6cacaafccc 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java +++ b/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java @@ -57,12 +57,12 @@ public class AccountClient this.apiBase = apiBase; } - public OAuthResponse login() throws IOException + public OAuthResponse login(int port) throws IOException { HttpUrl url = apiBase.newBuilder() .addPathSegment("account") .addPathSegment("login") - .addQueryParameter("uuid", uuid.toString()) + .addQueryParameter("port", Integer.toString(port)) .build(); log.debug("Built URI: {}", url); diff --git a/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java b/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java index dc1534ab94..c50b5720f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java +++ b/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java @@ -35,5 +35,5 @@ public class AccountSession { private final UUID uuid; private final Instant created; - private String username; + private final String username; } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java index 81f08dd3e6..04d264ef5b 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java +++ b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java @@ -25,12 +25,14 @@ package net.runelite.client.account; import com.google.gson.Gson; +import com.sun.net.httpserver.HttpServer; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Writer; +import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.time.Instant; @@ -42,13 +44,11 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.client.util.LinkBrowser; -import net.runelite.client.ws.WSClient; import net.runelite.http.api.account.OAuthResponse; -import net.runelite.http.api.ws.messages.LoginResponse; +import okhttp3.HttpUrl; @Singleton @Slf4j @@ -59,26 +59,29 @@ public class SessionManager private final EventBus eventBus; private final ConfigManager configManager; - private final WSClient wsClient; private final File sessionFile; private final AccountClient accountClient; private final Gson gson; + private final String oauthRedirect; + + private HttpServer server; @Inject private SessionManager( @Named("sessionfile") File sessionfile, ConfigManager configManager, EventBus eventBus, - WSClient wsClient, AccountClient accountClient, - Gson gson) + Gson gson, + @Named("runelite.oauth.redirect") String oauthRedirect + ) { this.configManager = configManager; this.eventBus = eventBus; - this.wsClient = wsClient; this.sessionFile = sessionfile; this.accountClient = accountClient; this.gson = gson; + this.oauthRedirect = oauthRedirect; eventBus.register(this); } @@ -113,7 +116,7 @@ public class SessionManager return; } - openSession(session, false); + openSession(session); } private void saveSession() @@ -141,19 +144,12 @@ public class SessionManager } /** - * Set the given session as the active session and open a socket to the - * server with the given session + * Set the given session as the active session * * @param session session */ - private void openSession(AccountSession session, boolean openSocket) + private void openSession(AccountSession session) { - // Change session on the websocket - if (openSocket) - { - wsClient.changeSession(session.getUuid()); - } - accountSession = session; if (session.getUsername() != null) @@ -168,8 +164,6 @@ public class SessionManager private void closeSession() { - wsClient.changeSession(null); - if (accountSession == null) { return; @@ -197,49 +191,85 @@ public class SessionManager public void login() { - // If a session is already open, use that id. Otherwise generate a new id. - UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID(); - accountClient.setUuid(uuid); + if (server == null) + { + try + { + startServer(); + } + catch (IOException ex) + { + log.error("Unable to start http server", ex); + return; + } + } final OAuthResponse login; try { - login = accountClient.login(); + login = accountClient.login(server.getAddress().getPort()); } catch (IOException ex) { - log.warn("Unable to get oauth url", ex); + log.error("Unable to get oauth url", ex); return; } - // Create new session - openSession(new AccountSession(login.getUid(), Instant.now()), true); - // Navigate to login link LinkBrowser.browse(login.getOauthUrl()); } - @Subscribe - public void onLoginResponse(LoginResponse loginResponse) - { - log.debug("Now signed in as {}", loginResponse.getUsername()); - - AccountSession session = getAccountSession(); - session.setUsername(loginResponse.getUsername()); - - // Open session, again, now that we have a username - // This triggers onSessionOpen - // The socket is already opened here anyway so we pass true for openSocket - openSession(session, true); - - // Save session to disk - saveSession(); - } - public void logout() { closeSession(); deleteSession(); } + + private void startServer() throws IOException + { + server = HttpServer.create(new InetSocketAddress("localhost", 0), 1); + server.createContext("/oauth", req -> + { + try + { + final HttpUrl url = HttpUrl.get("http://localhost" + req.getRequestURI()); + final String username = url.queryParameter("username"); + final UUID sessionId = UUID.fromString(url.queryParameter("sessionId")); + + log.debug("Now signed in as {}", username); + + // open the session, which triggers the sessonopen event + AccountSession session = new AccountSession(sessionId, Instant.now(), username); + openSession(session); + + // Save session to disk + saveSession(); + + req.getResponseHeaders().set("Location", oauthRedirect); + req.sendResponseHeaders(302, 0); + } + catch (Exception e) + { + log.warn("failure serving oauth response", e); + req.sendResponseHeaders(400, 0); + req.getResponseBody().write(e.getMessage().getBytes(StandardCharsets.UTF_8)); + } + finally + { + req.close(); + stopServer(); + } + }); + + log.debug("Starting server {}", server); + server.start(); + } + + private void stopServer() + { + log.debug("Stopping server {}", server); + server.stop(0); + server = null; + } } diff --git a/runelite-client/src/main/resources/net/runelite/client/runelite.properties b/runelite-client/src/main/resources/net/runelite/client/runelite.properties index 601193633f..892e84181f 100644 --- a/runelite-client/src/main/resources/net/runelite/client/runelite.properties +++ b/runelite-client/src/main/resources/net/runelite/client/runelite.properties @@ -20,4 +20,5 @@ runelite.session=https://api.runelite.net/session runelite.static.base=https://static.runelite.net runelite.ws=https://api.runelite.net/ws runelite.config=https://static.runelite.net/config.json -runelite.osrstwitter.link=https://twitter.com/OldSchoolRS \ No newline at end of file +runelite.osrstwitter.link=https://twitter.com/OldSchoolRS +runelite.oauth.redirect=https://runelite.net/logged-in \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java b/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java index 4b46a8844f..b6e86871b7 100644 --- a/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java @@ -29,14 +29,11 @@ import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; import java.io.File; import java.io.IOException; -import java.time.Instant; -import java.util.UUID; import java.util.concurrent.ScheduledExecutorService; import javax.inject.Inject; import javax.inject.Named; import net.runelite.api.Client; import net.runelite.client.RuneLite; -import net.runelite.client.account.AccountSession; import net.runelite.client.eventbus.EventBus; import org.junit.Assert; import static org.junit.Assert.assertNotNull; @@ -89,9 +86,6 @@ public class ConfigManagerTest @Test public void testGetConfig() throws IOException { - AccountSession accountSession = new AccountSession(UUID.randomUUID(), Instant.now()); - accountSession.setUsername("test"); - manager.setConfiguration("test", "key", "moo"); TestConfig conf = manager.getConfig(TestConfig.class); @@ -101,9 +95,6 @@ public class ConfigManagerTest @Test public void testGetConfigDefault() throws IOException { - AccountSession accountSession = new AccountSession(UUID.randomUUID(), Instant.now()); - accountSession.setUsername("test"); - TestConfig conf = manager.getConfig(TestConfig.class); Assert.assertEquals("default", conf.key()); } @@ -111,9 +102,6 @@ public class ConfigManagerTest @Test public void testSetConfig() throws IOException { - AccountSession accountSession = new AccountSession(UUID.randomUUID(), Instant.now()); - accountSession.setUsername("test"); - TestConfig conf = manager.getConfig(TestConfig.class); conf.key("new value"); @@ -123,9 +111,6 @@ public class ConfigManagerTest @Test public void testGetConfigDescriptor() throws IOException { - AccountSession accountSession = new AccountSession(UUID.randomUUID(), Instant.now()); - accountSession.setUsername("test"); - TestConfig conf = manager.getConfig(TestConfig.class); ConfigDescriptor descriptor = manager.getConfigDescriptor(conf); Assert.assertEquals(2, descriptor.getItems().size()); From 70ca9a77063454d96f42eba35528f07cf334cd03 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 08:35:40 -0400 Subject: [PATCH 07/21] chat channel: use fc max size from container --- .../src/main/java/net/runelite/api/NameableContainer.java | 7 +++++++ .../client/plugins/chatchannel/ChatChannelPlugin.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/runelite-api/src/main/java/net/runelite/api/NameableContainer.java b/runelite-api/src/main/java/net/runelite/api/NameableContainer.java index a76bb78891..f67a53ca90 100644 --- a/runelite-api/src/main/java/net/runelite/api/NameableContainer.java +++ b/runelite-api/src/main/java/net/runelite/api/NameableContainer.java @@ -33,6 +33,13 @@ public interface NameableContainer */ int getCount(); + /** + * Get the maximum size of the container. + * + * @return + */ + int getSize(); + /** * Get the members in this container * diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java index 32dd1709d9..94aefa7402 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java @@ -608,7 +608,7 @@ public class ChatChannelPlugin extends Plugin Widget chatTitle = client.getWidget(WidgetInfo.FRIENDS_CHAT_TITLE); if (friendsChatManager != null && friendsChatManager.getCount() > 0 && chatTitle != null) { - chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)"); + chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/" + friendsChatManager.getSize() + ")"); } } else if (event.getScriptId() == ScriptID.CLAN_SIDEPANEL_DRAW) From f8c27b680bc2728ad159976606e030c202ba2afc Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 09:26:54 -0400 Subject: [PATCH 08/21] runelite: set jagex.disableBouncyCastle=true --- runelite-client/src/main/java/net/runelite/client/RuneLite.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index a9e5bde5e9..465739304f 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -304,6 +304,7 @@ public class RuneLite // Client size must be set prior to init applet.setSize(Constants.GAME_FIXED_SIZE); + System.setProperty("jagex.disableBouncyCastle", "true"); // Change user.home so the client places jagexcache in the .runelite directory String oldHome = System.setProperty("user.home", RUNELITE_DIR.getAbsolutePath()); try From 3ef90957718198742ac8d30b7bad1a30b67b88db Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 12:25:10 -0400 Subject: [PATCH 09/21] cannon: use varp for cannonball count Co-authored-by: Bonfire <5704760+Bonfire@users.noreply.github.com> --- .../main/java/net/runelite/api/VarPlayer.java | 1 + .../client/plugins/cannon/CannonPlugin.java | 131 ++---------------- .../plugins/cannon/CannonPluginTest.java | 125 +++++++++-------- 3 files changed, 79 insertions(+), 178 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java index ce6ff390f7..d0ae07ade7 100644 --- a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java +++ b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java @@ -39,6 +39,7 @@ import lombok.Getter; @Getter public enum VarPlayer { + CANNON_AMMO(3), ATTACK_STYLE(43), QUEST_POINTS(101), IS_POISONED(102), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java index 2c69cef83d..19f5712810 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java @@ -24,14 +24,10 @@ */ package net.runelite.client.plugins.cannon; -import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; import java.awt.Color; import java.util.ArrayList; import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.inject.Inject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -40,25 +36,22 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameObject; import net.runelite.api.GameState; -import net.runelite.api.GraphicID; import net.runelite.api.InventoryID; import net.runelite.api.Item; -import net.runelite.api.ItemContainer; import net.runelite.api.ItemID; import net.runelite.api.MenuAction; import net.runelite.api.ObjectID; import net.runelite.api.Player; -import net.runelite.api.Projectile; +import net.runelite.api.VarPlayer; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.ProjectileMoved; +import net.runelite.api.events.VarbitChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; @@ -80,17 +73,10 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager; @Slf4j public class CannonPlugin extends Plugin { - private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)"); static final int MAX_OVERLAY_DISTANCE = 4100; static final int MAX_CBALLS = 30; - private static final Set CANNONBALL_PROJECTILE_IDS = ImmutableSet.of( - GraphicID.CANNONBALL, GraphicID.GRANITE_CANNONBALL, - GraphicID.CANNONBALL_OR, GraphicID.GRANITE_CANNONBALL_OR - ); - private CannonCounter counter; - private boolean skipProjectileCheckThisTick; private boolean cannonBallNotificationSent; private WorldPoint clickedCannonLocation; private boolean firstCannonLoad; @@ -151,6 +137,7 @@ public class CannonPlugin extends Plugin { overlayManager.add(cannonOverlay); overlayManager.add(cannonSpotOverlay); + clientThread.invoke(() -> cballsLeft = client.getVar(VarPlayer.CANNON_AMMO)); } @Override @@ -165,7 +152,6 @@ public class CannonPlugin extends Plugin cannonBallNotificationSent = false; cballsLeft = 0; removeCounter(); - skipProjectileCheckThisTick = false; spotPoints.clear(); } @@ -278,7 +264,7 @@ public class CannonPlugin extends Plugin } } } - + @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { @@ -309,32 +295,16 @@ public class CannonPlugin extends Plugin } @Subscribe - public void onProjectileMoved(ProjectileMoved event) + public void onVarbitChanged(VarbitChanged varbitChanged) { - Projectile projectile = event.getProjectile(); - - if (CANNONBALL_PROJECTILE_IDS.contains(projectile.getId()) && cannonPosition != null && cannonWorld == client.getWorld()) + if (varbitChanged.getIndex() == VarPlayer.CANNON_AMMO.getId()) { - WorldPoint projectileLoc = WorldPoint.fromLocal(client, projectile.getX1(), projectile.getY1(), client.getPlane()); + cballsLeft = client.getVar(VarPlayer.CANNON_AMMO); - //Check to see if projectile x,y is 0 else it will continuously decrease while ball is flying. - if (cannonPosition.contains(projectileLoc) && projectile.getX() == 0 && projectile.getY() == 0) + if (config.showCannonNotifications() && !cannonBallNotificationSent && cballsLeft > 0 && config.lowWarningThreshold() >= cballsLeft) { - // When there's a chat message about cannon reloaded/unloaded/out of ammo, - // the message event runs before the projectile event. However they run - // in the opposite order on the server. So if both fires in the same tick, - // we don't want to update the cannonball counter if it was set to a specific - // amount. - if (!skipProjectileCheckThisTick) - { - cballsLeft--; - - if (config.showCannonNotifications() && !cannonBallNotificationSent && cballsLeft > 0 && config.lowWarningThreshold() >= cballsLeft) - { - notifier.notify(String.format("Your cannon has %d cannon balls remaining!", cballsLeft)); - cannonBallNotificationSent = true; - } - } + notifier.notify(String.format("Your cannon has %d cannon balls remaining!", cballsLeft)); + cannonBallNotificationSent = true; } } } @@ -351,32 +321,13 @@ public class CannonPlugin extends Plugin { cannonPlaced = true; addCounter(); - cballsLeft = 0; firstCannonLoad = true; - - final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY); - if (inventory != null) - { - int invCballs = inventory.count(ItemID.GRANITE_CANNONBALL) > 0 - ? inventory.count(ItemID.GRANITE_CANNONBALL) - : inventory.count(ItemID.CANNONBALL); - // Cannonballs are always forcibly loaded after the furnace is added. If the player has more than - // the max number of cannon balls in their inventory, the cannon will always be fully filled. - // This is preferable to using the proceeding "You load the cannon with x cannon balls" message - // since it will show a lower number of cannon balls if the cannon is already partially-filled - // prior to being placed. - if (invCballs >= MAX_CBALLS) - { - cballsLeft = MAX_CBALLS; - } - } } else if (event.getMessage().contains("You pick up the cannon") || event.getMessage().contains("Your cannon has decayed. Speak to Nulodion to get a new one!") || event.getMessage().contains("Your cannon has been destroyed!")) { cannonPlaced = false; - cballsLeft = 0; removeCounter(); cannonPosition = null; } @@ -410,83 +361,21 @@ public class CannonPlugin extends Plugin clickedCannonLocation = null; } - Matcher m = NUMBER_PATTERN.matcher(event.getMessage()); - if (m.find()) - { - // The cannon will usually refill to MAX_CBALLS, but if the - // player didn't have enough cannonballs in their inventory, - // it could fill up less than that. Filling the cannon to - // cballsLeft + amt is not always accurate though because our - // counter doesn't decrease if the player has been too far away - // from the cannon due to the projectiels not being in memory, - // so our counter can be higher than it is supposed to be. - int amt = Integer.valueOf(m.group()); - if (cballsLeft + amt >= MAX_CBALLS) - { - skipProjectileCheckThisTick = true; - cballsLeft = MAX_CBALLS; - } - else - { - cballsLeft += amt; - } - } - else if (event.getMessage().equals("You load the cannon with one cannonball.")) - { - if (cballsLeft + 1 >= MAX_CBALLS) - { - skipProjectileCheckThisTick = true; - cballsLeft = MAX_CBALLS; - } - else - { - cballsLeft++; - } - } - cannonBallNotificationSent = false; } else if (event.getMessage().contains("Your cannon is out of ammo!")) { - skipProjectileCheckThisTick = true; - - // If the player was out of range of the cannon, some cannonballs - // may have been used without the client knowing, so having this - // extra check is a good idea. - cballsLeft = 0; - if (config.showCannonNotifications()) { notifier.notify("Your cannon is out of ammo!"); } } - else if (event.getMessage().startsWith("Your cannon contains")) - { - Matcher m = NUMBER_PATTERN.matcher(event.getMessage()); - if (m.find()) - { - cballsLeft = Integer.parseInt(m.group()); - } - } - else if (event.getMessage().startsWith("You unload your cannon and receive Cannonball") - || event.getMessage().startsWith("You unload your cannon and receive Granite cannonball")) - { - skipProjectileCheckThisTick = true; - - cballsLeft = 0; - } else if (event.getMessage().equals("This isn't your cannon!") || event.getMessage().equals("This is not your cannon.")) { clickedCannonLocation = null; } } - @Subscribe - public void onGameTick(GameTick event) - { - skipProjectileCheckThisTick = false; - } - Color getStateColor() { if (cballsLeft > 15) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java index 12bc19ead8..a1f602c26d 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java @@ -31,10 +31,9 @@ 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.InventoryID; -import net.runelite.api.ItemContainer; -import net.runelite.api.ItemID; +import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.VarbitChanged; import net.runelite.client.Notifier; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.OverlayManager; @@ -45,8 +44,11 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import static org.mockito.ArgumentMatchers.any; import org.mockito.Mock; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -89,13 +91,12 @@ public class CannonPluginTest @Bind private OverlayManager overlayManager; - private static final ChatMessage ADD_FURNACE = new ChatMessage(); + private static final VarbitChanged cannonAmmoChanged = new VarbitChanged(); @BeforeClass - public static void chatMessageSetup() + public static void cannonVarpSetup() { - ADD_FURNACE.setType(ChatMessageType.SPAM); - ADD_FURNACE.setMessage("You add the furnace."); + cannonAmmoChanged.setIndex(VarPlayer.CANNON_AMMO.getId()); } @Before @@ -105,82 +106,92 @@ public class CannonPluginTest } @Test - public void addWrongTypeOfCannonballs() + public void testAmmoCountOnPlace() { - final ChatMessage message = new ChatMessage(); - message.setType(ChatMessageType.GAMEMESSAGE); - message.setMessage("Your cannon contains 20 x Cannonball.
You can only add cannonballs of the same kind."); + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.SPAM); + chatMessage.setMessage("You add the furnace."); - plugin.onChatMessage(message); - - assertEquals(20, plugin.getCballsLeft()); - } - - @Test - public void addMaxCannonballs() - { - final ItemContainer inventory = mock(ItemContainer.class); - when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory); - when(inventory.count(ItemID.CANNONBALL)).thenReturn(100); - when(inventory.count(ItemID.GRANITE_CANNONBALL)).thenReturn(0); - - plugin.onChatMessage(ADD_FURNACE); + plugin.onChatMessage(chatMessage); assertTrue(plugin.isCannonPlaced()); - assertEquals(30, plugin.getCballsLeft()); + plugin.onVarbitChanged(cannonAmmoChanged); + assertEquals(0, plugin.getCballsLeft()); - plugin.onChatMessage(loadCannonballs(30)); + // Some time passes... + + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(30); + plugin.onVarbitChanged(cannonAmmoChanged); assertEquals(30, plugin.getCballsLeft()); } @Test - public void addNotMaxCannonballs() + public void testCannonInfoBox() { - final ItemContainer inventory = mock(ItemContainer.class); - when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory); - when(inventory.count(ItemID.GRANITE_CANNONBALL)).thenReturn(12); + when(config.showInfobox()).thenReturn(true); - plugin.onChatMessage(ADD_FURNACE); + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.SPAM); + chatMessage.setMessage("You add the furnace."); + + plugin.onChatMessage(chatMessage); assertTrue(plugin.isCannonPlaced()); assertEquals(0, plugin.getCballsLeft()); - - plugin.onChatMessage(loadCannonballs(12)); - assertEquals(12, plugin.getCballsLeft()); + verify(infoBoxManager).addInfoBox(any(CannonCounter.class)); } @Test - public void addReclaimedCannonballs() + public void testThresholdNotificationShouldNotify() { - final ItemContainer inventory = mock(ItemContainer.class); - when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory); - when(inventory.count(ItemID.CANNONBALL)).thenReturn(1250); + when(config.showCannonNotifications()).thenReturn(true); + when(config.lowWarningThreshold()).thenReturn(10); - plugin.onChatMessage(ADD_FURNACE); - assertTrue(plugin.isCannonPlaced()); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(30); + plugin.onVarbitChanged(cannonAmmoChanged); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(10); + plugin.onVarbitChanged(cannonAmmoChanged); - assertEquals(30, plugin.getCballsLeft()); - - plugin.onChatMessage(loadCannonballs(18)); - assertEquals(30, plugin.getCballsLeft()); + verify(notifier, times(1)).notify("Your cannon has 10 cannon balls remaining!"); } - private static ChatMessage loadCannonballs(final int numCannonballs) + @Test + public void testThresholdNotificationShouldNotifyOnce() { - final ChatMessage message = new ChatMessage(); - message.setType(ChatMessageType.GAMEMESSAGE); + when(config.showCannonNotifications()).thenReturn(true); + when(config.lowWarningThreshold()).thenReturn(10); - // Cannons use the same chat message for loading cannonballs regardless of whether they're normal or granite. - if (numCannonballs == 1) + for (int cballs = 15; cballs >= 8; --cballs) { - message.setMessage("You load the cannon with one cannonball."); - } - else - { - message.setMessage(String.format("You load the cannon with %s cannonballs.", numCannonballs)); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(cballs); + plugin.onVarbitChanged(cannonAmmoChanged); } - return message; + verify(notifier, times(1)).notify("Your cannon has 10 cannon balls remaining!"); } + @Test + public void testThresholdNotificationsShouldNotNotify() + { + when(config.showCannonNotifications()).thenReturn(true); + when(config.lowWarningThreshold()).thenReturn(0); + + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(30); + plugin.onVarbitChanged(cannonAmmoChanged); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(10); + plugin.onVarbitChanged(cannonAmmoChanged); + + verify(notifier, never()).notify("Your cannon has 10 cannon balls remaining!"); + } + + @Test + public void testCannonOutOfAmmo() + { + when(config.showCannonNotifications()).thenReturn(true); + ChatMessage cannonOutOfAmmo = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "Your cannon is out of ammo!", "", 0); + + plugin.onChatMessage(cannonOutOfAmmo); + + verify(notifier, times(1)).notify("Your cannon is out of ammo!"); + } } From 82c93f45da679ad08b2828e157cbb7c2fb539c5c Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 13:53:59 -0400 Subject: [PATCH 10/21] Move party messages from http-api --- checkstyle.xml | 3 + runelite-client/pom.xml | 5 +- .../client/{ws => party}/PartyMember.java | 2 +- .../client/{ws => party}/PartyService.java | 14 +- .../client/{ws => party}/WSClient.java | 9 +- .../client/party/WebsocketGsonFactory.java | 88 +++++++ .../client/party/messages/Handshake.java | 34 +++ .../runelite/client/party/messages/Join.java | 37 +++ .../runelite/client/party/messages/Part.java | 29 +++ .../party/messages/PartyChatMessage.java | 33 +++ .../party/messages/PartyMemberMessage.java | 12 + .../client/party/messages/PartyMessage.java | 33 +++ .../client/party/messages/UserJoin.java | 38 +++ .../client/party/messages/UserPart.java | 36 +++ .../client/party/messages/UserSync.java | 34 +++ .../party/messages/WebsocketMessage.java | 35 +++ .../client/plugins/discord/DiscordPlugin.java | 8 +- .../plugins/discord/DiscordUserInfo.java | 2 +- .../plugins/dpscounter/DpsCounterPlugin.java | 6 +- .../client/plugins/dpscounter/DpsOverlay.java | 2 +- .../client/plugins/dpscounter/DpsUpdate.java | 2 +- .../client/plugins/party/PartyMemberBox.java | 2 +- .../client/plugins/party/PartyPanel.java | 2 +- .../client/plugins/party/PartyPlugin.java | 12 +- .../plugins/party/PartyWorldMapPoint.java | 2 +- .../client/plugins/party/data/PartyData.java | 2 +- .../party/messages/CharacterNameUpdate.java | 2 +- .../party/messages/LocationUpdate.java | 2 +- .../plugins/party/messages/SkillUpdate.java | 2 +- .../plugins/party/messages/TilePing.java | 2 +- .../client/plugins/raids/RaidsPlugin.java | 8 +- .../specialcounter/SpecialCounterPlugin.java | 4 +- .../specialcounter/SpecialCounterUpdate.java | 2 +- .../util/RuntimeTypeAdapterFactory.java | 239 ++++++++++++++++++ .../plugins/discord/DiscordStateTest.java | 2 +- .../client/plugins/raids/RaidsPluginTest.java | 4 +- .../SpecialCounterPluginTest.java | 4 +- suppressions.xml | 31 +++ 38 files changed, 734 insertions(+), 50 deletions(-) rename runelite-client/src/main/java/net/runelite/client/{ws => party}/PartyMember.java (97%) rename runelite-client/src/main/java/net/runelite/client/{ws => party}/PartyService.java (96%) rename runelite-client/src/main/java/net/runelite/client/{ws => party}/WSClient.java (95%) create mode 100644 runelite-client/src/main/java/net/runelite/client/party/WebsocketGsonFactory.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/Handshake.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/Join.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/Part.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/PartyChatMessage.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/PartyMemberMessage.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/PartyMessage.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/UserJoin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/UserPart.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/UserSync.java create mode 100644 runelite-client/src/main/java/net/runelite/client/party/messages/WebsocketMessage.java create mode 100644 runelite-client/src/main/java/net/runelite/client/util/RuntimeTypeAdapterFactory.java create mode 100644 suppressions.xml diff --git a/checkstyle.xml b/checkstyle.xml index 2e9c6131cb..5c8832b782 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -56,4 +56,7 @@ + + + diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 3ba6bc32e6..16052c8db0 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -261,7 +261,7 @@ net.runelite.arn http-api - 1.0.0 + 1.0.6 net.runelite @@ -486,6 +486,9 @@ false true + + **/RuntimeTypeAdapterFactory.java + diff --git a/runelite-client/src/main/java/net/runelite/client/ws/PartyMember.java b/runelite-client/src/main/java/net/runelite/client/party/PartyMember.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/ws/PartyMember.java rename to runelite-client/src/main/java/net/runelite/client/party/PartyMember.java index cdc6ac1033..70789f58f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/PartyMember.java +++ b/runelite-client/src/main/java/net/runelite/client/party/PartyMember.java @@ -22,7 +22,7 @@ * (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.ws; +package net.runelite.client.party; import java.awt.image.BufferedImage; import java.util.UUID; diff --git a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java similarity index 96% rename from runelite-client/src/main/java/net/runelite/client/ws/PartyService.java rename to runelite-client/src/main/java/net/runelite/client/party/PartyService.java index 123a172a0b..2a1e1caeff 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java +++ b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java @@ -23,7 +23,7 @@ * (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.ws; +package net.runelite.client.party; import com.google.common.base.CharMatcher; import com.google.common.hash.Hashing; @@ -52,14 +52,14 @@ import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; +import net.runelite.client.party.messages.Join; +import net.runelite.client.party.messages.Part; +import net.runelite.client.party.messages.PartyChatMessage; +import net.runelite.client.party.messages.UserJoin; +import net.runelite.client.party.messages.UserPart; +import net.runelite.client.party.messages.UserSync; import net.runelite.client.util.Text; import static net.runelite.client.util.Text.JAGEX_PRINTABLE_CHAR_MATCHER; -import net.runelite.http.api.ws.messages.party.Join; -import net.runelite.http.api.ws.messages.party.Part; -import net.runelite.http.api.ws.messages.party.PartyChatMessage; -import net.runelite.http.api.ws.messages.party.UserJoin; -import net.runelite.http.api.ws.messages.party.UserPart; -import net.runelite.http.api.ws.messages.party.UserSync; @Slf4j @Singleton diff --git a/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java b/runelite-client/src/main/java/net/runelite/client/party/WSClient.java similarity index 95% rename from runelite-client/src/main/java/net/runelite/client/ws/WSClient.java rename to runelite-client/src/main/java/net/runelite/client/party/WSClient.java index ea42605075..55c67fc3e3 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java +++ b/runelite-client/src/main/java/net/runelite/client/party/WSClient.java @@ -22,7 +22,7 @@ * (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.ws; +package net.runelite.client.party; import com.google.gson.Gson; import com.google.gson.JsonParseException; @@ -37,10 +37,9 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.client.RuneLite; import net.runelite.client.eventbus.EventBus; -import net.runelite.http.api.ws.WebsocketGsonFactory; -import net.runelite.http.api.ws.WebsocketMessage; -import net.runelite.http.api.ws.messages.Handshake; -import net.runelite.http.api.ws.messages.party.PartyMessage; +import net.runelite.client.party.messages.Handshake; +import net.runelite.client.party.messages.PartyMessage; +import net.runelite.client.party.messages.WebsocketMessage; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Request; diff --git a/runelite-client/src/main/java/net/runelite/client/party/WebsocketGsonFactory.java b/runelite-client/src/main/java/net/runelite/client/party/WebsocketGsonFactory.java new file mode 100644 index 0000000000..f88330636c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/WebsocketGsonFactory.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017, Adam + * 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.party; + +import com.google.gson.Gson; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import net.runelite.client.party.messages.Handshake; +import net.runelite.client.party.messages.Join; +import net.runelite.client.party.messages.Part; +import net.runelite.client.party.messages.PartyChatMessage; +import net.runelite.client.party.messages.UserJoin; +import net.runelite.client.party.messages.UserPart; +import net.runelite.client.party.messages.UserSync; +import net.runelite.client.party.messages.WebsocketMessage; +import net.runelite.client.util.RuntimeTypeAdapterFactory; +import net.runelite.http.api.RuneLiteAPI; + +public class WebsocketGsonFactory +{ + private static final Collection> MESSAGES; + + static + { + final List> messages = new ArrayList<>(); + messages.add(Handshake.class); + messages.add(Join.class); + messages.add(Part.class); + messages.add(UserJoin.class); + messages.add(UserPart.class); + messages.add(UserSync.class); + messages.add(PartyChatMessage.class); + MESSAGES = messages; + } + + public static RuntimeTypeAdapterFactory factory(final Collection> messages) + { + final RuntimeTypeAdapterFactory factory = RuntimeTypeAdapterFactory.of(WebsocketMessage.class); + + for (Class message : MESSAGES) + { + factory.registerSubtype(message); + } + + for (Class message : messages) + { + factory.registerSubtype(message); + } + + return factory; + } + + public static Gson build(final RuntimeTypeAdapterFactory factory) + { + return RuneLiteAPI.GSON.newBuilder() + .registerTypeAdapterFactory(factory) + .create(); + } + + public static Gson build() + { + return build(factory(Collections.emptyList())); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/Handshake.java b/runelite-client/src/main/java/net/runelite/client/party/messages/Handshake.java new file mode 100644 index 0000000000..ac9f9b9d3c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/Handshake.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017, Adam + * 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.party.messages; + +import java.util.UUID; +import lombok.Data; + +@Data +public class Handshake extends WebsocketMessage +{ + private UUID session; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/Join.java b/runelite-client/src/main/java/net/runelite/client/party/messages/Join.java new file mode 100644 index 0000000000..c63fa3ffae --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/Join.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class Join extends WebsocketMessage +{ + private final UUID partyId; + private final String name; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/Part.java b/runelite-client/src/main/java/net/runelite/client/party/messages/Part.java new file mode 100644 index 0000000000..53f903b160 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/Part.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +public class Part extends WebsocketMessage +{ +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/PartyChatMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyChatMessage.java new file mode 100644 index 0000000000..32156a9142 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyChatMessage.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Tomas Slusny + * 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.party.messages; + +import lombok.Value; + +@Value +public class PartyChatMessage extends PartyMemberMessage +{ + private final String value; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMemberMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMemberMessage.java new file mode 100644 index 0000000000..d706360484 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMemberMessage.java @@ -0,0 +1,12 @@ +package net.runelite.client.party.messages; + +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public abstract class PartyMemberMessage extends PartyMessage +{ + private UUID memberId; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMessage.java new file mode 100644 index 0000000000..58b2327fb4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMessage.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +public abstract class PartyMessage extends WebsocketMessage +{ + public PartyMessage() + { + _party = true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/UserJoin.java b/runelite-client/src/main/java/net/runelite/client/party/messages/UserJoin.java new file mode 100644 index 0000000000..2254f93fae --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/UserJoin.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class UserJoin extends WebsocketMessage +{ + private final UUID memberId; + private final UUID partyId; + private final String name; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/UserPart.java b/runelite-client/src/main/java/net/runelite/client/party/messages/UserPart.java new file mode 100644 index 0000000000..2407db13d4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/UserPart.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class UserPart extends WebsocketMessage +{ + private final UUID memberId; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/UserSync.java b/runelite-client/src/main/java/net/runelite/client/party/messages/UserSync.java new file mode 100644 index 0000000000..6d06655e95 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/UserSync.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class UserSync extends PartyMemberMessage +{ +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/WebsocketMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/WebsocketMessage.java new file mode 100644 index 0000000000..1685b58108 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/WebsocketMessage.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, Adam + * 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.party.messages; + +public class WebsocketMessage +{ + protected boolean _party; + + public boolean isParty() + { + return _party; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java index 58cf1cad70..b83c61fd46 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java @@ -51,6 +51,10 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; +import net.runelite.client.party.messages.UserSync; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.task.Schedule; @@ -58,11 +62,7 @@ import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; import net.runelite.discord.DiscordUser; -import net.runelite.http.api.ws.messages.party.UserSync; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java index 1f96e67051..0d0c5b6e52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java @@ -26,7 +26,7 @@ package net.runelite.client.plugins.discord; import lombok.EqualsAndHashCode; import lombok.Value; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java index ecd962ce85..b8636fd2b5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java @@ -47,9 +47,9 @@ import net.runelite.client.events.PartyChanged; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; @PluginDescriptor( name = "DPS Counter", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java index ead4ded77e..538a154495 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java @@ -42,7 +42,7 @@ import net.runelite.client.ui.overlay.components.TitleComponent; import net.runelite.client.ui.overlay.tooltip.Tooltip; import net.runelite.client.ui.overlay.tooltip.TooltipManager; import net.runelite.client.util.QuantityFormatter; -import net.runelite.client.ws.PartyService; +import net.runelite.client.party.PartyService; class DpsOverlay extends OverlayPanel { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java index ee1b652c34..ba37b04a44 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.dpscounter; import lombok.EqualsAndHashCode; import lombok.Value; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java index 832989f5a5..53c6c8aab2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java @@ -45,7 +45,7 @@ import net.runelite.client.ui.FontManager; import net.runelite.client.ui.components.MouseDragEventForwarder; import net.runelite.client.ui.components.ProgressBar; import net.runelite.client.util.ImageUtil; -import net.runelite.client.ws.PartyMember; +import net.runelite.client.party.PartyMember; class PartyMemberBox extends JPanel { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java index 2affaf1214..32bbab4ebc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java @@ -47,7 +47,7 @@ import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.DragAndDropReorderPane; import net.runelite.client.ui.components.PluginErrorPanel; -import net.runelite.client.ws.PartyService; +import net.runelite.client.party.PartyService; class PartyPanel extends PluginPanel { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index 927f575b9d..1a6226f6ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -66,6 +66,12 @@ import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; +import net.runelite.client.party.messages.UserJoin; +import net.runelite.client.party.messages.UserPart; +import net.runelite.client.party.messages.UserSync; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.party.data.PartyData; @@ -83,12 +89,6 @@ import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; -import net.runelite.http.api.ws.messages.party.UserJoin; -import net.runelite.http.api.ws.messages.party.UserPart; -import net.runelite.http.api.ws.messages.party.UserSync; @PluginDescriptor( name = "Party", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java index e85e32430c..6ee6360e57 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java @@ -30,7 +30,7 @@ import net.runelite.api.Point; import net.runelite.api.coords.WorldPoint; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; import net.runelite.client.util.ImageUtil; -import net.runelite.client.ws.PartyMember; +import net.runelite.client.party.PartyMember; class PartyWorldMapPoint extends WorldMapPoint { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java index b821420a68..ee6279ce8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java @@ -31,7 +31,7 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; -import net.runelite.client.ws.PartyMember; +import net.runelite.client.party.PartyMember; @Setter @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java index aff6c058c9..576f86aca6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java @@ -25,7 +25,7 @@ package net.runelite.client.plugins.party.messages; import lombok.Data; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Data public class CharacterNameUpdate extends PartyMemberMessage diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java index f5bf7131ce..8762b8d726 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.party.messages; import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.api.coords.WorldPoint; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java index 10f5810b0f..7d9ceb8c64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.party.messages; import lombok.AllArgsConstructor; import lombok.Getter; import net.runelite.api.Skill; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @AllArgsConstructor @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java index fb4f812a81..487175a0e6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.party.messages; import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.api.coords.WorldPoint; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 382828dfcb..575e807097 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -82,6 +82,10 @@ import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.game.SpriteManager; import net.runelite.client.input.KeyManager; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; +import net.runelite.client.party.messages.PartyChatMessage; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.raids.events.RaidReset; @@ -94,11 +98,7 @@ import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.ImageCapture; import net.runelite.client.util.Text; import static net.runelite.client.util.Text.sanitize; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; import net.runelite.http.api.chat.LayoutRoom; -import net.runelite.http.api.ws.messages.party.PartyChatMessage; @PluginDescriptor( name = "Chambers Of Xeric", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index 9391d82ee6..4d757f9775 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -67,8 +67,8 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.ImageUtil; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; @PluginDescriptor( name = "Special Attack Counter", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java index 2c7bcbe21b..d9416ecdf7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java @@ -26,7 +26,7 @@ package net.runelite.client.plugins.specialcounter; import lombok.EqualsAndHashCode; import lombok.Value; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/util/RuntimeTypeAdapterFactory.java b/runelite-client/src/main/java/net/runelite/client/util/RuntimeTypeAdapterFactory.java new file mode 100644 index 0000000000..640b9f2668 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/RuntimeTypeAdapterFactory.java @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.runelite.client.util; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.internal.Streams; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Adapts values whose runtime type may differ from their declaration type. This + * is necessary when a field's type is not the same type that GSON should create + * when deserializing that field. For example, consider these types: + *

   {@code
+ *   abstract class Shape {
+ *     int x;
+ *     int y;
+ *   }
+ *   class Circle extends Shape {
+ *     int radius;
+ *   }
+ *   class Rectangle extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Diamond extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Drawing {
+ *     Shape bottomShape;
+ *     Shape topShape;
+ *   }
+ * }
+ *

Without additional type information, the serialized JSON is ambiguous. Is + * the bottom shape in this drawing a rectangle or a diamond?

   {@code
+ *   {
+ *     "bottomShape": {
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * This class addresses this problem by adding type information to the + * serialized JSON and honoring that type information when the JSON is + * deserialized:
   {@code
+ *   {
+ *     "bottomShape": {
+ *       "type": "Diamond",
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "type": "Circle",
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * Both the type field name ({@code "type"}) and the type labels ({@code + * "Rectangle"}) are configurable. + * + *

Registering Types

+ * Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field + * name to the {@link #of} factory method. If you don't supply an explicit type + * field name, {@code "type"} will be used.
   {@code
+ *   RuntimeTypeAdapterFactory shapeAdapterFactory
+ *       = RuntimeTypeAdapterFactory.of(Shape.class, "type");
+ * }
+ * Next register all of your subtypes. Every subtype must be explicitly + * registered. This protects your application from injection attacks. If you + * don't supply an explicit type label, the type's simple name will be used. + *
   {@code
+ *   shapeAdapter.registerSubtype(Rectangle.class, "Rectangle");
+ *   shapeAdapter.registerSubtype(Circle.class, "Circle");
+ *   shapeAdapter.registerSubtype(Diamond.class, "Diamond");
+ * }
+ * Finally, register the type adapter factory in your application's GSON builder: + *
   {@code
+ *   Gson gson = new GsonBuilder()
+ *       .registerTypeAdapterFactory(shapeAdapterFactory)
+ *       .create();
+ * }
+ * Like {@code GsonBuilder}, this API supports chaining:
   {@code
+ *   RuntimeTypeAdapterFactory shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
+ *       .registerSubtype(Rectangle.class)
+ *       .registerSubtype(Circle.class)
+ *       .registerSubtype(Diamond.class);
+ * }
+ */ +public final class RuntimeTypeAdapterFactory implements TypeAdapterFactory { + private final Class baseType; + private final String typeFieldName; + private final Map> labelToSubtype = new LinkedHashMap>(); + private final Map, String> subtypeToLabel = new LinkedHashMap, String>(); + + private RuntimeTypeAdapterFactory(Class baseType, String typeFieldName) { + if (typeFieldName == null || baseType == null) { + throw new NullPointerException(); + } + this.baseType = baseType; + this.typeFieldName = typeFieldName; + } + + /** + * Creates a new runtime type adapter using for {@code baseType} using {@code + * typeFieldName} as the type field name. Type field names are case sensitive. + */ + public static RuntimeTypeAdapterFactory of(Class baseType, String typeFieldName) { + return new RuntimeTypeAdapterFactory(baseType, typeFieldName); + } + + /** + * Creates a new runtime type adapter for {@code baseType} using {@code "type"} as + * the type field name. + */ + public static RuntimeTypeAdapterFactory of(Class baseType) { + return new RuntimeTypeAdapterFactory(baseType, "type"); + } + + /** + * Registers {@code type} identified by {@code label}. Labels are case + * sensitive. + * + * @throws IllegalArgumentException if either {@code type} or {@code label} + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type, String label) { + if (type == null || label == null) { + throw new NullPointerException(); + } + if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) { + throw new IllegalArgumentException("types and labels must be unique"); + } + labelToSubtype.put(label, type); + subtypeToLabel.put(type, label); + return this; + } + + /** + * Registers {@code type} identified by its {@link Class#getSimpleName simple + * name}. Labels are case sensitive. + * + * @throws IllegalArgumentException if either {@code type} or its simple name + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type) { + return registerSubtype(type, type.getSimpleName()); + } + + public TypeAdapter create(Gson gson, TypeToken type) { + if (type.getRawType() != baseType) { + return null; + } + + final Map> labelToDelegate + = new LinkedHashMap>(); + final Map, TypeAdapter> subtypeToDelegate + = new LinkedHashMap, TypeAdapter>(); + for (Map.Entry> entry : labelToSubtype.entrySet()) { + TypeAdapter delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue())); + labelToDelegate.put(entry.getKey(), delegate); + subtypeToDelegate.put(entry.getValue(), delegate); + } + + return new TypeAdapter() { + @Override public R read(JsonReader in) throws IOException { + JsonElement jsonElement = Streams.parse(in); + JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName); + if (labelJsonElement == null) { + throw new JsonParseException("cannot deserialize " + baseType + + " because it does not define a field named " + typeFieldName); + } + String label = labelJsonElement.getAsString(); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) labelToDelegate.get(label); + if (delegate == null) { + throw new JsonParseException("cannot deserialize " + baseType + " subtype named " + + label + "; did you forget to register a subtype?"); + } + return delegate.fromJsonTree(jsonElement); + } + + @Override public void write(JsonWriter out, R value) throws IOException { + Class srcType = value.getClass(); + String label = subtypeToLabel.get(srcType); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) subtypeToDelegate.get(srcType); + if (delegate == null) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + "; did you forget to register a subtype?"); + } + JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject(); + if (jsonObject.has(typeFieldName)) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + " because it already defines a field named " + typeFieldName); + } + JsonObject clone = new JsonObject(); + clone.add(typeFieldName, new JsonPrimitive(label)); + for (Map.Entry e : jsonObject.entrySet()) { + clone.add(e.getKey(), e.getValue()); + } + Streams.write(clone, out); + } + }.nullSafe(); + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java index 5213e5e174..0f15ffec4f 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java @@ -32,7 +32,7 @@ import javax.inject.Named; import net.runelite.api.Client; import net.runelite.client.discord.DiscordPresence; import net.runelite.client.discord.DiscordService; -import net.runelite.client.ws.PartyService; +import net.runelite.client.party.PartyService; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java index ff8ecbc5a6..ef8ceae5c8 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java @@ -37,8 +37,8 @@ import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.ImageCapture; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Before; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java index 4846efdd9a..da98d11a5e 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java @@ -49,8 +49,8 @@ import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.AsyncBufferedImage; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/suppressions.xml b/suppressions.xml new file mode 100644 index 0000000000..efac9fd008 --- /dev/null +++ b/suppressions.xml @@ -0,0 +1,31 @@ + + + + + + From ceb1c9613426a803c2ad0da8ab8b01bd8dc66c5d Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Fri, 10 Jun 2022 15:01:39 -0700 Subject: [PATCH 11/21] timers: Don't clear stamina on death As of 8aaaa320d308fa751a7acad6cf21a07b910c19ed, a player's stamina timer is determined from their vars thus does not need to be automatically cleared on death. --- .../main/java/net/runelite/client/plugins/timers/GameTimer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index 6278889dde..fcb177b448 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -40,7 +40,7 @@ import static net.runelite.client.util.RSTimeUnit.GAME_TICKS; @Getter(AccessLevel.PACKAGE) enum GameTimer { - STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", true), + STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", false), ANTIFIRE(ItemID.ANTIFIRE_POTION4, GameTimerImageType.ITEM, "Antifire", 6, ChronoUnit.MINUTES), EXANTIFIRE(ItemID.EXTENDED_ANTIFIRE4, GameTimerImageType.ITEM, "Extended antifire", 12, ChronoUnit.MINUTES), OVERLOAD(ItemID.OVERLOAD_4, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true), From 05567739b95eae36ba26219f85220865a9a8e7f2 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 15:47:45 -0400 Subject: [PATCH 12/21] spec counter: add config option for infoboxes --- .../plugins/specialcounter/SpecialCounterConfig.java | 11 +++++++++++ .../plugins/specialcounter/SpecialCounterPlugin.java | 10 ++++++++-- .../specialcounter/SpecialCounterPluginTest.java | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java index 4249fa3be8..9773544618 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java @@ -66,6 +66,17 @@ public interface SpecialCounterConfig extends Config return Color.WHITE; } + @ConfigItem( + position = 3, + keyName = "infobox", + name = "Infobox", + description = "Adds an infobox counting special attacks" + ) + default boolean infobox() + { + return true; + } + @ConfigItem( position = 10, keyName = "dragonWarhammerThreshold", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index 4d757f9775..fccb15e6ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -293,7 +293,10 @@ public class SpecialCounterPlugin extends Plugin int hit = getHit(specialWeapon, hitsplat); int localPlayerId = client.getLocalPlayer().getId(); - updateCounter(specialWeapon, null, hit); + if (config.infobox()) + { + updateCounter(specialWeapon, null, hit); + } if (!party.getMembers().isEmpty()) { @@ -359,7 +362,10 @@ public class SpecialCounterPlugin extends Plugin // Otherwise we only add the count if it is against a npc we are already tracking if (interactedNpcIds.contains(event.getNpcId())) { - updateCounter(event.getWeapon(), name, event.getHit()); + if (config.infobox()) + { + updateCounter(event.getWeapon(), name, event.getHit()); + } } if (event.getWorld() == client.getWorld()) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java index da98d11a5e..55bfdc6237 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java @@ -115,6 +115,8 @@ public class SpecialCounterPluginTest { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + when(specialCounterConfig.infobox()).thenReturn(true); + // Set up spec weapon ItemContainer equipment = mock(ItemContainer.class); when(equipment.getItem(EquipmentInventorySlot.WEAPON.getSlotIdx())).thenReturn(new Item(ItemID.BANDOS_GODSWORD, 1)); From 169ec74a018420d024c91126f5c830b661dbd78a Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 16:03:55 -0400 Subject: [PATCH 13/21] party: no longer use account session id This is no longer required because the oauth responses don't come back via websocket anymore --- .../runelite/client/party/PartyService.java | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/party/PartyService.java b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java index 2a1e1caeff..3fd143bede 100644 --- a/runelite-client/src/main/java/net/runelite/client/party/PartyService.java +++ b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java @@ -44,8 +44,6 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.ItemComposition; -import net.runelite.client.account.AccountSession; -import net.runelite.client.account.SessionManager; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.eventbus.EventBus; @@ -72,7 +70,6 @@ public class PartyService private final Client client; private final WSClient wsClient; - private final SessionManager sessionManager; private final EventBus eventBus; private final ChatMessageManager chat; private final List members = new ArrayList<>(); @@ -83,11 +80,10 @@ public class PartyService private String partyPassphrase; @Inject - private PartyService(final Client client, final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus, final ChatMessageManager chat) + private PartyService(final Client client, final WSClient wsClient, final EventBus eventBus, final ChatMessageManager chat) { this.client = client; this.wsClient = wsClient; - this.sessionManager = sessionManager; this.eventBus = eventBus; this.chat = chat; eventBus.register(this); @@ -169,12 +165,7 @@ public class PartyService if (partyId == null) { - // close the websocket if the session id isn't for an account - if (sessionManager.getAccountSession() == null) - { - wsClient.changeSession(null); - } - + wsClient.changeSession(null); eventBus.post(new PartyChanged(partyPassphrase, partyId)); return; } @@ -182,10 +173,7 @@ public class PartyService // If there isn't already a session open, open one if (!wsClient.sessionExists()) { - AccountSession accountSession = sessionManager.getAccountSession(); - // Use the existing account session, if it exists, otherwise generate a new session id - UUID uuid = accountSession != null ? accountSession.getUuid() : UUID.randomUUID(); - wsClient.changeSession(uuid); + wsClient.changeSession(UUID.randomUUID()); } eventBus.post(new PartyChanged(partyPassphrase, partyId)); From d4a3fe0069f7dc6236a1f12778e4e9f5eb66ea3d Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 17:44:13 -0400 Subject: [PATCH 14/21] party: send join on reconnect If the server expires the membership before the client in the party reconnects, it will falsely assume it is in a party when it isn't. Additionally since users are resynced on reconnect, this was duplicating members as it would get joins for already joined members. --- .../runelite/client/party/PartyService.java | 34 ++++++++++++++++--- .../net/runelite/client/party/WSClient.java | 7 +++- .../client/plugins/discord/DiscordPlugin.java | 2 +- .../plugins/dpscounter/DpsCounterPlugin.java | 2 +- .../client/plugins/party/PartyPlugin.java | 15 ++++---- .../client/plugins/raids/RaidsPlugin.java | 6 +--- .../specialcounter/SpecialCounterPlugin.java | 2 +- .../client/plugins/raids/RaidsPluginTest.java | 7 +--- 8 files changed, 46 insertions(+), 29 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/party/PartyService.java b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java index 3fd143bede..ebd9371d0f 100644 --- a/runelite-client/src/main/java/net/runelite/client/party/PartyService.java +++ b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java @@ -53,6 +53,7 @@ import net.runelite.client.events.PartyMemberAvatar; import net.runelite.client.party.messages.Join; import net.runelite.client.party.messages.Part; import net.runelite.client.party.messages.PartyChatMessage; +import net.runelite.client.party.messages.PartyMessage; import net.runelite.client.party.messages.UserJoin; import net.runelite.client.party.messages.UserPart; import net.runelite.client.party.messages.UserSync; @@ -180,6 +181,22 @@ public class PartyService wsClient.send(new Join(partyId, USERNAME)); } + public void send(T message) + { + if (!wsClient.isOpen()) + { + log.debug("Reconnecting to server"); + + PartyMember local = getLocalMember(); + members.removeIf(m -> m != local); + + wsClient.connect(); + wsClient.send(new Join(partyId, USERNAME)); + } + + wsClient.send(message); + } + @Subscribe(priority = 1) // run prior to plugins so that the member is joined by the time the plugins see it. public void onUserJoin(final UserJoin message) { @@ -190,13 +207,17 @@ public class PartyService return; } - final PartyMember partyMember = new PartyMember(message.getMemberId(), cleanUsername(message.getName())); - members.add(partyMember); + PartyMember partyMember = getMemberById(message.getMemberId()); + if (partyMember == null) + { + partyMember = new PartyMember(message.getMemberId(), cleanUsername(message.getName())); + members.add(partyMember); + log.debug("User {} joins party, {} members", partyMember, members.size()); + } final PartyMember localMember = getLocalMember(); - // Send info to other clients that this user successfully finished joining party - if (localMember != null && message.getMemberId().equals(localMember.getMemberId())) + if (localMember != null && localMember == partyMember) { final UserSync userSync = new UserSync(); userSync.setMemberId(message.getMemberId()); @@ -207,7 +228,10 @@ public class PartyService @Subscribe(priority = 1) // run prior to plugins so that the member is removed by the time the plugins see it. public void onUserPart(final UserPart message) { - members.removeIf(member -> member.getMemberId().equals(message.getMemberId())); + if (members.removeIf(member -> member.getMemberId().equals(message.getMemberId()))) + { + log.debug("User {} leaves party, {} members", message.getMemberId(), members.size()); + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/party/WSClient.java b/runelite-client/src/main/java/net/runelite/client/party/WSClient.java index 55c67fc3e3..302ebcbcc5 100644 --- a/runelite-client/src/main/java/net/runelite/client/party/WSClient.java +++ b/runelite-client/src/main/java/net/runelite/client/party/WSClient.java @@ -96,7 +96,7 @@ public class WSClient extends WebSocketListener implements AutoCloseable } } - private void connect() + void connect() { if (sessionId == null) { @@ -115,6 +115,11 @@ public class WSClient extends WebSocketListener implements AutoCloseable send(handshake); } + boolean isOpen() + { + return webSocket != null; + } + public void registerMessage(final Class message) { if (messages.add(message)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java index b83c61fd46..a7de70a68f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java @@ -281,7 +281,7 @@ public class DiscordPlugin extends Plugin discordUser.avatar ); userInfo.setMemberId(localMember.getMemberId()); - wsClient.send(userInfo); + partyService.send(userInfo); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java index b8636fd2b5..5a71ea0da8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java @@ -199,7 +199,7 @@ public class DpsCounterPlugin extends Plugin { final DpsUpdate dpsUpdate = new DpsUpdate(hit, isBoss); dpsUpdate.setMemberId(localMember.getMemberId()); - wsClient.send(dpsUpdate); + partyService.send(dpsUpdate); } if (dpsConfig.bossDamage() && !isBoss) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index 1a6226f6ee..068f3e0efc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -104,9 +104,6 @@ public class PartyPlugin extends Plugin @Inject private PartyService party; - @Inject - private WSClient ws; - @Inject private OverlayManager overlayManager; @@ -266,7 +263,7 @@ public class PartyPlugin extends Plugin event.consume(); final TilePing tilePing = new TilePing(selectedSceneTile.getWorldLocation()); tilePing.setMemberId(party.getLocalMember().getMemberId()); - wsClient.send(tilePing); + party.send(tilePing); } @Subscribe @@ -326,7 +323,7 @@ public class PartyPlugin extends Plugin final LocationUpdate locationUpdate = new LocationUpdate(location); locationUpdate.setMemberId(localMember.getMemberId()); - wsClient.send(locationUpdate); + party.send(locationUpdate); } @Subscribe @@ -342,7 +339,7 @@ public class PartyPlugin extends Plugin // Request sync final UserSync userSync = new UserSync(); userSync.setMemberId(party.getLocalMember().getMemberId()); - ws.send(userSync); + party.send(userSync); } } @@ -442,21 +439,21 @@ public class PartyPlugin extends Plugin { final SkillUpdate update = new SkillUpdate(Skill.HITPOINTS, currentHealth, realHealth); update.setMemberId(localMember.getMemberId()); - ws.send(update); + party.send(update); } if (forceSend || currentPrayer != lastPray) { final SkillUpdate update = new SkillUpdate(Skill.PRAYER, currentPrayer, realPrayer); update.setMemberId(localMember.getMemberId()); - ws.send(update); + party.send(update); } if (forceSend || !characterName.equals(lastCharacterName)) { final CharacterNameUpdate update = new CharacterNameUpdate(characterName); update.setMemberId(localMember.getMemberId()); - ws.send(update); + party.send(update); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 575e807097..3f47bedc7c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -84,7 +84,6 @@ import net.runelite.client.game.SpriteManager; import net.runelite.client.input.KeyManager; import net.runelite.client.party.PartyMember; import net.runelite.client.party.PartyService; -import net.runelite.client.party.WSClient; import net.runelite.client.party.messages.PartyChatMessage; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -156,9 +155,6 @@ public class RaidsPlugin extends Plugin @Inject private PartyService party; - @Inject - private WSClient ws; - @Inject private ChatCommandManager chatCommandManager; @@ -494,7 +490,7 @@ public class RaidsPlugin extends Plugin { final PartyChatMessage message = new PartyChatMessage(layoutMessage); message.setMemberId(localMember.getMemberId()); - ws.send(message); + party.send(message); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index fccb15e6ee..7183d2c0d5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -302,7 +302,7 @@ public class SpecialCounterPlugin extends Plugin { final SpecialCounterUpdate specialCounterUpdate = new SpecialCounterUpdate(interactingId, specialWeapon, hit, client.getWorld(), localPlayerId); specialCounterUpdate.setMemberId(party.getLocalMember().getMemberId()); - wsClient.send(specialCounterUpdate); + party.send(specialCounterUpdate); } playerInfoDrops.add(createSpecInfoDrop(specialWeapon, hit, localPlayerId)); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java index ef8ceae5c8..9bab623f62 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java @@ -34,11 +34,10 @@ import net.runelite.client.Notifier; import net.runelite.client.chat.ChatClient; import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.RuneLiteConfig; +import net.runelite.client.party.PartyService; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.ImageCapture; -import net.runelite.client.party.PartyService; -import net.runelite.client.party.WSClient; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Before; @@ -92,10 +91,6 @@ public class RaidsPluginTest @Bind OverlayManager overlayManager; - @Mock - @Bind - WSClient wsClient; - @Mock @Bind RaidsConfig raidsConfig; From 589f48043d642d1c775e1c8461761f76dedb6c9b Mon Sep 17 00:00:00 2001 From: RuneLite updater Date: Fri, 10 Jun 2022 23:01:38 +0000 Subject: [PATCH 15/21] Release 1.8.22 --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- pom.xml | 4 ++-- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-jshell/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index 356da2ebaf..6170d04476 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index ebbab9d1f0..915c4fb61a 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index fde8166548..b4baca38ad 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 cache diff --git a/pom.xml b/pom.xml index 419e85b806..f63c5634c0 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 pom RuneLite @@ -63,7 +63,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - HEAD + runelite-parent-1.8.22 diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index 2a2c09bdbf..151dd6f787 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 16052c8db0..7ca735aa2c 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 client diff --git a/runelite-jshell/pom.xml b/runelite-jshell/pom.xml index 3c11cefde0..fe3c118db2 100644 --- a/runelite-jshell/pom.xml +++ b/runelite-jshell/pom.xml @@ -30,7 +30,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 jshell diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index f9e22547df..52cee7c4ac 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22-SNAPSHOT + 1.8.22 script-assembler-plugin From 5384163164620deef039fb13413e9ad704d1088b Mon Sep 17 00:00:00 2001 From: RuneLite updater Date: Fri, 10 Jun 2022 23:01:42 +0000 Subject: [PATCH 16/21] Bump for 1.8.23-SNAPSHOT [ci skip] --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- pom.xml | 4 ++-- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-jshell/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index 6170d04476..645526da0c 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index 915c4fb61a..03add8de0e 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index b4baca38ad..4361d10310 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT cache diff --git a/pom.xml b/pom.xml index f63c5634c0..c04c87490a 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT pom RuneLite @@ -63,7 +63,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - runelite-parent-1.8.22 + HEAD diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index 151dd6f787..37f30a7021 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 7ca735aa2c..29e3fcf44f 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT client diff --git a/runelite-jshell/pom.xml b/runelite-jshell/pom.xml index fe3c118db2..75e508c003 100644 --- a/runelite-jshell/pom.xml +++ b/runelite-jshell/pom.xml @@ -30,7 +30,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT jshell diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index 52cee7c4ac..7574c24f15 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.8.22 + 1.8.23-SNAPSHOT script-assembler-plugin From db0e56194eed5ccd62228fa067e0e6b32fe9b888 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jun 2022 22:57:30 -0400 Subject: [PATCH 17/21] entity hider: fix hide pets The check for this got accidentally inverted when moving it out of the mixins --- .../runelite/client/plugins/entityhider/EntityHiderPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java index a03d163fec..a8754571e4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java @@ -182,7 +182,7 @@ public class EntityHiderPlugin extends Plugin { NPC npc = (NPC) renderable; - if (npc.getComposition().isFollower() && npc == client.getFollower()) + if (npc.getComposition().isFollower() && npc != client.getFollower()) { return !hidePets; } From 221cb9f9601b477773df4b8d4576315284f4df5b Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 8 Jun 2022 11:12:55 +0000 Subject: [PATCH 18/21] Update Item IDs to 2022-06-08-rev205 --- .../src/main/java/net/runelite/api/ItemID.java | 12 ++++++++++++ .../src/main/java/net/runelite/api/NullItemID.java | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java index 1f2c1d054d..e84aea67af 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -12677,5 +12677,17 @@ public final class ItemID public static final int VOID_MELEE_HELM_LOR = 27007; public static final int DRAGON_DEFENDER_LT = 27008; public static final int RUNE_DEFENDER_LT = 27009; + public static final int PREFORM = 27010; + public static final int DOUBLE_AMMO_MOULD = 27012; + public static final int KOVACS_GROG = 27014; + public static final int SMITHING_CATALYST = 27017; + public static final int ORE_PACK = 27019; + public static final int COLOSSAL_BLADE = 27021; + public static final int SMITHS_TUNIC = 27023; + public static final int SMITHS_TROUSERS = 27025; + public static final int SMITHS_BOOTS = 27027; + public static final int SMITHS_GLOVES = 27029; + public static final int SMITHS_GLOVES_I = 27031; + public static final int GIANTS_FOUNDRY_TESTER = 27033; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java index 97ac498d04..96ffcad99b 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -14122,5 +14122,18 @@ public final class NullItemID public static final int NULL_26995 = 26995; public static final int NULL_26998 = 26998; public static final int NULL_26999 = 26999; + public static final int NULL_27011 = 27011; + public static final int NULL_27013 = 27013; + public static final int NULL_27015 = 27015; + public static final int NULL_27016 = 27016; + public static final int NULL_27018 = 27018; + public static final int NULL_27020 = 27020; + public static final int NULL_27022 = 27022; + public static final int NULL_27024 = 27024; + public static final int NULL_27026 = 27026; + public static final int NULL_27028 = 27028; + public static final int NULL_27030 = 27030; + public static final int NULL_27032 = 27032; + public static final int NULL_27034 = 27034; /* This file is automatically generated. Do not edit. */ } From 8ee0172f87feab90e08c4d5d69f82648516c52ce Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 8 Jun 2022 11:12:55 +0000 Subject: [PATCH 19/21] Update Item variations to 2022-06-08-rev205 --- runelite-client/src/main/resources/item_variations.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index bada1e25f8..97e59fe155 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -10687,5 +10687,9 @@ "ensouled hellhound head": [ 26996, 26997 + ], + "smiths gloves": [ + 27029, + 27031 ] } \ No newline at end of file From c7932a87f0fcdba23af2c9c4b72c5a1fbcb4b6ea Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 8 Jun 2022 11:12:57 +0000 Subject: [PATCH 20/21] Update Object IDs to 2022-06-08-rev205 --- .../java/net/runelite/api/NullObjectID.java | 138 ++++++++++++++++++ .../main/java/net/runelite/api/ObjectID.java | 57 +++++++- 2 files changed, 193 insertions(+), 2 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java index fe126902af..fe12690901 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -21643,6 +21643,10 @@ public final class NullObjectID public static final int NULL_43851 = 43851; public static final int NULL_43852 = 43852; public static final int NULL_43853 = 43853; + public static final int NULL_43854 = 43854; + public static final int NULL_43855 = 43855; + public static final int NULL_43856 = 43856; + public static final int NULL_43859 = 43859; public static final int NULL_43871 = 43871; public static final int NULL_43872 = 43872; public static final int NULL_43874 = 43874; @@ -22154,5 +22158,139 @@ public final class NullObjectID public static final int NULL_44598 = 44598; public static final int NULL_44599 = 44599; public static final int NULL_44600 = 44600; + public static final int NULL_44603 = 44603; + public static final int NULL_44618 = 44618; + public static final int NULL_44639 = 44639; + public static final int NULL_44640 = 44640; + public static final int NULL_44641 = 44641; + public static final int NULL_44642 = 44642; + public static final int NULL_44643 = 44643; + public static final int NULL_44644 = 44644; + public static final int NULL_44645 = 44645; + public static final int NULL_44646 = 44646; + public static final int NULL_44647 = 44647; + public static final int NULL_44648 = 44648; + public static final int NULL_44649 = 44649; + public static final int NULL_44650 = 44650; + public static final int NULL_44651 = 44651; + public static final int NULL_44652 = 44652; + public static final int NULL_44653 = 44653; + public static final int NULL_44654 = 44654; + public static final int NULL_44655 = 44655; + public static final int NULL_44656 = 44656; + public static final int NULL_44657 = 44657; + public static final int NULL_44658 = 44658; + public static final int NULL_44659 = 44659; + public static final int NULL_44660 = 44660; + public static final int NULL_44661 = 44661; + public static final int NULL_44662 = 44662; + public static final int NULL_44664 = 44664; + public static final int NULL_44665 = 44665; + public static final int NULL_44666 = 44666; + public static final int NULL_44667 = 44667; + public static final int NULL_44668 = 44668; + public static final int NULL_44669 = 44669; + public static final int NULL_44670 = 44670; + public static final int NULL_44671 = 44671; + public static final int NULL_44672 = 44672; + public static final int NULL_44673 = 44673; + public static final int NULL_44674 = 44674; + public static final int NULL_44675 = 44675; + public static final int NULL_44676 = 44676; + public static final int NULL_44677 = 44677; + public static final int NULL_44678 = 44678; + public static final int NULL_44679 = 44679; + public static final int NULL_44680 = 44680; + public static final int NULL_44681 = 44681; + public static final int NULL_44682 = 44682; + public static final int NULL_44684 = 44684; + public static final int NULL_44685 = 44685; + public static final int NULL_44686 = 44686; + public static final int NULL_44687 = 44687; + public static final int NULL_44688 = 44688; + public static final int NULL_44689 = 44689; + public static final int NULL_44690 = 44690; + public static final int NULL_44691 = 44691; + public static final int NULL_44692 = 44692; + public static final int NULL_44693 = 44693; + public static final int NULL_44694 = 44694; + public static final int NULL_44695 = 44695; + public static final int NULL_44696 = 44696; + public static final int NULL_44697 = 44697; + public static final int NULL_44698 = 44698; + public static final int NULL_44699 = 44699; + public static final int NULL_44700 = 44700; + public static final int NULL_44701 = 44701; + public static final int NULL_44702 = 44702; + public static final int NULL_44703 = 44703; + public static final int NULL_44704 = 44704; + public static final int NULL_44705 = 44705; + public static final int NULL_44706 = 44706; + public static final int NULL_44707 = 44707; + public static final int NULL_44708 = 44708; + public static final int NULL_44709 = 44709; + public static final int NULL_44710 = 44710; + public static final int NULL_44711 = 44711; + public static final int NULL_44712 = 44712; + public static final int NULL_44713 = 44713; + public static final int NULL_44714 = 44714; + public static final int NULL_44715 = 44715; + public static final int NULL_44716 = 44716; + public static final int NULL_44717 = 44717; + public static final int NULL_44718 = 44718; + public static final int NULL_44719 = 44719; + public static final int NULL_44720 = 44720; + public static final int NULL_44721 = 44721; + public static final int NULL_44722 = 44722; + public static final int NULL_44723 = 44723; + public static final int NULL_44724 = 44724; + public static final int NULL_44725 = 44725; + public static final int NULL_44729 = 44729; + public static final int NULL_44730 = 44730; + public static final int NULL_44731 = 44731; + public static final int NULL_44732 = 44732; + public static final int NULL_44733 = 44733; + public static final int NULL_44734 = 44734; + public static final int NULL_44735 = 44735; + public static final int NULL_44736 = 44736; + public static final int NULL_44737 = 44737; + public static final int NULL_44738 = 44738; + public static final int NULL_44739 = 44739; + public static final int NULL_44740 = 44740; + public static final int NULL_44741 = 44741; + public static final int NULL_44742 = 44742; + public static final int NULL_44743 = 44743; + public static final int NULL_44744 = 44744; + public static final int NULL_44745 = 44745; + public static final int NULL_44746 = 44746; + public static final int NULL_44747 = 44747; + public static final int NULL_44748 = 44748; + public static final int NULL_44749 = 44749; + public static final int NULL_44750 = 44750; + public static final int NULL_44751 = 44751; + public static final int NULL_44752 = 44752; + public static final int NULL_44753 = 44753; + public static final int NULL_44754 = 44754; + public static final int NULL_44755 = 44755; + public static final int NULL_44756 = 44756; + public static final int NULL_44757 = 44757; + public static final int NULL_44758 = 44758; + public static final int NULL_44759 = 44759; + public static final int NULL_44760 = 44760; + public static final int NULL_44764 = 44764; + public static final int NULL_44765 = 44765; + public static final int NULL_44766 = 44766; + public static final int NULL_44767 = 44767; + public static final int NULL_44768 = 44768; + public static final int NULL_44769 = 44769; + public static final int NULL_44770 = 44770; + public static final int NULL_44771 = 44771; + public static final int NULL_44773 = 44773; + public static final int NULL_44774 = 44774; + public static final int NULL_44775 = 44775; + public static final int NULL_44776 = 44776; + public static final int NULL_44777 = 44777; + public static final int NULL_44778 = 44778; + public static final int NULL_44779 = 44779; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/ObjectID.java b/runelite-api/src/main/java/net/runelite/api/ObjectID.java index 2133546b01..79b28f50e0 100644 --- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java @@ -17473,7 +17473,7 @@ public final class ObjectID public static final int OLD_MANS_COFFIN = 33265; public static final int OLD_SHRINE = 33307; public static final int BARREL_OF_WATER = 33308; - public static final int BUCKETS = 33309; + public static final int PILE_OF_BUCKETS = 33309; public static final int FIRE_PIT_33310 = 33310; public static final int FIRE_33311 = 33311; public static final int LITTLE_BOULDER = 33312; @@ -20915,7 +20915,7 @@ public final class ObjectID public static final int MOUNTED_HARPOONFISH = 40963; public static final int HAMMERS_40964 = 40964; public static final int ROPES = 40965; - public static final int BUCKETS_40966 = 40966; + public static final int BUCKETS = 40966; public static final int HARPOONS = 40967; public static final int CRATE_40993 = 40993; public static final int BARREL_40994 = 40994; @@ -22197,6 +22197,15 @@ public final class ObjectID public static final int BLOOD_RIFT_43825 = 43825; public static final int PLANT_43827 = 43827; public static final int BARRIER_43849 = 43849; + public static final int BROKEN_TRIP_HAMMER = 43857; + public static final int REPAIRED_TRIP_HAMMER = 43858; + public static final int BROKEN_GRINDSTONE = 43860; + public static final int REPAIRED_GRINDSTONE = 43861; + public static final int BROKEN_POLISHING_WHEEL = 43862; + public static final int REPAIRED_POLISHING_WHEEL = 43863; + public static final int CRUCIBLE = 43864; + public static final int MOULD_JIG = 43865; + public static final int BIG_CHEST_43866 = 43866; public static final int RUBBLE_43867 = 43867; public static final int STAIRS_43868 = 43868; public static final int SCIMITAR = 43869; @@ -22419,5 +22428,49 @@ public final class ObjectID public static final int LION_GUARD = 44584; public static final int WARP = 44585; public static final int WARP_44586 = 44586; + public static final int LAVA_POOL = 44601; + public static final int WATERFALL_44602 = 44602; + public static final int PREFORM_STORAGE = 44604; + public static final int CRATE_44605 = 44605; + public static final int BELT_SYSTEM = 44606; + public static final int BROKEN_TRIP_HAMMER_44607 = 44607; + public static final int BROKEN_GRINDSTONE_44608 = 44608; + public static final int BROKEN_POLISHING_WHEEL_44609 = 44609; + public static final int EXIT_44610 = 44610; + public static final int CRUCIBLE_44611 = 44611; + public static final int MOULD_JIG_44612 = 44612; + public static final int BIG_CHEST_44613 = 44613; + public static final int LAVA_POOL_44614 = 44614; + public static final int WATERFALL_44615 = 44615; + public static final int PREFORM_STORAGE_44616 = 44616; + public static final int CRATE_44617 = 44617; + public static final int TRIP_HAMMER = 44619; + public static final int GRINDSTONE = 44620; + public static final int POLISHING_WHEEL = 44621; + public static final int CRUCIBLE_EMPTY = 44622; + public static final int CRUCIBLE_PARTIALLY_FULL = 44623; + public static final int CRUCIBLE_FULL = 44624; + public static final int MOULD_JIG_EMPTY = 44625; + public static final int MOULD_JIG_SETUP = 44626; + public static final int MOULD_JIG_POURED_METAL = 44627; + public static final int MOULD_JIG_COOLING_METAL = 44628; + public static final int MOULD_JIG_COOLED_METAL = 44629; + public static final int BANK_CHEST_44630 = 44630; + public static final int LAVA_POOL_44631 = 44631; + public static final int WATERFALL_44632 = 44632; + public static final int PREFORM_STORAGE_44633 = 44633; + public static final int PREFORM_STORAGE_44634 = 44634; + public static final int CAVE_44635 = 44635; + public static final int EXIT_44636 = 44636; + public static final int CRATE_44637 = 44637; + public static final int CRATE_44638 = 44638; + public static final int WATERFALL_44663 = 44663; + public static final int MOULDS = 44683; + public static final int CHEST_44726 = 44726; + public static final int HAMMER_44727 = 44727; + public static final int WHEELBARROW_44728 = 44728; + public static final int WATERWHEEL = 44761; + public static final int BELT_SYSTEM_44762 = 44762; + public static final int BELT_SYSTEM_44763 = 44763; /* This file is automatically generated. Do not edit. */ } From b886d454c9fe84e8c205cf3e8955656e43d5c6c7 Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Wed, 8 Jun 2022 11:12:57 +0000 Subject: [PATCH 21/21] Update NPC IDs to 2022-06-08-rev205 --- runelite-api/src/main/java/net/runelite/api/NpcID.java | 6 ++++++ runelite-api/src/main/java/net/runelite/api/NullNpcID.java | 2 ++ 2 files changed, 8 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/NpcID.java b/runelite-api/src/main/java/net/runelite/api/NpcID.java index 0dc00a80d1..70fddc4af5 100644 --- a/runelite-api/src/main/java/net/runelite/api/NpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java @@ -9650,6 +9650,12 @@ public final class NpcID public static final int REANIMATED_HELLHOUND = 11463; public static final int APPRENTICE_TAMARA_11464 = 11464; public static final int APPRENTICE_TAMARA_11465 = 11465; + public static final int SMITHING_CATALYST = 11466; + public static final int HILL_GIANT_11467 = 11467; + public static final int KOVAC = 11468; + public static final int KOVAC_11469 = 11469; + public static final int KOVAC_11470 = 11470; + public static final int KOVAC_11472 = 11472; public static final int TARIK_11473 = 11473; public static final int MAISA_11474 = 11474; public static final int MAISA_11475 = 11475; diff --git a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java index 217962287b..60bb2d45c5 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java @@ -1801,8 +1801,10 @@ public final class NullNpcID public static final int NULL_11461 = 11461; public static final int NULL_11471 = 11471; public static final int NULL_11488 = 11488; + public static final int NULL_11494 = 11494; public static final int NULL_11512 = 11512; public static final int NULL_11559 = 11559; + public static final int NULL_11560 = 11560; public static final int NULL_11567 = 11567; public static final int NULL_11568 = 11568; public static final int NULL_11611 = 11611;