Add DWORD properties and titles list to character stats payload

Parse augmentation, rating, mastery, society, and general DWORD properties
from the 0x0013 login message. Capture the full titles list from 0x0029.
Both are included in the character_stats WebSocket payload for the new
TreeStats-style character window in the frontend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
erik 2026-02-27 14:39:08 +00:00
parent a4d2108b3a
commit a446158f63
2 changed files with 38 additions and 1 deletions

View file

@ -42,6 +42,19 @@ namespace MosswartMassacre
// Cached title data (populated from network messages)
private static int currentTitle = -1;
private static List<string> titlesList = new List<string>();
// Cached DWORD properties (populated from 0x0013 message)
private static Dictionary<int, int> characterProperties = new Dictionary<int, int>();
// DWORD blacklist — exclude cosmetic/internal properties (same as TreeStats)
private static readonly HashSet<int> dwordBlacklist = new HashSet<int> {
2, 5, 7, 10, 17, 19, 20, 24, 25, 26, 28, 30, 33, 35, 36, 38, 43, 45,
86, 87, 88, 89, 90, 91, 92, 98,
105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 117, 125, 129, 131, 134,
158, 159, 160, 166, 170, 171, 172, 174, 175, 176, 177, 178, 179, 188, 193,
270, 271, 272, 293
};
/// <summary>
/// Reset all cached data. Call on plugin init.
@ -58,6 +71,8 @@ namespace MosswartMassacre
luminanceEarned = -1;
luminanceTotal = -1;
currentTitle = -1;
titlesList.Clear();
characterProperties.Clear();
}
/// <summary>
@ -142,6 +157,18 @@ namespace MosswartMassacre
else if (key == Constants.MaximumLuminanceKey)
luminanceTotal = value;
}
// Parse DWORD properties (augmentations, ratings, masteries, society, etc.)
MessageStruct dwords = props.Struct("dwords");
characterProperties.Clear();
for (int i = 0; i < dwords.Count; i++)
{
var tmpStruct = dwords.Struct(i);
int key = tmpStruct.Value<Int32>("key");
int value = tmpStruct.Value<Int32>("value");
if (!dwordBlacklist.Contains(key))
characterProperties[key] = value;
}
}
catch (Exception ex)
{
@ -185,6 +212,14 @@ namespace MosswartMassacre
{
try
{
// Capture full titles list
MessageStruct titles = e.Message.Struct("titles");
titlesList.Clear();
for (int i = 0; i < titles.Count; i++)
{
titlesList.Add(titles.Struct(i).Value<string>("value"));
}
currentTitle = e.Message.Value<Int32>("current");
}
catch (Exception ex)
@ -325,7 +360,9 @@ namespace MosswartMassacre
attributes = attributes,
vitals = vitals,
skills = skills,
allegiance = allegiance
allegiance = allegiance,
properties = characterProperties.Count > 0 ? new Dictionary<int, int>(characterProperties) : null,
titles = titlesList.Count > 0 ? new List<string>(titlesList) : null
};
_ = WebSocket.SendCharacterStatsAsync(payload);