feat(net): #13 scaffold trailer fields on PlayerDescriptionParser.Parsed

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.
This commit is contained in:
Erik 2026-05-10 08:06:33 +02:00
parent 1e6a8123c6
commit d3b58c97e0

View file

@ -177,6 +177,46 @@ public static class PlayerDescriptionParser
Cooldown = 0x08,
}
/// <summary>Bitmask of which optional trailer sections are present in
/// the PlayerDescription wire payload. Holtburger
/// <c>events.rs:503-607</c>; ACE <c>CharacterOptionDataFlag</c>.</summary>
[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,
}
/// <summary>One shortcut bar entry. 16 bytes wire size.
/// holtburger shortcuts.rs:13-34.</summary>
public readonly record struct Shortcut(
uint Index,
uint ObjectGuid,
ushort SpellId,
ushort Layer);
/// <summary>One inventory entry — a guid plus a ContainerType discriminator
/// (0=NonContainer, 1=Container, 2=Foci).</summary>
public readonly record struct InventoryEntry(
uint Guid,
uint ContainerType);
/// <summary>One equipped object entry.</summary>
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<AttributeEntry> Attributes,
IReadOnlyList<SkillEntry> Skills,
IReadOnlyDictionary<uint, float> Spells,
IReadOnlyList<EnchantmentEntry> Enchantments);
IReadOnlyList<EnchantmentEntry> Enchantments,
CharacterOptionDataFlag OptionFlags,
uint Options1,
uint Options2,
IReadOnlyList<Shortcut> Shortcuts,
IReadOnlyList<IReadOnlyList<uint>> HotbarSpells,
IReadOnlyList<(uint Id, uint Amount)> DesiredComps,
uint SpellbookFilters,
ReadOnlyMemory<byte> GameplayOptions,
IReadOnlyList<InventoryEntry> Inventory,
IReadOnlyList<EquippedEntry> Equipped);
/// <summary>
/// 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<Shortcut>(),
System.Array.Empty<IReadOnlyList<uint>>(),
System.Array.Empty<(uint, uint)>(),
0u,
ReadOnlyMemory<byte>.Empty,
System.Array.Empty<InventoryEntry>(),
System.Array.Empty<EquippedEntry>());
}
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<EnchantmentEntry>());
System.Array.Empty<EnchantmentEntry>(),
CharacterOptionDataFlag.None, 0u, 0u,
System.Array.Empty<Shortcut>(),
System.Array.Empty<IReadOnlyList<uint>>(),
System.Array.Empty<(uint, uint)>(),
0u,
ReadOnlyMemory<byte>.Empty,
System.Array.Empty<InventoryEntry>(),
System.Array.Empty<EquippedEntry>());
}
// ── Attribute block reader ──────────────────────────────────────────────