Merge remote-tracking branch 'runelite/master' into 3107-merge
This commit is contained in:
@@ -68,15 +68,4 @@ public interface FpsConfig extends Config
|
|||||||
{
|
{
|
||||||
return true;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ package net.runelite.client.plugins.fps;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.FontMetrics;
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Point;
|
import net.runelite.api.Point;
|
||||||
import net.runelite.api.Varbits;
|
|
||||||
import net.runelite.api.events.FocusChanged;
|
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.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
@@ -51,6 +51,10 @@ import net.runelite.client.ui.overlay.OverlayUtil;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class FpsOverlay extends Overlay
|
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
|
// Local dependencies
|
||||||
private final Client client;
|
private final Client client;
|
||||||
private final FpsPlugin plugin;
|
private final FpsPlugin plugin;
|
||||||
@@ -84,62 +88,30 @@ public class FpsOverlay extends Overlay
|
|||||||
return isEnforced() ? Color.red : Color.yellow;
|
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
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
if (!plugin.isDrawFps() && !plugin.isDrawPing())
|
if (!plugin.isDrawFps())
|
||||||
{
|
{
|
||||||
return null;
|
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 int width = (int) client.getRealDimensions().getWidth();
|
||||||
final FontMetrics fontMetrics = graphics.getFontMetrics();
|
final Point point = new Point(width - textWidth - xOffset, textHeight + Y_OFFSET);
|
||||||
|
OverlayUtil.renderTextLocation(graphics, point, text, getFpsValueColor());
|
||||||
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,27 +27,19 @@ package net.runelite.client.plugins.fps;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Singleton;
|
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.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.GameState;
|
|
||||||
import net.runelite.api.events.ConfigChanged;
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.FocusChanged;
|
import net.runelite.api.events.FocusChanged;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.eventbus.EventBus;
|
import net.runelite.client.eventbus.EventBus;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.DrawManager;
|
import net.runelite.client.ui.DrawManager;
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
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.
|
||||||
*
|
*
|
||||||
* <p>Overlay paints the current FPS, the color depends on whether or not FPS is being enforced.
|
* <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.
|
* The overlay is lightweight and is merely and indicator.
|
||||||
@@ -55,15 +47,11 @@ import net.runelite.client.util.ping.Ping;
|
|||||||
* <p>Draw Listener, sleeps a calculated amount after each canvas paint operation.
|
* <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
|
* 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.
|
* 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(
|
@PluginDescriptor(
|
||||||
name = "Performance",
|
name = "Performance",
|
||||||
description = "Show current Ping and FPS or set an FPS limit",
|
description = "Show current FPS or set an FPS limit",
|
||||||
tags = {"frames", "framerate", "limit", "overlay", "ping"},
|
tags = {"frames", "framerate", "limit", "overlay"},
|
||||||
enabledByDefault = false
|
enabledByDefault = false
|
||||||
)
|
)
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -71,9 +59,6 @@ public class FpsPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
static final String CONFIG_GROUP_KEY = "fpscontrol";
|
static final String CONFIG_GROUP_KEY = "fpscontrol";
|
||||||
|
|
||||||
@Getter
|
|
||||||
private int ping;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OverlayManager overlayManager;
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
@@ -86,30 +71,18 @@ public class FpsPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private DrawManager drawManager;
|
private DrawManager drawManager;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private FpsConfig fpsConfig;
|
private FpsConfig fpsConfig;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EventBus eventBus;
|
private EventBus eventBus;
|
||||||
|
|
||||||
private final ScheduledExecutorService pingExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor());
|
|
||||||
|
|
||||||
private boolean loaded = false;
|
|
||||||
|
|
||||||
private boolean shutdown;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private FpsLimitMode limitMode;
|
private FpsLimitMode limitMode;
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private boolean drawFps;
|
private boolean drawFps;
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private boolean drawPing;
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
FpsConfig provideConfig(ConfigManager configManager)
|
FpsConfig provideConfig(ConfigManager configManager)
|
||||||
{
|
{
|
||||||
@@ -124,7 +97,6 @@ public class FpsPlugin extends Plugin
|
|||||||
|
|
||||||
limitMode = fpsConfig.limitMode();
|
limitMode = fpsConfig.limitMode();
|
||||||
drawFps = fpsConfig.drawFps();
|
drawFps = fpsConfig.drawFps();
|
||||||
drawPing = fpsConfig.drawPing();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,11 +106,6 @@ public class FpsPlugin extends Plugin
|
|||||||
overlay.onFocusChanged(event);
|
overlay.onFocusChanged(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onGameStateChanged(GameStateChanged event)
|
|
||||||
{
|
|
||||||
shutdown = event.getGameState() != GameState.LOGGED_IN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
@@ -146,17 +113,9 @@ public class FpsPlugin extends Plugin
|
|||||||
|
|
||||||
limitMode = fpsConfig.limitMode();
|
limitMode = fpsConfig.limitMode();
|
||||||
drawFps = fpsConfig.drawFps();
|
drawFps = fpsConfig.drawFps();
|
||||||
drawPing = fpsConfig.drawPing();
|
|
||||||
overlayManager.add(overlay);
|
overlayManager.add(overlay);
|
||||||
drawManager.registerEveryFrameListener(drawListener);
|
drawManager.registerEveryFrameListener(drawListener);
|
||||||
drawListener.reloadConfig();
|
drawListener.reloadConfig();
|
||||||
shutdown = client.getGameState() != GameState.LOGGED_IN;
|
|
||||||
|
|
||||||
if (!loaded)
|
|
||||||
{
|
|
||||||
pingExecutorService.scheduleAtFixedRate(this::getPingToCurrentWorld, 5, 5, TimeUnit.SECONDS);
|
|
||||||
loaded = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -166,25 +125,11 @@ public class FpsPlugin extends Plugin
|
|||||||
|
|
||||||
overlayManager.remove(overlay);
|
overlayManager.remove(overlay);
|
||||||
drawManager.unregisterEveryFrameListener(drawListener);
|
drawManager.unregisterEveryFrameListener(drawListener);
|
||||||
shutdown = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSubscriptions()
|
private void addSubscriptions()
|
||||||
{
|
{
|
||||||
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||||
eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ enum ItemIdentification
|
|||||||
MAGIC_SAPLING(Type.SAPLING, "Magic", "MAG", ItemID.MAGIC_SAPLING, ItemID.MAGIC_SEEDLING, ItemID.MAGIC_SEEDLING_W),
|
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),
|
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),
|
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),
|
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),
|
BANANA_SAPLING(Type.SAPLING, "Banana", "BAN", ItemID.BANANA_SAPLING, ItemID.BANANA_SEEDLING, ItemID.BANANA_SEEDLING_W),
|
||||||
|
|||||||
@@ -102,14 +102,19 @@ class NightmareZoneOverlay extends Overlay
|
|||||||
|
|
||||||
renderAbsorptionCounter();
|
renderAbsorptionCounter();
|
||||||
|
|
||||||
|
final int currentPoints = client.getVar(Varbits.NMZ_POINTS);
|
||||||
|
final int totalPoints = currentPoints + client.getVar(VarPlayer.NMZ_REWARD_POINTS);
|
||||||
|
|
||||||
panelComponent.getChildren().clear();
|
panelComponent.getChildren().clear();
|
||||||
|
|
||||||
TableComponent tableComponent = new TableComponent();
|
TableComponent tableComponent = new TableComponent();
|
||||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
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())
|
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);
|
panelComponent.getChildren().add(tableComponent);
|
||||||
|
|||||||
@@ -25,11 +25,14 @@
|
|||||||
package net.runelite.client.plugins.nightmarezone;
|
package net.runelite.client.plugins.nightmarezone;
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.runelite.api.ChatMessageType;
|
import net.runelite.api.ChatMessageType;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
@@ -56,6 +59,7 @@ import net.runelite.client.util.Text;
|
|||||||
public class NightmareZonePlugin extends Plugin
|
public class NightmareZonePlugin extends Plugin
|
||||||
{
|
{
|
||||||
private static final int[] NMZ_MAP_REGION = {9033};
|
private static final int[] NMZ_MAP_REGION = {9033};
|
||||||
|
private static final Duration HOUR = Duration.ofHours(1);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Notifier notifier;
|
private Notifier notifier;
|
||||||
@@ -75,6 +79,11 @@ public class NightmareZonePlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private EventBus eventBus;
|
private EventBus eventBus;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int pointsPerHour;
|
||||||
|
|
||||||
|
private Instant nmzSessionStartTime;
|
||||||
|
|
||||||
// This starts as true since you need to get
|
// This starts as true since you need to get
|
||||||
// above the threshold before sending notifications
|
// above the threshold before sending notifications
|
||||||
private boolean absorptionNotificationSend = true;
|
private boolean absorptionNotificationSend = true;
|
||||||
@@ -120,6 +129,8 @@ public class NightmareZonePlugin extends Plugin
|
|||||||
{
|
{
|
||||||
nmzWidget.setHidden(false);
|
nmzWidget.setHidden(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetPointsPerHour();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSubscriptions()
|
private void addSubscriptions()
|
||||||
@@ -155,6 +166,11 @@ public class NightmareZonePlugin extends Plugin
|
|||||||
absorptionNotificationSend = true;
|
absorptionNotificationSend = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nmzSessionStartTime != null)
|
||||||
|
{
|
||||||
|
resetPointsPerHour();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +178,11 @@ public class NightmareZonePlugin extends Plugin
|
|||||||
{
|
{
|
||||||
checkAbsorption();
|
checkAbsorption();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.moveOverlay())
|
||||||
|
{
|
||||||
|
pointsPerHour = calculatePointsPerHour();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onChatMessage(ChatMessage event)
|
private void onChatMessage(ChatMessage event)
|
||||||
@@ -239,6 +260,32 @@ public class NightmareZonePlugin extends Plugin
|
|||||||
return !Arrays.equals(client.getMapRegions(), NMZ_MAP_REGION);
|
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()
|
private void updateConfig()
|
||||||
{
|
{
|
||||||
this.moveOverlay = config.moveOverlay();
|
this.moveOverlay = config.moveOverlay();
|
||||||
|
|||||||
@@ -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,91 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -46,6 +47,7 @@ import javax.imageio.ImageIO;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
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.Plugin;
|
|||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
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;
|
||||||
@@ -98,8 +101,7 @@ import org.apache.commons.lang3.ArrayUtils;
|
|||||||
public class WorldHopperPlugin extends Plugin
|
public class WorldHopperPlugin extends Plugin
|
||||||
{
|
{
|
||||||
private static final int WORLD_FETCH_TIMER = 10;
|
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 TICK_THROTTLE = (int) Duration.ofMinutes(10).toMillis();
|
||||||
|
|
||||||
private static final int DISPLAY_SWITCHER_MAX_ATTEMPTS = 3;
|
private static final int DISPLAY_SWITCHER_MAX_ATTEMPTS = 3;
|
||||||
@@ -133,6 +135,12 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private EventBus eventBus;
|
private EventBus eventBus;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private WorldHopperPingOverlay worldHopperOverlay;
|
||||||
|
|
||||||
private ScheduledExecutorService hopperExecutorService;
|
private ScheduledExecutorService hopperExecutorService;
|
||||||
|
|
||||||
private NavigationButton navButton;
|
private NavigationButton navButton;
|
||||||
@@ -146,8 +154,9 @@ 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 Instant lastFetch;
|
private Instant lastFetch;
|
||||||
private boolean firstRun;
|
private boolean firstRun;
|
||||||
|
|
||||||
@@ -158,6 +167,11 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
private boolean ping;
|
private boolean ping;
|
||||||
private boolean showWorldHopMessage;
|
private boolean showWorldHopMessage;
|
||||||
private SubscriptionFilterMode subscriptionFilter;
|
private SubscriptionFilterMode subscriptionFilter;
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean displayPing;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private int currentPing;
|
||||||
|
|
||||||
private final HotkeyListener previousKeyListener = new HotkeyListener(() -> this.previousKey)
|
private final HotkeyListener previousKeyListener = new HotkeyListener(() -> this.previousKey)
|
||||||
{
|
{
|
||||||
@@ -189,6 +203,7 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
addSubscriptions();
|
addSubscriptions();
|
||||||
|
|
||||||
firstRun = true;
|
firstRun = true;
|
||||||
|
currentPing = -1;
|
||||||
|
|
||||||
keyManager.registerKeyListener(previousKeyListener);
|
keyManager.registerKeyListener(previousKeyListener);
|
||||||
keyManager.registerKeyListener(nextKeyListener);
|
keyManager.registerKeyListener(nextKeyListener);
|
||||||
@@ -213,11 +228,18 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
clientToolbar.addNavigation(navButton);
|
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);
|
worldResultFuture = executorService.scheduleAtFixedRate(this::tick, 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES);
|
||||||
|
|
||||||
hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor());
|
// Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway
|
||||||
pingFuture = hopperExecutorService.scheduleAtFixedRate(this::pingWorlds, WORLD_PING_TIMER, WORLD_PING_TIMER, TimeUnit.MINUTES);
|
pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS);
|
||||||
|
currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -228,6 +250,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);
|
||||||
|
|
||||||
@@ -482,7 +509,8 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
if (firstRun)
|
if (firstRun)
|
||||||
{
|
{
|
||||||
firstRun = false;
|
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()
|
new WorldClient().lookupWorlds()
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
.take(1)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(worldResult) ->
|
(worldResult) ->
|
||||||
{
|
{
|
||||||
@@ -775,7 +804,10 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
return null;
|
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)
|
if (worldResult == null || !this.showSidebar || !this.ping)
|
||||||
{
|
{
|
||||||
@@ -804,5 +836,66 @@ public class WorldHopperPlugin extends Plugin
|
|||||||
this.ping = config.ping();
|
this.ping = config.ping();
|
||||||
this.showWorldHopMessage = config.showWorldHopMessage();
|
this.showWorldHopMessage = config.showWorldHopMessage();
|
||||||
this.subscriptionFilter = config.subscriptionFilter();
|
this.subscriptionFilter = config.subscriptionFilter();
|
||||||
|
this.displayPing = config.displayPing();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ping the next world
|
||||||
|
*/
|
||||||
|
private void pingNextWorld()
|
||||||
|
{
|
||||||
|
if (worldResult == null || !config.showSidebar() || !config.ping())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<World> 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,12 @@
|
|||||||
"name": "Pollnivneach Rooftop",
|
"name": "Pollnivneach Rooftop",
|
||||||
"xp": 890
|
"xp": 890
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"level": 75,
|
||||||
|
"icon": 23962,
|
||||||
|
"name": "Prifddinas Agility Course",
|
||||||
|
"xp": 1220
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"level": 80,
|
"level": 80,
|
||||||
"icon": 11849,
|
"icon": 11849,
|
||||||
|
|||||||
@@ -240,6 +240,12 @@
|
|||||||
"name": "Lantadyme",
|
"name": "Lantadyme",
|
||||||
"xp": 134.5
|
"xp": 134.5
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"level": 74,
|
||||||
|
"icon": 23962,
|
||||||
|
"name": "Crystal Tree",
|
||||||
|
"xp": 13366
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"level": 75,
|
"level": 75,
|
||||||
"icon": 1513,
|
"icon": 1513,
|
||||||
|
|||||||
Reference in New Issue
Block a user