diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java index 539c810de2..16922d9874 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java @@ -68,15 +68,4 @@ public interface FpsConfig extends Config { return true; } - - @ConfigItem( - keyName = "drawPing", - name = "Draw ping indicator", - description = "Show a number in the corner for the current ping", - position = 3 - ) - default boolean drawPing() - { - return false; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java index 17afae61b6..0103337792 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java @@ -26,14 +26,14 @@ package net.runelite.client.plugins.fps; import java.awt.Color; import java.awt.Dimension; -import java.awt.FontMetrics; import java.awt.Graphics2D; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.Point; -import net.runelite.api.Varbits; import net.runelite.api.events.FocusChanged; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; @@ -51,6 +51,10 @@ import net.runelite.client.ui.overlay.OverlayUtil; @Singleton public class FpsOverlay extends Overlay { + private static final int Y_OFFSET = 1; + private static final int X_OFFSET = 1; + private static final String FPS_STRING = " FPS"; + // Local dependencies private final Client client; private final FpsPlugin plugin; @@ -84,62 +88,30 @@ public class FpsOverlay extends Overlay return isEnforced() ? Color.red : Color.yellow; } - private static Color getPingColor(int ping) - { - if (ping >= 100 || ping < 0) - { - return Color.red; - } - else if (ping >= 50) - { - return Color.yellow; - } - return Color.green; - } - - private int calculateOffset() - { - if ((client.getVar(Varbits.SIDE_PANELS) == 1) && client.isResized()) - { - return 27; - } - - return 2; - } - @Override public Dimension render(Graphics2D graphics) { - if (!plugin.isDrawFps() && !plugin.isDrawPing()) + if (!plugin.isDrawFps()) { return null; } - final int offset = calculateOffset(); + // On resizable bottom line mode the logout button is at the top right, so offset the overlay + // to account for it + Widget logoutButton = client.getWidget(WidgetInfo.RESIZABLE_MINIMAP_LOGOUT_BUTTON); + int xOffset = X_OFFSET; + if (logoutButton != null && !logoutButton.isHidden()) + { + xOffset += logoutButton.getWidth(); + } + + final String text = client.getFPS() + FPS_STRING; + final int textWidth = graphics.getFontMetrics().stringWidth(text); + final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent(); + final int width = (int) client.getRealDimensions().getWidth(); - final FontMetrics fontMetrics = graphics.getFontMetrics(); - - int baseYOffset = (fontMetrics.getAscent() - fontMetrics.getDescent()) + 1; - - if (plugin.isDrawFps()) - { - final String fpsText = String.format("%d FPS", client.getFPS()); - final int textWidth = fontMetrics.stringWidth(fpsText); - - final Point point = new Point(width - textWidth - offset, baseYOffset); - OverlayUtil.renderTextLocation(graphics, point, fpsText, getFpsValueColor()); - - baseYOffset += 11; - } - - if (plugin.isDrawPing()) - { - final String pingText = String.format("%dms", plugin.getPing()); - final int textWidth = fontMetrics.stringWidth(pingText); - - final Point point = new Point(width - textWidth - offset, baseYOffset); - OverlayUtil.renderTextLocation(graphics, point, pingText, getPingColor(plugin.getPing())); - } + final Point point = new Point(width - textWidth - xOffset, textHeight + Y_OFFSET); + OverlayUtil.renderTextLocation(graphics, point, text, getFpsValueColor()); return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java index b33699436a..4af5c588a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java @@ -27,27 +27,19 @@ package net.runelite.client.plugins.fps; import com.google.inject.Inject; import com.google.inject.Provides; import com.google.inject.Singleton; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import lombok.AccessLevel; import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.GameState; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.FocusChanged; -import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.DrawManager; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ExecutorServiceExceptionLogger; -import net.runelite.client.util.ping.Ping; /** - * Performance has two primary areas, this plugin class just keeps those areas up to date and handles setup / teardown. + * FPS Control has two primary areas, this plugin class just keeps those areas up to date and handles setup / teardown. * *

Overlay paints the current FPS, the color depends on whether or not FPS is being enforced. * The overlay is lightweight and is merely and indicator. @@ -55,15 +47,11 @@ import net.runelite.client.util.ping.Ping; *

Draw Listener, sleeps a calculated amount after each canvas paint operation. * This is the heart of the plugin, the amount of sleep taken is regularly adjusted to account varying * game and system load, it usually finds the sweet spot in about two seconds. - * - *

Pinging the world, when logged in and ping display is enabled, every 5 seconds the remote server - * for the current world is pinged. A scheduled method in this class is responsible for that. When ping fails - * or those conditions are not met, ping will have the value of -1. */ @PluginDescriptor( name = "Performance", - description = "Show current Ping and FPS or set an FPS limit", - tags = {"frames", "framerate", "limit", "overlay", "ping"}, + description = "Show current FPS or set an FPS limit", + tags = {"frames", "framerate", "limit", "overlay"}, enabledByDefault = false ) @Singleton @@ -71,9 +59,6 @@ public class FpsPlugin extends Plugin { static final String CONFIG_GROUP_KEY = "fpscontrol"; - @Getter - private int ping; - @Inject private OverlayManager overlayManager; @@ -86,30 +71,18 @@ public class FpsPlugin extends Plugin @Inject private DrawManager drawManager; - @Inject - private Client client; - @Inject private FpsConfig fpsConfig; @Inject private EventBus eventBus; - private final ScheduledExecutorService pingExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); - - private boolean loaded = false; - - private boolean shutdown; - @Getter(AccessLevel.PACKAGE) private FpsLimitMode limitMode; @Getter(AccessLevel.PACKAGE) private boolean drawFps; - @Getter(AccessLevel.PACKAGE) - private boolean drawPing; - @Provides FpsConfig provideConfig(ConfigManager configManager) { @@ -124,7 +97,6 @@ public class FpsPlugin extends Plugin limitMode = fpsConfig.limitMode(); drawFps = fpsConfig.drawFps(); - drawPing = fpsConfig.drawPing(); } } @@ -134,11 +106,6 @@ public class FpsPlugin extends Plugin overlay.onFocusChanged(event); } - private void onGameStateChanged(GameStateChanged event) - { - shutdown = event.getGameState() != GameState.LOGGED_IN; - } - @Override protected void startUp() throws Exception { @@ -146,17 +113,9 @@ public class FpsPlugin extends Plugin limitMode = fpsConfig.limitMode(); drawFps = fpsConfig.drawFps(); - drawPing = fpsConfig.drawPing(); overlayManager.add(overlay); drawManager.registerEveryFrameListener(drawListener); drawListener.reloadConfig(); - shutdown = client.getGameState() != GameState.LOGGED_IN; - - if (!loaded) - { - pingExecutorService.scheduleAtFixedRate(this::getPingToCurrentWorld, 5, 5, TimeUnit.SECONDS); - loaded = true; - } } @Override @@ -166,25 +125,11 @@ public class FpsPlugin extends Plugin overlayManager.remove(overlay); drawManager.unregisterEveryFrameListener(drawListener); - shutdown = true; } private void addSubscriptions() { eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); - eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); - } - - private void getPingToCurrentWorld() - { - if (!shutdown && drawPing) - { - ping = Ping.ping(String.format("oldschool%d.runescape.com", client.getWorld() - 300)); - } - else - { - ping = -1; - } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java index d71bcc0074..8d411a4aaa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java @@ -72,6 +72,7 @@ enum ItemIdentification MAGIC_SAPLING(Type.SAPLING, "Magic", "MAG", ItemID.MAGIC_SAPLING, ItemID.MAGIC_SEEDLING, ItemID.MAGIC_SEEDLING_W), REDWOOD_SAPLING(Type.SAPLING, "Red", "RED", ItemID.REDWOOD_SAPLING, ItemID.REDWOOD_SEEDLING, ItemID.REDWOOD_SEEDLING_W), SPIRIT_SAPLING(Type.SAPLING, "Spirit", "SPI", ItemID.SPIRIT_SAPLING, ItemID.SPIRIT_SEEDLING, ItemID.SPIRIT_SEEDLING_W), + CRYSTAL_SAPLING(Type.SAPLING, "Crystal", "CRY", ItemID.CRYSTAL_SAPLING, ItemID.CRYSTAL_SEEDLING, ItemID.CRYSTAL_SEEDLING_W), APPLE_SAPLING(Type.SAPLING, "Apple", "APP", ItemID.APPLE_SAPLING, ItemID.APPLE_SEEDLING, ItemID.APPLE_SEEDLING_W), BANANA_SAPLING(Type.SAPLING, "Banana", "BAN", ItemID.BANANA_SAPLING, ItemID.BANANA_SEEDLING, ItemID.BANANA_SEEDLING_W), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index 247b2f97ab..c13389485d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -102,14 +102,19 @@ class NightmareZoneOverlay extends Overlay renderAbsorptionCounter(); + final int currentPoints = client.getVar(Varbits.NMZ_POINTS); + final int totalPoints = currentPoints + client.getVar(VarPlayer.NMZ_REWARD_POINTS); + panelComponent.getChildren().clear(); + TableComponent tableComponent = new TableComponent(); tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT); - tableComponent.addRow("Points:", StackFormatter.formatNumber(client.getVar(Varbits.NMZ_POINTS))); + tableComponent.addRow("Points:", StackFormatter.formatNumber(currentPoints)); + tableComponent.addRow("Points/Hour:", StackFormatter.formatNumber(plugin.getPointsPerHour())); if (plugin.isShowtotalpoints()) { - tableComponent.addRow("Total:", StackFormatter.formatNumber(client.getVar(VarPlayer.NMZ_REWARD_POINTS) + client.getVar(Varbits.NMZ_POINTS))); + tableComponent.addRow("Total:", StackFormatter.formatNumber(totalPoints)); } panelComponent.getChildren().add(tableComponent); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java index 9c32dabc51..7993ae37ca 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java @@ -25,11 +25,14 @@ package net.runelite.client.plugins.nightmarezone; import com.google.inject.Provides; + import java.awt.Color; import java.util.Arrays; import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; +import java.time.Duration; +import java.time.Instant; import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; @@ -56,6 +59,7 @@ import net.runelite.client.util.Text; public class NightmareZonePlugin extends Plugin { private static final int[] NMZ_MAP_REGION = {9033}; + private static final Duration HOUR = Duration.ofHours(1); @Inject private Notifier notifier; @@ -75,6 +79,11 @@ public class NightmareZonePlugin extends Plugin @Inject private EventBus eventBus; + @Getter + private int pointsPerHour; + + private Instant nmzSessionStartTime; + // This starts as true since you need to get // above the threshold before sending notifications private boolean absorptionNotificationSend = true; @@ -120,6 +129,8 @@ public class NightmareZonePlugin extends Plugin { nmzWidget.setHidden(false); } + + resetPointsPerHour(); } private void addSubscriptions() @@ -155,6 +166,11 @@ public class NightmareZonePlugin extends Plugin absorptionNotificationSend = true; } + if (nmzSessionStartTime != null) + { + resetPointsPerHour(); + } + return; } @@ -162,6 +178,11 @@ public class NightmareZonePlugin extends Plugin { checkAbsorption(); } + + if (config.moveOverlay()) + { + pointsPerHour = calculatePointsPerHour(); + } } private void onChatMessage(ChatMessage event) @@ -239,6 +260,32 @@ public class NightmareZonePlugin extends Plugin return !Arrays.equals(client.getMapRegions(), NMZ_MAP_REGION); } + private int calculatePointsPerHour() + { + Instant now = Instant.now(); + final int currentPoints = client.getVar(Varbits.NMZ_POINTS); + + if (nmzSessionStartTime == null) + { + nmzSessionStartTime = now; + } + + Duration timeSinceStart = Duration.between(nmzSessionStartTime, now); + + if (!timeSinceStart.isZero()) + { + return (int) ((double) currentPoints * (double) HOUR.toMillis() / (double) timeSinceStart.toMillis()); + } + + return 0; + } + + private void resetPointsPerHour() + { + nmzSessionStartTime = null; + pointsPerHour = 0; + } + private void updateConfig() { this.moveOverlay = config.moveOverlay(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java index 8035af73fb..d21ed61e80 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Lotto + * Copyright (c) 2019, gregg1494 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -123,4 +124,15 @@ public interface WorldHopperConfig extends Config { return SubscriptionFilterMode.BOTH; } + + @ConfigItem( + keyName = "displayPing", + name = "Display current ping", + description = "Displays ping to current game world", + position = 7 + ) + default boolean displayPing() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java new file mode 100644 index 0000000000..1839b14ddd --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019, gregg1494 + * 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.worldhopper; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; + +class WorldHopperPingOverlay extends Overlay +{ + private static final int Y_OFFSET = 11; + private static final int X_OFFSET = 1; + + private final Client client; + private final WorldHopperPlugin worldHopperPlugin; + + @Inject + private WorldHopperPingOverlay(Client client, WorldHopperPlugin worldHopperPlugin) + { + this.client = client; + this.worldHopperPlugin = worldHopperPlugin; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.DYNAMIC); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!worldHopperPlugin.isDisplayPing()) + { + return null; + } + + final int ping = worldHopperPlugin.getCurrentPing(); + if (ping < 0) + { + return null; + } + + final String text = ping + " ms"; + final int textWidth = graphics.getFontMetrics().stringWidth(text); + final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent(); + + // Adjust ping offset for logout button + Widget logoutButton = client.getWidget(WidgetInfo.RESIZABLE_MINIMAP_LOGOUT_BUTTON); + int xOffset = X_OFFSET; + if (logoutButton != null && !logoutButton.isHidden()) + { + xOffset += logoutButton.getWidth(); + } + + final int width = (int) client.getRealDimensions().getWidth(); + final Point point = new Point(width - textWidth - xOffset, textHeight + Y_OFFSET); + OverlayUtil.renderTextLocation(graphics, point, text, Color.YELLOW); + + return null; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 8513a87814..1b232678b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2017, Adam * Copyright (c) 2018, Lotto + * Copyright (c) 2019, gregg1494 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,6 +47,7 @@ import javax.imageio.ImageIO; import javax.inject.Inject; import javax.inject.Singleton; import javax.swing.SwingUtilities; +import lombok.AccessLevel; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; @@ -78,6 +80,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; +import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ExecutorServiceExceptionLogger; import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.Text; @@ -98,8 +101,7 @@ import org.apache.commons.lang3.ArrayUtils; public class WorldHopperPlugin extends Plugin { private static final int WORLD_FETCH_TIMER = 10; - private static final int WORLD_PING_TIMER = 10; - private static final int REFRESH_THROTTLE = 60_000; // ms + private static final int REFRESH_THROTTLE = 60_000; // ms private static final int TICK_THROTTLE = (int) Duration.ofMinutes(10).toMillis(); private static final int DISPLAY_SWITCHER_MAX_ATTEMPTS = 3; @@ -133,6 +135,12 @@ public class WorldHopperPlugin extends Plugin @Inject private EventBus eventBus; + @Inject + private OverlayManager overlayManager; + + @Inject + private WorldHopperPingOverlay worldHopperOverlay; + private ScheduledExecutorService hopperExecutorService; private NavigationButton navButton; @@ -146,8 +154,9 @@ public class WorldHopperPlugin extends Plugin private int favoriteWorld1, favoriteWorld2; - private ScheduledFuture worldResultFuture, pingFuture; + private ScheduledFuture worldResultFuture, pingFuture, currPingFuture; private WorldResult worldResult; + private int currentWorld; private Instant lastFetch; private boolean firstRun; @@ -158,6 +167,11 @@ public class WorldHopperPlugin extends Plugin private boolean ping; private boolean showWorldHopMessage; private SubscriptionFilterMode subscriptionFilter; + @Getter(AccessLevel.PACKAGE) + private boolean displayPing; + + @Getter(AccessLevel.PACKAGE) + private int currentPing; private final HotkeyListener previousKeyListener = new HotkeyListener(() -> this.previousKey) { @@ -189,6 +203,7 @@ public class WorldHopperPlugin extends Plugin addSubscriptions(); firstRun = true; + currentPing = -1; keyManager.registerKeyListener(previousKeyListener); keyManager.registerKeyListener(nextKeyListener); @@ -213,11 +228,18 @@ public class WorldHopperPlugin extends Plugin clientToolbar.addNavigation(navButton); } - panel.setFilterMode(this.subscriptionFilter); + overlayManager.add(worldHopperOverlay); + + panel.setFilterMode(config.subscriptionFilter()); + + // The plugin has its own executor for pings, as it blocks for a long time + hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); + // On first run this schedules an initial ping on hopperExecutorService worldResultFuture = executorService.scheduleAtFixedRate(this::tick, 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES); - hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); - pingFuture = hopperExecutorService.scheduleAtFixedRate(this::pingWorlds, WORLD_PING_TIMER, WORLD_PING_TIMER, TimeUnit.MINUTES); + // Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway + pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS); + currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS); } @Override @@ -228,6 +250,11 @@ public class WorldHopperPlugin extends Plugin pingFuture.cancel(true); pingFuture = null; + currPingFuture.cancel(true); + currPingFuture = null; + + overlayManager.remove(worldHopperOverlay); + keyManager.unregisterKeyListener(previousKeyListener); keyManager.unregisterKeyListener(nextKeyListener); @@ -482,7 +509,8 @@ public class WorldHopperPlugin extends Plugin if (firstRun) { firstRun = false; - hopperExecutorService.execute(this::pingWorlds); + // On first run we ping all of the worlds at once to initialize the ping values + hopperExecutorService.execute(this::pingInitialWorlds); } } @@ -504,6 +532,7 @@ public class WorldHopperPlugin extends Plugin new WorldClient().lookupWorlds() .subscribeOn(Schedulers.io()) + .take(1) .subscribe( (worldResult) -> { @@ -775,7 +804,10 @@ public class WorldHopperPlugin extends Plugin return null; } - private void pingWorlds() + /** + * Ping all worlds. This takes a long time and is only run on first run. + */ + private void pingInitialWorlds() { if (worldResult == null || !this.showSidebar || !this.ping) { @@ -804,5 +836,66 @@ public class WorldHopperPlugin extends Plugin this.ping = config.ping(); this.showWorldHopMessage = config.showWorldHopMessage(); this.subscriptionFilter = config.subscriptionFilter(); + this.displayPing = config.displayPing(); + } + + /** + * Ping the next world + */ + private void pingNextWorld() + { + if (worldResult == null || !config.showSidebar() || !config.ping()) + { + return; + } + + List worlds = worldResult.getWorlds(); + if (worlds.isEmpty()) + { + return; + } + + if (currentWorld >= worlds.size()) + { + // Wrap back around + currentWorld = 0; + } + + World world = worlds.get(currentWorld++); + + // If we are displaying the ping overlay, there is a separate scheduled task for the current world + boolean displayPing = config.displayPing() && client.getGameState() == GameState.LOGGED_IN; + if (displayPing && client.getWorld() == world.getId()) + { + return; + } + + int ping = Ping.ping(world); + log.trace("Ping for world {} is: {}", world.getId(), ping); + SwingUtilities.invokeLater(() -> panel.updatePing(world.getId(), ping)); + } + + /** + * Ping the current world for the ping overlay + */ + private void pingCurrentWorld() + { + // There is no reason to ping the current world if not logged in, as the overlay doesn't draw + if (worldResult == null || !config.displayPing() || client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + final World currentWorld = worldResult.findWorld(client.getWorld()); + if (currentWorld == null) + { + log.debug("unable to find current world: {}", client.getWorld()); + return; + } + + currentPing = Ping.ping(currentWorld); + log.trace("Ping for current world is: {}", currentPing); + + SwingUtilities.invokeLater(() -> panel.updatePing(currentWorld.getId(), currentPing)); } } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json index 19fca53730..b72b8d59e9 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json @@ -78,6 +78,12 @@ "name": "Pollnivneach Rooftop", "xp": 890 }, + { + "level": 75, + "icon": 23962, + "name": "Prifddinas Agility Course", + "xp": 1220 + }, { "level": 80, "icon": 11849, diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json index bc5cde0ef6..5953579264 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json @@ -240,6 +240,12 @@ "name": "Lantadyme", "xp": 134.5 }, + { + "level": 74, + "icon": 23962, + "name": "Crystal Tree", + "xp": 13366 + }, { "level": 75, "icon": 1513,