Add typed field-flight prototype and preserve native qualification failures
This commit is contained in:
@@ -3,16 +3,18 @@ import re
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/ERR_OrdinaryLookObserver.c'
|
||||
def cpp(s):
|
||||
s=s.replace('protected ', '')
|
||||
s=s.replace('protected ', '').replace('out bool held', 'bool& held')
|
||||
types=('ERR_GameMode','BaseWorld','PlayerController','IEntity','PlayerCamera','ERR_PlayerLife','PlayerManager','CameraManager')
|
||||
for typ in types:s=re.sub(r'\b'+typ+r' (\w+)',typ+r'* \1',s)
|
||||
for name in ('mode','world','controller','actor','manager','cameras','m_Mode','m_World','m_Controller','m_Actor','m_Camera','m_Life','s_Request'):
|
||||
s=s.replace(name+'.',name+'->')
|
||||
for scope in ('System','Replication','RplSession','RplMode','ERR_Phase','ERR_GameMode','ERR_Actors','ERR_OrdinaryInputObserverRules'):
|
||||
for scope in ('System','Replication','RplSession','RplMode','ERR_Phase','ERR_GameMode','ERR_Actors','ERR_OrdinaryInputObserverRules','CompartmentAccessComponent'):
|
||||
s=s.replace(scope+'.',scope+'::')
|
||||
s=s.replace('GetGame().','GetGame()->').replace('Players().','Players()->').replace('GetInputManager().','GetInputManager()->').replace('GetMenuManager().','GetMenuManager()->')
|
||||
s=s.replace('null','nullptr').replace('new ERR_OrdinaryLookObserver()', 'new ERR_OrdinaryLookObserver()')
|
||||
s=s.replace('nonce.Length()', 'int(nonce.size())').replace('allowed.Contains(nonce[i])', '(allowed.find(nonce[i]) != string::npos)')
|
||||
return s
|
||||
shared='\n'.join(cpp(body(ROOT/'addons/core/Scripts/Game/ERR/ERR_OrdinaryInputObserver.c', signature)) for signature in ('static bool Nonce(', 'static bool HeldScope(', 'static bool PhaseAllowed('))
|
||||
methods='\n'.join(cpp(body(P,signature)) for signature in (
|
||||
'protected static bool Enabled(', 'static void Sample(', 'protected void Cancel(', 'protected bool Context(', 'protected static bool FiniteVector(', 'protected void Observe('))
|
||||
run(r'''
|
||||
@@ -26,7 +28,7 @@ using string=std::string;using UUID=string;
|
||||
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 a,float b,float c){return {{a,b,c}};}
|
||||
struct BaseWorld {};
|
||||
struct IEntity {BaseWorld* world=nullptr;bool living=true;vector origin=Vector(100,2,100);vector GetOrigin(){return origin;} vector matrix[4]={Vector(1,0,0),Vector(0,1,0),Vector(0,0,1),Vector(100,2,100)};BaseWorld* GetWorld(){return world;}void GetTransform(vector out[4]){for(int i=0;i<4;i++)out[i]=matrix[i];}};
|
||||
struct IEntity {BaseWorld* world=nullptr;bool living=true,vehicle=false;vector origin=Vector(100,2,100);vector GetOrigin(){return origin;} vector matrix[4]={Vector(1,0,0),Vector(0,1,0),Vector(0,0,1),Vector(100,2,100)};BaseWorld* GetWorld(){return world;}void GetTransform(vector out[4]){for(int i=0;i<4;i++)out[i]=matrix[i];}};
|
||||
struct CameraManager;
|
||||
struct PlayerCamera:IEntity {CameraManager* replaceDuringRead=nullptr;void GetWorldCameraTransform(vector out[4]);};
|
||||
struct CameraManager {PlayerCamera* current=nullptr;PlayerCamera* CurrentCamera(){return current;}};
|
||||
@@ -35,7 +37,7 @@ struct PlayerController {int id=1;IEntity* actor=nullptr;PlayerCamera* camera=nu
|
||||
struct PlayerManager {PlayerController* controller=nullptr;IEntity* actor=nullptr;PlayerController* GetPlayerController(int){return controller;}IEntity* GetPlayerControlledEntity(int){return actor;}};
|
||||
struct ERR_PlayerLife {UUID AccountId="account";};
|
||||
struct Roster {ERR_PlayerLife* life=nullptr;IEntity* actor=nullptr;ERR_PlayerLife* CurrentActor(IEntity* value){return value==actor?life:nullptr;}};
|
||||
namespace ERR_Phase {enum {PRISON,EXTRACTION};}
|
||||
namespace ERR_Phase {enum {PRISON=1,RADIO_SEARCH=2,EXTRACTION=4};}
|
||||
struct ERR_GameMode {static ERR_GameMode* current;bool active=true;int phase=ERR_Phase::PRISON;BaseWorld* world=nullptr;Roster* roster=nullptr;static ERR_GameMode* Get(){return current;}bool Active(){return active;}int Phase(){return phase;}BaseWorld* GetWorld(){return world;}Roster* Players(){return roster;}};ERR_GameMode* ERR_GameMode::current=nullptr;
|
||||
struct InputManager {float right=0,up=0;float GetActionValue(string name){return name=="CharacterTurnRight"?right:up;}};
|
||||
struct MenuManager {bool open=false;void* GetTopMenu(){return open?this:nullptr;}};
|
||||
@@ -43,7 +45,10 @@ struct Game {BaseWorld* world=nullptr;PlayerController* controller=nullptr;Playe
|
||||
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;}}
|
||||
struct ERR_OrdinaryInputObserverRules {
|
||||
'''+shared+r'''
|
||||
};
|
||||
namespace CompartmentAccessComponent {IEntity* GetVehicleIn(IEntity* actor){return actor->vehicle?actor:nullptr;}}
|
||||
namespace ERR_Actors {bool CanFight(IEntity* actor){return actor&&actor->living;}}
|
||||
int headers=0,samples=0,cancels=0;string reason;vector lastDirection,lastCamera,lastBody,lastFacing,lastTurn;
|
||||
void PrintFormat(string,string,int,int){headers++;}
|
||||
@@ -52,7 +57,7 @@ void PrintFormat(string,string,int,int,vector direction,vector camera,vector act
|
||||
class ERR_OrdinaryLookObserver {public:
|
||||
static ERR_OrdinaryLookObserver* s_Request;static bool s_Attempted;
|
||||
ERR_GameMode* m_Mode=nullptr;BaseWorld* m_World=nullptr;PlayerController* m_Controller=nullptr;IEntity* m_Actor=nullptr;PlayerCamera* m_Camera=nullptr;ERR_PlayerLife* m_Life=nullptr;
|
||||
UUID m_Account;string m_Nonce;int m_Start=0,m_Previous=0,m_Index=0;bool m_Stopped=false;
|
||||
UUID m_Account;string m_Nonce;int m_Start=0,m_Previous=0,m_Index=0;bool m_Stopped=false,m_HeldAction=false;int m_ObservedPhase=-1;
|
||||
'''+methods+r'''
|
||||
};
|
||||
ERR_OrdinaryLookObserver* ERR_OrdinaryLookObserver::s_Request=nullptr;bool ERR_OrdinaryLookObserver::s_Attempted=false;
|
||||
@@ -61,6 +66,16 @@ struct Fixture {BaseWorld world,foreignWorld;ERR_GameMode mode;IEntity actor,oth
|
||||
void sample(int index=1,int now=1100){ERR_OrdinaryLookObserver::Sample(&mode,&world,&controller,&actor,"Run42",1000,index,now);}
|
||||
};
|
||||
int main(){
|
||||
|
||||
// Held mode changes only admissible phase, never the original pins or clock.
|
||||
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();auto p=ERR_OrdinaryLookObserver::s_Request;assert(p&&p->m_HeldAction&&p->m_ObservedPhase==ERR_Phase::PRISON);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,1200);f.sample(3,1300);assert(samples==3&&!cancels&&p->m_Start==1000&&p->m_ObservedPhase==ERR_Phase::RADIO_SEARCH);f.mode.phase=ERR_Phase::PRISON;f.sample(4,1400);assert(samples==3&&cancels==1);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(5,1500);assert(samples==3&&cancels==1);}
|
||||
for(int fault=0;fault<5;fault++){Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; if(fault==0)System::cli["errOrdinaryHeldAction"]="foreign";if(fault==1)System::cli.erase("errOrdinaryGateObserve");if(fault==2)System::cli["errOrdinaryGateObserve"]="foreign";if(fault==3)f.mode.phase=ERR_Phase::RADIO_SEARCH;if(fault==4)System::cli["errOrdinaryHeldAction"]="";f.sample();assert(!samples);f.mode.phase=ERR_Phase::PRISON;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample(2,1200);assert(!samples);}
|
||||
for(int fault=0;fault<8;fault++){Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,1200);assert(samples==2&&!cancels);if(fault==0)System::cli.erase("errOrdinaryHeldAction");if(fault==1)System::cli["errOrdinaryGateObserve"]="foreign";if(fault==2)f.actor.vehicle=true;if(fault==3)f.menus.open=true;if(fault==4)f.life.AccountId="replacement";if(fault==5)f.mode.phase=ERR_Phase::EXTRACTION;if(fault==6)f.players.actor=nullptr;if(fault==7)game.world=nullptr;f.sample(3,1300);assert(samples==2&&cancels==1);}
|
||||
{Fixture f;f.sample();System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample(2,1200);assert(samples==1&&cancels==1);}
|
||||
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,45999);assert(samples==2);f.sample(3,46000);assert(samples==2&&cancels==1);}
|
||||
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(451,1200);assert(samples==1&&cancels==1);}
|
||||
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.controller.camera=&f.otherCamera;f.sample(2,1200);assert(samples==1&&cancels==1);}
|
||||
{Fixture f;f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,1200);assert(samples==1&&cancels==1);}
|
||||
{Fixture f;f.sample();assert(headers==1&&samples==1&&!cancels);assert(lastDirection[0]==1&&lastDirection[2]==0);assert(lastFacing[2]==1);assert(lastCamera[1]!=lastBody[1]);assert(lastTurn[0]==.25f&&lastTurn[1]==-.1f);f.sample(2,1200);assert(headers==1&&samples==2);}
|
||||
{Fixture f;f.actor.origin=Vector(100.04,1.999,99.97);f.actor.matrix[3]=Vector(100,2,100);f.actor.matrix[2]=Vector(0,0,-1);f.sample();assert(samples==1&&!cancels);assert(lastBody[0]==f.actor.origin[0]&&lastBody[1]==f.actor.origin[1]&&lastBody[2]==f.actor.origin[2]);assert(lastBody[0]!=f.actor.matrix[3][0]);assert(lastFacing[2]==-1);assert(lastCamera[1]==f.camera.matrix[3][1]&&lastDirection[0]==1);}
|
||||
for(int fault=0;fault<7;fault++){Fixture f;if(fault==0)System::cli.erase("errOrdinaryLookObserve");if(fault==1)System::cli["errOrdinaryLookObserve"]="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";f.sample();assert(!samples&&!headers&&!cancels&&!ERR_OrdinaryLookObserver::s_Attempted);}
|
||||
|
||||
Reference in New Issue
Block a user