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 e771a649a8..669d7c775f 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
@@ -88,6 +88,7 @@ public class ChatCommandsPlugin extends Plugin
{
private static final Pattern KILLCOUNT_PATTERN = Pattern.compile("Your (.+) (?:kill|harvest|lap|completion) count is:
(\\d+)");
private static final Pattern RAIDS_PATTERN = Pattern.compile("Your completed (.+) count is: (\\d+)");
+ private static final Pattern RAIDS_DURATION_PATTERN = Pattern.compile("Congratulations - your raid is complete! Duration ([0-9:]+)");
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("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: [0-9:]+\\. Personal best: ([0-9:]+)");
@@ -256,6 +257,17 @@ public class ChatCommandsPlugin extends Plugin
int kc = Integer.parseInt(matcher.group(2));
setKc(boss, kc);
+ if (lastPb > -1)
+ {
+ // lastPb contains the last raid duration and not the personal best, because the raid
+ // complete message does not include the pb. We have to check if it is a new pb:
+ int currentPb = getPb(boss);
+ if (currentPb <= 0 || lastPb < currentPb)
+ {
+ setPb(boss, lastPb);
+ }
+ lastPb = -1;
+ }
lastBossKill = boss;
return;
}
@@ -317,29 +329,44 @@ public class ChatCommandsPlugin extends Plugin
matchPb(matcher);
}
+ matcher = RAIDS_DURATION_PATTERN.matcher(message);
+ if (matcher.find())
+ {
+ matchPb(matcher);
+ }
+
lastBossKill = null;
}
+ private static int timeStringToSeconds(String timeString)
+ {
+ String[] s = timeString.split(":");
+ if (s.length == 2) // mm:ss
+ {
+ return Integer.parseInt(s[0]) * 60 + Integer.parseInt(s[1]);
+ }
+ else if (s.length == 3) // h:mm:ss
+ {
+ return Integer.parseInt(s[0]) * 60 * 60 + Integer.parseInt(s[1]) * 60 + Integer.parseInt(s[2]);
+ }
+ return Integer.parseInt(timeString);
+ }
+
private void matchPb(Matcher matcher)
{
- String personalBest = matcher.group(1);
- String[] s = personalBest.split(":");
- if (s.length == 2)
+ int seconds = timeStringToSeconds(matcher.group(1));
+ if (lastBossKill != null)
{
- int seconds = Integer.parseInt(s[0]) * 60 + Integer.parseInt(s[1]);
- 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;
- }
+ // 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/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java
index 175fd22a41..69e3b01397 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
@@ -40,6 +40,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.ArgumentMatchers.eq;
import org.mockito.Mock;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@@ -356,4 +360,35 @@ public class ChatCommandsPluginTest
verify(configManager).setConfiguration(eq("personalbest.adam"), eq("gauntlet"), eq(10 * 60 + 24));
verify(configManager).setConfiguration(eq("killcount.adam"), eq("gauntlet"), eq(124));
}
+
+ @Test
+ public void testCoXKill()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Congratulations - your raid is complete! Duration 37:04", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Chambers of Xeric count is: 51.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("chambers of xeric"), eq(51));
+ verify(configManager).setConfiguration(eq("personalbest.adam"), eq("chambers of xeric"), eq(37 * 60 + 4));
+ }
+
+ @Test
+ public void testCoXKillNoPb()
+ {
+ when(client.getUsername()).thenReturn("Adam");
+ when(configManager.getConfiguration(anyString(), anyString(), any())).thenReturn(2224);
+
+ ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Congratulations - your raid is complete! Duration 1:45:04", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Chambers of Xeric count is: 52.", null, 0);
+ chatCommandsPlugin.onChatMessage(chatMessage);
+
+ verify(configManager).setConfiguration(eq("killcount.adam"), eq("chambers of xeric"), eq(52));
+ verify(configManager, never()).setConfiguration(eq("personalbest.adam"), eq("chambers of xeric"), anyInt());
+ }
}