Observe native prison lock geometry and requalify Core loops

This commit is contained in:
2026-09-19 18:58:12 +02:00
parent e10b8799e9
commit b7fba094d7
39 changed files with 9884 additions and 12 deletions
+99
View File
@@ -0,0 +1,99 @@
"""Execute actual gate observer bodies; fake only native boundaries, no engine claim."""
import re
from policy_harness import ROOT, body, run
P=ROOT/'addons/core/Scripts/Game/ERR/ERR_OrdinaryGateObserver.c'
def cpp(s):
s=s.replace('protected ', '').replace('out float ', 'float& ').replace('out bool ', 'bool& ')
types=('ERR_GameMode','BaseWorld','PlayerController','IEntity','ERR_PlayerLife','PlayerManager','BaseUserAction','ERR_UnlockPrisonAction','UserActionContext')
for typ in types:s=re.sub(r'\b'+typ+r' (\w+)',typ+r'* \1',s)
s=s.replace('array<BaseUserAction>', 'Array<BaseUserAction*>').replace('array<bool>', 'Array<bool>')
s=s.replace('foreach (BaseUserAction* action : actions)', 'for (BaseUserAction* action : actions)')
s=s.replace('int matches;', 'int matches=0;')
for typ in ('BaseActionsManagerComponent','BaseDoorComponent','SCR_InteractionHandlerComponent'):
s=s.replace('FindComponent('+typ+')', 'FindComponent('+typ+'Key)')
s=s.replace(typ+'.Cast(', 'static_cast<'+typ+'*>(')
s=s.replace('ERR_UnlockPrisonAction.Cast(', 'dynamic_cast<ERR_UnlockPrisonAction*>(')
for name in ('mode','world','controller','actor','players','action','candidate','expected','context','m_Mode','m_World','m_Controller','m_Actor','m_Life','m_Gate','m_Manager','m_Lock','m_Context','m_Door','m_Handler','s_Request'):
s=s.replace(name+'.',name+'->')
for scope in ('System','Replication','RplSession','RplMode','ERR_Phase','ERR_GameMode','ERR_Actors','ERR_OrdinaryInputObserverRules','CompartmentAccessComponent'):
s=s.replace(scope+'.',scope+'::')
for getter in ('GetGame','Players','PrisonEscape','GetInputManager','GetMenuManager'):
s=s.replace(getter+'().',getter+'()->')
return s.replace('null','nullptr').replace('string.Format(', 'Format(')
accessor=cpp(body(P,'bool ERR_GateReadProgress('))
methods='\n'.join(cpp(body(P,s)) for s in ('protected static bool Enabled(', 'static void Sample(', 'protected bool BindGate(', 'protected bool Context(', 'protected void Cancel(', 'protected bool CachedPermission(', 'protected static bool FiniteVector(', 'protected void Observe('))
run(r'''
#include <cassert>
#include <cmath>
#include <limits>
#include <map>
#include <string>
#include <vector>
using string=std::string;using UUID=string;
template<class T> struct Array:std::vector<T> {using std::vector<T>::vector;int Count(){return this->size();}};
struct vector {float v[3]={0,0,0};float& operator[](int i){return v[i];}float Length(){return std::sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);}vector operator/(float n){return {{v[0]/n,v[1]/n,v[2]/n}};}};
vector Vector(float x,float y,float z){return {{x,y,z}};}
enum {BaseActionsManagerComponentKey,BaseDoorComponentKey,SCR_InteractionHandlerComponentKey};
struct BaseWorld{};
struct IEntity {BaseWorld* world=nullptr;bool living=true,vehicle=false;void* components[3]={};vector origin=Vector(6090,210,7158);BaseWorld* GetWorld(){return world;}void* FindComponent(int key){return components[key];}vector forward=Vector(0,0,1.5);vector GetOrigin(){return origin;}void GetTransform(vector out[4]){out[2]=forward;out[3]=origin;}};
struct BaseUserAction {virtual ~BaseUserAction()=default;IEntity* owner=nullptr;int id=4;float duration=4;IEntity* GetOwner(){return owner;}int GetActionID(){return id;}float GetActionDuration(){return duration;}};
struct ERR_UnlockPrisonAction:BaseUserAction{};
struct UserActionContext {Array<BaseUserAction*> actions;vector origin=Vector(6092,212,7154);float radius=2;void GetActionsList(Array<BaseUserAction*>& out){out=actions;}vector GetOrigin(){return origin;}float GetRadius(){return radius;}};
struct BaseActionsManagerComponent {UserActionContext* context=nullptr;BaseUserAction* action=nullptr;UserActionContext* GetContext(string){return context;}BaseUserAction* FindAction(int id){return action&&action->id==id?action:nullptr;}};
struct BaseDoorComponent {float state=0,control=0;float GetNormalizedDoorState(){return state;}float GetControlValue(){return control;}};
struct SCR_InteractionHandlerComponent {BaseUserAction* selected=nullptr;UserActionContext* current=nullptr;BaseUserAction* m_pLastUserAction=nullptr;UserActionContext* m_pLastContext=nullptr;float m_fCurrentProgress=0;bool m_bIsPerforming=false;IEntity* actor=nullptr;Array<BaseUserAction*> filtered;Array<bool> permitted;
BaseUserAction* GetSelectedAction(){return selected;}UserActionContext* GetCurrentContext(){return current;}IEntity* GetControlledEntity(){return actor;}void GetFilteredActions(Array<BaseUserAction*>& actions,Array<bool>& allowed){actions=filtered;allowed=permitted;}
'''+accessor+r'''
};
struct PlayerController:IEntity {int id=1;IEntity* actor=nullptr;int GetPlayerId(){return id;}IEntity* GetControlledEntity(){return actor;}};
struct PlayerManager {PlayerController* controller=nullptr;IEntity* actor=nullptr;PlayerController* GetPlayerController(int){return controller;}IEntity* GetPlayerControlledEntity(int){return actor;}};
struct ERR_PlayerLife {UUID AccountId="original-account";};
struct Roster {ERR_PlayerLife* life=nullptr;IEntity* actor=nullptr;ERR_PlayerLife* CurrentActor(IEntity* value){return value==actor?life:nullptr;}};
struct Prison {IEntity* gate=nullptr;bool registered=true,lost=false;bool Registered(){return registered;}bool GateLost(){return lost;}IEntity* Gate(){return gate;}};
namespace ERR_Phase {enum {PRISON,RADIO_SEARCH,EXTRACTION};}
struct ERR_GameMode {static ERR_GameMode* current;bool active=true;int phase=ERR_Phase::PRISON;BaseWorld* world=nullptr;Roster* roster=nullptr;Prison* prison=nullptr;static ERR_GameMode* Get(){return current;}bool Active(){return active;}int Phase(){return phase;}BaseWorld* GetWorld(){return world;}Roster* Players(){return roster;}Prison* PrisonEscape(){return prison;}vector prisonPosition=Vector(6090,210,7160);vector PrisonPosition(){return prisonPosition;}};ERR_GameMode* ERR_GameMode::current=nullptr;
struct InputManager {float pressed=0;ERR_GameMode* changeDuringRead=nullptr;float GetActionValue(string name){assert(name=="PerformAction");if(changeDuringRead)changeDuringRead->active=false;return pressed;}};
struct MenuManager {bool open=false;void* GetTopMenu(){return open?this:nullptr;}};
struct Game {BaseWorld* world=nullptr;PlayerController* controller=nullptr;PlayerManager* players=nullptr;InputManager* input=nullptr;MenuManager* menus=nullptr;BaseWorld* GetWorld(){return world;}PlayerController* GetPlayerController(){return controller;}PlayerManager* GetPlayerManager(){return players;}InputManager* GetInputManager(){return input;}MenuManager* GetMenuManager(){return menus;}} game;Game* activeGame=&game;Game* GetGame(){return activeGame;}
namespace System {bool console=false;std::map<string,string> cli;bool IsConsoleApp(){return console;}bool GetCLIParam(string key,string& value){if(!cli.count(key))return false;value=cli[key];return true;}}
namespace Replication {bool server=true;bool IsServer(){return server;}}
namespace RplMode {enum {None,Listen,Dedicated};}namespace RplSession {int mode=RplMode::None;int Mode(){return mode;}}
namespace ERR_OrdinaryInputObserverRules {bool Nonce(string n){return !n.empty()&&n.size()<=32&&n.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")==string::npos;}}
namespace ERR_Actors {bool CanFight(IEntity* actor){return actor&&actor->living;}}
namespace CompartmentAccessComponent {IEntity* GetVehicleIn(IEntity* actor){return actor->vehicle?actor:nullptr;}}
int headers=0,samples=0,geometries=0,cancels=0;string reason;bool lastSelected=false,lastContext=false,lastPermitted=false,lastBound=false,lastPerforming=false;float lastProgress=0;int lastPhase=0;
string Format(string,int phase,bool selected,bool context,bool permitted,bool bound,bool performing,float progress,float duration,float pressed){assert(duration==4);lastPhase=phase;lastSelected=selected;lastContext=context;lastPermitted=permitted;lastBound=bound;lastPerforming=performing;lastProgress=progress;return "SAMPLE";}
vector lastPrison,lastGate,lastForward;
string Format(string,vector,vector,float,float,float,vector prison,vector gate,vector forward){lastPrison=prison;lastGate=gate;lastForward=forward;return "GEOMETRY";}
void PrintFormat(string,string,int,int){headers++;}
void PrintFormat(string format,string,int,int,string value){if(format.find("CANCELLED")!=string::npos){cancels++;reason=value;}else if(value=="SAMPLE")samples++;else if(value=="GEOMETRY")geometries++;else assert(false);}
class ERR_OrdinaryGateObserver {public:
static ERR_OrdinaryGateObserver* s_Request;static bool s_Attempted;
ERR_GameMode* m_Mode=nullptr;BaseWorld* m_World=nullptr;PlayerController* m_Controller=nullptr;IEntity* m_Actor=nullptr;ERR_PlayerLife* m_Life=nullptr;UUID m_Account;IEntity* m_Gate=nullptr;BaseActionsManagerComponent* m_Manager=nullptr;ERR_UnlockPrisonAction* m_Lock=nullptr;UserActionContext* m_Context=nullptr;BaseDoorComponent* m_Door=nullptr;SCR_InteractionHandlerComponent* m_Handler=nullptr;
string m_Nonce;int m_Start=0,m_Previous=0,m_Index=0;bool m_Stopped=false;
'''+methods+r'''
};
ERR_OrdinaryGateObserver* ERR_OrdinaryGateObserver::s_Request=nullptr;bool ERR_OrdinaryGateObserver::s_Attempted=false;
struct Fixture {BaseWorld world,otherWorld;ERR_GameMode mode;IEntity actor,otherActor,gate,otherGate;PlayerController controller,otherController;PlayerManager players;Roster roster;ERR_PlayerLife life,otherLife;Prison prison;InputManager input;MenuManager menus;BaseActionsManagerComponent manager,otherManager;BaseDoorComponent door,otherDoor;UserActionContext context,otherContext;SCR_InteractionHandlerComponent handler,otherHandler;ERR_UnlockPrisonAction lock,otherLock;BaseUserAction foreignAction;
Fixture(){delete ERR_OrdinaryGateObserver::s_Request;ERR_OrdinaryGateObserver::s_Request=nullptr;ERR_OrdinaryGateObserver::s_Attempted=false;headers=samples=geometries=cancels=0;reason="";System::console=false;System::cli={{"errOrdinaryScenario","core"},{"errOrdinaryInputObserve","Run42"},{"errOrdinaryGateObserve","Run42"}};Replication::server=true;RplSession::mode=RplMode::None;activeGame=&game;ERR_GameMode::current=&mode;mode.world=&world;mode.roster=&roster;mode.prison=&prison;actor.world=gate.world=&world;controller.actor=&actor;controller.components[SCR_InteractionHandlerComponentKey]=&handler;players.controller=&controller;players.actor=&actor;roster.actor=&actor;roster.life=&life;prison.gate=&gate;gate.components[BaseActionsManagerComponentKey]=&manager;gate.components[BaseDoorComponentKey]=&door;manager.context=&context;manager.action=&lock;lock.owner=&gate;context.actions={&lock};handler.actor=&actor;handler.selected=handler.m_pLastUserAction=&lock;handler.current=handler.m_pLastContext=&context;handler.filtered={&lock};handler.permitted={true};game={&world,&controller,&players,&input,&menus};}
void sample(int index=1,int now=1100){ERR_OrdinaryGateObserver::Sample(&mode,&world,&controller,&actor,"Run42",1000,index,now);}
};
int main(){
{Fixture f;f.handler.m_bIsPerforming=true;f.handler.m_fCurrentProgress=2.25;f.input.pressed=1;f.sample();assert(headers==1&&samples==1&&geometries==1&&!cancels);assert(lastSelected&&lastContext&&lastPermitted&&lastBound&&lastPerforming&&lastProgress==2.25f);assert(lastPrison[2]==7160&&lastGate[2]==7158&&lastForward[2]==1);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.handler.m_bIsPerforming=false;f.handler.m_fCurrentProgress=0;f.door.control=1;f.sample(2,1200);assert(samples==2&&headers==1&&!cancels&&lastPhase==ERR_Phase::RADIO_SEARCH);}
// Actual accessor never attributes accumulated progress from another selection/context.
for(int fault=0;fault<5;fault++){Fixture f;f.handler.m_bIsPerforming=true;f.handler.m_fCurrentProgress=3;BaseUserAction* expected=&f.lock;UserActionContext* ctx=&f.context;if(fault==0)expected=nullptr;if(fault==1)f.handler.selected=&f.foreignAction;if(fault==2)f.handler.current=&f.otherContext;if(fault==3)f.handler.m_pLastUserAction=&f.foreignAction;if(fault==4)f.handler.m_pLastContext=&f.otherContext;float progress=99;bool performing=true;assert(!f.handler.ERR_GateReadProgress(expected,ctx,progress,performing));assert(progress==0&&!performing);}
{Fixture f;f.handler.selected=&f.foreignAction;f.handler.m_fCurrentProgress=3;f.handler.m_bIsPerforming=true;f.sample();assert(samples==1&&!lastSelected&&!lastBound&&!lastPerforming&&lastProgress==0);}
// Cached flags cannot become positive via a missing/mismatched native array.
for(int fault=0;fault<4;fault++){Fixture f;if(fault==0)f.handler.filtered.clear();if(fault==1)f.handler.permitted.clear();if(fault==2)f.handler.filtered={&f.foreignAction};if(fault==3)f.handler.permitted={false};f.sample();assert(samples==1&&!lastPermitted);}
for(int fault=0;fault<8;fault++){Fixture f;if(fault==0)System::cli.erase("errOrdinaryGateObserve");if(fault==1)System::cli["errOrdinaryGateObserve"]="foreign";if(fault==2)System::cli["errOrdinaryInputObserve"]="foreign";if(fault==3)System::console=true;if(fault==4)Replication::server=false;if(fault==5)RplSession::mode=RplMode::Listen;if(fault==6)System::cli["errOrdinaryScenario"]="other";if(fault==7)RplSession::mode=RplMode::Dedicated;f.sample();assert(!samples&&!cancels&&!ERR_OrdinaryGateObserver::s_Attempted);}
// Registration cannot recover after initial absent/ambiguous/native-mismatched gate.
for(int fault=0;fault<8;fault++){Fixture f;if(fault==0)f.prison.registered=false;if(fault==1)f.prison.lost=true;if(fault==2)f.prison.gate=nullptr;if(fault==3)f.context.actions.clear();if(fault==4){f.otherLock.owner=&f.gate;f.context.actions.push_back(&f.otherLock);}if(fault==5)f.lock.owner=&f.otherGate;if(fault==6)f.lock.duration=3;if(fault==7)f.manager.action=&f.foreignAction;f.sample();assert(!samples&&cancels==1&&reason=="original-prison-lock-unavailable");f.prison.registered=true;f.prison.lost=false;f.prison.gate=&f.gate;f.context.actions={&f.lock};f.lock.owner=&f.gate;f.lock.duration=4;f.manager.action=&f.lock;f.sample(2,1200);assert(!samples&&cancels==1);}
for(int fault=0;fault<26;fault++){Fixture f;f.sample();if(fault==0)game.controller=&f.otherController;if(fault==1)f.controller.actor=&f.otherActor;if(fault==2)f.handler.actor=&f.otherActor;if(fault==3)f.players.actor=&f.otherActor;if(fault==4)f.players.controller=&f.otherController;if(fault==5)f.life.AccountId="replacement";if(fault==6)f.roster.life=&f.otherLife;if(fault==7)f.actor.world=&f.otherWorld;if(fault==8)f.gate.world=&f.otherWorld;if(fault==9)f.mode.active=false;if(fault==10)f.mode.phase=ERR_Phase::EXTRACTION;if(fault==11)f.actor.living=false;if(fault==12)f.actor.vehicle=true;if(fault==13)activeGame=nullptr;if(fault==14)f.menus.open=true;if(fault==15)f.prison.registered=false;if(fault==16)f.prison.gate=&f.otherGate;if(fault==17)f.prison.lost=true;if(fault==18)f.gate.components[BaseActionsManagerComponentKey]=&f.otherManager;if(fault==19)f.gate.components[BaseDoorComponentKey]=&f.otherDoor;if(fault==20)f.controller.components[SCR_InteractionHandlerComponentKey]=&f.otherHandler;if(fault==21)f.manager.context=&f.otherContext;if(fault==22)f.manager.action=&f.otherLock;if(fault==23)f.lock.owner=&f.otherGate;if(fault==24)f.lock.duration=5;if(fault==25)f.controller.id=0;f.sample(2,1200);assert(samples==1&&cancels==1&&reason=="native-player-or-prison-context-lost");f.sample(3,1300);assert(cancels==1);}
{Fixture f;f.input.changeDuringRead=&f.mode;f.sample();assert(!samples&&!headers&&cancels==1);}
for(int fault=0;fault<5;fault++){Fixture f;f.sample();int index=2,now=1200;if(fault==0)index=1;if(fault==1)index=3;if(fault==2)index=451;if(fault==3)now=1099;if(fault==4)now=46000;f.sample(index,now);assert(samples==1&&cancels==1&&reason=="sample-or-clock-bound");}
for(int fault=0;fault<9;fault++){Fixture f;if(fault==0)f.input.pressed=std::numeric_limits<float>::quiet_NaN();if(fault==1)f.handler.m_fCurrentProgress=-1;if(fault==2)f.door.state=2;if(fault==3)f.door.control=std::numeric_limits<float>::infinity();if(fault==4)f.context.radius=0;if(fault==5)f.actor.origin[0]=std::numeric_limits<float>::infinity();if(fault==6)f.mode.prisonPosition[1]=std::numeric_limits<float>::quiet_NaN();if(fault==7)f.gate.origin[0]=std::numeric_limits<float>::infinity();if(fault==8)f.gate.forward=Vector(0,0,0);f.sample();assert(!samples&&cancels==1&&reason=="invalid-native-action-sample");}
{Fixture f;System::cli["errOrdinaryScenario"]="chat";f.sample();System::cli.erase("errOrdinaryGateObserve");f.sample(2,1200);assert(cancels==1);System::cli["errOrdinaryGateObserve"]="Run42";f.sample(3,1300);assert(samples==1&&cancels==1);}
{Fixture f;f.sample();ERR_OrdinaryGateObserver::Sample(&f.mode,&f.otherWorld,&f.controller,&f.actor,"Run42",1000,2,1200);assert(cancels==1&&reason=="original-binding-changed");}
}
''')
print('PASS: actual gate observer binds native registered action/context and current life, reads accumulated progress, refuses stale bindings and never revives outside original bounds')