diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java
index 12dc9b068c..aca0d2ac66 100644
--- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java
+++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java
@@ -44,6 +44,7 @@ public final class AnimationID
public static final int WOODCUTTING_DRAGON = 2846;
public static final int WOODCUTTING_INFERNAL = 2117;
public static final int WOODCUTTING_3A_AXE = 7264;
+ public static final int WOODCUTTING_CRYSTAL = 8324;
public static final int CONSUMING = 829; // consuming consumables
public static final int FIREMAKING = 733;
public static final int DEATH = 836;
@@ -94,6 +95,7 @@ public final class AnimationID
public static final int FISHING_BARBTAIL_HARPOON = 5108;
public static final int FISHING_DRAGON_HARPOON = 7401;
public static final int FISHING_INFERNAL_HARPOON = 7402;
+ public static final int FISHING_CRYSTAL_HARPOON = 8336;
public static final int FISHING_OILY_ROD = 622;
public static final int FISHING_KARAMBWAN = 1193;
public static final int FISHING_CRUSHING_INFERNAL_EELS = 7553;
@@ -107,9 +109,11 @@ public final class AnimationID
public static final int MINING_ADAMANT_PICKAXE = 628;
public static final int MINING_RUNE_PICKAXE = 624;
public static final int MINING_DRAGON_PICKAXE = 7139;
- public static final int MINING_DRAGON_PICKAXE_ORN = 642;
+ public static final int MINING_DRAGON_PICKAXE_UPGRADED = 642;
+ public static final int MINING_DRAGON_PICKAXE_OR = 8346;
public static final int MINING_INFERNAL_PICKAXE = 4482;
public static final int MINING_3A_PICKAXE = 7283;
+ public static final int MINING_CRYSTAL_PICKAXE = 8347;
public static final int MINING_MOTHERLODE_BRONZE = 6753;
public static final int MINING_MOTHERLODE_IRON = 6754;
public static final int MINING_MOTHERLODE_STEEL = 6755;
@@ -118,9 +122,11 @@ public final class AnimationID
public static final int MINING_MOTHERLODE_ADAMANT = 6756;
public static final int MINING_MOTHERLODE_RUNE = 6752;
public static final int MINING_MOTHERLODE_DRAGON = 6758;
- public static final int MINING_MOTHERLODE_DRAGON_ORN = 335;
+ public static final int MINING_MOTHERLODE_DRAGON_UPGRADED = 335;
+ public static final int MINING_MOTHERLODE_DRAGON_OR = 8344;
public static final int MINING_MOTHERLODE_INFERNAL = 4481;
public static final int MINING_MOTHERLODE_3A = 7282;
+ public static final int MINING_MOTHERLODE_CRYSTAL = 8345;
public static final int DENSE_ESSENCE_CHIPPING = 7201;
public static final int DENSE_ESSENCE_CHISELING = 7202;
public static final int HERBLORE_POTIONMAKING = 363; //used for both herb and secondary
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 80988d8df5..6649cdc977 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
@@ -91,8 +91,8 @@ public class ChatCommandsPlugin extends Plugin
private static final Pattern RAIDS_PATTERN = Pattern.compile("Your completed (.+) count is:
(\\d+)");
private static final Pattern WINTERTODT_PATTERN = Pattern.compile("Your subdued Wintertodt count is: (\\d+)");
private static final Pattern BARROWS_PATTERN = Pattern.compile("Your Barrows chest count is: (\\d+)");
- private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?:Fight|Lap) duration: [0-9:]+. Personal best: ([0-9:]+)");
- private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?:Fight|Lap) duration: ([0-9:]+) \\(new personal best\\)");
+ private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: [0-9:]+\\. Personal best: ([0-9:]+)");
+ private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: ([0-9:]+) \\(new personal best\\)");
private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?");
private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?");
private static final String TOTAL_LEVEL_COMMAND_STRING = "!total";
@@ -113,6 +113,7 @@ public class ChatCommandsPlugin extends Plugin
private boolean logKills;
private HiscoreEndpoint hiscoreEndpoint; // hiscore endpoint for current player
private String lastBossKill;
+ private int lastPb = -1;
@Inject
private Client client;
@@ -244,7 +245,17 @@ public class ChatCommandsPlugin extends Plugin
int kc = Integer.parseInt(matcher.group(2));
setKc(boss, kc);
- lastBossKill = boss;
+ // We either already have the pb, or need to remember the boss for the upcoming pb
+ if (lastPb > -1)
+ {
+ log.debug("Got out-of-order personal best for {}: {}", boss, lastPb);
+ setPb(boss, lastPb);
+ lastPb = -1;
+ }
+ else
+ {
+ lastBossKill = boss;
+ }
return;
}
@@ -312,19 +323,16 @@ public class ChatCommandsPlugin extends Plugin
setKc("Barrows Chests", kc);
}
- if (lastBossKill != null)
+ matcher = KILL_DURATION_PATTERN.matcher(message);
+ if (matcher.find())
{
- matcher = KILL_DURATION_PATTERN.matcher(message);
- if (matcher.find())
- {
- matchPb(matcher);
- }
+ matchPb(matcher);
+ }
- matcher = NEW_PB_PATTERN.matcher(message);
- if (matcher.find())
- {
- matchPb(matcher);
- }
+ matcher = NEW_PB_PATTERN.matcher(message);
+ if (matcher.find())
+ {
+ matchPb(matcher);
}
lastBossKill = null;
@@ -337,8 +345,19 @@ public class ChatCommandsPlugin extends Plugin
if (s.length == 2)
{
int seconds = Integer.parseInt(s[0]) * 60 + Integer.parseInt(s[1]);
- log.debug("Got personal best for {}: {}", lastBossKill, seconds);
- setPb(lastBossKill, seconds);
+ if (lastBossKill != null)
+ {
+ // Most bosses sent boss kill message, and then pb message, so we
+ // use the remembered lastBossKill
+ log.debug("Got personal best for {}: {}", lastBossKill, seconds);
+ setPb(lastBossKill, seconds);
+ lastPb = -1;
+ }
+ else
+ {
+ // Some bosses send the pb message, and then the kill message!
+ lastPb = seconds;
+ }
}
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java
index ea63fe7136..7e78d776f1 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java
@@ -84,71 +84,74 @@ enum DiscordGameEventType
BOSS_SMOKE_DEVIL("Thermonuclear smoke devil", DiscordAreaType.BOSSES, 9363, 9619),
BOSS_VORKATH("Vorkath", DiscordAreaType.BOSSES, 9023),
BOSS_WINTERTODT("Wintertodt", DiscordAreaType.BOSSES, 6462),
+ BOSS_ZALCANO("Zalcano", DiscordAreaType.BOSSES, 13250),
BOSS_ZULRAH("Zulrah", DiscordAreaType.BOSSES, 9007),
// Cities
- CITY_AL_KHARID("Al Kharid", DiscordAreaType.CITIES, 13105, 13106),
- CITY_APE_ATOLL("Ape Atoll", DiscordAreaType.CITIES, 10795, 11051, 10974, 11050),
- CITY_ARCEUUS_HOUSE("Arceuus", DiscordAreaType.CITIES, 6459, 6715, 6458, 6714),
- CITY_ARDOUGNE("Ardougne", DiscordAreaType.CITIES, 10548, 10547, 10292, 10291, 10036, 10035, 9780, 9779),
- CITY_BARBARIAN_VILLAGE("Barbarian Village", DiscordAreaType.CITIES, 12341),
- CITY_BANDIT_CAMP("Bandit Camp", DiscordAreaType.CITIES, 12591),
- CITY_BEDABIN_CAMP("Bedabin Camp", DiscordAreaType.CITIES, 12590),
- CITY_BRIMHAVEN("Brimhaven", DiscordAreaType.CITIES, 11057, 11058),
- CITY_BURGH_DE_ROTT("Burgh de Rott", DiscordAreaType.CITIES, 13874, 13873, 14130, 14129),
- CITY_BURTHORPE("Burthorpe", DiscordAreaType.CITIES, 11319, 11575),
- CITY_CANIFIS("Canifis", DiscordAreaType.CITIES, 13878),
- CITY_CATHERBY("Catherby", DiscordAreaType.CITIES, 11317, 11318, 11061),
- CITY_CORSAIR_CAVE("Corsair Cove", DiscordAreaType.CITIES, 10028, 10284),
- CITY_DORGESH_KAAN("Dorgesh-Kaan", DiscordAreaType.CITIES, 10835, 10834),
- CITY_DRAYNOR("Draynor", DiscordAreaType.CITIES, 12338),
- CITY_EDGEVILLE("Edgeville", DiscordAreaType.CITIES, 12342),
- CITY_ENTRANA("Entrana", DiscordAreaType.CITIES, 11060, 11316),
- CITY_FALADOR("Falador", DiscordAreaType.CITIES, 11828, 11572, 11571, 11827, 12084),
- CITY_GOBLIN_VILLAGE("Goblin Village", DiscordAreaType.CITIES, 11830),
- CITY_GUTANOTH("Gu'Tanoth", DiscordAreaType.CITIES, 10031),
- CITY_HOSIDIUS_HOUSE("Hosidius", DiscordAreaType.CITIES, 6713, 6712, 6455, 6711, 6710, 6965, 6966, 7222, 7223, 6967),
- CITY_JATISZO("Jatizso", DiscordAreaType.CITIES, 9531),
- CITY_JIGGIG("Jiggig", DiscordAreaType.CITIES, 9775),
- CITY_KARAMJA("Karamja", DiscordAreaType.CITIES, 11569, 11568, 11567, 11566, 11313, 11312, 11311),
- CITY_KELDAGRIM("Keldagrim", DiscordAreaType.CITIES, 11423, 11422, 11679, 11678),
- CITY_LLETYA("Lletya", DiscordAreaType.CITIES, 9265),
- CITY_LOVAKENGJ_HOUSE("Lovakengj", DiscordAreaType.CITIES, 5692, 5948, 5691, 5947, 6203, 6202, 5690, 5946),
- CITY_LUMBRIDGE("Lumbridge", DiscordAreaType.CITIES, 12850),
- CITY_LUNAR_ISLE("Lunar Isle", DiscordAreaType.CITIES, 8253, 8252, 8509, 8508),
- CITY_MEIYERDITCH("Meiyerditch", DiscordAreaType.CITIES, 14132, 14388, 14387, 14386, 14385),
- CITY_MISCELLANIA("Miscellania", DiscordAreaType.CITIES, 10044, 10300),
- CITY_MOS_LE_HARMLESS("Mos Le'Harmless", DiscordAreaType.CITIES, 14638),
- CITY_MORTTON("Mort'ton", DiscordAreaType.CITIES, 13875),
- CITY_MOR_UI_REK("Mor UI Rek", DiscordAreaType.CITIES, 9808, 9807, 10064, 10063),
+ CITY_AL_KHARID("Al Kharid" , DiscordAreaType.CITIES, 13105, 13106),
+ CITY_APE_ATOLL("Ape Atoll" , DiscordAreaType.CITIES, 10795, 11051, 10974, 11050),
+ CITY_ARCEUUS_HOUSE("Arceuus" , DiscordAreaType.CITIES, 6459, 6715, 6458, 6714),
+ CITY_ARDOUGNE("Ardougne" , DiscordAreaType.CITIES, 10548, 10547, 10292, 10291, 10036, 10035, 9780, 9779),
+ CITY_BARBARIAN_VILLAGE("Barbarian Village" , DiscordAreaType.CITIES, 12341),
+ CITY_BANDIT_CAMP("Bandit Camp" , DiscordAreaType.CITIES, 12591),
+ CITY_BEDABIN_CAMP("Bedabin Camp" , DiscordAreaType.CITIES, 12590),
+ CITY_BRIMHAVEN("Brimhaven" , DiscordAreaType.CITIES, 11057, 11058),
+ CITY_BURGH_DE_ROTT("Burgh de Rott" , DiscordAreaType.CITIES, 13874, 13873, 14130, 14129),
+ CITY_BURTHORPE("Burthorpe" , DiscordAreaType.CITIES, 11319, 11575),
+ CITY_CANIFIS("Canifis" , DiscordAreaType.CITIES, 13878),
+ CITY_CATHERBY("Catherby" , DiscordAreaType.CITIES, 11317, 11318, 11061),
+ CITY_CORSAIR_CAVE("Corsair Cove" , DiscordAreaType.CITIES, 10028, 10284),
+ CITY_DORGESH_KAAN("Dorgesh-Kaan" , DiscordAreaType.CITIES, 10835, 10834),
+ CITY_DRAYNOR("Draynor" , DiscordAreaType.CITIES, 12338),
+ CITY_EDGEVILLE("Edgeville" , DiscordAreaType.CITIES, 12342),
+ CITY_ENTRANA("Entrana" , DiscordAreaType.CITIES, 11060, 11316),
+ CITY_FALADOR("Falador" , DiscordAreaType.CITIES, 11828, 11572, 11571, 11827, 12084),
+ CITY_GOBLIN_VILLAGE("Goblin Village" , DiscordAreaType.CITIES, 11830),
+ CITY_GUTANOTH("Gu'Tanoth" , DiscordAreaType.CITIES, 10031),
+ CITY_GWENITH("Gwenith", DiscordAreaType.CITIES, 8501, 8757, 9013),
+ CITY_HOSIDIUS_HOUSE("Hosidius" , DiscordAreaType.CITIES, 6713, 6712, 6455, 6711, 6710, 6965, 6966, 7222, 7223, 6967),
+ CITY_JATISZO("Jatizso" , DiscordAreaType.CITIES, 9531),
+ CITY_JIGGIG("Jiggig" , DiscordAreaType.CITIES, 9775),
+ CITY_KARAMJA("Karamja" , DiscordAreaType.CITIES, 11569, 11568, 11567, 11566, 11313, 11312, 11311),
+ CITY_KELDAGRIM("Keldagrim" , DiscordAreaType.CITIES, 11423, 11422, 11679, 11678),
+ CITY_LLETYA("Lletya" , DiscordAreaType.CITIES, 9265),
+ CITY_LOVAKENGJ_HOUSE("Lovakengj" , DiscordAreaType.CITIES, 5692, 5948, 5691, 5947, 6203, 6202, 5690, 5946),
+ CITY_LUMBRIDGE("Lumbridge" , DiscordAreaType.CITIES, 12850),
+ CITY_LUNAR_ISLE("Lunar Isle" , DiscordAreaType.CITIES, 8253, 8252, 8509, 8508),
+ CITY_MEIYERDITCH("Meiyerditch" , DiscordAreaType.CITIES, 14132, 14388, 14387, 14386, 14385),
+ CITY_MISCELLANIA("Miscellania" , DiscordAreaType.CITIES, 10044, 10300),
+ CITY_MOS_LE_HARMLESS("Mos Le'Harmless" , DiscordAreaType.CITIES, 14638),
+ CITY_MORTTON("Mort'ton" , DiscordAreaType.CITIES, 13875),
+ CITY_MOR_UI_REK("Mor UI Rek" , DiscordAreaType.CITIES, 9808, 9807, 10064, 10063),
CITY_MOUNT_KARUULM("Mount Karuulm", DiscordAreaType.CITIES, 5179, 4923, 5180),
- CITY_NARDAH("Nardah", DiscordAreaType.CITIES, 13613),
- CITY_NEITIZNOT("Neitiznot", DiscordAreaType.CITIES, 9275),
- CITY_PISCATORIS("Piscatoris", DiscordAreaType.CITIES, 9273),
- CITY_POLLNIVNEACH("Pollnivneach", DiscordAreaType.CITIES, 13358),
- CITY_PORT_KHAZARD("Port Khazard", DiscordAreaType.CITIES, 10545),
- CITY_PORT_PHASMATYS("Port Phasmatys", DiscordAreaType.CITIES, 14646),
- CITY_PORT_SARIM("Port Sarim", DiscordAreaType.CITIES, 12082),
- CITY_PISCARILIUS_HOUSE("Port Piscarilius", DiscordAreaType.CITIES, 6971, 7227, 6970, 7226),
- CITY_RELLEKKA("Rellekka", DiscordAreaType.CITIES, 10553),
- CITY_RIMMINGTON("Rimmington", DiscordAreaType.CITIES, 11826, 11570),
- CITY_SEERS_VILLAGE("Seers' Village", DiscordAreaType.CITIES, 10806),
- CITY_SHAYZIEN_HOUSE("Shayzien", DiscordAreaType.CITIES, 5944, 5943, 6200, 6199, 5688),
- CITY_SHILO_VILLAGE("Shilo Village", DiscordAreaType.CITIES, 11310),
- CITY_SOPHANEM("Sophanem", DiscordAreaType.CITIES, 13099),
- CITY_TAI_BWO_WANNAI("Tai Bwo Wannai", DiscordAreaType.CITIES, 11056, 11055),
- CITY_TAVERLEY("Taverley", DiscordAreaType.CITIES, 11574, 11573),
- CITY_TREE_GNOME_STRONGHOLD("Tree Gnome Stronghold", DiscordAreaType.CITIES, 9782, 9781),
- CITY_TREE_GNOME_VILLAGE("Tree Gnome Village", DiscordAreaType.CITIES, 10033),
- CITY_TROLL_STRONGHOLD("Troll Stronghold", DiscordAreaType.CITIES, 11321),
- CITY_TYRAS_CAMP("Tyras Camp", DiscordAreaType.CITIES, 8753, 8752),
- CITY_UZER("Uzer", DiscordAreaType.CITIES, 13872),
- CITY_VARROCK("Varrock", DiscordAreaType.CITIES, 12596, 12597, 12598, 12852, 12853, 12854, 13108, 13109, 13110),
- CITY_WITCHHAVEN("Witchaven", DiscordAreaType.CITIES, 10803),
+ CITY_NARDAH("Nardah" , DiscordAreaType.CITIES, 13613),
+ CITY_NEITIZNOT("Neitiznot" , DiscordAreaType.CITIES, 9275),
+ CITY_PISCATORIS("Piscatoris" , DiscordAreaType.CITIES, 9273),
+ CITY_POLLNIVNEACH("Pollnivneach" , DiscordAreaType.CITIES, 13358),
+ CITY_PORT_KHAZARD("Port Khazard" , DiscordAreaType.CITIES, 10545),
+ CITY_PORT_PHASMATYS("Port Phasmatys" , DiscordAreaType.CITIES, 14646),
+ CITY_PORT_SARIM("Port Sarim" , DiscordAreaType.CITIES, 12082),
+ CITY_PISCARILIUS_HOUSE("Port Piscarilius" , DiscordAreaType.CITIES, 6971, 7227, 6970, 7226),
+ CITY_PRIFDDINAS("Prifddinas", DiscordAreaType.CITIES, 12894, 12895, 13150, 13151),
+ CITY_RELLEKKA("Rellekka" , DiscordAreaType.CITIES, 10553),
+ CITY_RIMMINGTON("Rimmington" , DiscordAreaType.CITIES, 11826, 11570),
+ CITY_SEERS_VILLAGE("Seers' Village" , DiscordAreaType.CITIES, 10806),
+ CITY_SHAYZIEN_HOUSE("Shayzien" , DiscordAreaType.CITIES, 5944, 5943, 6200, 6199, 5688),
+ CITY_SHILO_VILLAGE("Shilo Village" , DiscordAreaType.CITIES, 11310),
+ CITY_SOPHANEM("Sophanem" , DiscordAreaType.CITIES, 13099),
+ CITY_TAI_BWO_WANNAI("Tai Bwo Wannai" , DiscordAreaType.CITIES, 11056, 11055),
+ CITY_TAVERLEY("Taverley" , DiscordAreaType.CITIES, 11574, 11573),
+ CITY_TREE_GNOME_STRONGHOLD("Tree Gnome Stronghold" , DiscordAreaType.CITIES, 9782, 9781),
+ CITY_TREE_GNOME_VILLAGE("Tree Gnome Village" , DiscordAreaType.CITIES, 10033),
+ CITY_TROLL_STRONGHOLD("Troll Stronghold" , DiscordAreaType.CITIES, 11321),
+ CITY_TYRAS_CAMP("Tyras Camp" , DiscordAreaType.CITIES, 8753, 8752),
+ CITY_UZER("Uzer" , DiscordAreaType.CITIES, 13872),
+ CITY_VARROCK("Varrock" , DiscordAreaType.CITIES, 12596, 12597, 12598, 12852, 12853, 12854, 13108, 13109, 13110),
+ CITY_WITCHHAVEN("Witchaven" , DiscordAreaType.CITIES, 10803),
CITY_WOODCUTTING_GUILD("Woodcutting Guild", DiscordAreaType.CITIES, 6454, 6198, 6298),
- CITY_YANILLE("Yanille", DiscordAreaType.CITIES, 10288, 10032),
- CITY_ZANARIS("Zanaris", DiscordAreaType.CITIES, 9285, 9541, 9540, 9797),
- CITY_ZULANDRA("Zul-Andra", DiscordAreaType.CITIES, 8751),
+ CITY_YANILLE("Yanille" , DiscordAreaType.CITIES, 10288, 10032),
+ CITY_ZANARIS("Zanaris" , DiscordAreaType.CITIES, 9285, 9541, 9540, 9797),
+ CITY_ZULANDRA("Zul-Andra" , DiscordAreaType.CITIES, 8751),
// Dungeons
DUNGEON_ABANDONED_MINE("Abandoned Mine", DiscordAreaType.DUNGEONS, 13718, 11079, 11078, 11077, 10823, 10822, 10821),
@@ -180,6 +183,7 @@ enum DiscordGameEventType
DUNGEON_GOBLIN_CAVE("Goblin Cave", DiscordAreaType.DUNGEONS, 10393),
DUNGEON_GRAND_TREE_TUNNELS("Grand Tree Tunnels", DiscordAreaType.DUNGEONS, 9882),
DUNGEON_HAM("H.A.M Dungeon", DiscordAreaType.DUNGEONS, 12694, 10321),
+ DUNGEON_IORWERTH("Iorwerth Dungeon", DiscordAreaType.DUNGEONS, 12738, 12993, 12994),
DUNGEON_JATIZSO_MINES("Jatizo Mines", DiscordAreaType.DUNGEONS, 9631),
DUNGEON_JIGGIG_BURIAL_TOMB("Jiggig Burial Tomb", DiscordAreaType.DUNGEONS, 9875, 9874),
DUNGEON_JOGRE("Jogre Dungeon", DiscordAreaType.DUNGEONS, 11412),
@@ -211,6 +215,7 @@ enum DiscordGameEventType
DUNGEON_THE_WARRENS("The Warrens", DiscordAreaType.DUNGEONS, 7070, 7326),
DUNGEON_TOLNA("Dungeon of Tolna", DiscordAreaType.DUNGEONS, 13209),
DUNGEON_TOWER_OF_LIFE("Tower of Life Basement", DiscordAreaType.DUNGEONS, 12100),
+ DUNGEON_TRAHAEARN_MINE("Trahaearn Mine", DiscordAreaType.DUNGEONS, 13249),
DUNGEON_TUNNEL_OF_CHAOS("Tunnel of Chaos", DiscordAreaType.DUNGEONS, 12625),
DUNGEON_UNDERGROUND_PASS("Underground Pass", DiscordAreaType.DUNGEONS, 9369, 9370),
DUNGEON_VARROCKSEWERS("Varrock Sewers", DiscordAreaType.DUNGEONS, 12954, 13210),
@@ -232,6 +237,7 @@ enum DiscordGameEventType
MG_CLAN_WARS("Clan Wars", DiscordAreaType.MINIGAMES, 13135, 13134, 13133, 13131, 13130, 13387, 13386),
MG_DUEL_ARENA("Duel Arena", DiscordAreaType.MINIGAMES, 13362),
MG_FISHING_TRAWLER("Fishing Trawler", DiscordAreaType.MINIGAMES, 7499),
+ MG_GAUNTLET("Gauntlet", DiscordAreaType.MINIGAMES, 12995),
MG_INFERNO("The Inferno", DiscordAreaType.MINIGAMES, 9043),
MG_LAST_MAN_STANDING("Last Man Standing", DiscordAreaType.MINIGAMES, 13660, 13659, 13658, 13916, 13915, 13914),
MG_MAGE_TRAINING_ARENA("Mage Training Arena", DiscordAreaType.MINIGAMES, 13462, 13463),
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/fps/FpsConfig.java
index 539c810de2..16922d9874 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java
@@ -68,15 +68,4 @@ 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/fps/FpsOverlay.java
index 17afae61b6..0103337792 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java
@@ -26,14 +26,14 @@ package net.runelite.client.plugins.fps;
import java.awt.Color;
import java.awt.Dimension;
-import java.awt.FontMetrics;
import java.awt.Graphics2D;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client;
import net.runelite.api.Point;
-import net.runelite.api.Varbits;
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.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
@@ -51,6 +51,10 @@ import net.runelite.client.ui.overlay.OverlayUtil;
@Singleton
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
private final Client client;
private final FpsPlugin plugin;
@@ -84,62 +88,30 @@ 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 (!plugin.isDrawFps() && !plugin.isDrawPing())
+ if (!plugin.isDrawFps())
{
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 FontMetrics fontMetrics = graphics.getFontMetrics();
-
- 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()));
- }
+ final Point point = new Point(width - textWidth - xOffset, textHeight + Y_OFFSET);
+ OverlayUtil.renderTextLocation(graphics, point, text, getFpsValueColor());
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/fps/FpsPlugin.java
index b33699436a..4af5c588a8 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java
@@ -27,27 +27,19 @@ package net.runelite.client.plugins.fps;
import com.google.inject.Inject;
import com.google.inject.Provides;
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.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.api.events.GameStateChanged;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus;
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;
/**
- * 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.
*
* 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.
@@ -55,15 +47,11 @@ import net.runelite.client.util.ping.Ping;
*
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 = "Performance",
- description = "Show current Ping and FPS or set an FPS limit",
- tags = {"frames", "framerate", "limit", "overlay", "ping"},
+ description = "Show current FPS or set an FPS limit",
+ tags = {"frames", "framerate", "limit", "overlay"},
enabledByDefault = false
)
@Singleton
@@ -71,9 +59,6 @@ public class FpsPlugin extends Plugin
{
static final String CONFIG_GROUP_KEY = "fpscontrol";
- @Getter
- private int ping;
-
@Inject
private OverlayManager overlayManager;
@@ -86,30 +71,18 @@ public class FpsPlugin extends Plugin
@Inject
private DrawManager drawManager;
- @Inject
- private Client client;
-
@Inject
private FpsConfig fpsConfig;
@Inject
private EventBus eventBus;
- private final ScheduledExecutorService pingExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor());
-
- private boolean loaded = false;
-
- private boolean shutdown;
-
@Getter(AccessLevel.PACKAGE)
private FpsLimitMode limitMode;
@Getter(AccessLevel.PACKAGE)
private boolean drawFps;
- @Getter(AccessLevel.PACKAGE)
- private boolean drawPing;
-
@Provides
FpsConfig provideConfig(ConfigManager configManager)
{
@@ -124,7 +97,6 @@ public class FpsPlugin extends Plugin
limitMode = fpsConfig.limitMode();
drawFps = fpsConfig.drawFps();
- drawPing = fpsConfig.drawPing();
}
}
@@ -134,11 +106,6 @@ public class FpsPlugin extends Plugin
overlay.onFocusChanged(event);
}
- private void onGameStateChanged(GameStateChanged event)
- {
- shutdown = event.getGameState() != GameState.LOGGED_IN;
- }
-
@Override
protected void startUp() throws Exception
{
@@ -146,17 +113,9 @@ public class FpsPlugin extends Plugin
limitMode = fpsConfig.limitMode();
drawFps = fpsConfig.drawFps();
- drawPing = fpsConfig.drawPing();
overlayManager.add(overlay);
drawManager.registerEveryFrameListener(drawListener);
drawListener.reloadConfig();
- shutdown = client.getGameState() != GameState.LOGGED_IN;
-
- if (!loaded)
- {
- pingExecutorService.scheduleAtFixedRate(this::getPingToCurrentWorld, 5, 5, TimeUnit.SECONDS);
- loaded = true;
- }
}
@Override
@@ -166,25 +125,11 @@ public class FpsPlugin extends Plugin
overlayManager.remove(overlay);
drawManager.unregisterEveryFrameListener(drawListener);
- shutdown = true;
}
private void addSubscriptions()
{
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
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;
- }
}
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
index 09bc5ab850..5ce500c999 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
@@ -195,11 +195,12 @@ public class IdleNotifierPlugin extends Plugin
case WOODCUTTING_DRAGON:
case WOODCUTTING_INFERNAL:
case WOODCUTTING_3A_AXE:
- /* Cooking(Fire, Range) */
+ case WOODCUTTING_CRYSTAL:
+ /* Cooking(Fire, Range) */
case COOKING_FIRE:
case COOKING_RANGE:
case COOKING_WINE:
- /* Crafting(Gem Cutting, Glassblowing, Spinning, Battlestaves, Pottery) */
+ /* Crafting(Gem Cutting, Glassblowing, Spinning, Battlestaves, Pottery) */
case GEM_CUTTING_OPAL:
case GEM_CUTTING_JADE:
case GEM_CUTTING_REDTOPAZ:
@@ -214,7 +215,7 @@ public class IdleNotifierPlugin extends Plugin
case CRAFTING_LEATHER:
case CRAFTING_POTTERS_WHEEL:
case CRAFTING_POTTERY_OVEN:
- /* Fletching(Cutting, Stringing) */
+ /* Fletching(Cutting, Stringing) */
case FLETCHING_BOW_CUTTING:
case FLETCHING_STRING_NORMAL_SHORTBOW:
case FLETCHING_STRING_OAK_SHORTBOW:
@@ -228,11 +229,11 @@ public class IdleNotifierPlugin extends Plugin
case FLETCHING_STRING_MAPLE_LONGBOW:
case FLETCHING_STRING_YEW_LONGBOW:
case FLETCHING_STRING_MAGIC_LONGBOW:
- /* Smithing(Anvil, Furnace, Cannonballs */
+ /* Smithing(Anvil, Furnace, Cannonballs */
case SMITHING_ANVIL:
case SMITHING_SMELTING:
case SMITHING_CANNONBALL:
- /* Fishing */
+ /* Fishing */
case FISHING_CRUSHING_INFERNAL_EELS:
case FISHING_CUTTING_SACRED_EELS:
case FISHING_BIG_NET:
@@ -246,7 +247,7 @@ public class IdleNotifierPlugin extends Plugin
case FISHING_OILY_ROD:
case FISHING_KARAMBWAN:
case FISHING_BAREHAND:
- /* Mining(Normal) */
+ /* Mining(Normal) */
case MINING_BRONZE_PICKAXE:
case MINING_IRON_PICKAXE:
case MINING_STEEL_PICKAXE:
@@ -255,16 +256,32 @@ public class IdleNotifierPlugin extends Plugin
case MINING_ADAMANT_PICKAXE:
case MINING_RUNE_PICKAXE:
case MINING_DRAGON_PICKAXE:
- case MINING_DRAGON_PICKAXE_ORN:
+ case MINING_DRAGON_PICKAXE_UPGRADED:
+ case MINING_DRAGON_PICKAXE_OR:
case MINING_INFERNAL_PICKAXE:
case MINING_3A_PICKAXE:
+ case MINING_CRYSTAL_PICKAXE:
case DENSE_ESSENCE_CHIPPING:
case DENSE_ESSENCE_CHISELING:
- /* Herblore */
+ /* Mining(Motherlode) */
+ case MINING_MOTHERLODE_BRONZE:
+ case MINING_MOTHERLODE_IRON:
+ case MINING_MOTHERLODE_STEEL:
+ case MINING_MOTHERLODE_BLACK:
+ case MINING_MOTHERLODE_MITHRIL:
+ case MINING_MOTHERLODE_ADAMANT:
+ case MINING_MOTHERLODE_RUNE:
+ case MINING_MOTHERLODE_DRAGON:
+ case MINING_MOTHERLODE_DRAGON_UPGRADED:
+ case MINING_MOTHERLODE_DRAGON_OR:
+ case MINING_MOTHERLODE_INFERNAL:
+ case MINING_MOTHERLODE_3A:
+ case MINING_MOTHERLODE_CRYSTAL:
+ /* Herblore */
case HERBLORE_PESTLE_AND_MORTAR:
case HERBLORE_POTIONMAKING:
case HERBLORE_MAKE_TAR:
- /* Magic */
+ /* Magic */
case MAGIC_CHARGING_ORBS:
case MAGIC_LUNAR_PLANK_MAKE:
case MAGIC_LUNAR_STRING_JEWELRY:
@@ -273,16 +290,16 @@ public class IdleNotifierPlugin extends Plugin
case MAGIC_ENCHANTING_AMULET_1:
case MAGIC_ENCHANTING_AMULET_2:
case MAGIC_ENCHANTING_AMULET_3:
- /* Prayer */
+ /* Prayer */
case USING_GILDED_ALTAR:
- /* Farming */
+ /* Farming */
case FARMING_MIX_ULTRACOMPOST:
case FARMING_HARVEST_BUSH:
case FARMING_HARVEST_HERB:
case FARMING_HARVEST_FRUIT_TREE:
case FARMING_HARVEST_FLOWER:
case FARMING_HARVEST_ALLOTMENT:
- /* Misc */
+ /* Misc */
case PISCARILIUS_CRANE_REPAIR:
case HOME_MAKE_TABLET:
case SAND_COLLECTION:
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java
index d71bcc0074..8d411a4aaa 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java
@@ -72,6 +72,7 @@ enum ItemIdentification
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),
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),
BANANA_SAPLING(Type.SAPLING, "Banana", "BAN", ItemID.BANANA_SAPLING, ItemID.BANANA_SEEDLING, ItemID.BANANA_SEEDLING_W),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
index 880a74c8fe..c38ed61de1 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
@@ -43,18 +43,7 @@ import javax.inject.Singleton;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.AnimationID;
-import static net.runelite.api.AnimationID.IDLE;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_3A;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_ADAMANT;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BLACK;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BRONZE;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON_ORN;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_INFERNAL;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_IRON;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_MITHRIL;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_RUNE;
-import static net.runelite.api.AnimationID.MINING_MOTHERLODE_STEEL;
+import static net.runelite.api.AnimationID.*;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
@@ -451,7 +440,9 @@ public class MotherlodePlugin extends Plugin
case MINING_MOTHERLODE_ADAMANT:
case MINING_MOTHERLODE_RUNE:
case MINING_MOTHERLODE_DRAGON:
- case MINING_MOTHERLODE_DRAGON_ORN:
+ case MINING_MOTHERLODE_DRAGON_UPGRADED:
+ case MINING_MOTHERLODE_DRAGON_OR:
+ case MINING_MOTHERLODE_CRYSTAL:
case MINING_MOTHERLODE_INFERNAL:
case MINING_MOTHERLODE_3A:
lastAnimation = animation;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java
index 247b2f97ab..c13389485d 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java
@@ -102,14 +102,19 @@ class NightmareZoneOverlay extends Overlay
renderAbsorptionCounter();
+ final int currentPoints = client.getVar(Varbits.NMZ_POINTS);
+ final int totalPoints = currentPoints + client.getVar(VarPlayer.NMZ_REWARD_POINTS);
+
panelComponent.getChildren().clear();
+
TableComponent tableComponent = new TableComponent();
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())
{
- 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);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java
index 9c32dabc51..7993ae37ca 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java
@@ -25,11 +25,14 @@
package net.runelite.client.plugins.nightmarezone;
import com.google.inject.Provides;
+
import java.awt.Color;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AccessLevel;
+import java.time.Duration;
+import java.time.Instant;
import lombok.Getter;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
@@ -56,6 +59,7 @@ import net.runelite.client.util.Text;
public class NightmareZonePlugin extends Plugin
{
private static final int[] NMZ_MAP_REGION = {9033};
+ private static final Duration HOUR = Duration.ofHours(1);
@Inject
private Notifier notifier;
@@ -75,6 +79,11 @@ public class NightmareZonePlugin extends Plugin
@Inject
private EventBus eventBus;
+ @Getter
+ private int pointsPerHour;
+
+ private Instant nmzSessionStartTime;
+
// This starts as true since you need to get
// above the threshold before sending notifications
private boolean absorptionNotificationSend = true;
@@ -120,6 +129,8 @@ public class NightmareZonePlugin extends Plugin
{
nmzWidget.setHidden(false);
}
+
+ resetPointsPerHour();
}
private void addSubscriptions()
@@ -155,6 +166,11 @@ public class NightmareZonePlugin extends Plugin
absorptionNotificationSend = true;
}
+ if (nmzSessionStartTime != null)
+ {
+ resetPointsPerHour();
+ }
+
return;
}
@@ -162,6 +178,11 @@ public class NightmareZonePlugin extends Plugin
{
checkAbsorption();
}
+
+ if (config.moveOverlay())
+ {
+ pointsPerHour = calculatePointsPerHour();
+ }
}
private void onChatMessage(ChatMessage event)
@@ -239,6 +260,32 @@ public class NightmareZonePlugin extends Plugin
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()
{
this.moveOverlay = config.moveOverlay();
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java
index b98fe9fdc6..6e0a086f05 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java
@@ -453,6 +453,7 @@ public class WintertodtPlugin extends Plugin
case WOODCUTTING_DRAGON:
case WOODCUTTING_INFERNAL:
case WOODCUTTING_3A_AXE:
+ case WOODCUTTING_CRYSTAL:
setActivity(WintertodtActivity.WOODCUTTING);
break;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java
index 709ea85378..dfdf86f6f4 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java
@@ -33,6 +33,7 @@ import static net.runelite.api.AnimationID.WOODCUTTING_3A_AXE;
import static net.runelite.api.AnimationID.WOODCUTTING_ADAMANT;
import static net.runelite.api.AnimationID.WOODCUTTING_BLACK;
import static net.runelite.api.AnimationID.WOODCUTTING_BRONZE;
+import static net.runelite.api.AnimationID.WOODCUTTING_CRYSTAL;
import static net.runelite.api.AnimationID.WOODCUTTING_DRAGON;
import static net.runelite.api.AnimationID.WOODCUTTING_INFERNAL;
import static net.runelite.api.AnimationID.WOODCUTTING_IRON;
@@ -42,6 +43,7 @@ import static net.runelite.api.AnimationID.WOODCUTTING_STEEL;
import static net.runelite.api.ItemID.ADAMANT_AXE;
import static net.runelite.api.ItemID.BLACK_AXE;
import static net.runelite.api.ItemID.BRONZE_AXE;
+import static net.runelite.api.ItemID.CRYSTAL_AXE;
import static net.runelite.api.ItemID.DRAGON_AXE;
import static net.runelite.api.ItemID.INFERNAL_AXE;
import static net.runelite.api.ItemID.IRON_AXE;
@@ -63,7 +65,8 @@ enum Axe
RUNE(WOODCUTTING_RUNE, RUNE_AXE),
DRAGON(WOODCUTTING_DRAGON, DRAGON_AXE),
INFERNAL(WOODCUTTING_INFERNAL, INFERNAL_AXE),
- THIRDAGE(WOODCUTTING_3A_AXE, _3RD_AGE_AXE);
+ THIRDAGE(WOODCUTTING_3A_AXE, _3RD_AGE_AXE),
+ CRYSTAL(WOODCUTTING_CRYSTAL, CRYSTAL_AXE);
private final Integer animId;
private final Integer itemId;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java
index 8035af73fb..d21ed61e80 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, Lotto
+ * Copyright (c) 2019, gregg1494
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -123,4 +124,15 @@ public interface WorldHopperConfig extends Config
{
return SubscriptionFilterMode.BOTH;
}
+
+ @ConfigItem(
+ keyName = "displayPing",
+ name = "Display current ping",
+ description = "Displays ping to current game world",
+ position = 7
+ )
+ default boolean displayPing()
+ {
+ return false;
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java
new file mode 100644
index 0000000000..1839b14ddd
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019, 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;
+ }
+}
\ No newline at end of file
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 8513a87814..1b232678b3 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
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2017, Adam
* Copyright (c) 2018, Lotto
+ * Copyright (c) 2019, gregg1494
* All rights reserved.
*
* 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.Singleton;
import javax.swing.SwingUtilities;
+import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
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.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton;
+import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ExecutorServiceExceptionLogger;
import net.runelite.client.util.HotkeyListener;
import net.runelite.client.util.Text;
@@ -98,8 +101,7 @@ import org.apache.commons.lang3.ArrayUtils;
public class WorldHopperPlugin extends Plugin
{
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 DISPLAY_SWITCHER_MAX_ATTEMPTS = 3;
@@ -133,6 +135,12 @@ public class WorldHopperPlugin extends Plugin
@Inject
private EventBus eventBus;
+ @Inject
+ private OverlayManager overlayManager;
+
+ @Inject
+ private WorldHopperPingOverlay worldHopperOverlay;
+
private ScheduledExecutorService hopperExecutorService;
private NavigationButton navButton;
@@ -146,8 +154,9 @@ public class WorldHopperPlugin extends Plugin
private int favoriteWorld1, favoriteWorld2;
- private ScheduledFuture> worldResultFuture, pingFuture;
+ private ScheduledFuture> worldResultFuture, pingFuture, currPingFuture;
private WorldResult worldResult;
+ private int currentWorld;
private Instant lastFetch;
private boolean firstRun;
@@ -158,6 +167,11 @@ public class WorldHopperPlugin extends Plugin
private boolean ping;
private boolean showWorldHopMessage;
private SubscriptionFilterMode subscriptionFilter;
+ @Getter(AccessLevel.PACKAGE)
+ private boolean displayPing;
+
+ @Getter(AccessLevel.PACKAGE)
+ private int currentPing;
private final HotkeyListener previousKeyListener = new HotkeyListener(() -> this.previousKey)
{
@@ -189,6 +203,7 @@ public class WorldHopperPlugin extends Plugin
addSubscriptions();
firstRun = true;
+ currentPing = -1;
keyManager.registerKeyListener(previousKeyListener);
keyManager.registerKeyListener(nextKeyListener);
@@ -213,11 +228,18 @@ public class WorldHopperPlugin extends Plugin
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);
- hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor());
- pingFuture = hopperExecutorService.scheduleAtFixedRate(this::pingWorlds, WORLD_PING_TIMER, WORLD_PING_TIMER, TimeUnit.MINUTES);
+ // Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway
+ pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS);
+ currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS);
}
@Override
@@ -228,6 +250,11 @@ public class WorldHopperPlugin extends Plugin
pingFuture.cancel(true);
pingFuture = null;
+ currPingFuture.cancel(true);
+ currPingFuture = null;
+
+ overlayManager.remove(worldHopperOverlay);
+
keyManager.unregisterKeyListener(previousKeyListener);
keyManager.unregisterKeyListener(nextKeyListener);
@@ -482,7 +509,8 @@ public class WorldHopperPlugin extends Plugin
if (firstRun)
{
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()
.subscribeOn(Schedulers.io())
+ .take(1)
.subscribe(
(worldResult) ->
{
@@ -775,7 +804,10 @@ public class WorldHopperPlugin extends Plugin
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)
{
@@ -804,5 +836,66 @@ public class WorldHopperPlugin extends Plugin
this.ping = config.ping();
this.showWorldHopMessage = config.showWorldHopMessage();
this.subscriptionFilter = config.subscriptionFilter();
+ this.displayPing = config.displayPing();
+ }
+
+ /**
+ * Ping the next world
+ */
+ private void pingNextWorld()
+ {
+ if (worldResult == null || !config.showSidebar() || !config.ping())
+ {
+ return;
+ }
+
+ List 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));
}
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java
index d15ddf86b1..1f47124afa 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java
@@ -72,7 +72,7 @@ enum QuestStartLocation
DARKNESS_OF_HALLOWVALE(Quest.DARKNESS_OF_HALLOWVALE, new WorldPoint(3494, 9628, 0)),
DEATH_PLATEAU_TROLL_STRONGHOLD(new Quest[]{Quest.DEATH_PLATEAU, Quest.TROLL_STRONGHOLD}, new WorldPoint(2895, 3528, 0)),
DEATH_TO_THE_DORGESHUUN(Quest.DEATH_TO_THE_DORGESHUUN, new WorldPoint(3316, 9613, 0)),
- THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1846, 3556, 0)),
+ THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1780, 3569, 0)),
DESERT_TREASURE(Quest.DESERT_TREASURE, new WorldPoint(3177, 3043, 0)),
DEVIOUS_MINDS(Quest.DEVIOUS_MINDS, new WorldPoint(3405, 3492, 0)),
THE_DIG_SITE(Quest.THE_DIG_SITE, new WorldPoint(3363, 3337, 0)),
diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json
index 19fca53730..b72b8d59e9 100644
--- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json
+++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json
@@ -78,6 +78,12 @@
"name": "Pollnivneach Rooftop",
"xp": 890
},
+ {
+ "level": 75,
+ "icon": 23962,
+ "name": "Prifddinas Agility Course",
+ "xp": 1220
+ },
{
"level": 80,
"icon": 11849,
diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json
index bc5cde0ef6..5953579264 100644
--- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json
+++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json
@@ -240,6 +240,12 @@
"name": "Lantadyme",
"xp": 134.5
},
+ {
+ "level": 74,
+ "icon": 23962,
+ "name": "Crystal Tree",
+ "xp": 13366
+ },
{
"level": 75,
"icon": 1513,
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java
index 9d2ffa67e7..31c9bfd205 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java
@@ -266,4 +266,94 @@ public class ChatCommandsPluginTest
verify(configManager).setConfiguration(eq("personalbest.adam"), eq("prifddinas agility course"), eq(61));
verify(configManager).setConfiguration(eq("killcount.adam"), eq("prifddinas agility course"), eq(2));
}
-}
\ No newline at end of file
+
+ @Test
+ public void testZukNewPb()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: 2.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: 104:31 (new personal best)", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("personalbest.adam"), eq("tzkal-zuk"), eq(104 * 60 + 31));
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("tzkal-zuk"), eq(2));
+ }
+
+ @Test
+ public void testZukKill()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: 3.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: 172:18. Personal best: 134:52", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("personalbest.adam"), eq("tzkal-zuk"), eq(134 * 60 + 52));
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("tzkal-zuk"), eq(3));
+ }
+
+ @Test
+ public void testGgNewPb()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: 1:36 (new personal best)", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: 179.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("personalbest.adam"), eq("grotesque guardians"), eq(96));
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("grotesque guardians"), eq(179));
+ }
+
+ @Test
+ public void testGgKill()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: 2:41. Personal best: 2:14", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: 32.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("personalbest.adam"), eq("grotesque guardians"), eq(2 * 60 + 14));
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("grotesque guardians"), eq(32));
+ }
+
+ @Test
+ public void testGuantletPersonalBest()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: 10:24. Personal best: 7:59.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: 124.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("gauntlet"), eq(124));
+ verify(configManager).setConfiguration(eq("personalbest.adam"), eq("gauntlet"), eq(7 * 60 + 59));
+ }
+
+ @Test
+ public void testGuantletNewPersonalBest()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: 10:24 (new personal best).", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: 124.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("personalbest.adam"), eq("gauntlet"), eq(10 * 60 + 24));
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("gauntlet"), eq(124));
+ }
+}