Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
"""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 <cassert>
|
||||
float worldTime=0;
|
||||
template<class...T>void 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')
|
||||
Reference in New Issue
Block a user