From a9f270cbcb3f8f605a99fec0843b931d8d801bbd Mon Sep 17 00:00:00 2001 From: Austin <42952632+AustinGarrettR@users.noreply.github.com> Date: Wed, 18 Mar 2020 12:17:06 -0600 Subject: [PATCH 01/16] skybox: add nightmare dungeon area --- .../net/runelite/client/plugins/skybox/skybox.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skybox/skybox.txt b/runelite-client/src/main/resources/net/runelite/client/plugins/skybox/skybox.txt index 9451d6a707..de37f0f479 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skybox/skybox.txt +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skybox/skybox.txt @@ -215,7 +215,6 @@ R 42 69 43 71 R 45 68 45 69 R 49 149 50 149 R 55 151 56 151 -R 58 151 58 152 r 39 72 r 39 156 r 51 150 @@ -964,4 +963,8 @@ R 49 193 51 194 // Braindeath Island #8AD2DF -R 33 79 33 80 \ No newline at end of file +R 33 79 33 80 + +// Nightmare dungeon (Morytania underground) +#0a0a0a +R 58 151 60 153 From f9436d06e39bd173f8bceb932a964c2c28ff4459 Mon Sep 17 00:00:00 2001 From: DeliciousLunch55 Date: Wed, 18 Mar 2020 13:29:18 -0500 Subject: [PATCH 02/16] cannon plugin: add cannoning spot for Lizard Shamans --- .../java/net/runelite/client/plugins/cannon/CannonSpots.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java index b8b8ddd9c5..ec552d16f3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java @@ -49,6 +49,7 @@ public enum CannonSpots KALPHITE(new WorldPoint(3307, 9528, 0)), LESSER_DEMON(new WorldPoint(2838, 9559, 0), new WorldPoint(3163, 10114, 0)), LIZARDMEN(new WorldPoint(1500, 3703, 0)), + LIZARDMEN_SHAMAN(new WorldPoint(1423, 3715, 0)), MINIONS_OF_SCARABAS(new WorldPoint(3297, 9252, 0)), SMOKE_DEVIL(new WorldPoint(2398, 9444, 0)), CAVE_HORROR(new WorldPoint(3785, 9460, 0)), From 6c5c579fd105108e2002a6ec575af5affbe67d83 Mon Sep 17 00:00:00 2001 From: Justin Hiltz Date: Wed, 18 Mar 2020 17:18:13 -0300 Subject: [PATCH 03/16] custom cursor: add option to use equipped weapon --- .../plugins/customcursor/CustomCursor.java | 3 +- .../customcursor/CustomCursorPlugin.java | 67 ++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursor.java b/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursor.java index 5012f3d564..37208ddd23 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursor.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursor.java @@ -38,6 +38,7 @@ public enum CustomCursor DRAGON_DAGGER_POISON("Dragon Dagger (p)", "cursor-dragon-dagger-p.png"), TROUT("Trout", "cursor-trout.png"), DRAGON_SCIMITAR("Dragon Scimitar", "cursor-dragon-scimitar.png"), + EQUIPPED_WEAPON("Equipped Weapon"), CUSTOM_IMAGE("Custom Image"); private final String name; @@ -55,4 +56,4 @@ public enum CustomCursor this.name = name; this.cursorImage = ImageUtil.getResourceStreamFromClass(CustomCursorPlugin.class, icon); } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java index 2c5d87361f..e1472ca26d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java @@ -30,10 +30,18 @@ import java.io.File; import javax.imageio.ImageIO; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.client.RuneLite; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientUI; @@ -48,12 +56,21 @@ public class CustomCursorPlugin extends Plugin { private static final File CUSTOM_IMAGE_FILE = new File(RuneLite.RUNELITE_DIR, "cursor.png"); + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + @Inject private ClientUI clientUI; @Inject private CustomCursorConfig config; + @Inject + private ItemManager itemManager; + @Provides CustomCursorConfig provideConfig(ConfigManager configManager) { @@ -81,6 +98,15 @@ public class CustomCursorPlugin extends Plugin } } + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) + { + if (config.selectedCursor() == CustomCursor.EQUIPPED_WEAPON && event.getContainerId() == InventoryID.EQUIPMENT.getId()) + { + updateCursor(); + } + } + private void updateCursor() { CustomCursor selectedCursor = config.selectedCursor(); @@ -108,10 +134,45 @@ public class CustomCursorPlugin extends Plugin { clientUI.resetCursor(); } - return; } + else if (selectedCursor == CustomCursor.EQUIPPED_WEAPON) + { + clientThread.invokeLater(() -> + { + final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT); - assert selectedCursor.getCursorImage() != null; - clientUI.setCursor(selectedCursor.getCursorImage(), selectedCursor.getName()); + if (equipment == null) + { + clientUI.resetCursor(); + return; + } + + final Item[] items = equipment.getItems(); + final int weaponIdx = EquipmentInventorySlot.WEAPON.getSlotIdx(); + + if (items == null || weaponIdx >= items.length) + { + clientUI.resetCursor(); + return; + } + + final Item weapon = items[EquipmentInventorySlot.WEAPON.getSlotIdx()]; + final BufferedImage image = itemManager.getImage(weapon.getId()); + + if (weapon.getQuantity() > 0) + { + clientUI.setCursor(image, selectedCursor.getName()); + } + else + { + clientUI.resetCursor(); + } + }); + } + else + { + assert selectedCursor.getCursorImage() != null; + clientUI.setCursor(selectedCursor.getCursorImage(), selectedCursor.getName()); + } } } \ No newline at end of file From a8d9d524caca289e0d0310f301d5a80008b56fad Mon Sep 17 00:00:00 2001 From: DeliciousLunch55 Date: Wed, 18 Mar 2020 15:23:09 -0500 Subject: [PATCH 04/16] cannon plugin: update Gnome Stronghold dungeon Bloodvelds cannon location. (#11028) --- .../java/net/runelite/client/plugins/cannon/CannonSpots.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java index ec552d16f3..1292443299 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java @@ -33,7 +33,7 @@ import net.runelite.api.coords.WorldPoint; public enum CannonSpots { - BLOODVELDS(new WorldPoint(2439, 9821, 0), new WorldPoint(2448, 9821, 0), new WorldPoint(2472, 9833, 0), new WorldPoint(2453, 9817, 0)), + BLOODVELDS(new WorldPoint(2439, 9821, 0), new WorldPoint(2448, 9821, 0), new WorldPoint(2472, 9832, 0), new WorldPoint(2453, 9817, 0)), FIRE_GIANTS(new WorldPoint(2393, 9782, 0), new WorldPoint(2412, 9776, 0), new WorldPoint(2401, 9780, 0)), ABERRANT_SPECTRES(new WorldPoint(2456, 9791, 0)), HELLHOUNDS(new WorldPoint(2431, 9776, 0), new WorldPoint(2413, 9786, 0), new WorldPoint(2783, 9686, 0), new WorldPoint(3198, 10071, 0)), From 902078cb620e4fc447b74ce3040b8b6e308b56d2 Mon Sep 17 00:00:00 2001 From: melkypie <5113962+melkypie@users.noreply.github.com> Date: Sun, 15 Mar 2020 18:45:20 +0200 Subject: [PATCH 05/16] friendslist: update titles using onScriptPostFired rather than onGameTick --- .../plugins/friendlist/FriendListPlugin.java | 67 ++++++++++--------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index cbe43c0aea..da491c4c76 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -30,8 +30,9 @@ import net.runelite.api.Client; import net.runelite.api.Friend; import net.runelite.api.Ignore; import net.runelite.api.NameableContainer; +import net.runelite.api.ScriptID; import net.runelite.api.VarPlayer; -import net.runelite.api.events.GameTick; +import net.runelite.api.events.ScriptPostFired; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.eventbus.Subscribe; @@ -62,43 +63,49 @@ public class FriendListPlugin extends Plugin } @Subscribe - public void onGameTick(GameTick tick) + public void onScriptPostFired(ScriptPostFired event) { - final int world = client.getWorld(); - final boolean isMember = client.getVar(VarPlayer.MEMBERSHIP_DAYS) > 0; - - final NameableContainer friendContainer = client.getFriendContainer(); - final int friendCount = friendContainer.getCount(); - if (friendCount >= 0) + if (event.getScriptId() == ScriptID.FRIENDS_UPDATE) { - final int limit = isMember ? MAX_FRIENDS_P2P : MAX_FRIENDS_F2P; + final int world = client.getWorld(); + final boolean isMember = client.getVar(VarPlayer.MEMBERSHIP_DAYS) > 0; + final NameableContainer friendContainer = client.getFriendContainer(); + final int friendCount = friendContainer.getCount(); + if (friendCount >= 0) + { + final int limit = isMember ? MAX_FRIENDS_P2P : MAX_FRIENDS_F2P; - final String title = "Friends - W" + - world + - " (" + - friendCount + - "/" + - limit + - ")"; + final String title = "Friends - W" + + world + + " (" + + friendCount + + "/" + + limit + + ")"; - setFriendsListTitle(title); + setFriendsListTitle(title); + } } - - final NameableContainer ignoreContainer = client.getIgnoreContainer(); - final int ignoreCount = ignoreContainer.getCount(); - if (ignoreCount >= 0) + else if (event.getScriptId() == ScriptID.IGNORE_UPDATE) { - final int limit = isMember ? MAX_IGNORES_P2P : MAX_IGNORES_F2P; + final int world = client.getWorld(); + final boolean isMember = client.getVar(VarPlayer.MEMBERSHIP_DAYS) > 0; + final NameableContainer ignoreContainer = client.getIgnoreContainer(); + final int ignoreCount = ignoreContainer.getCount(); + if (ignoreCount >= 0) + { + final int limit = isMember ? MAX_IGNORES_P2P : MAX_IGNORES_F2P; - final String title = "Ignores - W" + - world + - " (" + - ignoreCount + - "/" + - limit + - ")"; + final String title = "Ignores - W" + + world + + " (" + + ignoreCount + + "/" + + limit + + ")"; - setIgnoreListTitle(title); + setIgnoreListTitle(title); + } } } From 59361c0d95a681a5f110a47e4c5d7a600a3581a1 Mon Sep 17 00:00:00 2001 From: melkypie <5113962+melkypie@users.noreply.github.com> Date: Wed, 18 Mar 2020 13:46:27 +0200 Subject: [PATCH 06/16] timetracking: add ability to sort timers Lets the user sort by ascending or descending time. Co-authored-by: jakewilson --- .../plugins/timetracking/SortOrder.java | 32 +++++++++++++++++++ .../timetracking/TimeTrackingConfig.java | 11 +++++++ .../timetracking/TimeTrackingPlugin.java | 4 ++- .../timetracking/clocks/ClockManager.java | 30 +++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java new file mode 100644 index 0000000000..14e3924e6f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020, Jake Wilson + * 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.timetracking; + +public enum SortOrder +{ + NONE, + ASC, + DESC +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java index 099c7a8f70..94d388e40d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java @@ -83,6 +83,17 @@ public interface TimeTrackingConfig extends Config return 5; } + @ConfigItem( + keyName = "sortOrder", + name = "Sort Order", + description = "The order in which to sort the timers", + position = 5 + ) + default SortOrder sortOrder() + { + return SortOrder.NONE; + } + @ConfigItem( keyName = "activeTab", name = "Active Tab", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java index 917dabc86c..e8b1c70ff3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java @@ -224,13 +224,15 @@ public class TimeTrackingPlugin extends Plugin long unitTime = Instant.now().toEpochMilli() / 200; boolean clockDataChanged = false; + boolean timerOrderChanged = false; if (unitTime % 5 == 0) { clockDataChanged = clockManager.checkCompletion(); + timerOrderChanged = clockManager.checkTimerOrder(); } - if (unitTime % panel.getUpdateInterval() == 0 || clockDataChanged) + if (unitTime % panel.getUpdateInterval() == 0 || clockDataChanged || timerOrderChanged) { panel.update(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java index 42686dae70..342da8c3f7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java @@ -24,10 +24,12 @@ */ package net.runelite.client.plugins.timetracking.clocks; +import com.google.common.collect.Comparators; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.inject.Singleton; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.inject.Inject; @@ -36,6 +38,7 @@ import joptsimple.internal.Strings; import lombok.Getter; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.timetracking.SortOrder; import net.runelite.client.plugins.timetracking.TimeTrackingConfig; @Singleton @@ -131,6 +134,33 @@ public class ClockManager return changed; } + /** + * Checks to ensure the timers are in the correct order. + * If they are not, sort them and rebuild the clock panel + * + * @return whether the timer order was changed or not + */ + public boolean checkTimerOrder() + { + SortOrder sortOrder = config.sortOrder(); + if (sortOrder != SortOrder.NONE) + { + Comparator comparator = Comparator.comparingLong(Timer::getDisplayTime); + if (sortOrder == SortOrder.DESC) + { + comparator = comparator.reversed(); + } + + if (!Comparators.isInOrder(timers, comparator)) + { + timers.sort(comparator); + SwingUtilities.invokeLater(clockTabPanel::rebuild); + return true; + } + } + return false; + } + public void loadTimers() { final String timersJson = configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.TIMERS); From df18bdb542a93b09a2f0ffde28703d3ee671b8ff Mon Sep 17 00:00:00 2001 From: melkypie <5113962+melkypie@users.noreply.github.com> Date: Wed, 18 Mar 2020 13:56:35 +0200 Subject: [PATCH 07/16] timetracking: add timer warning colors Lets the user choose a time for showing when the timer should turn orange. Co-authored-by: jakewilson --- .../timetracking/TimeTrackingConfig.java | 12 +++++++++ .../timetracking/TimeTrackingPlugin.java | 1 + .../timetracking/clocks/ClockManager.java | 11 ++++++++ .../timetracking/clocks/ClockPanel.java | 11 ++++++-- .../plugins/timetracking/clocks/Timer.java | 12 +++++++++ .../timetracking/clocks/TimerPanel.java | 25 +++++++++++++++++++ 6 files changed, 70 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java index 94d388e40d..0f7598e4ca 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java @@ -94,6 +94,18 @@ public interface TimeTrackingConfig extends Config return SortOrder.NONE; } + @ConfigItem( + keyName = "timerWarningThreshold", + name = "Timer Warning Threshold", + description = "The time at which to change the timer color to the warning color", + position = 6 + ) + @Units(Units.SECONDS) + default int timerWarningThreshold() + { + return 10; + } + @ConfigItem( keyName = "activeTab", name = "Active Tab", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java index e8b1c70ff3..c3def0d822 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java @@ -230,6 +230,7 @@ public class TimeTrackingPlugin extends Plugin { clockDataChanged = clockManager.checkCompletion(); timerOrderChanged = clockManager.checkTimerOrder(); + clockManager.checkForWarnings(); } if (unitTime % panel.getUpdateInterval() == 0 || clockDataChanged || timerOrderChanged) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java index 342da8c3f7..1f01e1c3c1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java @@ -161,6 +161,17 @@ public class ClockManager return false; } + /** + * Sets the warning flag on each timer that should be in the warning state + */ + public void checkForWarnings() + { + for (Timer timer : timers) + { + timer.setWarning(timer.getDisplayTime() <= config.timerWarningThreshold()); + } + } + public void loadTimers() { final String timersJson = configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.TIMERS); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockPanel.java index 612a5a0918..2cf45b8f36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockPanel.java @@ -64,7 +64,7 @@ abstract class ClockPanel extends JPanel private final FlatTextField nameInput; private final JToggleButton startPauseButton; - private final FlatTextField displayInput; + protected final FlatTextField displayInput; @Getter private final Clock clock; @@ -150,6 +150,7 @@ abstract class ClockPanel extends JPanel clock.setDuration(Math.max(0, duration)); clock.reset(); + clockManager.checkForWarnings(); updateDisplayInput(); updateActivityStatus(); clockManager.saveTimers(); @@ -199,6 +200,7 @@ abstract class ClockPanel extends JPanel resetButton.addActionListener(e -> { clock.reset(); + clockManager.checkForWarnings(); reset(); clockManager.saveToConfig(); }); @@ -238,7 +240,7 @@ abstract class ClockPanel extends JPanel boolean isActive = clock.isActive(); displayInput.setEditable(editable && !isActive); - displayInput.getTextField().setForeground(isActive ? ACTIVE_CLOCK_COLOR : INACTIVE_CLOCK_COLOR); + displayInput.getTextField().setForeground(getColor()); startPauseButton.setToolTipText(isActive ? "Pause " + clockType : "Start " + clockType); startPauseButton.setSelected(isActive); @@ -248,6 +250,11 @@ abstract class ClockPanel extends JPanel } } + protected Color getColor() + { + return clock.isActive() ? ACTIVE_CLOCK_COLOR : INACTIVE_CLOCK_COLOR; + } + static String getFormattedDuration(long duration) { long hours = duration / (60 * 60); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/Timer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/Timer.java index d4e0de6132..48adf0e768 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/Timer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/Timer.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.timetracking.clocks; import java.time.Instant; +import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -40,11 +41,16 @@ class Timer extends Clock // the number of seconds remaining on the timer, as of last updated time private long remaining; + // whether this timer is in the 'warning' state or not + @Getter(AccessLevel.NONE) + private transient boolean warning; + Timer(String name, long duration) { super(name); this.duration = duration; this.remaining = duration; + this.warning = false; } @Override @@ -66,6 +72,7 @@ class Timer extends Clock if (remaining <= 0) { remaining = duration; + warning = false; } lastUpdate = Instant.now().getEpochSecond(); active = true; @@ -96,4 +103,9 @@ class Timer extends Clock remaining = duration; lastUpdate = Instant.now().getEpochSecond(); } + + boolean isWarning() + { + return warning && (remaining > 0); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/TimerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/TimerPanel.java index c1fc578dff..af65253480 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/TimerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/TimerPanel.java @@ -24,12 +24,16 @@ */ package net.runelite.client.plugins.timetracking.clocks; +import java.awt.Color; import java.awt.Dimension; import javax.swing.JButton; +import net.runelite.client.ui.ColorScheme; import net.runelite.client.util.SwingUtil; class TimerPanel extends ClockPanel { + private static final Color WARNING_COLOR = ColorScheme.BRAND_ORANGE; + TimerPanel(ClockManager clockManager, Timer timer) { super(clockManager, timer, "timer", true); @@ -42,4 +46,25 @@ class TimerPanel extends ClockPanel deleteButton.addActionListener(e -> clockManager.removeTimer(timer)); rightActions.add(deleteButton); } + + @Override + void updateDisplayInput() + { + super.updateDisplayInput(); + + Timer timer = (Timer) getClock(); + if (timer.isWarning()) + { + displayInput.getTextField().setForeground(getColor()); + } + } + + @Override + protected Color getColor() + { + Timer timer = (Timer) getClock(); + Color warningColor = timer.isActive() ? WARNING_COLOR : WARNING_COLOR.darker(); + + return timer.isWarning() ? warningColor : super.getColor(); + } } From ed5c0f733625c8c7f2d4e8c986f3140873f3b84b Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 13 Mar 2020 18:55:33 -0400 Subject: [PATCH 08/16] overlay: add mouseover callback --- .../java/net/runelite/client/ui/overlay/Overlay.java | 4 ++++ .../runelite/client/ui/overlay/OverlayRenderer.java | 11 ++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java index 07b9518be3..abd2fc3f48 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java @@ -68,4 +68,8 @@ public abstract class Overlay implements LayoutableRenderableEntity { return this.getClass().getSimpleName(); } + + public void onMouseOver() + { + } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index ce634cc491..01cf3cec85 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -223,7 +223,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener if (!isResizeable) { // On fixed mode, ABOVE_CHATBOX_RIGHT is in the same location as - // BOTTOM_RIGHT and CANVAST_TOP_RIGHT is same as TOP_RIGHT. + // BOTTOM_RIGHT and CANVAS_TOP_RIGHT is same as TOP_RIGHT. // Just use BOTTOM_RIGHT and TOP_RIGHT to prevent overlays from // drawing over each other. switch (overlayPosition) @@ -304,9 +304,14 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener graphics.setColor(previous); } - if (menuEntries == null && !client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse)) + if (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse)) { - menuEntries = createRightClickMenuEntries(overlay); + if (menuEntries == null) + { + menuEntries = createRightClickMenuEntries(overlay); + } + + overlay.onMouseOver(); } } } From 023860f928bac02a9b6006bffdd147aca1f9d9b8 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 13 Mar 2020 18:55:50 -0400 Subject: [PATCH 09/16] client: add dps plugin Co-authored-by: Max Weber --- .../client/plugins/dpscounter/DpsConfig.java | 55 ++++ .../plugins/dpscounter/DpsCounterPlugin.java | 293 ++++++++++++++++++ .../client/plugins/dpscounter/DpsMember.java | 99 ++++++ .../client/plugins/dpscounter/DpsOverlay.java | 167 ++++++++++ .../client/plugins/dpscounter/DpsUpdate.java | 36 +++ 5 files changed, 650 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java new file mode 100644 index 0000000000..5720f57016 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 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.dpscounter; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("dpscounter") +public interface DpsConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "showDamage", + name = "Show damage", + description = "Show total damage instead of DPS" + ) + default boolean showDamage() + { + return false; + } + + @ConfigItem( + position = 1, + keyName = "autopause", + name = "Auto pause", + description = "Pause the DPS tracker when a boss dies" + ) + default boolean autopause() + { + return false; + } +} 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 new file mode 100644 index 0000000000..186c52d561 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2020 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.dpscounter; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Provides; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.Hitsplat; +import net.runelite.api.NPC; +import static net.runelite.api.NpcID.*; +import net.runelite.api.Player; +import net.runelite.api.events.HitsplatApplied; +import net.runelite.api.events.NpcDespawned; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.OverlayMenuClicked; +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; + +@PluginDescriptor( + name = "DPS Counter", + description = "Counts damage (per second) by a party", + enabledByDefault = false +) +@Slf4j +public class DpsCounterPlugin extends Plugin +{ + private static final ImmutableSet BOSSES = ImmutableSet.of( + ABYSSAL_SIRE, ABYSSAL_SIRE_5887, ABYSSAL_SIRE_5888, ABYSSAL_SIRE_5889, ABYSSAL_SIRE_5890, ABYSSAL_SIRE_5891, ABYSSAL_SIRE_5908, + CALLISTO, CALLISTO_6609, + CERBERUS, CERBERUS_5863, CERBERUS_5866, + CHAOS_ELEMENTAL, CHAOS_ELEMENTAL_6505, + CORPOREAL_BEAST, + GENERAL_GRAARDOR, GENERAL_GRAARDOR_6494, + GIANT_MOLE, GIANT_MOLE_6499, + KALPHITE_QUEEN, KALPHITE_QUEEN_963, KALPHITE_QUEEN_965, KALPHITE_QUEEN_4303, KALPHITE_QUEEN_4304, KALPHITE_QUEEN_6500, KALPHITE_QUEEN_6501, + KING_BLACK_DRAGON, KING_BLACK_DRAGON_2642, KING_BLACK_DRAGON_6502, + KRIL_TSUTSAROTH, KRIL_TSUTSAROTH_6495, + SARACHNIS, + VENENATIS, VENENATIS_6610, + VETION, VETION_REBORN, + + // ToB + THE_MAIDEN_OF_SUGADINTI, THE_MAIDEN_OF_SUGADINTI_8361, THE_MAIDEN_OF_SUGADINTI_8362, THE_MAIDEN_OF_SUGADINTI_8363, THE_MAIDEN_OF_SUGADINTI_8364, THE_MAIDEN_OF_SUGADINTI_8365, + PESTILENT_BLOAT, + NYLOCAS_VASILIAS, NYLOCAS_VASILIAS_8355, NYLOCAS_VASILIAS_8356, NYLOCAS_VASILIAS_8357, + SOTETSEG, SOTETSEG_8388, + XARPUS_8340, XARPUS_8341, + VERZIK_VITUR_8370, + VERZIK_VITUR_8372, + VERZIK_VITUR_8374, + + // CoX + TEKTON, TEKTON_7541, TEKTON_7542, TEKTON_ENRAGED, TEKTON_ENRAGED_7544, TEKTON_7545, + VESPULA, VESPULA_7531, VESPULA_7532, ABYSSAL_PORTAL, + VANGUARD, VANGUARD_7526, VANGUARD_7527, VANGUARD_7528, VANGUARD_7529, + GREAT_OLM, GREAT_OLM_LEFT_CLAW, GREAT_OLM_RIGHT_CLAW_7553, GREAT_OLM_7554, GREAT_OLM_LEFT_CLAW_7555, + DEATHLY_RANGER, DEATHLY_MAGE, + MUTTADILE, MUTTADILE_7562, MUTTADILE_7563, + VASA_NISTIRIO, VASA_NISTIRIO_7567, + GUARDIAN, GUARDIAN_7570, GUARDIAN_7571, GUARDIAN_7572, + LIZARDMAN_SHAMAN_7573, LIZARDMAN_SHAMAN_7574, + ICE_DEMON, ICE_DEMON_7585, + SKELETAL_MYSTIC, SKELETAL_MYSTIC_7605, SKELETAL_MYSTIC_7606, + + THE_NIGHTMARE, THE_NIGHTMARE_9426, THE_NIGHTMARE_9427, THE_NIGHTMARE_9428, THE_NIGHTMARE_9429, THE_NIGHTMARE_9430, THE_NIGHTMARE_9431, THE_NIGHTMARE_9432, THE_NIGHTMARE_9433 + ); + + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private PartyService partyService; + + @Inject + private WSClient wsClient; + + @Inject + private DpsOverlay dpsOverlay; + + @Inject + private DpsConfig dpsConfig; + + @Getter(AccessLevel.PACKAGE) + private final Map members = new ConcurrentHashMap<>(); + @Getter(AccessLevel.PACKAGE) + private final DpsMember total = new DpsMember("Total"); + + @Provides + DpsConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(DpsConfig.class); + } + + @Override + protected void startUp() + { + total.reset(); + overlayManager.add(dpsOverlay); + wsClient.registerMessage(DpsUpdate.class); + } + + @Override + protected void shutDown() + { + wsClient.unregisterMessage(DpsUpdate.class); + overlayManager.remove(dpsOverlay); + members.clear(); + } + + @Subscribe + public void onPartyChanged(PartyChanged partyChanged) + { + members.clear(); + } + + @Subscribe + public void onHitsplatApplied(HitsplatApplied hitsplatApplied) + { + Player player = client.getLocalPlayer(); + Actor actor = hitsplatApplied.getActor(); + if (!(actor instanceof NPC)) + { + return; + } + + Hitsplat hitsplat = hitsplatApplied.getHitsplat(); + + switch (hitsplat.getHitsplatType()) + { + case DAMAGE_ME: + int hit = hitsplat.getAmount(); + // Update local member + PartyMember localMember = partyService.getLocalMember(); + // If not in a party, user local player name + final String name = localMember == null ? player.getName() : localMember.getName(); + DpsMember dpsMember = members.computeIfAbsent(name, DpsMember::new); + dpsMember.addDamage(hit); + + // broadcast damage + if (localMember != null) + { + final DpsUpdate specialCounterUpdate = new DpsUpdate(hit); + specialCounterUpdate.setMemberId(localMember.getMemberId()); + wsClient.send(specialCounterUpdate); + } + // apply to total + break; + case DAMAGE_OTHER: + final int npcId = ((NPC) actor).getId(); + boolean isBoss = BOSSES.contains(npcId); + if (actor != player.getInteracting() && !isBoss) + { + // only track damage to npcs we are attacking, or is a nearby common boss + return; + } + // apply to total + break; + default: + return; + } + + unpause(); + total.addDamage(hitsplat.getAmount()); + } + + @Subscribe + public void onDpsUpdate(DpsUpdate dpsUpdate) + { + if (partyService.getLocalMember().getMemberId().equals(dpsUpdate.getMemberId())) + { + return; + } + + String name = partyService.getMemberById(dpsUpdate.getMemberId()).getName(); + if (name == null) + { + return; + } + + unpause(); + + DpsMember dpsMember = members.computeIfAbsent(name, DpsMember::new); + dpsMember.addDamage(dpsUpdate.getHit()); + } + + @Subscribe + public void onOverlayMenuClicked(OverlayMenuClicked event) + { + if (event.getEntry() == DpsOverlay.RESET_ENTRY) + { + members.clear(); + total.reset(); + } + else if (event.getEntry() == DpsOverlay.UNPAUSE_ENTRY) + { + unpause(); + } + else if (event.getEntry() == DpsOverlay.PAUSE_ENTRY) + { + pause(); + } + } + + @Subscribe + public void onNpcDespawned(NpcDespawned npcDespawned) + { + NPC npc = npcDespawned.getNpc(); + + if (npc.isDead() && BOSSES.contains(npc.getId())) + { + log.debug("Boss has died!"); + + if (dpsConfig.autopause()) + { + pause(); + } + } + } + + private void pause() + { + if (total.isPaused()) + { + return; + } + + log.debug("Pausing"); + + for (DpsMember dpsMember : members.values()) + { + dpsMember.pause(); + } + total.pause(); + + dpsOverlay.setPaused(true); + } + + private void unpause() + { + if (!total.isPaused()) + { + return; + } + + log.debug("Unpausing"); + + for (DpsMember dpsMember : members.values()) + { + dpsMember.unpause(); + } + total.unpause(); + + dpsOverlay.setPaused(false); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java new file mode 100644 index 0000000000..e35bbedbd2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020 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.dpscounter; + +import java.time.Duration; +import java.time.Instant; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +class DpsMember +{ + private final String name; + private Instant start; + private Instant end; + private int damage; + + void addDamage(int amount) + { + if (start == null) + { + start = Instant.now(); + } + + damage += amount; + } + + float getDps() + { + if (start == null) + { + return 0; + } + + Instant now = end == null ? Instant.now() : end; + int diff = (int) (now.toEpochMilli() - start.toEpochMilli()) / 1000; + if (diff == 0) + { + return 0; + } + + return (float) damage / (float) diff; + } + + void pause() + { + end = Instant.now(); + } + + boolean isPaused() + { + return start == null || end != null; + } + + void unpause() + { + if (end == null) + { + return; + } + + start = start.plus(Duration.between(end, Instant.now())); + end = null; + } + + void reset() + { + damage = 0; + start = end = Instant.now(); + } + + Duration elapsed() + { + return Duration.between(start, end == null ? Instant.now() : end); + } +} 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 new file mode 100644 index 0000000000..44b31c481c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020 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.dpscounter; + +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.text.DecimalFormat; +import java.time.Duration; +import java.util.Map; +import javax.inject.Inject; +import net.runelite.api.Client; +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY; +import net.runelite.api.Player; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayMenuEntry; +import net.runelite.client.ui.overlay.components.ComponentConstants; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +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; + +class DpsOverlay extends Overlay +{ + private static final DecimalFormat DPS_FORMAT = new DecimalFormat("#0.0"); + private static final int PANEL_WIDTH_OFFSET = 10; // assumes 8 for panel component border + 2px between left and right + + static final OverlayMenuEntry RESET_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Reset", "DPS counter"); + static final OverlayMenuEntry PAUSE_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Pause", "DPS counter"); + static final OverlayMenuEntry UNPAUSE_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Unpause", "DPS counter"); + + private final DpsCounterPlugin dpsCounterPlugin; + private final DpsConfig dpsConfig; + private final PartyService partyService; + private final Client client; + private final TooltipManager tooltipManager; + + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + DpsOverlay(DpsCounterPlugin dpsCounterPlugin, DpsConfig dpsConfig, PartyService partyService, Client client, + TooltipManager tooltipManager) + { + super(dpsCounterPlugin); + this.dpsCounterPlugin = dpsCounterPlugin; + this.dpsConfig = dpsConfig; + this.partyService = partyService; + this.client = client; + this.tooltipManager = tooltipManager; + getMenuEntries().add(RESET_ENTRY); + setPaused(false); + } + + @Override + public void onMouseOver() + { + DpsMember total = dpsCounterPlugin.getTotal(); + Duration elapsed = total.elapsed(); + long s = elapsed.getSeconds(); + String format; + if (s >= 3600) + { + format = String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60)); + } + else + { + format = String.format("%d:%02d", s / 60, (s % 60)); + } + tooltipManager.add(new Tooltip("Elapsed time: " + format)); + } + + @Override + public Dimension render(Graphics2D graphics) + { + Map dpsMembers = dpsCounterPlugin.getMembers(); + if (dpsMembers.isEmpty()) + { + return null; + } + + boolean inParty = !partyService.getMembers().isEmpty(); + boolean showDamage = dpsConfig.showDamage(); + DpsMember total = dpsCounterPlugin.getTotal(); + boolean paused = total.isPaused(); + + panelComponent.getChildren().clear(); + + final String title = (inParty ? "Party " : "") + (showDamage ? "Damage" : "DPS") + (paused ? " (paused)" : ""); + panelComponent.getChildren().add( + TitleComponent.builder() + .text(title) + .build()); + + int maxWidth = ComponentConstants.STANDARD_WIDTH; + FontMetrics fontMetrics = graphics.getFontMetrics(); + + for (DpsMember dpsMember : dpsMembers.values()) + { + String left = dpsMember.getName(); + String right = showDamage ? QuantityFormatter.formatNumber(dpsMember.getDamage()) : DPS_FORMAT.format(dpsMember.getDps()); + maxWidth = Math.max(maxWidth, fontMetrics.stringWidth(left) + fontMetrics.stringWidth(right)); + panelComponent.getChildren().add( + LineComponent.builder() + .left(left) + .right(right) + .build()); + } + + panelComponent.setPreferredSize(new Dimension(maxWidth + PANEL_WIDTH_OFFSET, 0)); + + if (!inParty) + { + Player player = client.getLocalPlayer(); + if (player.getName() != null) + { + DpsMember self = dpsMembers.get(player.getName()); + + if (self != null && total.getDamage() > self.getDamage()) + { + panelComponent.getChildren().add( + LineComponent.builder() + .left(total.getName()) + .right(showDamage ? Integer.toString(total.getDamage()) : DPS_FORMAT.format(total.getDps())) + .build()); + } + } + } + + return panelComponent.render(graphics); + } + + void setPaused(boolean paused) + { + OverlayMenuEntry remove = paused ? PAUSE_ENTRY : UNPAUSE_ENTRY; + OverlayMenuEntry add = paused ? UNPAUSE_ENTRY : PAUSE_ENTRY; + getMenuEntries().remove(remove); + if (!getMenuEntries().contains(add)) + { + getMenuEntries().add(add); + } + } +} 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 new file mode 100644 index 0000000000..81e5859b38 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 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.dpscounter; + +import lombok.EqualsAndHashCode; +import lombok.Value; +import net.runelite.http.api.ws.messages.party.PartyMemberMessage; + +@Value +@EqualsAndHashCode(callSuper = true) +public class DpsUpdate extends PartyMemberMessage +{ + private int hit; +} From c3bb4f0d37ee02d644572fa844bf58c58b07e560 Mon Sep 17 00:00:00 2001 From: DeliciousLunch55 Date: Fri, 20 Mar 2020 22:31:27 -0500 Subject: [PATCH 10/16] cannon: Add Black Knights cannoning spot in Taverley Dungeon (#11046) --- .../java/net/runelite/client/plugins/cannon/CannonSpots.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java index 1292443299..85bc05f217 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonSpots.java @@ -38,6 +38,7 @@ public enum CannonSpots ABERRANT_SPECTRES(new WorldPoint(2456, 9791, 0)), HELLHOUNDS(new WorldPoint(2431, 9776, 0), new WorldPoint(2413, 9786, 0), new WorldPoint(2783, 9686, 0), new WorldPoint(3198, 10071, 0)), BLACK_DEMONS(new WorldPoint(2859, 9778, 0), new WorldPoint(2841, 9791, 0), new WorldPoint(1421, 10089, 1)), + BLACK_KNIGHTS(new WorldPoint(2906, 9685, 0)), ELVES(new WorldPoint(2044, 4635, 0), new WorldPoint(3278, 6098, 0)), SUQAHS(new WorldPoint(2114, 3943, 0)), TROLLS(new WorldPoint(2401, 3856, 0), new WorldPoint(1242, 3517, 0)), From 203ecce4db48683df07d95c913171b85fdacd472 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 22 Mar 2020 11:01:45 -0400 Subject: [PATCH 11/16] keyremapping: add option to block extra mouse buttons --- .../keyremapping/KeyRemappingConfig.java | 11 +++ .../keyremapping/KeyRemappingListener.java | 31 ++++++++ .../keyremapping/KeyRemappingPlugin.java | 6 ++ .../KeyRemappingListenerTest.java | 77 +++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java index 0ee4c58e22..6b108a011e 100755 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java @@ -241,4 +241,15 @@ public interface KeyRemappingConfig extends Config { return new ModifierlessKeybind(KeyEvent.VK_ESCAPE, 0); } + + @ConfigItem( + position = 20, + keyName = "consumeExtraMouseButtons", + name = "Block extra mouse buttons", + description = "Blocks mouse buttons 4 and 5" + ) + default boolean consumeExtraMouseButtons() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java index fbdc08a7aa..b40fecef4c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.keyremapping; import com.google.common.base.Strings; import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; @@ -39,6 +40,8 @@ import net.runelite.client.input.MouseAdapter; class KeyRemappingListener extends MouseAdapter implements KeyListener { + // Button numbers greater than BUTTON3 have no constant identifier + private static final int MOUSE_BUTTON_4 = 4; @Inject private KeyRemappingPlugin plugin; @@ -307,4 +310,32 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener } } } + + @Override + public MouseEvent mouseClicked(MouseEvent mouseEvent) + { + return consumeMouseEvent(mouseEvent); + } + + @Override + public MouseEvent mousePressed(MouseEvent mouseEvent) + { + return consumeMouseEvent(mouseEvent); + } + + @Override + public MouseEvent mouseReleased(MouseEvent mouseEvent) + { + return consumeMouseEvent(mouseEvent); + } + + private MouseEvent consumeMouseEvent(MouseEvent mouseEvent) + { + int button = mouseEvent.getButton(); + if (button >= MOUSE_BUTTON_4 && config.consumeExtraMouseButtons()) + { + mouseEvent.consume(); + } + return mouseEvent; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java index c2b2ee146f..dbf60a38c9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java @@ -43,6 +43,7 @@ import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyManager; +import net.runelite.client.input.MouseManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.JagexColors; @@ -69,6 +70,9 @@ public class KeyRemappingPlugin extends Plugin @Inject private KeyManager keyManager; + @Inject + private MouseManager mouseManager; + @Inject private KeyRemappingListener inputListener; @@ -81,6 +85,7 @@ public class KeyRemappingPlugin extends Plugin { typing = false; keyManager.registerKeyListener(inputListener); + mouseManager.registerMouseListener(inputListener); clientThread.invoke(() -> { @@ -104,6 +109,7 @@ public class KeyRemappingPlugin extends Plugin } }); + mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java new file mode 100644 index 0000000000..52bf3bc742 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, 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.keyremapping; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.awt.event.MouseEvent; +import javax.inject.Inject; +import net.runelite.api.Client; +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.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class KeyRemappingListenerTest +{ + @Inject + private KeyRemappingListener keyRemappingListener; + + @Mock + @Bind + private Client client; + + @Mock + @Bind + private KeyRemappingConfig keyRemappingConfig; + + @Before + public void setUp() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testMouseClicked() + { + when(keyRemappingConfig.consumeExtraMouseButtons()).thenReturn(true); + MouseEvent mouseEvent = mock(MouseEvent.class); + when(mouseEvent.getButton()).thenReturn(4); + keyRemappingListener.mousePressed(mouseEvent); + verify(mouseEvent).consume(); + + mouseEvent = mock(MouseEvent.class); + when(mouseEvent.getButton()).thenReturn(1); + keyRemappingListener.mousePressed(mouseEvent); + verify(mouseEvent, never()).consume(); + } +} From 0ee189cf9d3dda10364853b45c451d8c502c0732 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 22 Mar 2020 11:17:21 -0400 Subject: [PATCH 12/16] keyremapping: add test for typing mode change --- .../KeyRemappingListenerTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java index 52bf3bc742..96b131aacc 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java @@ -27,9 +27,12 @@ package net.runelite.client.plugins.keyremapping; import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.client.config.ModifierlessKeybind; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,6 +53,10 @@ public class KeyRemappingListenerTest @Bind private Client client; + @Mock + @Bind + private KeyRemappingPlugin keyRemappingPlugin; + @Mock @Bind private KeyRemappingConfig keyRemappingConfig; @@ -58,6 +65,33 @@ public class KeyRemappingListenerTest public void setUp() { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getGameState()).thenReturn(GameState.LOGGED_IN); + } + + @Test + public void testTypingStateChange() + { + when(keyRemappingConfig.cameraRemap()).thenReturn(true); + when(keyRemappingConfig.up()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_W, 0)); + when(keyRemappingConfig.down()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_S, 0)); + when(keyRemappingConfig.left()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_A, 0)); + when(keyRemappingConfig.right()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_D, 0)); + + when(keyRemappingPlugin.chatboxFocused()).thenReturn(true); + KeyEvent event = mock(KeyEvent.class); + when(event.getKeyCode()).thenReturn(KeyEvent.VK_D); + when(event.getExtendedKeyCode()).thenReturn(KeyEvent.VK_D); // for keybind matches() + keyRemappingListener.keyPressed(event); + verify(event).setKeyCode(KeyEvent.VK_RIGHT); + + // with the plugin now in typing mode, previously pressed and remapped keys should still be mapped + // on key release regardless + when(keyRemappingPlugin.isTyping()).thenReturn(true); + event = mock(KeyEvent.class); + when(event.getKeyCode()).thenReturn(KeyEvent.VK_D); + keyRemappingListener.keyReleased(event); + verify(event).setKeyCode(KeyEvent.VK_RIGHT); } @Test From 5da84178e7b30723b5b6e05338429ad19a5ca26b Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 22 Mar 2020 14:24:52 -0400 Subject: [PATCH 13/16] chatcommands: fix showing -1 experience/rank in lvl --- .../chatcommands/ChatCommandsPlugin.java | 32 ++++-- .../chatcommands/ChatCommandsPluginTest.java | 103 ++++++++++++++---- 2 files changed, 102 insertions(+), 33 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index ae704913b7..ad0e3a0727 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -55,8 +55,8 @@ import net.runelite.api.events.WidgetLoaded; import net.runelite.api.vars.AccountType; import net.runelite.api.widgets.Widget; import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID; -import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID; import static net.runelite.api.widgets.WidgetID.COUNTERS_LOG_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatCommandManager; @@ -119,7 +119,6 @@ public class ChatCommandsPlugin extends Plugin @VisibleForTesting static final int ADV_LOG_EXPLOITS_TEXT_INDEX = 1; - private final HiscoreClient hiscoreClient = new HiscoreClient(); private final ChatClient chatClient = new ChatClient(); private boolean bossLogLoaded; @@ -157,6 +156,9 @@ public class ChatCommandsPlugin extends Plugin @Inject private ChatKeyboardListener chatKeyboardListener; + @Inject + private HiscoreClient hiscoreClient; + @Override public void startUp() { @@ -1005,21 +1007,27 @@ public class ChatCommandsPlugin extends Plugin final Skill hiscoreSkill = result.getSkill(); - final String response = new ChatMessageBuilder() + ChatMessageBuilder chatMessageBuilder = new ChatMessageBuilder() .append(ChatColorType.NORMAL) .append("Level ") .append(ChatColorType.HIGHLIGHT) .append(skill.getName()).append(": ").append(String.valueOf(hiscoreSkill.getLevel())) - .append(ChatColorType.NORMAL) - .append(" Experience: ") - .append(ChatColorType.HIGHLIGHT) - .append(String.format("%,d", hiscoreSkill.getExperience())) - .append(ChatColorType.NORMAL) - .append(" Rank: ") - .append(ChatColorType.HIGHLIGHT) - .append(String.format("%,d", hiscoreSkill.getRank())) - .build(); + .append(ChatColorType.NORMAL); + if (hiscoreSkill.getExperience() != -1) + { + chatMessageBuilder.append(" Experience: ") + .append(ChatColorType.HIGHLIGHT) + .append(String.format("%,d", hiscoreSkill.getExperience())) + .append(ChatColorType.NORMAL); + } + if (hiscoreSkill.getRank() != -1) + { + chatMessageBuilder.append(" Rank: ") + .append(ChatColorType.HIGHLIGHT) + .append(String.format("%,d", hiscoreSkill.getRank())); + } + final String response = chatMessageBuilder.build(); log.debug("Setting response {}", response); final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index 27de559692..f0b3954bfa 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -27,32 +27,44 @@ package net.runelite.client.plugins.chatcommands; import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.io.IOException; import java.util.concurrent.ScheduledExecutorService; +import java.util.function.BiConsumer; import javax.inject.Inject; +import net.runelite.api.ChatMessageType; import static net.runelite.api.ChatMessageType.FRIENDSCHATNOTIFICATION; import static net.runelite.api.ChatMessageType.GAMEMESSAGE; import static net.runelite.api.ChatMessageType.TRADE; import net.runelite.api.Client; +import net.runelite.api.MessageNode; import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.config.ChatColorConfig; -import net.runelite.client.config.ConfigManager; import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID; import static net.runelite.api.widgets.WidgetID.COUNTERS_LOG_GROUP_ID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.chat.ChatCommandManager; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.config.ChatColorConfig; +import net.runelite.client.config.ConfigManager; +import net.runelite.http.api.hiscore.HiscoreClient; +import net.runelite.http.api.hiscore.HiscoreSkill; +import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; +import net.runelite.http.api.hiscore.Skill; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import static org.mockito.ArgumentMatchers.eq; import org.mockito.Mock; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -79,6 +91,18 @@ public class ChatCommandsPluginTest @Bind ChatColorConfig chatColorConfig; + @Mock + @Bind + ChatCommandManager chatCommandManager; + + @Mock + @Bind + HiscoreClient hiscoreClient; + + @Mock + @Bind + ChatMessageManager chatMessageManager; + @Mock @Bind ChatCommandsConfig chatCommandsConfig; @@ -92,6 +116,14 @@ public class ChatCommandsPluginTest Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); when(client.getUsername()).thenReturn(PLAYER_NAME); + + chatCommandsPlugin.startUp(); + } + + @After + public void after() + { + chatCommandsPlugin.shutDown(); } @Test @@ -380,22 +412,22 @@ public class ChatCommandsPluginTest chatCommandsPlugin.onGameTick(new GameTick()); String COUNTER_TEXT = "Duel Arena
Wins: 4
Losses: 2" + - "

