- The type of the item contained in the nodes of the graph
+ * @return - A topologically sorted list corresponding to graph.
+ *
+ * Multiple invocations with the same arguments may return lists that are not equal.
*/
- private List topologicalSort(Graph graph)
+ @VisibleForTesting
+ static List topologicalSort(Graph graph)
{
MutableGraph graphCopy = Graphs.copyOf(graph);
List l = new ArrayList<>();
@@ -737,7 +737,7 @@ public class PluginManager
l.add(n);
- for (T m : graphCopy.successors(n))
+ for (T m : new HashSet<>(graphCopy.successors(n)))
{
graphCopy.removeEdge(n, m);
if (graphCopy.inDegree(m) == 0)
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java
index f1e72c9303..3d86d52ad9 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java
@@ -1287,7 +1287,7 @@ public class ChatCommandsPlugin extends Plugin
ItemPrice item = retrieveFromList(results, search);
int itemId = item.getId();
- int itemPrice = runeLiteConfig.useWikiItemPrices() && item.getWikiPrice() > 0 ? item.getWikiPrice() : item.getPrice();
+ int itemPrice = runeLiteConfig.useWikiItemPrices() ? itemManager.getWikiPrice(item) : item.getPrice();
final ChatMessageBuilder builder = new ChatMessageBuilder()
.append(ChatColorType.NORMAL)
@@ -1407,21 +1407,11 @@ public class ChatCommandsPlugin extends Plugin
return;
}
- ChatMessageType type = chatMessage.getType();
-
- String player;
- if (type == ChatMessageType.PRIVATECHATOUT)
- {
- player = client.getLocalPlayer().getName();
- }
- else
- {
- player = Text.sanitize(chatMessage.getName());
- }
+ final HiscoreLookup lookup = getCorrectLookupFor(chatMessage);
try
{
- HiscoreResult playerStats = hiscoreClient.lookup(player);
+ HiscoreResult playerStats = hiscoreClient.lookup(lookup.getName(), lookup.getEndpoint());
if (playerStats == null)
{
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java
index 210ee8b935..4941ad5f3b 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java
@@ -29,7 +29,8 @@ import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.GameState;
-import net.runelite.api.events.GameStateChanged;
+import net.runelite.api.events.WorldChanged;
+import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.SessionOpen;
@@ -51,27 +52,33 @@ public class DefaultWorldPlugin extends Plugin
@Inject
private Client client;
+ @Inject
+ private ClientThread clientThread;
+
@Inject
private DefaultWorldConfig config;
@Inject
private WorldService worldService;
- private int worldCache;
- private boolean worldChangeRequired;
-
@Override
- protected void startUp() throws Exception
+ protected void startUp()
{
- worldChangeRequired = true;
- applyWorld();
+ clientThread.invokeLater(() ->
+ {
+ if (client.getGameState().getState() < GameState.LOGIN_SCREEN.getState())
+ {
+ return false;
+ }
+
+ applyWorld();
+ return true;
+ });
}
@Override
- protected void shutDown() throws Exception
+ protected void shutDown()
{
- worldChangeRequired = true;
- changeWorld(worldCache);
}
@Provides
@@ -83,29 +90,30 @@ public class DefaultWorldPlugin extends Plugin
@Subscribe
public void onSessionOpen(SessionOpen event)
{
- worldChangeRequired = true;
- applyWorld();
+ clientThread.invokeLater(this::applyWorld);
}
@Subscribe
- public void onGameStateChanged(GameStateChanged event)
+ public void onWorldChanged(WorldChanged worldChanged)
{
- if (event.getGameState() == GameState.LOGGED_IN)
- {
- config.lastWorld(client.getWorld());
- }
-
- applyWorld();
+ int world = client.getWorld();
+ config.lastWorld(world);
+ log.debug("Saving last world {}", world);
}
- private void changeWorld(int newWorld)
+ private void applyWorld()
{
- if (!worldChangeRequired || client.getGameState() != GameState.LOGIN_SCREEN)
+ if (client.getGameState() != GameState.LOGIN_SCREEN)
{
return;
}
- worldChangeRequired = false;
+ if (System.getProperty("cli.world") != null)
+ {
+ return;
+ }
+
+ final int newWorld = config.useLastWorld() ? config.lastWorld() : config.getWorld();
int correctedWorld = newWorld < 300 ? newWorld + 300 : newWorld;
// Old School RuneScape worlds start on 301 so don't even bother trying to find lower id ones
@@ -116,7 +124,6 @@ public class DefaultWorldPlugin extends Plugin
}
final WorldResult worldResult = worldService.getWorlds();
-
if (worldResult == null)
{
log.warn("Failed to lookup worlds.");
@@ -124,40 +131,21 @@ public class DefaultWorldPlugin extends Plugin
}
final World world = worldResult.findWorld(correctedWorld);
-
- if (world != null)
- {
- final net.runelite.api.World rsWorld = client.createWorld();
- rsWorld.setActivity(world.getActivity());
- rsWorld.setAddress(world.getAddress());
- rsWorld.setId(world.getId());
- rsWorld.setPlayerCount(world.getPlayers());
- rsWorld.setLocation(world.getLocation());
- rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes()));
-
- client.changeWorld(rsWorld);
- log.debug("Applied new world {}", correctedWorld);
- }
- else
+ if (world == null)
{
log.warn("World {} not found.", correctedWorld);
- }
- }
-
- private void applyWorld()
- {
- if (worldCache == 0)
- {
- worldCache = client.getWorld();
- log.debug("Stored old world {}", worldCache);
- }
-
- if (System.getProperty("cli.world") != null)
- {
return;
}
- final int newWorld = !config.useLastWorld() ? config.getWorld() : config.lastWorld();
- changeWorld(newWorld);
+ final net.runelite.api.World rsWorld = client.createWorld();
+ rsWorld.setActivity(world.getActivity());
+ rsWorld.setAddress(world.getAddress());
+ rsWorld.setId(world.getId());
+ rsWorld.setPlayerCount(world.getPlayers());
+ rsWorld.setLocation(world.getLocation());
+ rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes()));
+
+ client.changeWorld(rsWorld);
+ log.debug("Applied new world {}", correctedWorld);
}
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java
index ae22917b37..9cbfaf667b 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java
@@ -215,7 +215,7 @@ class GrandExchangeSearchPanel extends JPanel
ItemComposition itemComp = itemManager.getItemComposition(itemId);
ItemStats itemStats = itemManager.getItemStats(itemId, false);
- int itemPrice = useActivelyTradedPrice && item.getWikiPrice() > 0 ? item.getWikiPrice() : item.getPrice();
+ int itemPrice = useActivelyTradedPrice ? itemManager.getWikiPrice(item) : item.getPrice();
int itemLimit = itemStats != null ? itemStats.getGeLimit() : 0;
final int haPrice = itemComp.getHaPrice();
AsyncBufferedImage itemImage = itemManager.getImage(itemId);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemHotkeyListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemHotkeyListener.java
new file mode 100644
index 0000000000..a83210b0a7
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemHotkeyListener.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, Seth
+ * 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.grounditems;
+
+import java.time.Duration;
+import java.time.Instant;
+import javax.inject.Inject;
+import net.runelite.client.util.HotkeyListener;
+
+class GroundItemHotkeyListener extends HotkeyListener
+{
+ private final GroundItemsPlugin plugin;
+ private final GroundItemsConfig config;
+
+ private Instant lastPress;
+
+ @Inject
+ private GroundItemHotkeyListener(GroundItemsPlugin plugin, GroundItemsConfig config)
+ {
+ super(config::hotkey);
+
+ this.plugin = plugin;
+ this.config = config;
+ }
+
+ @Override
+ public void hotkeyPressed()
+ {
+ if (plugin.isHideAll())
+ {
+ plugin.setHideAll(false);
+ plugin.setHotKeyPressed(true);
+ lastPress = null;
+ }
+ else if (lastPress != null && !plugin.isHotKeyPressed() && config.doubleTapDelay() > 0 && Duration.between(lastPress, Instant.now()).compareTo(Duration.ofMillis(config.doubleTapDelay())) < 0)
+ {
+ plugin.setHideAll(true);
+ lastPress = null;
+ }
+ else
+ {
+ plugin.setHotKeyPressed(true);
+ lastPress = Instant.now();
+ }
+ }
+
+ @Override
+ public void hotkeyReleased()
+ {
+ plugin.setHotKeyPressed(false);
+ plugin.setTextBoxBounds(null);
+ plugin.setHiddenBoxBounds(null);
+ plugin.setHighlightBoxBounds(null);
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemMouseAdapter.java
similarity index 71%
rename from runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemInputListener.java
rename to runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemMouseAdapter.java
index da6c3a80c5..a61be015db 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemInputListener.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemMouseAdapter.java
@@ -25,69 +25,16 @@
package net.runelite.client.plugins.grounditems;
import java.awt.Point;
-import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
-import java.time.Duration;
-import java.time.Instant;
import javax.inject.Inject;
import javax.swing.SwingUtilities;
-import net.runelite.client.input.KeyListener;
import net.runelite.client.input.MouseAdapter;
-public class GroundItemInputListener extends MouseAdapter implements KeyListener
+class GroundItemMouseAdapter extends MouseAdapter
{
- private static final int HOTKEY = KeyEvent.VK_ALT;
-
- private Instant lastPress;
-
@Inject
private GroundItemsPlugin plugin;
- @Inject
- private GroundItemsConfig config;
-
- @Override
- public void keyTyped(KeyEvent e)
- {
-
- }
-
- @Override
- public void keyPressed(KeyEvent e)
- {
- if (e.getKeyCode() == HOTKEY)
- {
- if (plugin.isHideAll())
- {
- plugin.setHideAll(false);
- plugin.setHotKeyPressed(true);
- lastPress = null;
- }
- else if (lastPress != null && !plugin.isHotKeyPressed() && config.doubleTapDelay() > 0 && Duration.between(lastPress, Instant.now()).compareTo(Duration.ofMillis(config.doubleTapDelay())) < 0)
- {
- plugin.setHideAll(true);
- lastPress = null;
- }
- else
- {
- plugin.setHotKeyPressed(true);
- lastPress = Instant.now();
- }
- }
- }
-
- @Override
- public void keyReleased(KeyEvent e)
- {
- if (e.getKeyCode() == HOTKEY)
- {
- plugin.setHotKeyPressed(false);
- plugin.setTextBoxBounds(null);
- plugin.setHiddenBoxBounds(null);
- plugin.setHighlightBoxBounds(null);
- }
- }
-
@Override
public MouseEvent mousePressed(MouseEvent e)
{
@@ -134,4 +81,3 @@ public class GroundItemInputListener extends MouseAdapter implements KeyListener
return e;
}
}
-
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java
index 5869c07208..1031765645 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java
@@ -30,8 +30,9 @@ import net.runelite.client.config.Alpha;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
-import net.runelite.client.config.Units;
import net.runelite.client.config.ConfigSection;
+import net.runelite.client.config.Keybind;
+import net.runelite.client.config.Units;
import net.runelite.client.plugins.grounditems.config.DespawnTimerMode;
import net.runelite.client.plugins.grounditems.config.HighlightTier;
import net.runelite.client.plugins.grounditems.config.ItemHighlightMode;
@@ -447,4 +448,15 @@ public interface GroundItemsConfig extends Config
{
return Lootbeam.Style.MODERN;
}
+
+ @ConfigItem(
+ keyName = "hotkey",
+ name = "Hotkey",
+ description = "Configures the hotkey used by the Ground Items plugin",
+ position = 33
+ )
+ default Keybind hotkey()
+ {
+ return Keybind.ALT;
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java
index af5282db14..c4524bf353 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java
@@ -140,7 +140,10 @@ public class GroundItemsPlugin extends Plugin
private List highlightedItemsList = new CopyOnWriteArrayList<>();
@Inject
- private GroundItemInputListener inputListener;
+ private GroundItemHotkeyListener hotkeyListener;
+
+ @Inject
+ private GroundItemMouseAdapter mouseAdapter;
@Inject
private MouseManager mouseManager;
@@ -191,8 +194,8 @@ public class GroundItemsPlugin extends Plugin
protected void startUp()
{
overlayManager.add(overlay);
- mouseManager.registerMouseListener(inputListener);
- keyManager.registerKeyListener(inputListener);
+ mouseManager.registerMouseListener(mouseAdapter);
+ keyManager.registerKeyListener(hotkeyListener);
executor.execute(this::reset);
lastUsedItem = -1;
}
@@ -201,8 +204,8 @@ public class GroundItemsPlugin extends Plugin
protected void shutDown()
{
overlayManager.remove(overlay);
- mouseManager.unregisterMouseListener(inputListener);
- keyManager.unregisterKeyListener(inputListener);
+ mouseManager.unregisterMouseListener(mouseAdapter);
+ keyManager.unregisterKeyListener(hotkeyListener);
highlightedItems.invalidateAll();
highlightedItems = null;
hiddenItems.invalidateAll();
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java
index 0a14053e36..e401f39d9b 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java
@@ -33,6 +33,7 @@ import net.runelite.api.Client;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.NPC;
+import net.runelite.api.Point;
import net.runelite.api.TileObject;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
@@ -78,8 +79,8 @@ class InteractHighlightOverlay extends Overlay
return;
}
- MenuEntry top = menuEntries[menuEntries.length - 1];
- MenuAction menuAction = top.getType();
+ MenuEntry entry = client.isMenuOpen() ? hoveredMenuEntry(menuEntries) : menuEntries[menuEntries.length - 1];
+ MenuAction menuAction = entry.getType();
switch (menuAction)
{
@@ -90,10 +91,11 @@ class InteractHighlightOverlay extends Overlay
case GAME_OBJECT_THIRD_OPTION:
case GAME_OBJECT_FOURTH_OPTION:
case GAME_OBJECT_FIFTH_OPTION:
+ case EXAMINE_OBJECT:
{
- int x = top.getParam0();
- int y = top.getParam1();
- int id = top.getIdentifier();
+ int x = entry.getParam0();
+ int y = entry.getParam1();
+ int id = entry.getIdentifier();
TileObject tileObject = plugin.findTileObject(x, y, id);
if (tileObject != null && config.objectShowHover() && (tileObject != plugin.getInteractedObject() || !config.objectShowInteract()))
{
@@ -108,8 +110,9 @@ class InteractHighlightOverlay extends Overlay
case NPC_THIRD_OPTION:
case NPC_FOURTH_OPTION:
case NPC_FIFTH_OPTION:
+ case EXAMINE_NPC:
{
- int id = top.getIdentifier();
+ int id = entry.getIdentifier();
NPC npc = plugin.findNpc(id);
if (npc != null && config.npcShowHover() && (npc != plugin.getInteractedTarget() || !config.npcShowInteract()))
{
@@ -155,4 +158,29 @@ class InteractHighlightOverlay extends Overlay
}
return end;
}
+
+ private MenuEntry hoveredMenuEntry(final MenuEntry[] menuEntries)
+ {
+ final int menuX = client.getMenuX();
+ final int menuY = client.getMenuY();
+ final int menuWidth = client.getMenuWidth();
+ final Point mousePosition = client.getMouseCanvasPosition();
+
+ int dy = mousePosition.getY() - menuY;
+ dy -= 19; // Height of Choose Option
+ if (dy < 0)
+ {
+ return menuEntries[menuEntries.length - 1];
+ }
+
+ int idx = dy / 15; // Height of each menu option
+ idx = menuEntries.length - 1 - idx;
+
+ if (mousePosition.getX() > menuX && mousePosition.getX() < menuX + menuWidth
+ && idx >= 0 && idx < menuEntries.length)
+ {
+ return menuEntries[idx];
+ }
+ return menuEntries[menuEntries.length - 1];
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java
index f87bcaeef3..28f90cfc6f 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java
@@ -34,18 +34,23 @@ import static net.runelite.api.ObjectID.MAGIC_TREE_10834;
import static net.runelite.api.NullObjectID.NULL_10835;
import static net.runelite.api.ObjectID.MAHOGANY;
import static net.runelite.api.ObjectID.MAHOGANY_36688;
+import static net.runelite.api.ObjectID.MAHOGANY_40760;
import static net.runelite.api.ObjectID.MAPLE_TREE_10832;
import static net.runelite.api.ObjectID.MAPLE_TREE_36681;
+import static net.runelite.api.ObjectID.MAPLE_TREE_40754;
import static net.runelite.api.ObjectID.OAK_10820;
import static net.runelite.api.ObjectID.OAK_TREE_4540;
import static net.runelite.api.ObjectID.REDWOOD_29670;
import static net.runelite.api.ObjectID.TEAK;
import static net.runelite.api.ObjectID.TEAK_36686;
+import static net.runelite.api.ObjectID.TEAK_40758;
import static net.runelite.api.ObjectID.TREE;
import static net.runelite.api.ObjectID.TREE_1277;
import static net.runelite.api.ObjectID.TREE_1278;
import static net.runelite.api.ObjectID.TREE_1279;
import static net.runelite.api.ObjectID.TREE_1280;
+import static net.runelite.api.ObjectID.TREE_40750;
+import static net.runelite.api.ObjectID.TREE_40752;
import static net.runelite.api.ObjectID.WILLOW;
import static net.runelite.api.ObjectID.WILLOW_10829;
import static net.runelite.api.ObjectID.WILLOW_10831;
@@ -53,15 +58,16 @@ import static net.runelite.api.ObjectID.WILLOW_10833;
import static net.runelite.api.ObjectID.YEW;
import static net.runelite.api.NullObjectID.NULL_10823;
import static net.runelite.api.ObjectID.YEW_36683;
+import static net.runelite.api.ObjectID.YEW_40756;
import static net.runelite.client.util.RSTimeUnit.GAME_TICKS;
@Getter
enum Tree
{
- REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280),
+ REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280, TREE_40750, TREE_40752),
OAK_TREE(Duration.of(14, GAME_TICKS), OAK_TREE_4540, OAK_10820),
WILLOW_TREE(Duration.of(14, GAME_TICKS), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833),
- MAPLE_TREE(Duration.of(59, GAME_TICKS), MAPLE_TREE_10832, MAPLE_TREE_36681)
+ MAPLE_TREE(Duration.of(59, GAME_TICKS), MAPLE_TREE_10832, MAPLE_TREE_36681, MAPLE_TREE_40754)
{
@Override
Duration getRespawnTime(int region)
@@ -69,9 +75,9 @@ enum Tree
return region == MISCELLANIA_REGION ? Duration.of(14, GAME_TICKS) : super.respawnTime;
}
},
- TEAK_TREE(Duration.of(15, GAME_TICKS), TEAK, TEAK_36686),
- MAHOGANY_TREE(Duration.of(14, GAME_TICKS), MAHOGANY, MAHOGANY_36688),
- YEW_TREE(Duration.of(99, GAME_TICKS), YEW, NULL_10823, YEW_36683),
+ TEAK_TREE(Duration.of(15, GAME_TICKS), TEAK, TEAK_36686, TEAK_40758),
+ MAHOGANY_TREE(Duration.of(14, GAME_TICKS), MAHOGANY, MAHOGANY_36688, MAHOGANY_40760),
+ YEW_TREE(Duration.of(99, GAME_TICKS), YEW, NULL_10823, YEW_36683, YEW_40756),
MAGIC_TREE(Duration.of(199, GAME_TICKS), MAGIC_TREE_10834, NULL_10835),
REDWOOD(Duration.of(199, GAME_TICKS), ObjectID.REDWOOD, REDWOOD_29670);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java
index dbcfd6ddbd..8f6f9d6dbc 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java
@@ -124,7 +124,7 @@ class XpInfoBox extends JPanel
// Create open xp tracker menu
final JMenuItem openXpTracker = new JMenuItem("Open Wise Old Man");
openXpTracker.addActionListener(e -> LinkBrowser.browse(XpPanel.buildXpTrackerUrl(
- client.getLocalPlayer(), skill)));
+ client.getWorldType(), client.getLocalPlayer(), skill)));
// Create reset menu
final JMenuItem reset = new JMenuItem("Reset");
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java
index ed72128ef4..0ecce8290d 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java
@@ -29,6 +29,7 @@ import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
@@ -41,6 +42,7 @@ import javax.swing.border.EmptyBorder;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.Skill;
+import net.runelite.api.WorldType;
import net.runelite.client.game.SkillIconManager;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
@@ -83,7 +85,7 @@ class XpPanel extends PluginPanel
// Create open xp tracker menu
final JMenuItem openXpTracker = new JMenuItem("Open Wise Old Man");
openXpTracker.addActionListener(e -> LinkBrowser.browse(XpPanel.buildXpTrackerUrl(
- client.getLocalPlayer(), Skill.OVERALL)));
+ client.getWorldType(), client.getLocalPlayer(), Skill.OVERALL)));
// Create reset all menu
final JMenuItem reset = new JMenuItem("Reset All");
@@ -146,7 +148,7 @@ class XpPanel extends PluginPanel
add(errorPanel);
}
- static String buildXpTrackerUrl(final Actor player, final Skill skill)
+ static String buildXpTrackerUrl(final Set worldTypes, final Actor player, final Skill skill)
{
if (player == null)
{
@@ -155,7 +157,7 @@ class XpPanel extends PluginPanel
return new HttpUrl.Builder()
.scheme("https")
- .host("wiseoldman.net")
+ .host(worldTypes.contains(WorldType.SEASONAL) ? "seasonal.wiseoldman.net" : "wiseoldman.net")
.addPathSegment("players")
.addPathSegment(player.getName())
.addPathSegment("gained")
diff --git a/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java b/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java
index 4db58ccf98..090c0d21e9 100644
--- a/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java
+++ b/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java
@@ -89,6 +89,7 @@ public abstract class HotkeyListener implements KeyListener
}
isPressed = false;
isConsumingTyped = false;
+ hotkeyReleased();
}
}
@@ -99,4 +100,8 @@ public abstract class HotkeyListener implements KeyListener
protected void hotkeyReleased()
{
}
+
+ public void hotkeyReleased()
+ {
+ }
}
diff --git a/runelite-client/src/main/resources/net/runelite/client/runelite.properties b/runelite-client/src/main/resources/net/runelite/client/runelite.properties
index 262089b836..b719012af5 100644
--- a/runelite-client/src/main/resources/net/runelite/client/runelite.properties
+++ b/runelite-client/src/main/resources/net/runelite/client/runelite.properties
@@ -17,4 +17,5 @@ runelite.imgur.client.id=30d71e5f6860809
runelite.api.base=https://api.runelite.net/runelite-@project.version@
runelite.session=https://session.openosrs.dev
runelite.static.base=https://static.runelite.net
-runelite.ws=https://api.runelite.net/ws
\ No newline at end of file
+runelite.ws=https://api.runelite.net/ws
+runelite.config=https://static.runelite.net/config.json
\ No newline at end of file
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java
index 50692a915a..3166552b6a 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java
@@ -24,6 +24,8 @@
*/
package net.runelite.client.plugins;
+import com.google.common.graph.GraphBuilder;
+import com.google.common.graph.MutableGraph;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import com.google.inject.Guice;
@@ -40,6 +42,7 @@ import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
import net.runelite.api.Client;
@@ -51,6 +54,7 @@ import net.runelite.client.eventbus.EventBus;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -89,7 +93,7 @@ public class PluginManagerTest
.thenThrow(new RuntimeException("in plugin manager test"));
Injector injector = Guice.createInjector(Modules
- .override(new RuneLiteModule(okHttpClient, () -> null, true, false,
+ .override(new RuneLiteModule(okHttpClient, () -> null, () -> null, true, false,
RuneLite.DEFAULT_SESSION_FILE,
RuneLite.DEFAULT_CONFIG_FILE))
.with(BoundFieldModule.of(this)));
@@ -208,4 +212,23 @@ public class PluginManagerTest
}
}
+ @Test
+ public void testTopologicalSort()
+ {
+ MutableGraph graph = GraphBuilder
+ .directed()
+ .build();
+
+ graph.addNode(1);
+ graph.addNode(2);
+ graph.addNode(3);
+
+ graph.putEdge(1, 2);
+ graph.putEdge(1, 3);
+
+ List sorted = PluginManager.topologicalSort(graph);
+
+ assertTrue(sorted.indexOf(1) < sorted.indexOf(2));
+ assertTrue(sorted.indexOf(1) < sorted.indexOf(3));
+ }
}