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()); + } }