From e73ccc30691be9ffe9a85e7a89900194698447ed Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Mon, 4 Apr 2022 19:36:58 +0100 Subject: [PATCH] npcaggro: fix unintended loss of calibration After using 8ad5977ad5ef61ea84cb89a89956402e951b013f for a while, I noticed that the plugin would lose calibration seemingly at random. Given I was sitting at Redwoods, this didn't make sense. I want to give some context as to what was happening and why, baked permanently into the commit history: The plugin requires that a few things exist when it saves data, or else it assumes that something went wrong and it resets the config. One of these things is that the infobox object exists. Usually, this is fine, as one is created on login with the stored duration, as long as said duration is not negative. However, if the user stood in the same area for 10 minutes and then logged out somehow (either manually or through AFK), upon logging back in the config would not create a new infobox as the stored duration is negative. Either toggling the plugin or restarting the client at this point would clear the reference to the old Infobox, and a new one would not be created on login due to the aforementioned negative duration. If the plugin was toggled, the calibration is instantly lost, and the user now sees the tutorial overlay. If the client was restarted, it would appear as if the plugin is working fine, and it would fix itself if the player moved far enough. If they just logged out, however, it would clear its config. Either way, in most situations, the user is now forced to recalibrate the plugin when they've done nothing wrong, only commited the heinous crime of XP wasting. Most of this was due to how the plugin tracked the aggro time, which was through its infobox. This really shouldn't be how it does it, and so now it keeps track of the time separately, and doesn't rely on the creation of the infobox to block the saving of data. --- .../npcunaggroarea/AggressionTimer.java | 13 ++--- .../npcunaggroarea/NpcAggroAreaOverlay.java | 3 +- .../npcunaggroarea/NpcAggroAreaPlugin.java | 56 +++++++++---------- 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/AggressionTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/AggressionTimer.java index 7194d2ddd6..2d5f4df4f1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/AggressionTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/AggressionTimer.java @@ -29,22 +29,17 @@ import java.awt.image.BufferedImage; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; -import lombok.Getter; -import lombok.Setter; -import net.runelite.client.plugins.Plugin; import net.runelite.client.ui.overlay.infobox.Timer; class AggressionTimer extends Timer { - @Getter - @Setter - private boolean visible; + private final NpcAggroAreaPlugin plugin; - AggressionTimer(Duration duration, BufferedImage image, Plugin plugin, boolean visible) + AggressionTimer(Duration duration, BufferedImage image, NpcAggroAreaPlugin plugin) { super(duration.toMillis(), ChronoUnit.MILLIS, image, plugin); setTooltip("Time until NPCs become unaggressive"); - this.visible = visible; + this.plugin = plugin; } @Override @@ -63,6 +58,6 @@ class AggressionTimer extends Timer @Override public boolean render() { - return visible && super.render(); + return plugin.shouldDisplayTimer() && super.render(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaOverlay.java index 5aad9ce8c6..72691c4dac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaOverlay.java @@ -84,8 +84,7 @@ class NpcAggroAreaOverlay extends Overlay } Color outlineColor = config.unaggroAreaColor(); - AggressionTimer timer = plugin.getCurrentTimer(); - if (outlineColor == null || timer == null || Instant.now().compareTo(timer.getEndTime()) < 0) + if (outlineColor == null || (plugin.getEndTime() != null && Instant.now().isBefore(plugin.getEndTime()))) { outlineColor = config.aggroAreaColor(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java index 148876e631..359d306e7b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java @@ -82,7 +82,7 @@ public class NpcAggroAreaPlugin extends Plugin private static final int SAFE_AREA_RADIUS = 10; private static final int UNKNOWN_AREA_RADIUS = SAFE_AREA_RADIUS * 2; - private static final int AGGRESSIVE_TIME_SECONDS = 600; + private static final Duration AGGRESSIVE_TIME_DURATION = Duration.ofSeconds(600); private static final Splitter NAME_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults(); private static final WorldArea WILDERNESS_ABOVE_GROUND = new WorldArea(2944, 3523, 448, 448, 0); private static final WorldArea WILDERNESS_UNDERGROUND = new WorldArea(2944, 9918, 320, 442, 0); @@ -124,7 +124,7 @@ public class NpcAggroAreaPlugin extends Plugin private boolean active; @Getter - private AggressionTimer currentTimer; + private Instant endTime; private WorldPoint lastPlayerLocation; private WorldPoint previousUnknownCenter; @@ -156,7 +156,7 @@ public class NpcAggroAreaPlugin extends Plugin overlayManager.remove(notWorkingOverlay); Arrays.fill(safeCenters, null); lastPlayerLocation = null; - currentTimer = null; + endTime = null; loggingIn = false; npcNamePatterns = null; active = false; @@ -193,16 +193,6 @@ public class NpcAggroAreaPlugin extends Plugin coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2f; } - private void reevaluateActive() - { - if (currentTimer != null) - { - currentTimer.setVisible(active && config.showTimer()); - } - - calculateLinesToDisplay(); - } - private void calculateLinesToDisplay() { if (!active || !config.showAreaLines()) @@ -227,23 +217,29 @@ public class NpcAggroAreaPlugin extends Plugin private void removeTimer() { - infoBoxManager.removeInfoBox(currentTimer); - currentTimer = null; + infoBoxManager.removeIf(t -> t instanceof AggressionTimer); + endTime = null; notifyOnce = false; } private void createTimer(Duration duration) { removeTimer(); - BufferedImage image = itemManager.getImage(ItemID.ENSOULED_DEMON_HEAD); - currentTimer = new AggressionTimer(duration, image, this, active && config.showTimer()); - infoBoxManager.addInfoBox(currentTimer); + endTime = Instant.now().plus(duration); notifyOnce = true; + + if (duration.isNegative()) + { + return; + } + + BufferedImage image = itemManager.getImage(ItemID.ENSOULED_DEMON_HEAD); + infoBoxManager.addInfoBox(new AggressionTimer(duration, image, this)); } private void resetTimer() { - createTimer(Duration.ofSeconds(AGGRESSIVE_TIME_SECONDS)); + createTimer(AGGRESSIVE_TIME_DURATION); } private static boolean isInWilderness(WorldPoint location) @@ -301,7 +297,7 @@ public class NpcAggroAreaPlugin extends Plugin } } - reevaluateActive(); + calculateLinesToDisplay(); } private void recheckActive() @@ -326,7 +322,7 @@ public class NpcAggroAreaPlugin extends Plugin { WorldPoint newLocation = client.getLocalPlayer().getWorldLocation(); - if (active && currentTimer != null && currentTimer.cull() && notifyOnce) + if (active && notifyOnce && Instant.now().isAfter(endTime)) { if (config.notifyExpire()) { @@ -387,12 +383,6 @@ public class NpcAggroAreaPlugin extends Plugin case "npcUnaggroAlwaysActive": recheckActive(); break; - case "npcUnaggroShowTimer": - if (currentTimer != null) - { - currentTimer.setVisible(active && config.showTimer()); - } - break; case "npcUnaggroCollisionDetection": case "npcUnaggroShowAreaLines": calculateLinesToDisplay(); @@ -404,6 +394,11 @@ public class NpcAggroAreaPlugin extends Plugin } } + boolean shouldDisplayTimer() + { + return active && config.showTimer(); + } + private void loadConfig() { safeCenters[0] = configManager.getConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER1, WorldPoint.class); @@ -411,7 +406,7 @@ public class NpcAggroAreaPlugin extends Plugin lastPlayerLocation = configManager.getConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_LOCATION, WorldPoint.class); Duration timeLeft = configManager.getConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_DURATION, Duration.class); - if (timeLeft != null && !timeLeft.isNegative()) + if (timeLeft != null) { createTimer(timeLeft); } @@ -427,7 +422,7 @@ public class NpcAggroAreaPlugin extends Plugin private void saveConfig() { - if (safeCenters[0] == null || safeCenters[1] == null || lastPlayerLocation == null || currentTimer == null) + if (safeCenters[0] == null || safeCenters[1] == null || lastPlayerLocation == null || endTime == null) { resetConfig(); } @@ -436,7 +431,7 @@ public class NpcAggroAreaPlugin extends Plugin configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER1, safeCenters[0]); configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER2, safeCenters[1]); configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_LOCATION, lastPlayerLocation); - configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_DURATION, Duration.between(Instant.now(), currentTimer.getEndTime())); + configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_DURATION, Duration.between(Instant.now(), endTime)); } } @@ -486,6 +481,7 @@ public class NpcAggroAreaPlugin extends Plugin safeCenters[0] = null; safeCenters[1] = null; lastPlayerLocation = null; + endTime = null; break; } }