"""Execute production alarm lifecycle bodies with native audio/replication doubles. This checks ownership and finite playback policy, not native acoustics or network ordering. Successful breach routing is exercised in test_vehicle_security.py. """ import re from policy_harness import ROOT, body, run component = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_VehicleSecurityComponent.c' def translate(source): source = source.replace('protected ', '').replace('override ', '') source = source.replace('ERR_GameMode mode', 'ERR_GameMode* mode') for name in ('Replication', 'AudioHandle', 'AudioSystem', 'SCR_Global', 'ERR_Actors', 'ERR_VehicleAlarmPerception', 'ERR_GameMode', 'ERR_MissionRules', 'RplSession', 'RplMode'): source = source.replace(name + '.', name + '::') for name in ('GetGame()', 'GetWorld()', 'GetCallqueue()', 'GetOwner()', 'm_AlarmMode', 'mode'): source = source.replace(name + '.', name + '->') source = source.replace('array', 'std::vector').replace('array', 'std::vector') source = source.replace('vector horn = "0 1 1.2";', 'vector horn{0, 1, 1.2f};') for name, callback in (('StopAlarm', 'STOP_CALLBACK'), ('AlarmTick', 'TICK_CALLBACK')): for operation in ('CallLater', 'Remove', 'Insert'): source = source.replace(operation + '(' + name, operation + '(' + callback) return source.replace('super.OnDelete(owner)', 'Base::OnDelete(owner)').replace('null', 'nullptr') methods = '\n'.join(translate(body(component, signature)) for signature in ( 'bool AlarmActive(', 'bool AlarmPlaying(', 'protected void BeginAlarm(', 'protected void ApplyAlarm(', 'protected void AlarmTick(', 'protected void StopAlarm(', 'protected void CloseAlarm(', 'protected override void OnDelete(')) run(r''' #include #include #include #include #include #include #include using string=std::string; constexpr int STOP_CALLBACK=1,TICK_CALLBACK=2,FOREIGN_CALLBACK=99; struct vector { float x=0,y=0,z=0; vector Multiply4(const vector* t){return {t[3].x+x,t[3].y+y,t[3].z+z};} }; struct Entity { bool alive=true;vector position; void GetWorldTransform(vector* t){t[0]={1,0,0};t[1]={0,1,0};t[2]={0,0,1};t[3]=position;} }; using IEntity=Entity*; struct World {float now=100;float GetWorldTime(){return now;}}; struct Queue { struct Timer {int delay;bool repeat;}; std::map timers{{FOREIGN_CALLBACK,{1,true}}};int calls=0; void CallLater(int id,int delay,bool repeat){calls++;timers[id]={delay,repeat};} void Remove(int id){timers.erase(id);} }; struct Game {World* world=nullptr;Queue queue;World* GetWorld(){return world;}Queue* GetCallqueue(){return &queue;}}; Game* currentGame=nullptr;Game* GetGame(){return currentGame;} struct Invoker { std::set subscribers{FOREIGN_CALLBACK};int inserts=0; void Insert(int id){inserts++;subscribers.insert(id);}void Remove(int id){subscribers.erase(id);} }; struct ERR_GameMode { static ERR_GameMode* current;bool active=true;int phase=1;Invoker stopped; static ERR_GameMode* Get(){return current;}bool Active(){return active;}int Phase(){return phase;}Invoker& OnStop(){return stopped;} }; ERR_GameMode* ERR_GameMode::current=nullptr; struct ERR_MissionRules {static bool Terminal(int phase){return phase==2;}}; struct ERR_Actors {static bool Alive(IEntity owner){return owner&&owner->alive;}}; struct Replication {inline static bool server=true;inline static int bumps=0;static bool IsServer(){return server;}static void BumpMe(){bumps++;}}; struct SCR_Global {inline static bool edit=false;static bool IsEditMode(){return edit;}}; struct RplMode {enum {Client,Dedicated};}; struct RplSession {inline static int mode=RplMode::Client;static int Mode(){return mode;}}; struct AudioHandle {static const int Invalid=-1;}; struct AudioSystem { inline static int plays=0,next=10;inline static bool fail=false; inline static std::set sounds;inline static std::vector ended,moved; inline static vector lastPosition; static int PlayEvent(const string& resource,const string& event,const vector* t,const std::vector& signals,const std::vector& values){ assert(resource=="{7E64D37BE3E1F3FA}Sounds/Vehicles/Wheeled/UAZ469/Vehicles_UAZ469_Horn.acp"); assert(event=="SOUND_VEHICLE_HORN_LP"&&signals==std::vector{"HornState"}&&values==std::vector{1}); plays++;lastPosition=t[3];if(fail)return AudioHandle::Invalid;int handle=next++;sounds.insert(handle);return handle; } // Native name means playback completed, not currently audible (vanilla sound managers). static bool IsSoundPlayed(int handle){return !sounds.count(handle);} static void SetSoundTransformation(int handle,const vector* t){moved.push_back(handle);lastPosition=t[3];} static void TerminateSound(int handle){assert(handle!=AudioHandle::Invalid);ended.push_back(handle);sounds.erase(handle);} static void Reset(){plays=0;next=10;fail=false;sounds={99};ended.clear();moved.clear();lastPosition={};} }; struct ERR_VehicleAlarmPerception{inline static int emits=0;static void Emit(IEntity){emits++;}}; struct Base {int deleted=0;IEntity deletedOwner=nullptr;void OnDelete(IEntity owner){deleted++;deletedOwner=owner;}}; struct Security:Base { bool m_Breached=false,m_AlarmStarted=false,m_AlarmFinished=false,m_AlarmAudioAttempted=false; int m_AlarmState=0,m_AlarmHandle=AudioHandle::Invalid;float m_AlarmBegan=-1;ERR_GameMode* m_AlarmMode=nullptr; IEntity owner=nullptr;IEntity GetOwner(){return owner;} ''' + methods + r''' }; struct Fixture { World world;Game game;ERR_GameMode mode;Entity vehicle;Security alarm; Fixture(){ game.world=&world;currentGame=&game;ERR_GameMode::current=&mode;alarm.owner=&vehicle; Replication::server=true;Replication::bumps=0;SCR_Global::edit=false;RplSession::mode=RplMode::Client;AudioSystem::Reset();ERR_VehicleAlarmPerception::emits=0; } void start(){alarm.m_Breached=true;alarm.BeginAlarm();} void clean(){ assert(alarm.m_AlarmFinished&&!alarm.AlarmActive()&&!alarm.AlarmPlaying()&&alarm.m_AlarmHandle==AudioHandle::Invalid&&!alarm.m_AlarmMode); assert(game.queue.timers.size()==1&&game.queue.timers.count(FOREIGN_CALLBACK)); assert(mode.stopped.subscribers==std::set{FOREIGN_CALLBACK}); assert(AudioSystem::sounds.count(99)); } }; int main(){ // No direct trigger unless authority has committed the successful breach. for(int variant=0;variant<4;variant++){ Fixture f;f.alarm.m_Breached=true; if(variant==0)Replication::server=false; if(variant==1)f.alarm.m_Breached=false; if(variant==2)f.alarm.m_AlarmState=2; if(variant==3)f.alarm.m_AlarmFinished=true; f.alarm.BeginAlarm();assert(!f.alarm.m_AlarmStarted&&AudioSystem::plays==0&&Replication::bumps==0&&f.game.queue.calls==0); } { Fixture f;f.start();int handle=f.alarm.m_AlarmHandle; assert(f.alarm.AlarmActive()&&f.alarm.AlarmPlaying()&&AudioSystem::plays==1&&Replication::bumps==1&&ERR_VehicleAlarmPerception::emits==1); assert(f.game.queue.calls==2&&f.game.queue.timers[STOP_CALLBACK].delay==8000&&!f.game.queue.timers[STOP_CALLBACK].repeat); assert(f.game.queue.timers[TICK_CALLBACK].delay==100&&f.game.queue.timers[TICK_CALLBACK].repeat); assert(f.mode.stopped.inserts==1&&f.alarm.m_AlarmBegan==100); assert(AudioSystem::lastPosition.y==1&&std::abs(AudioSystem::lastPosition.z-1.2f)<0.001f); f.world.now=1099;f.vehicle.position={20,30,40};f.alarm.BeginAlarm();f.alarm.ApplyAlarm();f.alarm.AlarmTick(); assert(AudioSystem::plays==1&&AudioSystem::moved==std::vector{handle}); assert(AudioSystem::lastPosition.x==20&&AudioSystem::lastPosition.y==31&&std::abs(AudioSystem::lastPosition.z-41.2f)<0.001f); assert(f.game.queue.calls==2&&f.mode.stopped.inserts==1&&f.alarm.m_AlarmBegan==100&&Replication::bumps==1); f.world.now=8099;f.alarm.AlarmTick();assert(f.alarm.AlarmPlaying()); f.world.now=8100;f.alarm.AlarmTick();f.clean();assert(f.alarm.m_AlarmState==2&&Replication::bumps==2&&AudioSystem::ended==std::vector{handle}); f.alarm.StopAlarm();f.alarm.ApplyAlarm();f.alarm.BeginAlarm();f.alarm.AlarmTick(); assert(AudioSystem::plays==1&&AudioSystem::ended.size()==1&&Replication::bumps==2&&ERR_VehicleAlarmPerception::emits==1); } // Replicas close on authority completion, and a terminal snapshot wins even // when it arrives before active or is followed by stale active snapshots. for(bool completionFirst:{false,true}){ Fixture f;Replication::server=false; if(!completionFirst){f.alarm.m_AlarmState=1;f.alarm.ApplyAlarm();f.alarm.ApplyAlarm();assert(AudioSystem::plays==1&&f.game.queue.calls==2);} f.alarm.m_AlarmState=2;f.alarm.ApplyAlarm();f.clean(); f.alarm.m_AlarmState=1;f.alarm.ApplyAlarm();f.alarm.AlarmTick(); assert(!f.alarm.AlarmActive()&&AudioSystem::plays==(completionFirst?0:1)&&Replication::bumps==0&&ERR_VehicleAlarmPerception::emits==0); } // Replica initialization waits within the first deadline; readiness cannot // renew the deadline, and missing readiness cannot leave playback pending forever. for(int variant=0;variant<3;variant++){ Fixture f;Replication::server=false;f.mode.active=false; if(variant!=0)ERR_GameMode::current=nullptr; f.alarm.m_AlarmState=1;f.alarm.ApplyAlarm();assert(AudioSystem::plays==0&&!f.alarm.m_AlarmMode); f.world.now=4100;f.alarm.ApplyAlarm();f.alarm.AlarmTick();assert(AudioSystem::plays==0&&f.game.queue.calls==2); if(variant<2){ERR_GameMode::current=&f.mode;f.mode.active=true;f.alarm.AlarmTick();assert(AudioSystem::plays==1&&f.alarm.m_AlarmBegan==100);} f.world.now=8100;f.alarm.AlarmTick();f.clean();assert(Replication::bumps==0); } // Every live-to-invalid transition disposes only this alarm's handle. Native // client end is represented by inactive bound mode without firing OnStop. for(int variant=0;variant<10;variant++){ Fixture f;f.start();int handle=f.alarm.m_AlarmHandle;ERR_GameMode replacement; if(variant==0)f.vehicle.alive=false; if(variant==1)f.alarm.owner=nullptr; if(variant==2)f.mode.phase=2; if(variant==3){Replication::server=false;f.mode.active=false;} if(variant==4)ERR_GameMode::current=&replacement; if(variant==5)ERR_GameMode::current=nullptr; if(variant==6)f.world.now=99; if(variant==7)f.world.now=std::numeric_limits::quiet_NaN(); if(variant==8)f.game.world=nullptr; if(variant==9){Replication::server=false;f.world.now=8100;} f.alarm.AlarmTick();f.clean();assert(AudioSystem::ended==std::vector{handle}); } { Fixture f;f.start();int handle=f.alarm.m_AlarmHandle; // Native invoker calls the registered production callback. assert(f.mode.stopped.subscribers.count(STOP_CALLBACK));f.alarm.StopAlarm();f.clean(); assert(AudioSystem::ended==std::vector{handle}); } { Fixture f;f.start();int bumps=Replication::bumps;int handle=f.alarm.m_AlarmHandle; f.alarm.OnDelete(&f.vehicle);f.clean();assert(f.alarm.deleted==1&&f.alarm.deletedOwner==&f.vehicle&&Replication::bumps==bumps); assert(AudioSystem::ended==std::vector{handle});f.alarm.CloseAlarm();assert(AudioSystem::ended.size()==1); } // Engine audio load/play failure is one attempt, never a polling retry. { Fixture f;AudioSystem::fail=true;f.start();assert(AudioSystem::plays==1&&f.alarm.m_AlarmAudioAttempted&&!f.alarm.AlarmPlaying()); AudioSystem::fail=false;for(int n=0;n<5;n++){f.alarm.AlarmTick();f.alarm.ApplyAlarm();} assert(AudioSystem::plays==1&&AudioSystem::moved.empty());f.alarm.StopAlarm();f.clean();assert(AudioSystem::ended.empty()); } { Fixture f;f.start();int handle=f.alarm.m_AlarmHandle; assert(handle!=AudioHandle::Invalid&&!AudioSystem::IsSoundPlayed(handle)&&f.alarm.AlarmPlaying()); AudioSystem::sounds.erase(handle); assert(f.alarm.m_AlarmHandle==handle&&AudioSystem::IsSoundPlayed(handle)&&!f.alarm.AlarmPlaying()); f.alarm.AlarmTick();assert(AudioSystem::plays==1);f.alarm.StopAlarm();f.clean(); } { Fixture f;RplSession::mode=RplMode::Dedicated;f.start();assert(f.alarm.AlarmActive()&&!f.alarm.AlarmPlaying()&&AudioSystem::plays==0); f.alarm.AlarmTick();f.alarm.StopAlarm();f.clean();assert(AudioSystem::plays==0&&AudioSystem::ended.empty()); } for(int variant=0;variant<4;variant++){ Fixture f; if(variant==0)currentGame=nullptr; if(variant==1)f.game.world=nullptr; if(variant==2)SCR_Global::edit=true; if(variant==3)f.mode.phase=2; f.start();assert(f.alarm.m_AlarmFinished&&AudioSystem::plays==0&&f.alarm.m_AlarmState==2); currentGame=&f.game;f.clean(); } { Fixture f;f.start();currentGame=nullptr;f.alarm.AlarmTick(); assert(f.alarm.m_AlarmFinished&&AudioSystem::ended.size()==1&&f.mode.stopped.subscribers==std::set{FOREIGN_CALLBACK}); currentGame=&f.game;f.alarm.CloseAlarm();f.clean(); } } ''') print('PASS: production vehicle alarm single trigger/replica completion/no replay, fixed deadline/readiness wait, failed audio, dedicated server, moving exact handle, destruction/native end/deletion/clock and mission teardown. Native sound and multiplayer delivery require engine qualification.')