Repository: pajlads/DinkPlugin
Pull request #345 (2023-10-26 07:33:41)

feat: include skill xp in login notifications
In addition to skill levels, login notifications now include individual skill XP as well - could be useful for integrations that chart xp over time



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6a8880..3e7373c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
 ## Unreleased
 
+- Minor: Include individual skill XP in login notification metadata. (#345)
 - Bugfix: Improve handling of queued notifications upon concurrent config changes. (#355)
 
 ## 1.6.4
diff --git a/README.md b/README.md
index 3357049..3a00c6f 100644
--- a/README.md
+++ b/README.md
@@ -795,7 +795,7 @@ On login, Dink can submit a character summary containing data that spans multipl
       "highGambleCount": 0
     },
     "skills": {
-      "totalExperience": 337810454,
+      "totalExperience": 346380298,
       "totalLevel": 2164,
       "levels": {
         "Hunter": 90,
@@ -821,6 +821,31 @@ On login, Dink can submit a character summary containing data that spans multipl
         "Strength": 104,
         "Prayer": 91,
         "Farming": 100
+      },
+      "experience": {
+        "Hunter": 5420696,
+        "Thieving": 3696420,
+        "Runecraft": 3969420,
+        "Construction": 3680085,
+        "Cooking": 19696420,
+        "Magic": 28008135,
+        "Fletching": 13696420,
+        "Herblore": 5969420,
+        "Firemaking": 14420666,
+        "Attack": 30696420,
+        "Fishing": 6632248,
+        "Crafting": 9696420,
+        "Hitpoints": 46969666,
+        "Ranged": 42069420,
+        "Mining": 4696420,
+        "Smithing": 6428696,
+        "Agility": 2666420,
+        "Woodcutting": 9696666,
+        "Slayer": 21420696,
+        "Defence": 21212121,
+        "Strength": 23601337,
+        "Prayer": 6369666,
+        "Farming": 15666420
       }
     },
     "questCount": {
diff --git a/src/main/java/dinkplugin/notifiers/MetaNotifier.java b/src/main/java/dinkplugin/notifiers/MetaNotifier.java
index 6d51781..9b435db 100644
--- a/src/main/java/dinkplugin/notifiers/MetaNotifier.java
+++ b/src/main/java/dinkplugin/notifiers/MetaNotifier.java
@@ -20,11 +20,10 @@ import org.jetbrains.annotations.VisibleForTesting;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import java.util.Arrays;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
 
 @Singleton
 public class MetaNotifier extends BaseNotifier {
@@ -88,10 +87,15 @@ public class MetaNotifier extends BaseNotifier {
 
         long experienceTotal = client.getOverallExperience();
         int levelTotal = client.getTotalLevel();
-        Map<String, Integer> skillLevels = Arrays.stream(Skill.values()).collect(Collectors.toMap(Skill::getName, skill -> {
+        Map<String, Integer> skillLevels = new HashMap<>(32);
+        Map<String, Integer> skillExperience = new HashMap<>(32);
+        for (Skill skill : Skill.values()) {
+            int xp = client.getSkillExperience(skill);
             int lvl = client.getRealSkillLevel(skill);
-            return lvl < 99 ? lvl : Experience.getLevelForXp(client.getSkillExperience(skill));
-        }));
+            int virtualLevel = lvl < 99 ? lvl : Experience.getLevelForXp(xp);
+            skillExperience.put(skill.getName(), xp);
+            skillLevels.put(skill.getName(), virtualLevel);
+        }
 
         int questsCompleted = client.getVarbitValue(QuestNotifier.COMPLETED_ID);
         int questsTotal = client.getVarbitValue(QuestNotifier.TOTAL_ID);
@@ -116,7 +120,7 @@ public class MetaNotifier extends BaseNotifier {
             Progress.of(diaryCompleted, diaryTotal),
             Progress.of(diaryTaskCompleted, diaryTaskTotal),
             new LoginNotificationData.BarbarianAssault(gambleCount),
-            new LoginNotificationData.SkillData(experienceTotal, levelTotal, skillLevels),
+            new LoginNotificationData.SkillData(experienceTotal, levelTotal, skillLevels, skillExperience),
             Progress.of(questsCompleted, questsTotal),
             Progress.of(questPoints, questPointsTotal),
             new LoginNotificationData.SlayerData(slayerPoints, slayerStreak)
diff --git a/src/main/java/dinkplugin/notifiers/data/LoginNotificationData.java b/src/main/java/dinkplugin/notifiers/data/LoginNotificationData.java
index 7ad9ed8..b0f859f 100644
--- a/src/main/java/dinkplugin/notifiers/data/LoginNotificationData.java
+++ b/src/main/java/dinkplugin/notifiers/data/LoginNotificationData.java
@@ -27,6 +27,7 @@ public class LoginNotificationData extends NotificationData {
         long totalExperience;
         int totalLevel;
         Map<String, Integer> levels;
+        Map<String, Integer> experience;
     }
 
     @Value


Test patch:
diff --git a/src/test/java/dinkplugin/notifiers/MetaNotifierTest.java b/src/test/java/dinkplugin/notifiers/MetaNotifierTest.java
index 9631215..5938d9d 100644
--- a/src/test/java/dinkplugin/notifiers/MetaNotifierTest.java
+++ b/src/test/java/dinkplugin/notifiers/MetaNotifierTest.java
@@ -63,6 +63,7 @@ class MetaNotifierTest extends MockedNotifierTest {
         when(client.getVarbitValue(Varbits.BA_GC)).thenReturn(666);
 
         when(client.getRealSkillLevel(any())).thenReturn(level);
+        when(client.getSkillExperience(any())).thenReturn((int) xp);
         when(client.getTotalLevel()).thenReturn(skillCount * level);
         when(client.getOverallExperience()).thenReturn(skillCount * xp);
 
@@ -89,13 +90,15 @@ class MetaNotifierTest extends MockedNotifierTest {
         // verify handled
         Map<String, Integer> levels = Arrays.stream(Skill.values())
             .collect(Collectors.toMap(Skill::getName, s -> level));
+        Map<String, Integer> exp = Arrays.stream(Skill.values())
+            .collect(Collectors.toMap(Skill::getName, s -> (int) xp));
         LoginNotificationData extra = new LoginNotificationData(world,
             Progress.of(1312, 1477),
             Progress.of(1984, 2005),
             Progress.of(3, 48),
             null,
             new LoginNotificationData.BarbarianAssault(666),
-            new LoginNotificationData.SkillData(xp * skillCount, level * skillCount, levels),
+            new LoginNotificationData.SkillData(xp * skillCount, level * skillCount, levels, exp),
             Progress.of(21, 158), Progress.of(43, 300),
             new LoginNotificationData.SlayerData(2484, 300)
         );
@@ -126,13 +129,15 @@ class MetaNotifierTest extends MockedNotifierTest {
         // verify handled
         Map<String, Integer> levels = Arrays.stream(Skill.values())
             .collect(Collectors.toMap(Skill::getName, s -> level));
+        Map<String, Integer> exp = Arrays.stream(Skill.values())
+            .collect(Collectors.toMap(Skill::getName, s -> (int) xp));
         LoginNotificationData extra = new LoginNotificationData(world,
             null, // collection log data should not be present
             Progress.of(1984, 2005),
             Progress.of(3, 48),
             null,
             new LoginNotificationData.BarbarianAssault(666),
-            new LoginNotificationData.SkillData(xp * skillCount, level * skillCount, levels),
+            new LoginNotificationData.SkillData(xp * skillCount, level * skillCount, levels, exp),
             Progress.of(21, 158), Progress.of(43, 300),
             new LoginNotificationData.SlayerData(2484, 300)
         );