Repository: pajlads/DinkPlugin
Pull request #159 (2023-02-04 00:43:26)

fix: loosen diary area matching from message box
Fixes https://github.com/pajlads/DinkPlugin/pull/157#issuecomment-1416518570


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7bdec6b..289b466 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@
 - Minor: Clean up setting tooltips that stretched too wide, making them difficult to read. (#151)
 - Minor: Add warning when in-game kill count chat spam filter is enabled. (#154)
 - Minor: Include pet name in webhooks when available in chat via clan, collection log, or untradeable drop notifications. (#149, #153)
-- Bugfix: Improve identification of diary completions via message box events. (#157)
+- Bugfix: Improve identification of diary completions via message box events. (#157, #159)
 - Bugfix: Report correct item quantity from unsired loot. (#147)
 - Dev: Improve thread-safety of notifiers. (#156)
 
diff --git a/src/main/java/dinkplugin/notifiers/DiaryNotifier.java b/src/main/java/dinkplugin/notifiers/DiaryNotifier.java
index d4f1abb..428943b 100644
--- a/src/main/java/dinkplugin/notifiers/DiaryNotifier.java
+++ b/src/main/java/dinkplugin/notifiers/DiaryNotifier.java
@@ -81,19 +81,20 @@ public class DiaryNotifier extends BaseNotifier {
                 return;
             }
 
-            String area = matcher.group("area");
-            Optional<Integer> found = DIARIES.entrySet().stream()
-                .filter(e -> e.getValue().getRight() == difficulty && e.getValue().getLeft().equals(area))
-                .map(Map.Entry::getKey)
-                .findAny();
+            String area = matcher.group("area").trim();
+            Optional<Pair<Integer, String>> found = DIARIES.entrySet().stream()
+                .filter(e -> e.getValue().getRight() == difficulty && Utils.containsEither(e.getValue().getLeft(), area))
+                .findAny()
+                .map(entry -> Pair.of(entry.getKey(), entry.getValue().getLeft()));
             if (found.isPresent()) {
-                int varbitId = found.get();
+                Pair<Integer, String> entry = found.get();
+                int varbitId = entry.getKey();
                 if (isComplete(varbitId, 1)) {
                     diaryCompletionById.put(varbitId, 1);
                 } else {
                     diaryCompletionById.put(varbitId, 2);
                 }
-                handle(area, difficulty);
+                handle(entry.getValue(), difficulty);
             } else {
                 log.warn("Failed to match diary area: {}", area);
             }
@@ -188,7 +189,7 @@ public class DiaryNotifier extends BaseNotifier {
                 diaryCompletionById.put(id, value);
             }
         }
-        log.info("Finished initializing current diary completions: {} out of {}", getTotalCompleted(), diaryCompletionById.size());
+        log.debug("Finished initializing current diary completions: {} out of {}", getTotalCompleted(), diaryCompletionById.size());
     }
 
     private static boolean isComplete(int id, int value) {
diff --git a/src/main/java/dinkplugin/util/Utils.java b/src/main/java/dinkplugin/util/Utils.java
index 6d37656..9b59f99 100644
--- a/src/main/java/dinkplugin/util/Utils.java
+++ b/src/main/java/dinkplugin/util/Utils.java
@@ -54,6 +54,19 @@ public class Utils {
         return Character.toUpperCase(text.charAt(0)) + text.substring(1).toLowerCase();
     }
 
+    /**
+     * @param a some string
+     * @param b another string
+     * @return whether either string contains the other
+     */
+    public boolean containsEither(@NotNull String a, @NotNull String b) {
+        if (a.length() >= b.length()) {
+            return a.contains(b);
+        } else {
+            return b.contains(a);
+        }
+    }
+
     public boolean isSettingsOpen(@NotNull Client client) {
         Widget widget = client.getWidget(WidgetInfo.SETTINGS_INIT);
         return widget != null && !widget.isSelfHidden();


Test patch:
diff --git a/src/test/java/dinkplugin/notifiers/DiaryNotifierTest.java b/src/test/java/dinkplugin/notifiers/DiaryNotifierTest.java
index caf9aa4..9a9cfe3 100644
--- a/src/test/java/dinkplugin/notifiers/DiaryNotifierTest.java
+++ b/src/test/java/dinkplugin/notifiers/DiaryNotifierTest.java
@@ -120,6 +120,32 @@ class DiaryNotifierTest extends MockedNotifierTest {
         );
     }
 
+    @Test
+    void testNotifyWesternMessageBox() {
+        // initially many diary completions
+        when(client.getVarbitValue(anyInt())).thenReturn(1);
+        when(client.getVarbitValue(Varbits.DIARY_WESTERN_HARD)).thenReturn(0);
+        int total = AchievementDiary.DIARIES.size() - 3 - 1;
+
+        // perform enough ticks to trigger diary initialization
+        IntStream.range(0, 16).forEach(i -> notifier.onTick());
+
+        // trigger diary completion
+        notifier.onMessageBox("Congratulations! You have completed all of the hard tasks in the Western Province area. Speak to the Elder Gnome child at the Gnome Stronghold to claim your reward.");
+
+        // verify notification message
+        verify(messageHandler).createMessage(
+            PRIMARY_WEBHOOK_URL,
+            false,
+            NotificationBody.builder()
+                .text(String.format("%s has completed the %s %s Diary, for a total of %d", PLAYER_NAME, AchievementDiary.Difficulty.HARD, "Western Provinces", total + 1))
+                .extra(new DiaryNotificationData("Western Provinces", AchievementDiary.Difficulty.HARD, total + 1))
+                .type(NotificationType.ACHIEVEMENT_DIARY)
+                .playerName(PLAYER_NAME)
+                .build()
+        );
+    }
+
     @Test
     void testNotifyCooldown() {
         // initially many diary completions