Repository: pajlads/DinkPlugin
Pull request #353 (2023-11-01 01:16:20)

feat: allow pk loot to be sent to pk notifier override url
Requested in RL discord, and may render #348 obsolete (or at least the most requested use case for it)



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b6a5f47..c9df12a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
 ## Unreleased
 
+- Minor: Add loot notifier setting that redirects pk loot to the pk notifier override url. (#353)
 - Minor: Allow customization of which safe deaths can trigger notifications. (#363)
 - Bugfix: Avoid erroneous level notification on login when initial data is delayed. (#383)
 - Bugfix: Ensure diary notifications below the configured minimum difficulty are not sent. (#382)
diff --git a/src/main/java/dinkplugin/DinkPluginConfig.java b/src/main/java/dinkplugin/DinkPluginConfig.java
index c4b5fdd..72964e3 100644
--- a/src/main/java/dinkplugin/DinkPluginConfig.java
+++ b/src/main/java/dinkplugin/DinkPluginConfig.java
@@ -803,6 +803,19 @@ public interface DinkPluginConfig extends Config {
         return true;
     }
 
+    @ConfigItem(
+        keyName = "lootRedirectPlayerKill",
+        name = "Send PK Loot to PK URL",
+        description = "Whether to send PK loot to the PK override webhook URL, rather than the loot URL.<br/>" +
+            "Must have 'Include PK Loot' (above) enabled.<br/>" +
+            "Has no effect if the Player Kills notifier override URL is absent",
+        position = 35,
+        section = lootSection
+    )
+    default boolean lootRedirectPlayerKill() {
+        return false;
+    }
+
     @ConfigItem(
         keyName = "lootIncludeClueScrolls",
         name = "Include Clue Loot",
diff --git a/src/main/java/dinkplugin/notifiers/BaseNotifier.java b/src/main/java/dinkplugin/notifiers/BaseNotifier.java
index a6299c1..49dc9c7 100644
--- a/src/main/java/dinkplugin/notifiers/BaseNotifier.java
+++ b/src/main/java/dinkplugin/notifiers/BaseNotifier.java
@@ -40,7 +40,10 @@ public abstract class BaseNotifier {
     protected abstract String getWebhookUrl();
 
     protected final void createMessage(boolean sendImage, NotificationBody<?> body) {
-        String overrideUrl = getWebhookUrl();
+        this.createMessage(getWebhookUrl(), sendImage, body);
+    }
+
+    protected final void createMessage(String overrideUrl, boolean sendImage, NotificationBody<?> body) {
         String url = StringUtils.isNotBlank(overrideUrl) ? overrideUrl : config.primaryWebhook();
         messageHandler.createMessage(url, sendImage, body);
     }
diff --git a/src/main/java/dinkplugin/notifiers/LootNotifier.java b/src/main/java/dinkplugin/notifiers/LootNotifier.java
index 8e8d2a5..f6e356c 100644
--- a/src/main/java/dinkplugin/notifiers/LootNotifier.java
+++ b/src/main/java/dinkplugin/notifiers/LootNotifier.java
@@ -211,6 +211,12 @@ public class LootNotifier extends BaseNotifier {
         }
 
         if (sendMessage) {
+            String overrideUrl = getWebhookUrl();
+            if (config.lootRedirectPlayerKill() && !config.pkWebhook().isBlank()) {
+                if (type == LootRecordType.PLAYER || (type == LootRecordType.EVENT && "Loot Chest".equals(dropper))) {
+                    overrideUrl = config.pkWebhook();
+                }
+            }
             boolean screenshot = config.lootSendImage() && totalStackValue >= config.lootImageMinValue();
             Template notifyMessage = Template.builder()
                 .template(config.lootNotifyMessage())
@@ -220,7 +226,7 @@ public class LootNotifier extends BaseNotifier {
                 .replacement("%TOTAL_VALUE%", Replacements.ofText(QuantityFormatter.quantityToStackSize(totalStackValue)))
                 .replacement("%SOURCE%", Replacements.ofText(dropper))
                 .build();
-            createMessage(screenshot,
+            createMessage(overrideUrl, screenshot,
                 NotificationBody.builder()
                     .text(notifyMessage)
                     .embeds(embeds)


Test patch:
diff --git a/src/test/java/dinkplugin/notifiers/LootNotifierTest.java b/src/test/java/dinkplugin/notifiers/LootNotifierTest.java
index dc71330..23278e0 100644
--- a/src/test/java/dinkplugin/notifiers/LootNotifierTest.java
+++ b/src/test/java/dinkplugin/notifiers/LootNotifierTest.java
@@ -310,6 +310,67 @@ class LootNotifierTest extends MockedNotifierTest {
     @Test
     void testNotifyPlayer() {
         // prepare mocks
+        when(config.pkWebhook()).thenReturn("https://example.com/");
+        when(config.lootRedirectPlayerKill()).thenReturn(false);
+        Player player = mock(Player.class);
+        when(player.getName()).thenReturn(LOOTED_NAME);
+
+        // fire event
+        PlayerLootReceived event = new PlayerLootReceived(player, Arrays.asList(new ItemStack(ItemID.RUBY, 1, null), new ItemStack(ItemID.TUNA, 1, null)));
+        plugin.onPlayerLootReceived(event);
+
+        // verify notification message
+        verify(messageHandler).createMessage(
+            PRIMARY_WEBHOOK_URL,
+            false,
+            NotificationBody.builder()
+                .text(
+                    Template.builder()
+                        .template(String.format("%s has looted: 1 x {{ruby}} (%d) from %s for %s gp", PLAYER_NAME, RUBY_PRICE, LOOTED_NAME, QuantityFormatter.quantityToStackSize(RUBY_PRICE + TUNA_PRICE)))
+                        .replacement("{{ruby}}", Replacements.ofWiki("Ruby"))
+                        .build()
+                )
+                .extra(new LootNotificationData(Arrays.asList(new SerializedItemStack(ItemID.RUBY, 1, RUBY_PRICE, "Ruby"), new SerializedItemStack(ItemID.TUNA, 1, TUNA_PRICE, "Tuna")), LOOTED_NAME, LootRecordType.PLAYER, null))
+                .type(NotificationType.LOOT)
+                .build()
+        );
+    }
+
+    @Test
+    void testNotifyPlayerForwarded() {
+        // prepare mocks
+        String overrideUrl = "https://example.com/";
+        when(config.pkWebhook()).thenReturn(overrideUrl);
+        when(config.lootRedirectPlayerKill()).thenReturn(true);
+        Player player = mock(Player.class);
+        when(player.getName()).thenReturn(LOOTED_NAME);
+
+        // fire event
+        PlayerLootReceived event = new PlayerLootReceived(player, Arrays.asList(new ItemStack(ItemID.RUBY, 1, null), new ItemStack(ItemID.TUNA, 1, null)));
+        plugin.onPlayerLootReceived(event);
+
+        // verify notification message
+        verify(messageHandler).createMessage(
+            overrideUrl,
+            false,
+            NotificationBody.builder()
+                .text(
+                    Template.builder()
+                        .template(String.format("%s has looted: 1 x {{ruby}} (%d) from %s for %s gp", PLAYER_NAME, RUBY_PRICE, LOOTED_NAME, QuantityFormatter.quantityToStackSize(RUBY_PRICE + TUNA_PRICE)))
+                        .replacement("{{ruby}}", Replacements.ofWiki("Ruby"))
+                        .build()
+                )
+                .extra(new LootNotificationData(Arrays.asList(new SerializedItemStack(ItemID.RUBY, 1, RUBY_PRICE, "Ruby"), new SerializedItemStack(ItemID.TUNA, 1, TUNA_PRICE, "Tuna")), LOOTED_NAME, LootRecordType.PLAYER, null))
+                .type(NotificationType.LOOT)
+                .build()
+        );
+    }
+
+    @Test
+    void testNotifyPlayerForwardBlank() {
+        // prepare mocks
+        when(config.pkWebhook()).thenReturn("");
+        when(config.lootRedirectPlayerKill()).thenReturn(true);
         Player player = mock(Player.class);
         when(player.getName()).thenReturn(LOOTED_NAME);