"""Actual scene deadline + finalization; a late remote preload cannot hold an expired ticket.""" import os from pathlib import Path from policy_harness import ROOT, body, run base = ROOT/'addons/core/Scripts/Game/ERR/00_Core' finalizer = Path(os.environ.get('ERR_SPAWN_FINALIZATION_SOURCE', base/'ERR_SpawnFinalization.c')) scene = base/'ERR_SpawnClientScene.c' request = '\n'.join(body(scene, key) for key in ( 'bool ERR_SpawnSceneReady(', 'bool ERR_SpawnSceneVerified(', 'bool ERR_SpawnSceneMayFinish(', 'bool ERR_TakeScenePreload(')) request = request.replace('GetGame().GetWorld().GetWorldTime()', 'worldTime') handler = '\n'.join(body(finalizer, key) for key in ( 'override bool CanFinalize_S(', 'override SCR_ESpawnResult FinalizeRequest_S(')) for old, new in [('override ', ''), ('SCR_SpawnRequestComponent requestComponent', 'Request* requestComponent'), ('SCR_SpawnData data', 'Data* data'), ('IEntity entity', 'Actor* entity'), ('ERR_SpawnLogic logic', 'Logic* logic'), ('ERR_SpawnTicket ticket', 'Ticket* ticket'), ('ERR_GameMode.Get()', 'Mode::Get()'), ('SCR_ESpawnResult.', 'SCR_ESpawnResult::'), ('ticket.', 'ticket->'), ('requestComponent.', 'requestComponent->'), ('logic.', 'logic->'), ('super.', 'Native::')]: handler = handler.replace(old,new) run(r''' #include float worldTime=0; templatevoid PrintFormat(const char*,T...){} enum class SCR_ESpawnResult {OK,SPAWN_NOT_ALLOWED}; struct Request { bool m_ERRScenePending=true,m_ERRSceneAcknowledged=true,m_ERRSceneTimedOut=false; bool m_ERRSceneVerified=false,m_ERRScenePreloadRequired=false,nativePreloading=true; float m_ERRSceneDeadline=60000,m_ERRSceneStartedAt=0; int m_ERRSceneToken=1,ends=0,retained=0; bool IsPreloading(){return nativePreloading;} int GetPlayerId(){return 1;} void ERR_RefreshSceneInventory(){} bool ERR_VerifyLoadedScene(){return m_ERRSceneTimedOut||ERR_SpawnSceneVerified();} void ERR_EndSpawnScene(){ends++;m_ERRScenePending=false;m_ERRSceneAcknowledged=false;m_ERRSceneTimedOut=false;m_ERRSceneVerified=false;} void ERR_RetainSpawnScene(void*){retained++;} '''+request+r''' }; struct Data{};struct Actor{};struct Ticket{int releases=0;void ReleaseProtection(){releases++;}}; struct Mode{static inline bool current=true;static bool Get(){return current;}}; struct Logic{ Ticket ticket;bool hasTicket=true,allowed=true;int authorizationChecks=0; Ticket* TakeSpawnTicket(Request*,Data*,Actor*){if(!hasTicket)return nullptr;hasTicket=false;return &ticket;} bool MayFinalizeSpawn(Ticket*){authorizationChecks++;return allowed;} }; struct Native{ int assignments=0,preloadStarts=0; void OnFinalizeBegin_S(Request* request,Data*,Actor*){preloadStarts++;request->nativePreloading=true;} // Exact native SCR_SpawnHandlerComponent contract: no server-side timeout. bool CanFinalize_S(Request* request,Data*,Actor*){return !request->IsPreloading();} SCR_ESpawnResult FinalizeRequest_S(Request*,Data*,Actor*){assignments++;return SCR_ESpawnResult::OK;} }; struct Handler:Native{ Logic storage;Logic* logic=&storage;int rejects=0; Logic* ERR_AdmissionLogic(){return logic;} void ERR_RejectOwnedActor(Request*,Actor*,Data*){rejects++;} '''+handler+r''' }; int main(){ Data data;Actor actor; // Scene replication was acknowledged, native asset preload started, but its // remote completion is delayed. The server's own deadline must still reject. {Request request;Handler h; worldTime=59999;assert(!h.CanFinalize_S(&request,&data,&actor)); assert(!request.m_ERRSceneTimedOut&&h.assignments==0&&h.rejects==0); worldTime=60000;assert(h.CanFinalize_S(&request,&data,&actor)); assert(request.m_ERRSceneTimedOut&&request.nativePreloading&&!request.ERR_SpawnSceneVerified()); assert(h.FinalizeRequest_S(&request,&data,&actor)==SCR_ESpawnResult::SPAWN_NOT_ALLOWED); assert(h.rejects==1&&h.assignments==0&&h.storage.ticket.releases==1&&h.storage.authorizationChecks==0&&request.ends==1&&request.retained==0); // A late native completion cannot resurrect the consumed ticket or actor. request.nativePreloading=false; assert(h.FinalizeRequest_S(&request,&data,&actor)==SCR_ESpawnResult::SPAWN_NOT_ALLOWED); assert(h.rejects==1&&h.assignments==0&&request.ends==1);} // No scene acknowledgement also expires without starting a native preload. {Request request;Handler h;request.m_ERRSceneAcknowledged=false;request.nativePreloading=false;request.m_ERRScenePreloadRequired=true; worldTime=59999;assert(!h.CanFinalize_S(&request,&data,&actor)); worldTime=60000;assert(h.CanFinalize_S(&request,&data,&actor)&&h.preloadStarts==0); assert(h.FinalizeRequest_S(&request,&data,&actor)==SCR_ESpawnResult::SPAWN_NOT_ALLOWED&&h.assignments==0);} // Before the deadline, ordinary scene and native preload gates still hold. {Request request;Handler h;worldTime=1000;request.nativePreloading=false;request.m_ERRScenePreloadRequired=true; assert(!h.CanFinalize_S(&request,&data,&actor)&&h.preloadStarts==1); request.nativePreloading=false;assert(!h.CanFinalize_S(&request,&data,&actor)); request.m_ERRSceneVerified=true;assert(h.CanFinalize_S(&request,&data,&actor)); assert(h.FinalizeRequest_S(&request,&data,&actor)==SCR_ESpawnResult::OK&&h.assignments==1&&request.retained==1&&h.storage.ticket.releases==1);} // Invalid server snapshots already marked timed-out also take rejection only. {Request request;Handler h;worldTime=1;request.m_ERRSceneTimedOut=true; assert(h.CanFinalize_S(&request,&data,&actor)); assert(h.FinalizeRequest_S(&request,&data,&actor)==SCR_ESpawnResult::SPAWN_NOT_ALLOWED&&h.assignments==0);} } ''') print('PASS: actual scene deadline overrides delayed native preload only for rejection; late completion cannot assign, ordinary verified admission preserved')