From af5aa42a1dd6271ae68996a75eb1bce0a852486f Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 15 Aug 2019 13:33:03 -0400 Subject: [PATCH 1/7] xptracker: fix calculating xp offset from offline xp --- .../plugins/xptracker/XpTrackerPlugin.java | 12 +- .../xptracker/XpTrackerPluginTest.java | 123 ++++++++++++++++++ 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 6aa4238299..56ca040a8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -25,6 +25,7 @@ */ package net.runelite.client.plugins.xptracker; +import com.google.common.annotations.VisibleForTesting; import static com.google.common.base.MoreObjects.firstNonNull; import com.google.common.collect.ImmutableList; import com.google.inject.Binder; @@ -36,6 +37,8 @@ import java.util.EnumSet; import java.util.List; import java.util.Objects; import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Actor; import net.runelite.api.Client; @@ -114,6 +117,8 @@ public class XpTrackerPlugin extends Plugin private OverlayManager overlayManager; private NavigationButton navButton; + @Setter(AccessLevel.PACKAGE) + @VisibleForTesting private XpPanel xpPanel; private XpWorldType lastWorldType; private String lastUsername; @@ -412,7 +417,7 @@ public class XpTrackerPlugin extends Plugin log.debug("Skill xp for {} changed when offline: {} -> {}", skill, skillState.getCurrentXp(), currentXp); // Offset start xp for offline gains - long diff = skillState.getCurrentXp() - currentXp; + long diff = currentXp - skillState.getCurrentXp(); skillState.setStartXp(skillState.getStartXp() + diff); } } @@ -512,6 +517,11 @@ public class XpTrackerPlugin extends Plugin } } + XpStateSingle getSkillState(Skill skill) + { + return xpState.getSkill(skill); + } + XpSnapshotSingle getSkillSnapshot(Skill skill) { return xpState.getSkillSnapshot(skill); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java new file mode 100644 index 0000000000..372b51d9ed --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2019, 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.xptracker; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.EnumSet; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.Player; +import net.runelite.api.Skill; +import net.runelite.api.WorldType; +import net.runelite.api.events.ExperienceChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.client.game.NPCManager; +import net.runelite.client.game.SkillIconManager; +import net.runelite.client.ui.ClientToolbar; +import net.runelite.client.ui.overlay.OverlayManager; +import static org.junit.Assert.assertEquals; +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.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class XpTrackerPluginTest +{ + @Inject + private XpTrackerPlugin xpTrackerPlugin; + + @Mock + @Bind + private ClientToolbar clientToolbar; + + @Mock + @Bind + private Client client; + + @Mock + @Bind + private SkillIconManager skillIconManager; + + @Mock + @Bind + private XpTrackerConfig xpTrackerConfig; + + @Mock + @Bind + private NPCManager npcManager; + + @Mock + @Bind + private OverlayManager overlayManager; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getWorldType()).thenReturn(EnumSet.of(WorldType.MEMBERS)); + when(client.getLocalPlayer()).thenReturn(mock(Player.class)); + + xpTrackerPlugin.setXpPanel(mock(XpPanel.class)); + } + + @Test + public void testOfflineXp() + { + GameStateChanged gameStateChanged = new GameStateChanged(); + gameStateChanged.setGameState(GameState.LOGGING_IN); + + // Flag initialization of tracker + xpTrackerPlugin.onGameStateChanged(gameStateChanged); + when(client.getSkillExperience(Skill.ATTACK)).thenReturn(42); + // Initialize tracker + xpTrackerPlugin.onGameTick(new GameTick()); + + // Gain attack xp + when(client.getSkillExperience(Skill.ATTACK)).thenReturn(100); + ExperienceChanged experienceChanged = new ExperienceChanged(); + experienceChanged.setSkill(Skill.ATTACK); + xpTrackerPlugin.onExperienceChanged(experienceChanged); + + // Offline gain + when(client.getSkillExperience(Skill.ATTACK)).thenReturn(42000); + // Flag initialization of tracker + xpTrackerPlugin.onGameStateChanged(gameStateChanged); + // Initialize tracker + xpTrackerPlugin.onGameTick(new GameTick()); + + // Start at 42 xp, gain of 58 xp, offline gain of 41900 xp - offset start XP: 42 + 41900 + XpStateSingle skillState = xpTrackerPlugin.getSkillState(Skill.ATTACK); + assertEquals(41942, skillState.getStartXp()); + } +} \ No newline at end of file From 42516b1ba2c65e32408bbc8231a0f13d3faa3384 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 14 Aug 2019 19:00:19 -0400 Subject: [PATCH 2/7] api: add accessor for GameState state --- runelite-api/src/main/java/net/runelite/api/GameState.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/GameState.java b/runelite-api/src/main/java/net/runelite/api/GameState.java index 5f9083f9ca..526c89f06e 100644 --- a/runelite-api/src/main/java/net/runelite/api/GameState.java +++ b/runelite-api/src/main/java/net/runelite/api/GameState.java @@ -24,9 +24,12 @@ */ package net.runelite.api; +import lombok.Getter; + /** * An enumeration of game states the client is in. */ +@Getter public enum GameState { /** From 381a661658face65a46326ff7c974f2eec2545c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 14 Aug 2019 19:00:31 -0400 Subject: [PATCH 3/7] api: add setGameState --- runelite-api/src/main/java/net/runelite/api/Client.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 e19d64c90f..83aacc3bfd 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -131,6 +131,13 @@ public interface Client extends GameEngine */ GameState getGameState(); + /** + * Sets the current game state + * + * @param gameState + */ + void setGameState(GameState gameState); + /** * Gets the current logged in username. * From f401d417dd232f993bf7f11e34fc1bc9083e9424 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 14 Aug 2019 19:01:06 -0400 Subject: [PATCH 4/7] low memory plugin: run changeMemoryMode on game thread This method must now be called on game thread, and can be called regardless of game state. --- .../plugins/lowmemory/LowMemoryPlugin.java | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java index 41caa93ebd..195feefaf4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java @@ -26,9 +26,7 @@ package net.runelite.client.plugins.lowmemory; import javax.inject.Inject; import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.events.GameStateChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.callback.ClientThread; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -43,27 +41,18 @@ public class LowMemoryPlugin extends Plugin @Inject private Client client; + @Inject + private ClientThread clientThread; + @Override - protected void startUp() throws Exception + protected void startUp() { - if (client.getGameState() == GameState.LOGGED_IN) - { - client.changeMemoryMode(true); - } + clientThread.invoke(() -> client.changeMemoryMode(true)); } @Override - protected void shutDown() throws Exception + protected void shutDown() { - client.changeMemoryMode(false); - } - - @Subscribe - private void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGIN_SCREEN) - { - client.changeMemoryMode(true); - } + clientThread.invoke(() -> client.changeMemoryMode(false)); } } From 48a1bce947b29dbb0f5930df9eb840d315b1804a Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Fri, 16 Aug 2019 00:28:32 +0100 Subject: [PATCH 5/7] clues: Fix Bryophyta's staff having no name --- .../runelite/client/plugins/cluescrolls/clues/EmoteClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java index cc5df5a7ee..db46a9f020 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java @@ -77,7 +77,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu new EmoteClue("Panic in the heart of the Haunted Woods. Beware of double agents! Have no items equipped when you do.", "Haunted Woods", null, new WorldPoint(3611, 3492, 0), PANIC, emptySlot("Nothing at all", HEAD, CAPE, AMULET, WEAPON, BODY, SHIELD, LEGS, GLOVES, BOOTS, RING, AMMO)), new EmoteClue("Show your anger towards the Statue of Saradomin in Ellamaria's garden. Beware of double agents! Equip a zamorak godsword.", "Varrock Castle", BY_THE_BEAR_CAGE_IN_VARROCK_PALACE_GARDENS, new WorldPoint(3230, 3478, 0), ANGRY, item(ZAMORAK_GODSWORD)), new EmoteClue("Show your anger at the Wise old man. Beware of double agents! Equip an abyssal whip, a legend's cape and some spined chaps.", "Draynor Village", BEHIND_MISS_SCHISM_IN_DRAYNOR_VILLAGE, new WorldPoint(3088, 3254, 0), ANGRY, any("Abyssal whip", item(ABYSSAL_WHIP), item(VOLCANIC_ABYSSAL_WHIP), item(FROZEN_ABYSSAL_WHIP)), item(CAPE_OF_LEGENDS), item(SPINED_CHAPS)), - new EmoteClue("Beckon by a collection of crystalline maple trees. Beware of double agents! Equip Bryophyta's staff and a nature tiara.", "North of Prifddinas", CRYSTALLINE_MAPLE_TREES, new WorldPoint(2211, 3427, 0), BECKON, range(BRYOPHYTAS_STAFF_UNCHARGED, BRYOPHYTAS_STAFF), item(NATURE_TIARA)), + new EmoteClue("Beckon by a collection of crystalline maple trees. Beware of double agents! Equip Bryophyta's staff and a nature tiara.", "North of Prifddinas", CRYSTALLINE_MAPLE_TREES, new WorldPoint(2211, 3427, 0), BECKON, range("Bryophyta's staff", BRYOPHYTAS_STAFF_UNCHARGED, BRYOPHYTAS_STAFF), item(NATURE_TIARA)), new EmoteClue("Beckon in the Digsite, near the eastern winch. Bow before you talk to me. Equip a green gnome hat, snakeskin boots and an iron pickaxe.", "Digsite", DIGSITE, new WorldPoint(3370, 3425, 0), BECKON, BOW, item(GREEN_HAT), item(SNAKESKIN_BOOTS), item(IRON_PICKAXE)), new EmoteClue("Beckon in Tai Bwo Wannai. Clap before you talk to me. Equip green dragonhide chaps, a ring of dueling and a mithril medium helmet.", "Tai Bwo Wannai", SOUTH_OF_THE_SHRINE_IN_TAI_BWO_WANNAI_VILLAGE, new WorldPoint(2803, 3073, 0), BECKON, CLAP, item(GREEN_DHIDE_CHAPS), any("Ring of dueling", item(RING_OF_DUELING1), item(RING_OF_DUELING2), item(RING_OF_DUELING3), item(RING_OF_DUELING4), item(RING_OF_DUELING5), item(RING_OF_DUELING6), item(RING_OF_DUELING7), item(RING_OF_DUELING8)), item(MITHRIL_MED_HELM)), new EmoteClue("Beckon in the combat ring of Shayzien. Show your anger before you talk to me. Equip an adamant platebody, adamant full helm and adamant platelegs.", "Shayzien combat ring", WEST_OF_THE_SHAYZIEN_COMBAT_RING, new WorldPoint(1545, 3594, 0), BECKON, ANGRY, item(ADAMANT_PLATELEGS), item(ADAMANT_PLATEBODY), item(ADAMANT_FULL_HELM)), From a868adfc6c9d9e5b2f494da5d8bc74afa1b6820c Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Sun, 18 Aug 2019 01:35:53 +0200 Subject: [PATCH 6/7] raids: Update reload instance button to send a gamestate --- .../main/java/net/runelite/client/plugins/raids/RaidsPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPanel.java index 70cd5798d9..463236423f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPanel.java @@ -79,7 +79,7 @@ class RaidsPanel extends PluginPanel { if ((client.getGameState() == GameState.LOGGED_IN)) { - client.setGameState(40); + client.setGameState(GameState.CONNECTION_LOST); } }); From 78a3875ac546f696006ef891539d43261fa56dda Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Sun, 18 Aug 2019 01:58:36 +0200 Subject: [PATCH 7/7] client: Update XpTracker test --- .../runelite/client/plugins/xptracker/XpTrackerPlugin.java | 6 +++--- .../client/plugins/xptracker/XpTrackerPluginTest.java | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 1c5a8ef086..ae3324a75c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -202,7 +202,7 @@ public class XpTrackerPlugin extends Plugin eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); } - private void onGameStateChanged(GameStateChanged event) + void onGameStateChanged(GameStateChanged event) { GameState state = event.getGameState(); if (state == GameState.LOGGED_IN) @@ -360,7 +360,7 @@ public class XpTrackerPlugin extends Plugin } } - private void onExperienceChanged(ExperienceChanged event) + void onExperienceChanged(ExperienceChanged event) { final Skill skill = event.getSkill(); final int currentXp = client.getSkillExperience(skill); @@ -418,7 +418,7 @@ public class XpTrackerPlugin extends Plugin xpPanel.updateTotal(xpState.getTotalSnapshot()); } - private void onGameTick(GameTick event) + void onGameTick(GameTick event) { if (initializeTracker) { diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java index 372b51d9ed..8f65e81cbf 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java @@ -48,7 +48,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class XpTrackerPluginTest @@ -85,7 +85,6 @@ public class XpTrackerPluginTest { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); - when(client.getWorldType()).thenReturn(EnumSet.of(WorldType.MEMBERS)); when(client.getLocalPlayer()).thenReturn(mock(Player.class)); xpTrackerPlugin.setXpPanel(mock(XpPanel.class)); @@ -101,7 +100,7 @@ public class XpTrackerPluginTest xpTrackerPlugin.onGameStateChanged(gameStateChanged); when(client.getSkillExperience(Skill.ATTACK)).thenReturn(42); // Initialize tracker - xpTrackerPlugin.onGameTick(new GameTick()); + xpTrackerPlugin.onGameTick(GameTick.INSTANCE); // Gain attack xp when(client.getSkillExperience(Skill.ATTACK)).thenReturn(100); @@ -114,7 +113,7 @@ public class XpTrackerPluginTest // Flag initialization of tracker xpTrackerPlugin.onGameStateChanged(gameStateChanged); // Initialize tracker - xpTrackerPlugin.onGameTick(new GameTick()); + xpTrackerPlugin.onGameTick(GameTick.INSTANCE); // Start at 42 xp, gain of 58 xp, offline gain of 41900 xp - offset start XP: 42 + 41900 XpStateSingle skillState = xpTrackerPlugin.getSkillState(Skill.ATTACK);