From 6e09192ee240bd77e37e53b1c3c2c2dd3af720c7 Mon Sep 17 00:00:00 2001 From: Daniel Bolink Date: Wed, 4 Sep 2019 11:22:15 -0700 Subject: [PATCH 1/4] agility shortcuts: add Forthos dungeon and Catacombs of Kourend shortcuts --- .../java/net/runelite/client/game/AgilityShortcut.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java index 474345fb53..1185280e0f 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java +++ b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java @@ -88,6 +88,8 @@ public enum AgilityShortcut EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566), TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15 YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, CASTLE_WALL), + KOUREND_CATACOMBS_SOUTH_WEST_CREVICE_NORTH(17, "Crevice", new WorldPoint(1647, 10008, 0), CRACK_28892), + KOUREND_CATACOMBS_SOUTH_WEST_CREVICE_SOUTH(17, "Crevice", new WorldPoint(1645, 10001, 0), CRACK_28892), YANILLE_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056), COAL_TRUCKS_LOG_BALANCE(20, "Log Balance", new WorldPoint(2598, 3475, 0), LOG_BALANCE_23274), GRAND_EXCHANGE_UNDERWALL_TUNNEL(21, "Underwall Tunnel", new WorldPoint(3139, 3515, 0), UNDERWALL_TUNNEL_16529, UNDERWALL_TUNNEL_16530), @@ -95,6 +97,8 @@ public enum AgilityShortcut OBSERVATORY_SCALE_CLIFF(23, "Grapple Rocks", new WorldPoint(2447, 3155, 0), NULL_31849), EAGLES_PEAK_ROCK_CLIMB(25, "Rock Climb", new WorldPoint(2320, 3499, 0), ROCKS_19849), FALADOR_UNDERWALL_TUNNEL(26, "Underwall Tunnel", new WorldPoint(2947, 3313, 0), UNDERWALL_TUNNEL, UNDERWALL_TUNNEL_16528), + KOUREND_CATACOMBS_PILLAR_JUMP_NORTH(28, "Pillar Jump", new WorldPoint(1613, 10071, 0)), + KOUREND_CATACOMBS_PILLAR_JUMP_SOUTH(28, "Pillar Jump", new WorldPoint(1609, 10060, 0)), MOUNT_KARUULM_LOWER(29, "Rocks", new WorldPoint(1324, 3782, 0), ROCKS_34397), CORSAIR_COVE_RESOURCE_ROCKS(30, "Rocks", new WorldPoint(2486, 2898, 0), ROCKS_31758, ROCKS_31759), SOUTHEAST_KARAJMA_STEPPING_STONES(30, "Stepping Stones", new WorldPoint(2924, 2946, 0), STEPPING_STONES, STEPPING_STONES_23646, STEPPING_STONES_23647), @@ -105,6 +109,8 @@ public enum AgilityShortcut CAIRN_ISLE_ROCKS(32, "Rocks", null, ROCKS_2231), ARDOUGNE_LOG_BALANCE(33, "Log Balance", new WorldPoint(2602, 3336, 0), LOG_BALANCE_16546, LOG_BALANCE_16547, LOG_BALANCE_16548), BRIMHAVEN_DUNGEON_MEDIUM_PIPE(34, "Pipe Squeeze", null, new WorldPoint(2698, 9501, 0), PIPE_21727), + KOUREND_CATACOMBS_NORTH_EAST_CREVICE_NORTH(34, "Crevice", new WorldPoint(1715, 10057, 0), CRACK_28892), + KOUREND_CATACOMBS_NORTH_EAST_CREVICE_SOUTH(34, "Crevice", new WorldPoint(1705, 10077, 0), CRACK_28892), CATHERBY_OBELISK_GRAPPLE(36, "Grapple Rock", new WorldPoint(2841, 3434, 0), CROSSBOW_TREE_17062), GNOME_STRONGHOLD_ROCKS(37, "Rocks", new WorldPoint(2485, 3515, 0), ROCKS_16534, ROCKS_16535), AL_KHARID_MINING_PITCLIFF_SCRAMBLE(38, "Rocks", new WorldPoint(3305, 3315, 0), ROCKS_16549, ROCKS_16550), @@ -184,6 +190,7 @@ public enum AgilityShortcut TROLL_STRONGHOLD_WALL_CLIMB(73, "Rocks", new WorldPoint(2841, 3694, 0), ROCKS_16464), ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985 ), LAVA_DRAGON_ISLE_JUMP(74, "Stepping Stone", new WorldPoint(3200, 3807, 0), STEPPING_STONE_14918), + FORTHOS_DUNGEON_SPIKED_BLADES(75, "Spiked Blades", new WorldPoint(1819, 9946, 0), STRANGE_FLOOR_34834), REVENANT_CAVES_DEMONS_JUMP(75, "Jump", new WorldPoint(3199, 10135, 0), PILLAR_31561), REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561), REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561), From ed17bdaed351549e7547238e354a145154da3668 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Sun, 1 Sep 2019 22:41:28 +0100 Subject: [PATCH 2/4] idle notifer: add movement idle notification Co-authored-by: Adam --- .../idlenotifier/IdleNotifierConfig.java | 23 +++++++--- .../idlenotifier/IdleNotifierPlugin.java | 42 ++++++++++++++++++- .../idlenotifier/IdleNotifierPluginTest.java | 17 ++++++++ 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java index 7d846b9db9..200d00da4f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java @@ -53,11 +53,22 @@ public interface IdleNotifierConfig extends Config return true; } + @ConfigItem( + keyName = "movementidle", + name = "Idle Movement Notifications", + description = "Configures if idle movement notifications are enabled e.g. running, walking", + position = 3 + ) + default boolean movementIdle() + { + return false; + } + @ConfigItem( keyName = "logoutidle", name = "Idle Logout Notifications", description = "Configures if the idle logout notifications are enabled", - position = 3 + position = 4 ) default boolean logoutIdle() { @@ -68,7 +79,7 @@ public interface IdleNotifierConfig extends Config keyName = "timeout", name = "Idle Notification Delay (ms)", description = "The notification delay after the player is idle", - position = 4 + position = 5 ) default int getIdleNotificationDelay() { @@ -79,7 +90,7 @@ public interface IdleNotifierConfig extends Config keyName = "hitpoints", name = "Hitpoints Notification Threshold", description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.", - position = 5 + position = 6 ) default int getHitpointsThreshold() { @@ -90,7 +101,7 @@ public interface IdleNotifierConfig extends Config keyName = "prayer", name = "Prayer Notification Threshold", description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.", - position = 6 + position = 7 ) default int getPrayerThreshold() { @@ -100,7 +111,7 @@ public interface IdleNotifierConfig extends Config @ConfigItem( keyName = "oxygen", name = "Oxygen Notification Threshold", - position = 7, + position = 8, description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification." ) default int getOxygenThreshold() @@ -111,7 +122,7 @@ public interface IdleNotifierConfig extends Config @ConfigItem( keyName = "spec", name = "Special Attack Energy Notification Threshold", - position = 8, + position = 9, description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification." ) default int getSpecEnergyThreshold() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java index db2699d6d6..8d4efcdac6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java @@ -45,6 +45,7 @@ import net.runelite.api.Player; import net.runelite.api.Skill; import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; @@ -88,6 +89,9 @@ public class IdleNotifierPlugin extends Plugin private int lastAnimation = AnimationID.IDLE; private Instant lastInteracting; private Actor lastInteract; + private Instant lastMoving; + private WorldPoint lastPosition; + private boolean notifyPosition = false; private boolean notifyHitpoints = true; private boolean notifyPrayer = true; private boolean notifyOxygen = true; @@ -400,6 +404,11 @@ public class IdleNotifierPlugin extends Plugin notifier.notify("[" + local.getName() + "] is now idle!"); } + if (config.movementIdle() && checkMovementIdle(waitDuration, local)) + { + notifier.notify("[" + local.getName() + "] has stopped moving!"); + } + if (config.interactionIdle() && checkInteractionIdle(waitDuration, local)) { if (lastInteractWasCombat) @@ -638,6 +647,37 @@ public class IdleNotifierPlugin extends Plugin return false; } + private boolean checkMovementIdle(Duration waitDuration, Player local) + { + if (lastPosition == null) + { + lastPosition = local.getWorldLocation(); + return false; + } + + WorldPoint position = local.getWorldLocation(); + + if (lastPosition.equals(position)) + { + if (notifyPosition + && local.getAnimation() == IDLE + && Instant.now().compareTo(lastMoving.plus(waitDuration)) >= 0) + { + notifyPosition = false; + // Return true only if we weren't just breaking out of an animation + return lastAnimation == IDLE; + } + } + else + { + notifyPosition = true; + lastPosition = position; + lastMoving = Instant.now(); + } + + return false; + } + private void resetTimers() { final Player local = client.getLocalPlayer(); @@ -656,4 +696,4 @@ public class IdleNotifierPlugin extends Plugin lastInteract = null; } } -} \ No newline at end of file +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPluginTest.java index 39af7a8e28..f1f21f2898 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPluginTest.java @@ -36,6 +36,7 @@ import net.runelite.api.NPC; import net.runelite.api.NPCComposition; import net.runelite.api.Player; import net.runelite.api.VarPlayer; +import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; @@ -47,6 +48,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import org.mockito.Mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -272,4 +274,19 @@ public class IdleNotifierPluginTest plugin.onGameTick(new GameTick()); verify(notifier).notify(Matchers.eq("[" + PLAYER_NAME + "] has restored spec energy!")); } + + @Test + public void testMovementIdle() + { + when(config.movementIdle()).thenReturn(true); + + when(player.getWorldLocation()).thenReturn(new WorldPoint(0, 0, 0)); + plugin.onGameTick(new GameTick()); + when(player.getWorldLocation()).thenReturn(new WorldPoint(1, 0, 0)); + plugin.onGameTick(new GameTick()); + // No movement here + plugin.onGameTick(new GameTick()); + + verify(notifier).notify(eq("[" + PLAYER_NAME + "] has stopped moving!")); + } } \ No newline at end of file From 03c8166ff4f38f2f7dfae6a4830834bb23373c83 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 4 Sep 2019 19:38:52 -0400 Subject: [PATCH 3/4] chat message manager: fix recoloring messages with embedded tags --- .../client/chat/ChatMessageManager.java | 6 +- .../net/runelite/client/util/ColorUtil.java | 2 +- .../client/chat/ChatMessageManagerTest.java | 87 +++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java index e26220038d..fe0bfe0851 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java @@ -164,7 +164,11 @@ public class ChatMessageManager continue; } - messageNode.setValue(ColorUtil.wrapWithColorTag(messageNode.getValue(), chatColor.getColor())); + // Replace tags in the message with the new color so embedded won't reset the color + final Color color = chatColor.getColor(); + messageNode.setValue(ColorUtil.wrapWithColorTag( + messageNode.getValue().replace(ColorUtil.CLOSING_COLOR_TAG, ColorUtil.colorTag(color)), + color)); break; } } diff --git a/runelite-client/src/main/java/net/runelite/client/util/ColorUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ColorUtil.java index 8c6f124f4c..1933f8337b 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ColorUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ColorUtil.java @@ -35,7 +35,7 @@ public class ColorUtil public static final int MIN_RGB_VALUE = 0; private static final String OPENING_COLOR_TAG_START = " + * 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.chat; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.awt.Color; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.MessageNode; +import net.runelite.api.events.ChatMessage; +import net.runelite.client.config.ChatColorConfig; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.mockito.Matchers.eq; +import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ChatMessageManagerTest +{ + @Mock + @Bind + private Client client; + + @Mock + @Bind + private ChatColorConfig chatColorConfig; + + @Inject + private ChatMessageManager chatMessageManager; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + chatMessageManager.loadColors(); + } + + @Test + public void onChatMessage() + { + when(chatColorConfig.opaquePublicChat()).thenReturn(Color.decode("#b20000")); + + chatMessageManager.loadColors(); + + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.PUBLICCHAT); + + MessageNode messageNode = mock(MessageNode.class); + chatMessage.setMessageNode(messageNode); + + when(messageNode.getValue()).thenReturn("Your dodgy necklace protects you. It has 1 charge left."); + chatMessageManager.onChatMessage(chatMessage); + + verify(messageNode).setValue(eq("Your dodgy necklace protects you. It has 1 charge left.")); + } +} \ No newline at end of file From abe7c4085289ad3ba1daab4fb866a9a990620957 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 4 Sep 2019 19:39:23 -0400 Subject: [PATCH 4/4] devtools: add msg command --- .../net/runelite/client/plugins/devtools/DevToolsPlugin.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index d1cd2a2005..a6692a0491 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -352,6 +352,11 @@ public class DevToolsPlugin extends Plugin client.playSoundEffect(id); break; } + case "msg": + { + client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", String.join(" ", args), ""); + break; + } } }