fix(net,runtime): FA2 fix-round SHOULD-FIX -- fellowship mechanism parity, lookup reuse, router test, checkpoint defaults
Remaining SHOULD-FIX findings from the FA2 mechanism/blast reviews: Mechanism SF-3/SF-4 -- RuntimeFellowshipState.ApplyUpdateFellow now ports Fellowship::RecalculateEvenXPSplitting @0x005B92E0 (called from retail's AddFellow/UpdateFellow/RemoveFellow on every upsert/removal, but never from a full update -- that carries the server's own authoritative flag verbatim, lane B 6.2) and Fellowship::AddFellow @0x005B9480's locked/departed admission gate (a brand-new guid is refused while _locked unless it appears in the 0x02BE field-8 _fellows_departed table within 900s, @0x005B94A5). ApplyFullUpdate now stores update.Departed instead of discarding it. A TimeProvider dependency (defaulting to TimeProvider.System, matching the RuntimeCharacterOptionsState precedent) makes the 900s grace window testable. Mechanism SF-5 -- RuntimeAllegianceState's TryGetMember/TryGetPatron/ GetVassals now reuse ClientCommandResponses.AllegianceProfileLookups (promoted private -> internal, AcDream.Runtime added to Core.Net's InternalsVisibleTo) instead of re-implementing the retail walk a second time. Mechanism SF-6 -- RuntimeStateCheckpoint's Fellowship/Allegiance parameters are no longer trailing-optional. `default(RuntimeFellowshipSnapshot)`/ `default(RuntimeAllegianceSnapshot)` zero-init Name/AllegianceName to null, and C# does not allow a non-constant `new(...)` as an optional parameter's default value (CS1736) even when the struct declares an explicit parameterless constructor -- so the only way to guarantee a non-null default was to make the parameters required. Both snapshot types still gained an explicit parameterless constructor for callers that want an empty-but-safe `new()`. Blast SF-4 -- LiveSessionEventRouterTests gains FellowshipQuit_RoutesSelfGuidToClearAndOtherGuidToRemove, wiring real RuntimeFellowshipState/RuntimeAllegianceState owners through the one production registration site and dispatching a real 0x00A3 envelope for both a self-quit and an other-quit -- the one non-trivial lambda in the slice (the self-guid source that decides "remove one member" vs "clear the whole snapshot") was previously untested; every other router test defaults Fellowship/Allegiance to null. Blast SF-5 -- RuntimeFellowshipState.ResetSession dropped its disposed guard to match the precedent its own doc comment names (RuntimeInventoryState.ResetExternalContainer, RuntimeCommunicationState.ResetNegotiatedChannels -- both bare delegations with no disposal guard); the reset transaction is retryable and disposal is terminal, so a throwing guard could never converge on retry. RuntimeAllegianceState.ResetSession (new this fix round) matches the same shape from the start. Blast SF-7 -- IRuntimeAllegianceView.GetVassals' per-call List<> allocation is now documented as an intentional exception to the file's "Snapshot + TryGet*, no allocation" view convention (C# cannot yield-return from inside a lock). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
4272ad0ea4
commit
ded23067aa
8 changed files with 499 additions and 20 deletions
|
|
@ -239,10 +239,21 @@ public readonly record struct RuntimeStateCheckpoint(
|
|||
RuntimeWorldEnvironmentOwnershipSnapshot EnvironmentOwnership,
|
||||
RuntimePortalSnapshot Portal,
|
||||
RuntimeWorldTransitOwnershipSnapshot TransitOwnership,
|
||||
// Campaign FA slice FA2 (2026-08-12): default so every existing
|
||||
// positional construction site (tests) compiles unchanged.
|
||||
RuntimeFellowshipSnapshot Fellowship = default,
|
||||
RuntimeAllegianceSnapshot Allegiance = default);
|
||||
// Campaign FA slice FA2 (2026-08-12): originally trailing-optional
|
||||
// (`= default`) so every existing positional construction site (tests)
|
||||
// compiled unchanged. FA2 fix-round SHOULD-FIX 6 (blast review) made
|
||||
// both parameters REQUIRED instead: `default(RuntimeFellowshipSnapshot)`/
|
||||
// `default(RuntimeAllegianceSnapshot)` zero-init every field —
|
||||
// including Name/AllegianceName to null, not string.Empty — and C#
|
||||
// does not allow a non-constant expression (a real `new(...)` call) as
|
||||
// an optional-parameter default, so there is no way to give a
|
||||
// TRAILING-OPTIONAL parameter here a non-null default. Both snapshot
|
||||
// types still declare an explicit parameterless constructor
|
||||
// (`RuntimeFellowshipSnapshot()`/`RuntimeAllegianceSnapshot()`,
|
||||
// GameRuntimeGameplayViews.cs) so callers that want an empty-but-safe
|
||||
// snapshot can pass `new()` explicitly.
|
||||
RuntimeFellowshipSnapshot Fellowship,
|
||||
RuntimeAllegianceSnapshot Allegiance);
|
||||
|
||||
public interface IGameRuntimeView
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue