refactor(world): extract live entity network updates

Move Position, Vector, State, Movement, and equal-generation CreateObject routing out of GameWindow while preserving per-channel authority, ForcePosition acknowledgement, and motion-runtime ownership. Add adversarial authority and exact-wire coverage so reentrant updates and GUID reuse cannot publish stale state.
This commit is contained in:
Erik 2026-07-21 19:11:49 +02:00
parent c203e4799a
commit aa90c64666
19 changed files with 3701 additions and 2241 deletions

View file

@ -0,0 +1,48 @@
using AcDream.Core.Net;
using AcDream.Core.Net.Messages;
using AcDream.Core.Physics;
namespace AcDream.App.World;
internal interface ILiveEntitySameGenerationUpdateSink
{
void OnDescription(uint ownerGuid, PhysicsSpawnData description);
void OnAppearance(ObjDescEvent.Parsed appearance);
void OnParent(CreateParentUpdate parent);
void OnPosition(WorldSession.EntityPositionUpdate position);
void OnPickup(PickupEvent.Parsed pickup);
void OnMovement(WorldSession.EntityMotionUpdate movement);
void OnState(SetState.Parsed state);
void OnVector(VectorUpdate.Parsed vector);
}
/// <summary>
/// Pins the equal-generation <c>CObjectMaint::CreateObject</c> tail order from
/// retail <c>SmartBox::HandleCreateObject @ 0x00454C80</c>. The leading
/// PhysicsDesc effect-profile refresh is the isolated AP-119 adaptation; the
/// retail tail then remains ObjDesc, one Position relation, Movement, State,
/// and Vector. Each channel still owns an independent timestamp gate.
/// </summary>
internal static class LiveEntitySameGenerationUpdateRouter
{
public static void Apply(
SameGenerationCreateObjectEvents refresh,
ILiveEntitySameGenerationUpdateSink sink)
{
ArgumentNullException.ThrowIfNull(sink);
sink.OnDescription(refresh.Appearance.Guid, refresh.Description);
sink.OnAppearance(refresh.Appearance);
if (refresh.Parent is { } parent)
sink.OnParent(parent);
else if (refresh.Position is { } position)
sink.OnPosition(position);
else if (refresh.Pickup is { } pickup)
sink.OnPickup(pickup);
if (refresh.Movement is { } movement)
sink.OnMovement(movement);
sink.OnState(refresh.State);
sink.OnVector(refresh.Vector);
}
}