Ping (#78)
* Add option to draw ping underneath the fps * Move the ping package from the world hopper plugin to utils
This commit is contained in:
@@ -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();
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
* <p>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;
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
Reference in New Issue
Block a user