Commit graph

3 commits

Author SHA1 Message Date
Erik
5d717312cc feat(net): plumb IsGrounded through EntityPositionUpdate (L.3.2 Task 2)
PositionFlags.IsGrounded (0x04) was already parsed by UpdatePosition
but not exposed through the Parsed record or EntityPositionUpdate.
Adds the bool field to both records so OnLivePositionUpdated can
consume it for retail-faithful MoveOrTeleport routing
(acclient @ 0x00516330: has_contact=false → no-op during airborne arc).

Consumed in subsequent task (L.3.1+L.3.2 Task 3).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-03 10:15:02 +02:00
Erik
11974c2099 feat(net): track + echo movement sequence counters
Sprint 1a of the audit remediation plan.

Extracts the 4 movement sequence counters from inbound server messages
and echoes them in outbound MoveToState + AutonomousPosition instead
of hardcoded zeros:

- instanceSequence (slot 8 in CreateObject PhysicsData timestamps)
- teleportSequence (slot 4, also from PlayerTeleport 0xF751)
- serverControlSequence (slot 5)
- forcePositionSequence (slot 6, also from UpdatePosition 0xF748)

Source: holtburger player/types.rs:237-245, mutations.rs:182-706.
The server uses these to detect stale/reordered movement packets.
Previously all zeros → server couldn't distinguish epoch boundaries.

Changes:
- CreateObject.Parsed: +4 sequence fields extracted from timestamps
- UpdatePosition.Parsed: +3 sequence fields from trailing u16s
- WorldSession: tracks 4 counters, updates from CreateObject/
  UpdatePosition/PlayerTeleport for the player's own GUID
- GameWindow: passes tracked values to MoveToState.Build and
  AutonomousPosition.Build

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 13:45:39 +02:00
Erik
333a7c197a feat(net): Phase 6.7 — parse UpdatePosition (0xF748) into PositionUpdated event
Companion to the Phase 6.6 UpdateMotion parser. Without this, every
server-spawned entity stays frozen at its CreateObject origin forever
— NPCs don't patrol, creatures don't hunt, other players don't walk
past. UpdatePosition is the per-entity position delta the server sends
on every movement tick.

The wire format is straightforward but fiddly:
  u32 opcode | u32 guid | u32 flags | u32 cellId | 3xf32 pos
  (0..4) conditional f32 rotation components, present iff the
  corresponding OrientationHasNo* flag is CLEAR
  optional 3xf32 velocity iff HasVelocity
  optional u32 placementId iff HasPlacementID
  four u16 sequence numbers (consumed but not used)

Layout ported from references/ACE/Source/ACE.Server/Network/Structure/
PositionPack.cs::Write and ACE.Entity/Enum/PositionFlags.cs.

WorldSession dispatches PositionUpdated(guid, position, velocity) on
a successful parse. GameWindow wiring (guid → WorldEntity lookup and
transform swap) is deferred to the same follow-up commit that lands
Phase 6.6 wiring, after the in-flight Phase 9.1 translucent-pass work
merges so we don't step on GameWindow.cs edits.

96 Core.Net tests (was 89, +7 for UpdatePosition coverage).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:37:32 +02:00