diff --git a/src/AcDream.Core.Net/WorldSession.cs b/src/AcDream.Core.Net/WorldSession.cs index d00edbd9..a904140c 100644 --- a/src/AcDream.Core.Net/WorldSession.cs +++ b/src/AcDream.Core.Net/WorldSession.cs @@ -195,6 +195,25 @@ public sealed class WorldSession : IDisposable /// public event Action? ObjectIntPropertyUpdated; + /// Payload for : a PropertyInt change on + /// the player's OWN object (from PrivateUpdatePropertyInt 0x02CD — no guid on the wire). + public readonly record struct PlayerIntPropertyUpdate(uint Property, int Value); + + /// Fires when the session parses a PrivateUpdatePropertyInt (0x02CD) — one + /// PropertyInt updated on the player. B-Wire routes EncumbranceVal (5) to the burden bar. + public event Action? PlayerIntPropertyUpdated; + + /// Payload for : SetStackSize (0x0197) — a stack's + /// count + value after a merge / split. + public readonly record struct StackSizeUpdate(uint Guid, int StackSize, int Value); + + /// Fires when the session parses a SetStackSize (0x0197) top-level GameMessage. + public event Action? StackSizeUpdated; + + /// Fires when the session parses an InventoryRemoveObject (0x0024) — the guid left + /// the player's inventory view. + public event Action? InventoryObjectRemoved; + /// /// Fires when the server sends a PlayerTeleport (0xF751) game message, /// signalling that the player is entering portal space. The uint payload @@ -958,6 +977,25 @@ public sealed class WorldSession : IDisposable ObjectIntPropertyUpdated?.Invoke( new ObjectIntPropertyUpdate(p.Value.Guid, p.Value.Property, p.Value.Value)); } + else if (op == PrivateUpdatePropertyInt.Opcode) + { + var p = PrivateUpdatePropertyInt.TryParse(body); + if (p is not null) + PlayerIntPropertyUpdated?.Invoke( + new PlayerIntPropertyUpdate(p.Value.Property, p.Value.Value)); + } + else if (op == SetStackSize.Opcode) + { + var p = SetStackSize.TryParse(body); + if (p is not null) + StackSizeUpdated?.Invoke( + new StackSizeUpdate(p.Value.Guid, p.Value.StackSize, p.Value.Value)); + } + else if (op == InventoryRemoveObject.Opcode) + { + var p = InventoryRemoveObject.TryParse(body); + if (p is not null) InventoryObjectRemoved?.Invoke(p.Value.Guid); + } else if (op == GameEventEnvelope.Opcode) { // Phase F.1: 0xF7B0 is the GameEvent envelope. Parse the