From d06ffed7b2055e6ce6b28090c1c128d9424be5e5 Mon Sep 17 00:00:00 2001 From: iProdigy Date: Mon, 11 Nov 2024 12:05:16 -0800 Subject: [PATCH 1/3] feat(kc): use challenge time for tob notifications --- .../notifiers/KillCountNotifier.java | 31 ++++++++++++------- .../dinkplugin/util/KillCountService.java | 6 ++-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/main/java/dinkplugin/notifiers/KillCountNotifier.java b/src/main/java/dinkplugin/notifiers/KillCountNotifier.java index 0961b8f2..6c63acfd 100644 --- a/src/main/java/dinkplugin/notifiers/KillCountNotifier.java +++ b/src/main/java/dinkplugin/notifiers/KillCountNotifier.java @@ -1,13 +1,13 @@ package dinkplugin.notifiers; +import dinkplugin.message.NotificationBody; +import dinkplugin.message.NotificationType; import dinkplugin.message.templating.Replacements; import dinkplugin.message.templating.Template; +import dinkplugin.notifiers.data.BossNotificationData; import dinkplugin.util.KillCountService; import dinkplugin.util.TimeUtils; import dinkplugin.util.Utils; -import dinkplugin.message.NotificationBody; -import dinkplugin.message.NotificationType; -import dinkplugin.notifiers.data.BossNotificationData; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.Varbits; @@ -100,7 +100,7 @@ public void onWidget(WidgetLoaded event) { public void onTick() { BossNotificationData data = this.data.get(); if (data != null) { - if (data.getBoss() != null) { + if (data.getBoss() != null && data.getCount() != null) { // ensure notifier was not disabled during bad ticks wait period if (isEnabled()) { // once boss name has arrived, we notify at tick end (even if duration hasn't arrived) @@ -166,12 +166,14 @@ private void updateData(BossNotificationData updated) { // Boss data and timing are sent in separate messages // where the order of the messages differs depending on the boss. // Here, we update data without setting any not-null values back to null. + String boss = defaultIfNull(updated.getBoss(), old.getBoss()); + boolean tob = boss.startsWith("Theatre of Blood"); // prefer challenge time message that comes first: https://github.com/pajlads/DinkPlugin/issues/585 return new BossNotificationData( - defaultIfNull(updated.getBoss(), old.getBoss()), + boss, defaultIfNull(updated.getCount(), old.getCount()), defaultIfNull(updated.getGameMessage(), old.getGameMessage()), - defaultIfNull(updated.getTime(), old.getTime()), - defaultIfNull(updated.isPersonalBest(), old.isPersonalBest()), + updated.getTime() == null || (tob && old.getTime() != null) ? old.getTime() : updated.getTime(), + updated.isPersonalBest() == null || (tob && old.isPersonalBest() != null) ? old.isPersonalBest() : updated.isPersonalBest(), defaultIfNull(updated.getParty(), old.getParty()) ); } @@ -183,7 +185,12 @@ private static Optional parse(Client client, String messag Optional> boss = parseBoss(message); if (boss.isPresent()) return boss.map(pair -> new BossNotificationData(pair.getLeft(), pair.getRight(), message, null, null, Utils.getBossParty(client, pair.getLeft()))); - return parseTime(message).map(t -> new BossNotificationData(null, null, null, t.getLeft(), t.getRight(), null)); + + // TOB reports final wave duration before challenge time in the same message; skip to the part we care about + int tobIndex = message.startsWith("Wave") ? message.indexOf(KillCountService.TOB) : -1; + String msg = tobIndex < 0 ? message : message.substring(tobIndex); + + return parseTime(msg).map(t -> new BossNotificationData(tobIndex < 0 ? null : KillCountService.TOB, null, null, t.getLeft(), t.getRight(), null)); } private static Optional> parseTime(String message) { @@ -252,10 +259,10 @@ private static String parseSecondary(String boss) { int modeSeparator = boss.lastIndexOf(':'); String raid = modeSeparator > 0 ? boss.substring(0, modeSeparator) : boss; - if (raid.equalsIgnoreCase("Theatre of Blood") - || raid.equalsIgnoreCase("Tombs of Amascut") - || raid.equalsIgnoreCase("Chambers of Xeric") - || raid.equalsIgnoreCase("Chambers of Xeric Challenge Mode")) + if (raid.equalsIgnoreCase(KillCountService.TOB) + || raid.equalsIgnoreCase(KillCountService.TOA) + || raid.equalsIgnoreCase(KillCountService.COX) + || raid.equalsIgnoreCase(KillCountService.COX + " Challenge Mode")) return boss; return null; diff --git a/src/main/java/dinkplugin/util/KillCountService.java b/src/main/java/dinkplugin/util/KillCountService.java index fa47cb4d..3dd82789 100644 --- a/src/main/java/dinkplugin/util/KillCountService.java +++ b/src/main/java/dinkplugin/util/KillCountService.java @@ -40,9 +40,9 @@ public class KillCountService { public static final String GAUNTLET_NAME = "Gauntlet", GAUNTLET_BOSS = "Crystalline Hunllef"; public static final String CG_NAME = "Corrupted Gauntlet", CG_BOSS = "Corrupted Hunllef"; - private static final String TOA = "Tombs of Amascut"; - private static final String TOB = "Theatre of Blood"; - private static final String COX = "Chambers of Xeric"; + public static final String TOA = "Tombs of Amascut"; + public static final String TOB = "Theatre of Blood"; + public static final String COX = "Chambers of Xeric"; private static final String RL_CHAT_CMD_PLUGIN_NAME = ChatCommandsPlugin.class.getSimpleName().toLowerCase(); private static final String RL_LOOT_PLUGIN_NAME = LootTrackerPlugin.class.getSimpleName().toLowerCase(); From f1d90c05788fc6e573785890c0134f0eccf43bc9 Mon Sep 17 00:00:00 2001 From: iProdigy Date: Mon, 11 Nov 2024 12:05:31 -0800 Subject: [PATCH 2/3] chore: update mock tests --- .../notifiers/KillCountNotifierTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/test/java/dinkplugin/notifiers/KillCountNotifierTest.java b/src/test/java/dinkplugin/notifiers/KillCountNotifierTest.java index 9aed80c6..4ee40e69 100644 --- a/src/test/java/dinkplugin/notifiers/KillCountNotifierTest.java +++ b/src/test/java/dinkplugin/notifiers/KillCountNotifierTest.java @@ -326,6 +326,57 @@ void testNotifyChambersInterval() { ); } + @Test + void testNotifyTobPb() { + // more config + when(config.killCountNotifyInitial()).thenReturn(false); + when(config.killCountInterval()).thenReturn(99); + + // fire events + notifier.onGameMessage("Wave 'The Final Challenge' (Normal Mode) complete!\nDuration: 7:42.60\nTheatre of Blood completion time: 21:33.60 (new personal best)"); + notifier.onGameMessage("Theatre of Blood total completion time: 25:28.80 (new personal best)"); + String gameMessage = "Your completed Theatre of Blood count is: 1."; + notifier.onGameMessage(gameMessage); + notifier.onTick(); + + // check notification + verifyCreateMessage( + PRIMARY_WEBHOOK_URL, + true, + NotificationBody.builder() + .text(buildPbTemplate("Theatre of Blood", "21:33.60", 1)) + .extra(new BossNotificationData("Theatre of Blood", 1, gameMessage, Duration.ofMinutes(21).plusSeconds(33).plusMillis(600), true, Collections.emptyList())) + .playerName(PLAYER_NAME) + .type(NotificationType.KILL_COUNT) + .build() + ); + } + + @Test + void testNotifyTobInterval() { + // more config + when(config.killCountInterval()).thenReturn(5); + + // fire events + notifier.onGameMessage("Wave 'The Final Challenge' (Normal Mode) complete!\nDuration: 6:37.80\nTheatre of Blood completion time: 19:26.40. Personal best: 19:24.00"); + notifier.onGameMessage("Theatre of Blood total completion time: 26:34.20 (new personal best)"); + String gameMessage = "Your completed Theatre of Blood count is: 5."; + notifier.onGameMessage(gameMessage); + notifier.onTick(); + + // check notification + verifyCreateMessage( + PRIMARY_WEBHOOK_URL, + true, + NotificationBody.builder() + .text(buildTemplate("Theatre of Blood", 5)) + .extra(new BossNotificationData("Theatre of Blood", 5, gameMessage, Duration.ofMinutes(19).plusSeconds(26).plusMillis(400), false, Collections.emptyList())) + .playerName(PLAYER_NAME) + .type(NotificationType.KILL_COUNT) + .build() + ); + } + @Test void testNotifyGauntletPb() { // more config From bdc72f1870fadd84b38b0a1e7ec2d8422d5e4eaa Mon Sep 17 00:00:00 2001 From: iProdigy <8106344+iProdigy@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:13:18 -0800 Subject: [PATCH 3/3] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4635e4c1..624fce3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Unreleased +- Minor: Report challenge time for TOB KC notifications, rather than total completion time. (#591) - Minor: Add raid party members to kill count notification metadata. (#587) - Minor: Add `::DinkMigrate` command to import configuration from other Discord webhook plugins. (#564) - Minor: Remove boss image embed from kill count notifications with screenshots disabled. (#578)