From bb088dd57f58a3db97870eddc7ea0b3c5e47e6af Mon Sep 17 00:00:00 2001 From: sdburns1998 <49877861+sdburns1998@users.noreply.github.com> Date: Wed, 24 Apr 2019 02:34:28 +0200 Subject: [PATCH] Ping (#78) * Add option to draw ping underneath the fps * Move the ping package from the world hopper plugin to utils --- .../{fps => performance}/FpsDrawListener.java | 6 +- .../{fps => performance}/FpsLimitMode.java | 2 +- .../PerformanceConfig.java} | 17 ++++- .../PerformanceOverlay.java} | 71 +++++++++++++++---- .../PerformancePlugin.java} | 55 +++++++++++--- .../worldhopper/WorldHopperPlugin.java | 2 +- .../worldhopper => util}/ping/IPHlpAPI.java | 2 +- .../ping/IcmpEchoReply.java | 2 +- .../worldhopper => util}/ping/Ping.java | 19 +++-- 9 files changed, 135 insertions(+), 41 deletions(-) rename runelite-client/src/main/java/net/runelite/client/plugins/{fps => performance}/FpsDrawListener.java (97%) rename runelite-client/src/main/java/net/runelite/client/plugins/{fps => performance}/FpsLimitMode.java (97%) rename runelite-client/src/main/java/net/runelite/client/plugins/{fps/FpsConfig.java => performance/PerformanceConfig.java} (85%) rename runelite-client/src/main/java/net/runelite/client/plugins/{fps/FpsOverlay.java => performance/PerformanceOverlay.java} (66%) rename runelite-client/src/main/java/net/runelite/client/plugins/{fps/FpsPlugin.java => performance/PerformancePlugin.java} (65%) rename runelite-client/src/main/java/net/runelite/client/{plugins/worldhopper => util}/ping/IPHlpAPI.java (97%) rename runelite-client/src/main/java/net/runelite/client/{plugins/worldhopper => util}/ping/IcmpEchoReply.java (97%) rename runelite-client/src/main/java/net/runelite/client/{plugins/worldhopper => util}/ping/Ping.java (87%) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsDrawListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/performance/FpsDrawListener.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsDrawListener.java rename to runelite-client/src/main/java/net/runelite/client/plugins/performance/FpsDrawListener.java index 3be17f5577..ff1479968a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsDrawListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/performance/FpsDrawListener.java @@ -22,7 +22,7 @@ * (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.fps; +package net.runelite.client.plugins.performance; import javax.inject.Inject; import net.runelite.api.events.FocusChanged; @@ -44,7 +44,7 @@ public class FpsDrawListener implements Runnable { private static final int SAMPLE_SIZE = 4; - private final FpsConfig config; + private final PerformanceConfig config; private long targetDelay = 0; @@ -58,7 +58,7 @@ public class FpsDrawListener implements Runnable private long sleepDelay = 0; @Inject - private FpsDrawListener(FpsConfig config) + private FpsDrawListener(PerformanceConfig config) { this.config = config; reloadConfig(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsLimitMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/performance/FpsLimitMode.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsLimitMode.java rename to runelite-client/src/main/java/net/runelite/client/plugins/performance/FpsLimitMode.java index 8536f7a67a..dcc8ae308b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsLimitMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/performance/FpsLimitMode.java @@ -22,7 +22,7 @@ * (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.fps; +package net.runelite.client.plugins.performance; import lombok.Getter; import lombok.RequiredArgsConstructor; 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/performance/PerformanceConfig.java similarity index 85% rename from runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java rename to runelite-client/src/main/java/net/runelite/client/plugins/performance/PerformanceConfig.java index 73e7f3f8c5..2a344451dc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/performance/PerformanceConfig.java @@ -22,14 +22,14 @@ * (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.fps; +package net.runelite.client.plugins.performance; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup(FpsPlugin.CONFIG_GROUP_KEY) -public interface FpsConfig extends Config +@ConfigGroup(PerformancePlugin.CONFIG_GROUP_KEY) +public interface PerformanceConfig extends Config { @ConfigItem( keyName = "limitMode", @@ -63,4 +63,15 @@ 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/performance/PerformanceOverlay.java similarity index 66% rename from runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/performance/PerformanceOverlay.java index 654277744b..192e4dea86 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/performance/PerformanceOverlay.java @@ -22,14 +22,16 @@ * (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.fps; +package net.runelite.client.plugins.performance; import java.awt.Color; import java.awt.Dimension; +import java.awt.FontMetrics; import java.awt.Graphics2D; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.Point; +import net.runelite.api.Varbits; import net.runelite.api.events.FocusChanged; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; @@ -45,24 +47,22 @@ import net.runelite.client.ui.overlay.OverlayUtil; * This locks "FPS:" into one position (the far top right corner of the canvas), * along with a locked position for the FPS value. */ -public class FpsOverlay extends Overlay +public class PerformanceOverlay extends Overlay { - private static final int Y_OFFSET = 1; - private static final int VALUE_X_OFFSET = 1; - private static final String FPS_STRING = " FPS"; - // Local dependencies - private final FpsConfig config; + private final PerformanceConfig config; private final Client client; + private final PerformancePlugin plugin; // Often changing values private boolean isFocused = true; @Inject - private FpsOverlay(FpsConfig config, Client client) + private PerformanceOverlay(PerformancePlugin plugin, PerformanceConfig config, Client client) { this.config = config; this.client = client; + this.plugin = plugin; setLayer(OverlayLayer.ABOVE_WIDGETS); setPriority(OverlayPriority.HIGH); setPosition(OverlayPosition.DYNAMIC); @@ -84,21 +84,62 @@ 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 (!config.drawFps()) + if (!config.drawFps() && !config.drawPing()) { return null; } - - 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 offset = calculateOffset(); final int width = (int) client.getRealDimensions().getWidth(); - final Point point = new Point(width - textWidth - VALUE_X_OFFSET, textHeight + Y_OFFSET); - OverlayUtil.renderTextLocation(graphics, point, text, getFpsValueColor()); + final FontMetrics fontMetrics = graphics.getFontMetrics(); + + int baseYOffset = (fontMetrics.getAscent() - fontMetrics.getDescent()) + 1; + + if (config.drawFps()) + { + 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 (config.drawPing()) + { + 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())); + } 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/performance/PerformancePlugin.java similarity index 65% rename from runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java rename to runelite-client/src/main/java/net/runelite/client/plugins/performance/PerformancePlugin.java index 09e6522d87..e93e23e769 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/performance/PerformancePlugin.java @@ -22,10 +22,16 @@ * (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.fps; +package net.runelite.client.plugins.performance; import com.google.inject.Inject; import com.google.inject.Provides; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +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.client.config.ConfigManager; @@ -34,9 +40,11 @@ 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; /** - * FPS Control has two primary areas, this plugin class just keeps those areas up to date and handles setup / teardown. + * Performance 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. @@ -44,22 +52,29 @@ import net.runelite.client.ui.overlay.OverlayManager; *
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 = "FPS Control", - description = "Show current FPS and/or set an FPS limit", - tags = {"frames", "framerate", "limit", "overlay"}, + name = "Performance", + description = "Show current Ping and FPS or set an FPS limit", + tags = {"frames", "framerate", "limit", "overlay", "ping"}, enabledByDefault = false ) -public class FpsPlugin extends Plugin +public class PerformancePlugin extends Plugin { static final String CONFIG_GROUP_KEY = "fpscontrol"; + @Getter + private int ping; + @Inject private OverlayManager overlayManager; @Inject - private FpsOverlay overlay; + private PerformanceOverlay overlay; @Inject private FpsDrawListener drawListener; @@ -67,10 +82,18 @@ public class FpsPlugin extends Plugin @Inject private DrawManager drawManager; + @Inject + private Client client; + + @Inject + private PerformanceConfig performanceConfig; + + private final ScheduledExecutorService pingExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); + @Provides - FpsConfig provideConfig(ConfigManager configManager) + PerformanceConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(FpsConfig.class); + return configManager.getConfig(PerformanceConfig.class); } @Subscribe @@ -95,6 +118,7 @@ public class FpsPlugin extends Plugin overlayManager.add(overlay); drawManager.registerEveryFrameListener(drawListener); drawListener.reloadConfig(); + pingExecutorService.scheduleAtFixedRate(this::getPingToCurrentWorld, 5, 5, TimeUnit.SECONDS); } @Override @@ -102,5 +126,18 @@ public class FpsPlugin extends Plugin { overlayManager.remove(overlay); drawManager.unregisterEveryFrameListener(drawListener); + pingExecutorService.shutdown(); + } + + private void getPingToCurrentWorld() + { + if (client.getGameState().equals(GameState.LOGGED_IN) && performanceConfig.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/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 88b6089f4a..f541ab2152 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 @@ -75,7 +75,7 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.worldhopper.ping.Ping; +import net.runelite.client.util.ping.Ping; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ExecutorServiceExceptionLogger; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/IPHlpAPI.java b/runelite-client/src/main/java/net/runelite/client/util/ping/IPHlpAPI.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/IPHlpAPI.java rename to runelite-client/src/main/java/net/runelite/client/util/ping/IPHlpAPI.java index 109ea36f77..f92a2b7142 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/IPHlpAPI.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ping/IPHlpAPI.java @@ -22,7 +22,7 @@ * (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.ping; +package net.runelite.client.util.ping; import com.sun.jna.Library; import com.sun.jna.Native; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/IcmpEchoReply.java b/runelite-client/src/main/java/net/runelite/client/util/ping/IcmpEchoReply.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/IcmpEchoReply.java rename to runelite-client/src/main/java/net/runelite/client/util/ping/IcmpEchoReply.java index 0e1cc198a3..2756320990 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/IcmpEchoReply.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ping/IcmpEchoReply.java @@ -22,7 +22,7 @@ * (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.ping; +package net.runelite.client.util.ping; import com.sun.jna.Pointer; import com.sun.jna.Structure; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/Ping.java b/runelite-client/src/main/java/net/runelite/client/util/ping/Ping.java similarity index 87% rename from runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/Ping.java rename to runelite-client/src/main/java/net/runelite/client/util/ping/Ping.java index fd9a84fa57..9d189a6592 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/Ping.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ping/Ping.java @@ -22,7 +22,7 @@ * (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.ping; +package net.runelite.client.util.ping; import com.sun.jna.Memory; import com.sun.jna.Pointer; @@ -44,15 +44,20 @@ public class Ping private static final int PORT = 43594; public static int ping(World world) + { + return ping(world.getAddress()); + } + + public static int ping(String address) { try { switch (OSType.getOSType()) { case Windows: - return windowsPing(world); + return windowsPing(address); default: - return tcpPing(world); + return tcpPing(address); } } catch (IOException ex) @@ -62,11 +67,11 @@ public class Ping } } - private static int windowsPing(World world) throws UnknownHostException + private static int windowsPing(String worldAddress) throws UnknownHostException { IPHlpAPI ipHlpAPI = IPHlpAPI.INSTANCE; Pointer ptr = ipHlpAPI.IcmpCreateFile(); - InetAddress inetAddress = InetAddress.getByName(world.getAddress()); + InetAddress inetAddress = InetAddress.getByName(worldAddress); byte[] address = inetAddress.getAddress(); String dataStr = RUNELITE_PING; int dataLength = dataStr.length() + 1; @@ -88,12 +93,12 @@ public class Ping return rtt; } - private static int tcpPing(World world) throws IOException + private static int tcpPing(String worldAddress) throws IOException { try (Socket socket = new Socket()) { socket.setSoTimeout(TIMEOUT); - InetAddress inetAddress = InetAddress.getByName(world.getAddress()); + InetAddress inetAddress = InetAddress.getByName(worldAddress); long start = System.nanoTime(); socket.connect(new InetSocketAddress(inetAddress, PORT)); long end = System.nanoTime();