world hopper: add option to show current world ping
If enabled, the current world is pinged every second and the ping is drawn in an overlay Co-authored-by: gregg1494 <gregg1494@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||||
|
* Copyright (c) 2019, gregg1494 <https://github.com/gregg1494>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -123,4 +124,15 @@ public interface WorldHopperConfig extends Config
|
|||||||
{
|
{
|
||||||
return SubscriptionFilterMode.BOTH;
|
return SubscriptionFilterMode.BOTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "displayPing",
|
||||||
|
name = "Display current ping",
|
||||||
|
description = "Displays ping to current game world",
|
||||||
|
position = 7
|
||||||
|
)
|
||||||
|
default boolean displayPing()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, gregg1494 <https://github.com/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;
|
||||||
|
private final WorldHopperConfig worldHopperConfig;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private WorldHopperPingOverlay(Client client, WorldHopperPlugin worldHopperPlugin, WorldHopperConfig worldHopperConfig)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.worldHopperPlugin = worldHopperPlugin;
|
||||||
|
this.worldHopperConfig = worldHopperConfig;
|
||||||
|
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||||
|
setPriority(OverlayPriority.HIGH);
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (!worldHopperConfig.displayPing())
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||||
|
* Copyright (c) 2019, gregg1494 <https://github.com/gregg1494>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -45,6 +46,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.ChatMessageType;
|
import net.runelite.api.ChatMessageType;
|
||||||
@@ -78,6 +80,7 @@ import net.runelite.client.plugins.PluginDescriptor;
|
|||||||
import net.runelite.client.plugins.worldhopper.ping.Ping;
|
import net.runelite.client.plugins.worldhopper.ping.Ping;
|
||||||
import net.runelite.client.ui.ClientToolbar;
|
import net.runelite.client.ui.ClientToolbar;
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
import net.runelite.client.util.ExecutorServiceExceptionLogger;
|
import net.runelite.client.util.ExecutorServiceExceptionLogger;
|
||||||
import net.runelite.client.util.HotkeyListener;
|
import net.runelite.client.util.HotkeyListener;
|
||||||
import net.runelite.client.util.Text;
|
import net.runelite.client.util.Text;
|
||||||
@@ -130,6 +133,12 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private WorldHopperConfig config;
|
private WorldHopperConfig config;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private WorldHopperPingOverlay worldHopperOverlay;
|
||||||
|
|
||||||
private ScheduledExecutorService hopperExecutorService;
|
private ScheduledExecutorService hopperExecutorService;
|
||||||
|
|
||||||
private NavigationButton navButton;
|
private NavigationButton navButton;
|
||||||
@@ -143,12 +152,15 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
|
|
||||||
private int favoriteWorld1, favoriteWorld2;
|
private int favoriteWorld1, favoriteWorld2;
|
||||||
|
|
||||||
private ScheduledFuture<?> worldResultFuture, pingFuture;
|
private ScheduledFuture<?> worldResultFuture, pingFuture, currPingFuture;
|
||||||
private WorldResult worldResult;
|
private WorldResult worldResult;
|
||||||
private int currentWorld;
|
private int currentWorld;
|
||||||
private Instant lastFetch;
|
private Instant lastFetch;
|
||||||
private boolean firstRun;
|
private boolean firstRun;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private int currentPing;
|
||||||
|
|
||||||
private final HotkeyListener previousKeyListener = new HotkeyListener(() -> config.previousKey())
|
private final HotkeyListener previousKeyListener = new HotkeyListener(() -> config.previousKey())
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@@ -176,6 +188,7 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
firstRun = true;
|
firstRun = true;
|
||||||
|
currentPing = -1;
|
||||||
|
|
||||||
keyManager.registerKeyListener(previousKeyListener);
|
keyManager.registerKeyListener(previousKeyListener);
|
||||||
keyManager.registerKeyListener(nextKeyListener);
|
keyManager.registerKeyListener(nextKeyListener);
|
||||||
@@ -200,6 +213,8 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
clientToolbar.addNavigation(navButton);
|
clientToolbar.addNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlayManager.add(worldHopperOverlay);
|
||||||
|
|
||||||
panel.setFilterMode(config.subscriptionFilter());
|
panel.setFilterMode(config.subscriptionFilter());
|
||||||
|
|
||||||
// The plugin has its own executor for pings, as it blocks for a long time
|
// The plugin has its own executor for pings, as it blocks for a long time
|
||||||
@@ -209,6 +224,7 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
|
|
||||||
// Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway
|
// Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway
|
||||||
pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS);
|
pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS);
|
||||||
|
currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -217,6 +233,11 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
pingFuture.cancel(true);
|
pingFuture.cancel(true);
|
||||||
pingFuture = null;
|
pingFuture = null;
|
||||||
|
|
||||||
|
currPingFuture.cancel(true);
|
||||||
|
currPingFuture = null;
|
||||||
|
|
||||||
|
overlayManager.remove(worldHopperOverlay);
|
||||||
|
|
||||||
keyManager.unregisterKeyListener(previousKeyListener);
|
keyManager.unregisterKeyListener(previousKeyListener);
|
||||||
keyManager.unregisterKeyListener(nextKeyListener);
|
keyManager.unregisterKeyListener(nextKeyListener);
|
||||||
|
|
||||||
@@ -807,8 +828,39 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
|
|
||||||
World world = worlds.get(currentWorld++);
|
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);
|
int ping = Ping.ping(world);
|
||||||
log.trace("Ping for world {} is: {}", world.getId(), ping);
|
log.trace("Ping for world {} is: {}", world.getId(), ping);
|
||||||
SwingUtilities.invokeLater(() -> panel.updatePing(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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user