Last Man Standing
Rank: 0" + - "

Treasure Trails
Beginner: 0
Easy: 7" + - "
Medium: 28
Hard: 108
Elite: 15" + - "
Master: 27
Rank: Novice" + - "

Chompy Hunting
Kills: 1,000
Rank: Ogre Expert" + - "

Order of the White Knights
Rank: Master
with a kill score of 1,300" + - "

TzHaar Fight Cave
Fastest run: 38:10" + - "

Inferno
Fastest run: -

Zulrah
" + - "Fastest kill: 5:48

Vorkath
Fastest kill: 1:21" + - "

Galvek
Fastest kill: -

Grotesque Guardians
" + - "Fastest kill: 2:49

Alchemical Hydra
Fastest kill: -" + - "

Hespori
Fastest kill: 0:57

Nightmare
" + - "Fastest kill: 3:30

The Gauntlet
Fastest run: -" + - "

The Corrupted Gauntlet
Fastest run: -

Fragment of Seren
" + - "Fastest kill: -

Barbarian Assault
High-level gambles: " + - "15

Fremennik spirits rested: 0"; + "

Last Man Standing
Rank: 0" + + "

Treasure Trails
Beginner: 0
Easy: 7" + + "
Medium: 28
Hard: 108
Elite: 15" + + "
Master: 27
Rank: Novice" + + "

