From d3b58c97e017105ac3c10be65c66bcee95dc0f86 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 10 May 2026 08:06:33 +0200 Subject: [PATCH] feat(net): #13 scaffold trailer fields on PlayerDescriptionParser.Parsed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No behavior change yet — adds CharacterOptionDataFlag, Shortcut/Inventory/ EquippedEntry records, and extends Parsed with trailer fields filled with empty defaults. Sets up the per-section TDD walk in subsequent commits. --- .../Messages/PlayerDescriptionParser.cs | 72 ++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/src/AcDream.Core.Net/Messages/PlayerDescriptionParser.cs b/src/AcDream.Core.Net/Messages/PlayerDescriptionParser.cs index 406af15..520e84a 100644 --- a/src/AcDream.Core.Net/Messages/PlayerDescriptionParser.cs +++ b/src/AcDream.Core.Net/Messages/PlayerDescriptionParser.cs @@ -177,6 +177,46 @@ public static class PlayerDescriptionParser Cooldown = 0x08, } + /// Bitmask of which optional trailer sections are present in + /// the PlayerDescription wire payload. Holtburger + /// events.rs:503-607; ACE CharacterOptionDataFlag. + [Flags] + public enum CharacterOptionDataFlag : uint + { + None = 0, + Shortcut = 0x00000001, + SquelchList = 0x00000002, + MultiSpellList = 0x00000004, + DesiredComps = 0x00000008, + ExtendedMultiSpellLists = 0x00000010, + SpellbookFilters = 0x00000020, + CharacterOptions2 = 0x00000040, + TimestampFormat = 0x00000080, + GenericQualitiesData = 0x00000100, + GameplayOptions = 0x00000200, + SpellLists8 = 0x00000400, + } + + /// One shortcut bar entry. 16 bytes wire size. + /// holtburger shortcuts.rs:13-34. + public readonly record struct Shortcut( + uint Index, + uint ObjectGuid, + ushort SpellId, + ushort Layer); + + /// One inventory entry — a guid plus a ContainerType discriminator + /// (0=NonContainer, 1=Container, 2=Foci). + public readonly record struct InventoryEntry( + uint Guid, + uint ContainerType); + + /// One equipped object entry. + public readonly record struct EquippedEntry( + uint Guid, + uint EquipLocation, + uint Priority); + public readonly record struct Parsed( uint WeenieType, DescriptionPropertyFlag PropertyFlags, @@ -187,7 +227,17 @@ public static class PlayerDescriptionParser IReadOnlyList Attributes, IReadOnlyList Skills, IReadOnlyDictionary Spells, - IReadOnlyList Enchantments); + IReadOnlyList Enchantments, + CharacterOptionDataFlag OptionFlags, + uint Options1, + uint Options2, + IReadOnlyList Shortcuts, + IReadOnlyList> HotbarSpells, + IReadOnlyList<(uint Id, uint Amount)> DesiredComps, + uint SpellbookFilters, + ReadOnlyMemory GameplayOptions, + IReadOnlyList Inventory, + IReadOnlyList Equipped); /// /// Parse a PlayerDescription payload. The 0xF7B0 envelope has been @@ -260,7 +310,15 @@ public static class PlayerDescriptionParser return new Parsed( weenieType, propertyFlags, vectorFlags, hasHealth, - bundle, positions, attributes, skills, spells, enchantments); + bundle, positions, attributes, skills, spells, enchantments, + CharacterOptionDataFlag.None, 0u, 0u, + System.Array.Empty(), + System.Array.Empty>(), + System.Array.Empty<(uint, uint)>(), + 0u, + ReadOnlyMemory.Empty, + System.Array.Empty(), + System.Array.Empty()); } catch (FormatException ex) { @@ -281,7 +339,15 @@ public static class PlayerDescriptionParser { return new Parsed(weenieType, pFlags, vFlags, hasHealth, bundle, positions, attributes, skills, spells, - System.Array.Empty()); + System.Array.Empty(), + CharacterOptionDataFlag.None, 0u, 0u, + System.Array.Empty(), + System.Array.Empty>(), + System.Array.Empty<(uint, uint)>(), + 0u, + ReadOnlyMemory.Empty, + System.Array.Empty(), + System.Array.Empty()); } // ── Attribute block reader ──────────────────────────────────────────────