Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kc): use challenge time for tob notifications #591

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
31 changes: 19 additions & 12 deletions src/main/java/dinkplugin/notifiers/KillCountNotifier.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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())
);
}
Expand All @@ -183,7 +185,12 @@ private static Optional<BossNotificationData> parse(Client client, String messag
Optional<Pair<String, Integer>> 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<Pair<Duration, Boolean>> parseTime(String message) {
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/dinkplugin/util/KillCountService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
51 changes: 51 additions & 0 deletions src/test/java/dinkplugin/notifiers/KillCountNotifierTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down