Chompy Hunting
Kills: 1,000
Rank: Ogre Expert" + + "

Order of the White Knights
Rank: Master
with a kill score of 1,300" + + "

TzHaar Fight Cave
Fastest run: 38:10" + + "

Inferno
Fastest run: -

Zulrah
" + + "Fastest kill: 5:48

Vorkath
Fastest kill: 1:21" + + "

Galvek
Fastest kill: -

Grotesque Guardians
" + + "Fastest kill: 2:49

Alchemical Hydra
Fastest kill: -" + + "

Hespori
Fastest kill: 0:57

Nightmare
" + + "Fastest kill: 3:30

The Gauntlet
Fastest run: -" + + "

The Corrupted Gauntlet
Fastest run: -

Fragment of Seren
" + + "Fastest kill: -

Barbarian Assault
High-level gambles: " + + "15

Fremennik spirits rested: 0"; Widget countersPage = mock(Widget.class); when(countersPage.getText()).thenReturn(COUNTER_TEXT); @@ -411,7 +443,7 @@ public class ChatCommandsPluginTest verify(configManager).setConfiguration(eq("personalbest.adam"), eq("vorkath"), eq(1 * 60 + 21)); verify(configManager).setConfiguration(eq("personalbest.adam"), eq("grotesque guardians"), eq(2 * 60 + 49)); verify(configManager).setConfiguration(eq("personalbest.adam"), eq("hespori"), eq(57)); - verify(configManager).setConfiguration(eq("personalbest.adam"), eq("nightmare"), eq( 3 * 60 + 30)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("nightmare"), eq(3 * 60 + 30)); } @Test @@ -490,4 +522,33 @@ public class ChatCommandsPluginTest verifyNoMoreInteractions(configManager); } + + @Test + public void testPlayerSkillLookup() throws IOException + { + Player player = mock(Player.class); + when(player.getName()).thenReturn(PLAYER_NAME); + when(client.getLocalPlayer()).thenReturn(player); + + when(chatCommandsConfig.lvl()).thenReturn(true); + ArgumentCaptor> captor = ArgumentCaptor.forClass(BiConsumer.class); + verify(chatCommandManager).registerCommandAsync(eq("!lvl"), captor.capture()); + BiConsumer value = captor.getValue(); + + SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); + skillResult.setPlayer(PLAYER_NAME); + skillResult.setSkill(new Skill(10, 1000, -1)); + + when(hiscoreClient.lookup(PLAYER_NAME, HiscoreSkill.ZULRAH, null)).thenReturn(skillResult); + + MessageNode messageNode = mock(MessageNode.class); + + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.PUBLICCHAT); + chatMessage.setName(PLAYER_NAME); + chatMessage.setMessageNode(messageNode); + value.accept(chatMessage, "!lvl zulrah"); + + verify(messageNode).setRuneLiteFormatMessage("Level Zulrah: 1000 Rank: 10"); + } } From 046c20fb5bd5b3f7c89d635b7a7a83ddaf0d8450 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 22 Mar 2020 17:59:41 -0400 Subject: [PATCH 14/16] client: block extra mouse keys The key remapping plugin has no way to operate being on and also not blocking chat input, due to the other features of the plugin all doing key remaps and thus are required to know whether or not you are trying to type, or using a remapped key. This moves the blocking to the core, which we think won't affect many users anyway, and those that it does can just remap their mouse keys. --- .../runelite/client/input/MouseManager.java | 17 +++++++++ .../keyremapping/KeyRemappingConfig.java | 11 ------ .../keyremapping/KeyRemappingListener.java | 35 +------------------ .../keyremapping/KeyRemappingPlugin.java | 6 ---- .../KeyRemappingListenerTest.java | 17 --------- 5 files changed, 18 insertions(+), 68 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java b/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java index ba1e3b80e8..d444f93fe6 100644 --- a/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java +++ b/runelite-client/src/main/java/net/runelite/client/input/MouseManager.java @@ -33,6 +33,9 @@ import javax.inject.Singleton; @Singleton public class MouseManager { + // Button numbers greater than BUTTON3 have no constant identifier + private static final int MOUSE_BUTTON_4 = 4; + private final List mouseListeners = new CopyOnWriteArrayList<>(); private final List mouseWheelListeners = new CopyOnWriteArrayList<>(); @@ -74,6 +77,7 @@ public class MouseManager public MouseEvent processMousePressed(MouseEvent mouseEvent) { + checkExtraMouseButtons(mouseEvent); for (MouseListener mouseListener : mouseListeners) { mouseEvent = mouseListener.mousePressed(mouseEvent); @@ -83,6 +87,7 @@ public class MouseManager public MouseEvent processMouseReleased(MouseEvent mouseEvent) { + checkExtraMouseButtons(mouseEvent); for (MouseListener mouseListener : mouseListeners) { mouseEvent = mouseListener.mouseReleased(mouseEvent); @@ -92,6 +97,7 @@ public class MouseManager public MouseEvent processMouseClicked(MouseEvent mouseEvent) { + checkExtraMouseButtons(mouseEvent); for (MouseListener mouseListener : mouseListeners) { mouseEvent = mouseListener.mouseClicked(mouseEvent); @@ -99,6 +105,17 @@ public class MouseManager return mouseEvent; } + private void checkExtraMouseButtons(MouseEvent mouseEvent) + { + // Prevent extra mouse buttins from being passed into the client, + // as it treats them all as left click + int button = mouseEvent.getButton(); + if (button >= MOUSE_BUTTON_4) + { + mouseEvent.consume(); + } + } + public MouseEvent processMouseEntered(MouseEvent mouseEvent) { for (MouseListener mouseListener : mouseListeners) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java index 6b108a011e..0ee4c58e22 100755 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java @@ -241,15 +241,4 @@ public interface KeyRemappingConfig extends Config { return new ModifierlessKeybind(KeyEvent.VK_ESCAPE, 0); } - - @ConfigItem( - position = 20, - keyName = "consumeExtraMouseButtons", - name = "Block extra mouse buttons", - description = "Blocks mouse buttons 4 and 5" - ) - default boolean consumeExtraMouseButtons() - { - return false; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java index b40fecef4c..6ca245af1a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.keyremapping; import com.google.common.base.Strings; import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; @@ -36,13 +35,9 @@ import net.runelite.api.GameState; import net.runelite.api.VarClientStr; import net.runelite.client.callback.ClientThread; import net.runelite.client.input.KeyListener; -import net.runelite.client.input.MouseAdapter; -class KeyRemappingListener extends MouseAdapter implements KeyListener +class KeyRemappingListener implements KeyListener { - // Button numbers greater than BUTTON3 have no constant identifier - private static final int MOUSE_BUTTON_4 = 4; - @Inject private KeyRemappingPlugin plugin; @@ -310,32 +305,4 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener } } } - - @Override - public MouseEvent mouseClicked(MouseEvent mouseEvent) - { - return consumeMouseEvent(mouseEvent); - } - - @Override - public MouseEvent mousePressed(MouseEvent mouseEvent) - { - return consumeMouseEvent(mouseEvent); - } - - @Override - public MouseEvent mouseReleased(MouseEvent mouseEvent) - { - return consumeMouseEvent(mouseEvent); - } - - private MouseEvent consumeMouseEvent(MouseEvent mouseEvent) - { - int button = mouseEvent.getButton(); - if (button >= MOUSE_BUTTON_4 && config.consumeExtraMouseButtons()) - { - mouseEvent.consume(); - } - return mouseEvent; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java index dbf60a38c9..c2b2ee146f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java @@ -43,7 +43,6 @@ import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyManager; -import net.runelite.client.input.MouseManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.JagexColors; @@ -70,9 +69,6 @@ public class KeyRemappingPlugin extends Plugin @Inject private KeyManager keyManager; - @Inject - private MouseManager mouseManager; - @Inject private KeyRemappingListener inputListener; @@ -85,7 +81,6 @@ public class KeyRemappingPlugin extends Plugin { typing = false; keyManager.registerKeyListener(inputListener); - mouseManager.registerMouseListener(inputListener); clientThread.invoke(() -> { @@ -109,7 +104,6 @@ public class KeyRemappingPlugin extends Plugin } }); - mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java index 96b131aacc..867413420e 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java @@ -28,7 +28,6 @@ import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.GameState; @@ -38,7 +37,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -93,19 +91,4 @@ public class KeyRemappingListenerTest keyRemappingListener.keyReleased(event); verify(event).setKeyCode(KeyEvent.VK_RIGHT); } - - @Test - public void testMouseClicked() - { - when(keyRemappingConfig.consumeExtraMouseButtons()).thenReturn(true); - MouseEvent mouseEvent = mock(MouseEvent.class); - when(mouseEvent.getButton()).thenReturn(4); - keyRemappingListener.mousePressed(mouseEvent); - verify(mouseEvent).consume(); - - mouseEvent = mock(MouseEvent.class); - when(mouseEvent.getButton()).thenReturn(1); - keyRemappingListener.mousePressed(mouseEvent); - verify(mouseEvent, never()).consume(); - } } From a51724244fb49f9ebcd7c061132dc7b373d88471 Mon Sep 17 00:00:00 2001 From: xKylee <48519776+xKylee@users.noreply.github.com> Date: Mon, 23 Mar 2020 12:39:40 +0000 Subject: [PATCH 15/16] oops --- .../client/plugins/dpscounter/DpsConfig.java | 55 ---- .../plugins/dpscounter/DpsCounterPlugin.java | 293 ------------------ .../client/plugins/dpscounter/DpsMember.java | 99 ------ .../client/plugins/dpscounter/DpsOverlay.java | 167 ---------- .../client/plugins/dpscounter/DpsUpdate.java | 36 --- .../plugins/timetracking/SortOrder.java | 32 -- .../KeyRemappingListenerTest.java | 94 ------ 7 files changed, 776 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java deleted file mode 100644 index 5720f57016..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2020 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.dpscounter; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("dpscounter") -public interface DpsConfig extends Config -{ - @ConfigItem( - position = 0, - keyName = "showDamage", - name = "Show damage", - description = "Show total damage instead of DPS" - ) - default boolean showDamage() - { - return false; - } - - @ConfigItem( - position = 1, - keyName = "autopause", - name = "Auto pause", - description = "Pause the DPS tracker when a boss dies" - ) - default boolean autopause() - { - return false; - } -} 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 deleted file mode 100644 index 186c52d561..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2020 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.dpscounter; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Provides; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Actor; -import net.runelite.api.Client; -import net.runelite.api.Hitsplat; -import net.runelite.api.NPC; -import static net.runelite.api.NpcID.*; -import net.runelite.api.Player; -import net.runelite.api.events.HitsplatApplied; -import net.runelite.api.events.NpcDespawned; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.OverlayMenuClicked; -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; - -@PluginDescriptor( - name = "DPS Counter", - description = "Counts damage (per second) by a party", - enabledByDefault = false -) -@Slf4j -public class DpsCounterPlugin extends Plugin -{ - private static final ImmutableSet BOSSES = ImmutableSet.of( - ABYSSAL_SIRE, ABYSSAL_SIRE_5887, ABYSSAL_SIRE_5888, ABYSSAL_SIRE_5889, ABYSSAL_SIRE_5890, ABYSSAL_SIRE_5891, ABYSSAL_SIRE_5908, - CALLISTO, CALLISTO_6609, - CERBERUS, CERBERUS_5863, CERBERUS_5866, - CHAOS_ELEMENTAL, CHAOS_ELEMENTAL_6505, - CORPOREAL_BEAST, - GENERAL_GRAARDOR, GENERAL_GRAARDOR_6494, - GIANT_MOLE, GIANT_MOLE_6499, - KALPHITE_QUEEN, KALPHITE_QUEEN_963, KALPHITE_QUEEN_965, KALPHITE_QUEEN_4303, KALPHITE_QUEEN_4304, KALPHITE_QUEEN_6500, KALPHITE_QUEEN_6501, - KING_BLACK_DRAGON, KING_BLACK_DRAGON_2642, KING_BLACK_DRAGON_6502, - KRIL_TSUTSAROTH, KRIL_TSUTSAROTH_6495, - SARACHNIS, - VENENATIS, VENENATIS_6610, - VETION, VETION_REBORN, - - // ToB - THE_MAIDEN_OF_SUGADINTI, THE_MAIDEN_OF_SUGADINTI_8361, THE_MAIDEN_OF_SUGADINTI_8362, THE_MAIDEN_OF_SUGADINTI_8363, THE_MAIDEN_OF_SUGADINTI_8364, THE_MAIDEN_OF_SUGADINTI_8365, - PESTILENT_BLOAT, - NYLOCAS_VASILIAS, NYLOCAS_VASILIAS_8355, NYLOCAS_VASILIAS_8356, NYLOCAS_VASILIAS_8357, - SOTETSEG, SOTETSEG_8388, - XARPUS_8340, XARPUS_8341, - VERZIK_VITUR_8370, - VERZIK_VITUR_8372, - VERZIK_VITUR_8374, - - // CoX - TEKTON, TEKTON_7541, TEKTON_7542, TEKTON_ENRAGED, TEKTON_ENRAGED_7544, TEKTON_7545, - VESPULA, VESPULA_7531, VESPULA_7532, ABYSSAL_PORTAL, - VANGUARD, VANGUARD_7526, VANGUARD_7527, VANGUARD_7528, VANGUARD_7529, - GREAT_OLM, GREAT_OLM_LEFT_CLAW, GREAT_OLM_RIGHT_CLAW_7553, GREAT_OLM_7554, GREAT_OLM_LEFT_CLAW_7555, - DEATHLY_RANGER, DEATHLY_MAGE, - MUTTADILE, MUTTADILE_7562, MUTTADILE_7563, - VASA_NISTIRIO, VASA_NISTIRIO_7567, - GUARDIAN, GUARDIAN_7570, GUARDIAN_7571, GUARDIAN_7572, - LIZARDMAN_SHAMAN_7573, LIZARDMAN_SHAMAN_7574, - ICE_DEMON, ICE_DEMON_7585, - SKELETAL_MYSTIC, SKELETAL_MYSTIC_7605, SKELETAL_MYSTIC_7606, - - THE_NIGHTMARE, THE_NIGHTMARE_9426, THE_NIGHTMARE_9427, THE_NIGHTMARE_9428, THE_NIGHTMARE_9429, THE_NIGHTMARE_9430, THE_NIGHTMARE_9431, THE_NIGHTMARE_9432, THE_NIGHTMARE_9433 - ); - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private PartyService partyService; - - @Inject - private WSClient wsClient; - - @Inject - private DpsOverlay dpsOverlay; - - @Inject - private DpsConfig dpsConfig; - - @Getter(AccessLevel.PACKAGE) - private final Map members = new ConcurrentHashMap<>(); - @Getter(AccessLevel.PACKAGE) - private final DpsMember total = new DpsMember("Total"); - - @Provides - DpsConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(DpsConfig.class); - } - - @Override - protected void startUp() - { - total.reset(); - overlayManager.add(dpsOverlay); - wsClient.registerMessage(DpsUpdate.class); - } - - @Override - protected void shutDown() - { - wsClient.unregisterMessage(DpsUpdate.class); - overlayManager.remove(dpsOverlay); - members.clear(); - } - - @Subscribe - public void onPartyChanged(PartyChanged partyChanged) - { - members.clear(); - } - - @Subscribe - public void onHitsplatApplied(HitsplatApplied hitsplatApplied) - { - Player player = client.getLocalPlayer(); - Actor actor = hitsplatApplied.getActor(); - if (!(actor instanceof NPC)) - { - return; - } - - Hitsplat hitsplat = hitsplatApplied.getHitsplat(); - - switch (hitsplat.getHitsplatType()) - { - case DAMAGE_ME: - int hit = hitsplat.getAmount(); - // Update local member - PartyMember localMember = partyService.getLocalMember(); - // If not in a party, user local player name - final String name = localMember == null ? player.getName() : localMember.getName(); - DpsMember dpsMember = members.computeIfAbsent(name, DpsMember::new); - dpsMember.addDamage(hit); - - // broadcast damage - if (localMember != null) - { - final DpsUpdate specialCounterUpdate = new DpsUpdate(hit); - specialCounterUpdate.setMemberId(localMember.getMemberId()); - wsClient.send(specialCounterUpdate); - } - // apply to total - break; - case DAMAGE_OTHER: - final int npcId = ((NPC) actor).getId(); - boolean isBoss = BOSSES.contains(npcId); - if (actor != player.getInteracting() && !isBoss) - { - // only track damage to npcs we are attacking, or is a nearby common boss - return; - } - // apply to total - break; - default: - return; - } - - unpause(); - total.addDamage(hitsplat.getAmount()); - } - - @Subscribe - public void onDpsUpdate(DpsUpdate dpsUpdate) - { - if (partyService.getLocalMember().getMemberId().equals(dpsUpdate.getMemberId())) - { - return; - } - - String name = partyService.getMemberById(dpsUpdate.getMemberId()).getName(); - if (name == null) - { - return; - } - - unpause(); - - DpsMember dpsMember = members.computeIfAbsent(name, DpsMember::new); - dpsMember.addDamage(dpsUpdate.getHit()); - } - - @Subscribe - public void onOverlayMenuClicked(OverlayMenuClicked event) - { - if (event.getEntry() == DpsOverlay.RESET_ENTRY) - { - members.clear(); - total.reset(); - } - else if (event.getEntry() == DpsOverlay.UNPAUSE_ENTRY) - { - unpause(); - } - else if (event.getEntry() == DpsOverlay.PAUSE_ENTRY) - { - pause(); - } - } - - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) - { - NPC npc = npcDespawned.getNpc(); - - if (npc.isDead() && BOSSES.contains(npc.getId())) - { - log.debug("Boss has died!"); - - if (dpsConfig.autopause()) - { - pause(); - } - } - } - - private void pause() - { - if (total.isPaused()) - { - return; - } - - log.debug("Pausing"); - - for (DpsMember dpsMember : members.values()) - { - dpsMember.pause(); - } - total.pause(); - - dpsOverlay.setPaused(true); - } - - private void unpause() - { - if (!total.isPaused()) - { - return; - } - - log.debug("Unpausing"); - - for (DpsMember dpsMember : members.values()) - { - dpsMember.unpause(); - } - total.unpause(); - - dpsOverlay.setPaused(false); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java deleted file mode 100644 index e35bbedbd2..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsMember.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2020 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.dpscounter; - -import java.time.Duration; -import java.time.Instant; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -@Getter -class DpsMember -{ - private final String name; - private Instant start; - private Instant end; - private int damage; - - void addDamage(int amount) - { - if (start == null) - { - start = Instant.now(); - } - - damage += amount; - } - - float getDps() - { - if (start == null) - { - return 0; - } - - Instant now = end == null ? Instant.now() : end; - int diff = (int) (now.toEpochMilli() - start.toEpochMilli()) / 1000; - if (diff == 0) - { - return 0; - } - - return (float) damage / (float) diff; - } - - void pause() - { - end = Instant.now(); - } - - boolean isPaused() - { - return start == null || end != null; - } - - void unpause() - { - if (end == null) - { - return; - } - - start = start.plus(Duration.between(end, Instant.now())); - end = null; - } - - void reset() - { - damage = 0; - start = end = Instant.now(); - } - - Duration elapsed() - { - return Duration.between(start, end == null ? Instant.now() : end); - } -} 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 deleted file mode 100644 index 44b31c481c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2020 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.dpscounter; - -import java.awt.Dimension; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.text.DecimalFormat; -import java.time.Duration; -import java.util.Map; -import javax.inject.Inject; -import net.runelite.api.Client; -import static net.runelite.api.MenuAction.RUNELITE_OVERLAY; -import net.runelite.api.Player; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayMenuEntry; -import net.runelite.client.ui.overlay.components.ComponentConstants; -import net.runelite.client.ui.overlay.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; -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; - -class DpsOverlay extends Overlay -{ - private static final DecimalFormat DPS_FORMAT = new DecimalFormat("#0.0"); - private static final int PANEL_WIDTH_OFFSET = 10; // assumes 8 for panel component border + 2px between left and right - - static final OverlayMenuEntry RESET_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Reset", "DPS counter"); - static final OverlayMenuEntry PAUSE_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Pause", "DPS counter"); - static final OverlayMenuEntry UNPAUSE_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Unpause", "DPS counter"); - - private final DpsCounterPlugin dpsCounterPlugin; - private final DpsConfig dpsConfig; - private final PartyService partyService; - private final Client client; - private final TooltipManager tooltipManager; - - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - DpsOverlay(DpsCounterPlugin dpsCounterPlugin, DpsConfig dpsConfig, PartyService partyService, Client client, - TooltipManager tooltipManager) - { - super(dpsCounterPlugin); - this.dpsCounterPlugin = dpsCounterPlugin; - this.dpsConfig = dpsConfig; - this.partyService = partyService; - this.client = client; - this.tooltipManager = tooltipManager; - getMenuEntries().add(RESET_ENTRY); - setPaused(false); - } - - @Override - public void onMouseOver() - { - DpsMember total = dpsCounterPlugin.getTotal(); - Duration elapsed = total.elapsed(); - long s = elapsed.getSeconds(); - String format; - if (s >= 3600) - { - format = String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60)); - } - else - { - format = String.format("%d:%02d", s / 60, (s % 60)); - } - tooltipManager.add(new Tooltip("Elapsed time: " + format)); - } - - @Override - public Dimension render(Graphics2D graphics) - { - Map dpsMembers = dpsCounterPlugin.getMembers(); - if (dpsMembers.isEmpty()) - { - return null; - } - - boolean inParty = !partyService.getMembers().isEmpty(); - boolean showDamage = dpsConfig.showDamage(); - DpsMember total = dpsCounterPlugin.getTotal(); - boolean paused = total.isPaused(); - - panelComponent.getChildren().clear(); - - final String title = (inParty ? "Party " : "") + (showDamage ? "Damage" : "DPS") + (paused ? " (paused)" : ""); - panelComponent.getChildren().add( - TitleComponent.builder() - .text(title) - .build()); - - int maxWidth = ComponentConstants.STANDARD_WIDTH; - FontMetrics fontMetrics = graphics.getFontMetrics(); - - for (DpsMember dpsMember : dpsMembers.values()) - { - String left = dpsMember.getName(); - String right = showDamage ? QuantityFormatter.formatNumber(dpsMember.getDamage()) : DPS_FORMAT.format(dpsMember.getDps()); - maxWidth = Math.max(maxWidth, fontMetrics.stringWidth(left) + fontMetrics.stringWidth(right)); - panelComponent.getChildren().add( - LineComponent.builder() - .left(left) - .right(right) - .build()); - } - - panelComponent.setPreferredSize(new Dimension(maxWidth + PANEL_WIDTH_OFFSET, 0)); - - if (!inParty) - { - Player player = client.getLocalPlayer(); - if (player.getName() != null) - { - DpsMember self = dpsMembers.get(player.getName()); - - if (self != null && total.getDamage() > self.getDamage()) - { - panelComponent.getChildren().add( - LineComponent.builder() - .left(total.getName()) - .right(showDamage ? Integer.toString(total.getDamage()) : DPS_FORMAT.format(total.getDps())) - .build()); - } - } - } - - return panelComponent.render(graphics); - } - - void setPaused(boolean paused) - { - OverlayMenuEntry remove = paused ? PAUSE_ENTRY : UNPAUSE_ENTRY; - OverlayMenuEntry add = paused ? UNPAUSE_ENTRY : PAUSE_ENTRY; - getMenuEntries().remove(remove); - if (!getMenuEntries().contains(add)) - { - getMenuEntries().add(add); - } - } -} 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 deleted file mode 100644 index 81e5859b38..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020 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.dpscounter; - -import lombok.EqualsAndHashCode; -import lombok.Value; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; - -@Value -@EqualsAndHashCode(callSuper = true) -public class DpsUpdate extends PartyMemberMessage -{ - private int hit; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java deleted file mode 100644 index 14e3924e6f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/SortOrder.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2020, Jake Wilson - * 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.timetracking; - -public enum SortOrder -{ - NONE, - ASC, - DESC -} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java deleted file mode 100644 index 867413420e..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/keyremapping/KeyRemappingListenerTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2020, 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.keyremapping; - -import com.google.inject.Guice; -import com.google.inject.testing.fieldbinder.Bind; -import com.google.inject.testing.fieldbinder.BoundFieldModule; -import java.awt.event.KeyEvent; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.client.config.ModifierlessKeybind; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class KeyRemappingListenerTest -{ - @Inject - private KeyRemappingListener keyRemappingListener; - - @Mock - @Bind - private Client client; - - @Mock - @Bind - private KeyRemappingPlugin keyRemappingPlugin; - - @Mock - @Bind - private KeyRemappingConfig keyRemappingConfig; - - @Before - public void setUp() - { - Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); - - when(client.getGameState()).thenReturn(GameState.LOGGED_IN); - } - - @Test - public void testTypingStateChange() - { - when(keyRemappingConfig.cameraRemap()).thenReturn(true); - when(keyRemappingConfig.up()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_W, 0)); - when(keyRemappingConfig.down()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_S, 0)); - when(keyRemappingConfig.left()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_A, 0)); - when(keyRemappingConfig.right()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_D, 0)); - - when(keyRemappingPlugin.chatboxFocused()).thenReturn(true); - KeyEvent event = mock(KeyEvent.class); - when(event.getKeyCode()).thenReturn(KeyEvent.VK_D); - when(event.getExtendedKeyCode()).thenReturn(KeyEvent.VK_D); // for keybind matches() - keyRemappingListener.keyPressed(event); - verify(event).setKeyCode(KeyEvent.VK_RIGHT); - - // with the plugin now in typing mode, previously pressed and remapped keys should still be mapped - // on key release regardless - when(keyRemappingPlugin.isTyping()).thenReturn(true); - event = mock(KeyEvent.class); - when(event.getKeyCode()).thenReturn(KeyEvent.VK_D); - keyRemappingListener.keyReleased(event); - verify(event).setKeyCode(KeyEvent.VK_RIGHT); - } -} From 6a7da81f0f8c9837558500ab293b7b048781d3aa Mon Sep 17 00:00:00 2001 From: Kyle <48519776+xKylee@users.noreply.github.com> Date: Mon, 23 Mar 2020 13:05:48 +0000 Subject: [PATCH 16/16] Update Client.java --- runelite-api/src/main/java/net/runelite/api/Client.java | 5 +++++ 1 file changed, 5 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 fbefcc7f65..a62b01c548 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1817,6 +1817,11 @@ public interface Client extends GameShell * Get the item index of the item being dragged on an if1 widget */ int getIf1DraggedItemIndex(); + + /** + * If a widget is in target mode? + */ + boolean getSpellSelected(); /** * Sets if a widget is in target mode