"""Actual admission seed and one-time issuance methods; native boundaries are controlled doubles.""" import os,re from pathlib import Path from policy_harness import ROOT,body,run R=Path(os.environ.get('ERR_MOUNTED_STOCK_ROOT',ROOT));D=R/'addons/core/Scripts/Game/ERR/10_AI' seed=(D/'ERR_MountedMagazineSeed.c').read_text() assert 'GetDefaultMagazineOrProjectileName' not in seed and 'IsUsed(' not in seed for forbidden in ('TrySpawn','SetAmmoCount','DeleteEntity','GetChildren','GetSibling'):assert forbidden not in seed s=re.sub(r'//[^\n]*','',seed).replace('protected ','').replace('ref ','').replace('class ERR_MountedMagazineSeed : ERR_HQMountedAmmoSampler','struct ERR_MountedMagazineSeed : ERR_HQMountedAmmoSampler') for old,new in { 'InventoryItemComponent.Cast(gun.FindComponent(InventoryItemComponent))':'gun->item', 'InventoryItemComponent.Cast(loaded.FindComponent(InventoryItemComponent))':'loaded->item', 'InventoryItemComponent.Cast(weapon.GetOwner().FindComponent(InventoryItemComponent))':'weapon->GetOwner()->item', 'WeaponSlotComponent.Cast(weaponSlot.GetParentContainer())':'dynamic_cast(weaponSlot->GetParentContainer())', }.items():s=s.replace(old,new) s=s.replace('array seeds','Array& seeds').replace('array<','Array<').replace('foreach (','for (') s=re.sub(r'\bERR_MountedMagazineSeed (seed)\b',r'ERR_MountedMagazineSeed* \1',s) s=s.replace('ERR_HQMountedAmmoSnapshot shape','ERR_HQMountedAmmoSnapshot* shape').replace('ERR_ConvoyRules.','ERR_ConvoyRules::').replace('EMuzzleType.','EMuzzleType::') for obj in ['m_Weapon','m_Mount','m_WeaponSlot','m_Muzzle','m_Magazine','m_MagazineSlot','gun','loaded','gunItem','magazineItem','storage','shape','weapon','weaponSlot','mount','muzzle','magazine','item','seed']: s=re.sub(r'\b'+obj+r'\.',obj+'->',s) for call in ['GetPrefabData()','GetMagazineWell()','GetOwner()']:s=s.replace(call+'.',call+'->') s=s.replace('!seeds || ','') # native array parameter reference is non-null in C++ fixture s=re.sub(r'\b(IEntity|BaseWeaponComponent|WeaponSlotComponent|InventoryStorageSlot|BaseMuzzleComponent|BaseMagazineComponent|int) (\w+);',r'\1 \2{};',s).replace('\n}\n','\n};\n') common=r''' #include #include #include #include struct string:std::string{using std::string::string;string(std::string s):std::string(s){}bool IsEmpty(){return empty();}};using ResourceName=string; templatestruct Array:std::vector{using std::vector::vector;int Count(){return this->size();}void Insert(T t){this->push_back(t);}bool Contains(T t){return std::find(this->begin(),this->end(),t)!=this->end();}}; struct Entity;struct Weapon;struct Muzzle;struct Magazine;struct Slot; using IEntity=Entity*;using BaseWeaponComponent=Weapon*;using BaseMuzzleComponent=Muzzle*;using BaseMagazineComponent=Magazine*; struct Well{int type=1;int Type(){return type;}bool IsInherited(int other){return type==other;}}; struct Prefab{string name="AP-box";string GetPrefabName(){return name;}}; struct Item{Slot* slot=nullptr;Slot* GetParentSlot(){return slot;}};using InventoryItemComponent=Item*; struct Entity{Entity* parent=nullptr;Item* item=nullptr;Prefab* prefab=nullptr;Arrayallowed;Array weapons;bool complete=true;Prefab* GetPrefabData(){return prefab;}}; struct Container{IEntity owner=nullptr;virtual ~Container(){}IEntity GetOwner(){return owner;}}; struct Storage:Container{};using BaseInventoryStorageComponent=Storage*; struct Slot{Container* parent=nullptr;Storage* storage=nullptr;IEntity attached=nullptr;Container* GetParentContainer(){return parent;}IEntity GetAttachedEntity(){return attached;}Storage* GetStorage(){return storage;}};using InventoryStorageSlot=Slot*; struct Magazine:Container{Well* well=nullptr;int capacity=100,rounds=99;Well* GetMagazineWell(){return well;}int GetMaxAmmoCount(){return capacity;}int GetAmmoCount(){return rounds;}}; struct Muzzle:Container{Magazine* magazine=nullptr;Well* well=nullptr;int kind=0;Magazine* GetMagazine(){return magazine;}Well* GetMagazineWell(){return well;}int GetMuzzleType(){return kind;}}; struct Weapon:Container{Array muzzles;void GetMuzzlesList(Array& out){out=muzzles;}}; struct Mount:Container{Slot* slot=nullptr;IEntity gun=nullptr;Slot* GetSlotInfo(){return slot;}IEntity GetWeaponEntity(){return gun;}};using WeaponSlotComponent=Mount*; struct EMuzzleType{static const int MT_BaseMuzzle=0;}; struct ERR_ConvoyRules{static bool PartOf(IEntity a,IEntity root){for(int n=0;a&&n<32;n++,a=a->parent)if(a==root)return true;return false;}}; struct ERR_HQMountedAmmoSnapshot{bool Complete=false;}; struct ERR_HQMountedAmmoSampler{static void Collect(IEntity root,ERR_HQMountedAmmoSnapshot* result,Array& allowed,Array& weapons){result->Complete=root->complete;allowed=root->allowed;weapons=root->weapons;}}; ''' run(common+s+r''' struct Rig{Entity root,gun,loaded;Item gunItem,magItem;Prefab prefab;Slot gunSlot,magSlot;Mount mount;Storage storage;Weapon weapon;Muzzle muzzle;Magazine magazine;Well well; Rig(){gun.parent=&root;loaded.parent=&gun;gun.item=&gunItem;loaded.item=&magItem;loaded.prefab=&prefab; gunItem.slot=&gunSlot;magItem.slot=&magSlot;gunSlot.parent=&mount;gunSlot.attached=&gun;magSlot.parent=&muzzle;magSlot.attached=&loaded;magSlot.storage=&storage;storage.owner=&gun; mount.owner=&root;mount.slot=&gunSlot;mount.gun=&gun;weapon.owner=&gun;weapon.muzzles={&muzzle,&muzzle};muzzle.owner=&gun;muzzle.magazine=&magazine;muzzle.well=&well; magazine.owner=&loaded;magazine.well=&well;root.allowed={&root,&gun,&loaded};root.weapons={&weapon,&weapon};} }; int main(){ {Rig r;Array seeds;ERR_MountedMagazineSeed::Capture(&r.root,0,seeds);assert(seeds.Count()==1&&seeds[0]->Current()&&seeds[0]->Prefab=="AP-box"); assert(seeds[0]->Root==&r.root&&seeds[0]->VehicleIndex==0);r.magazine.rounds=0;assert(seeds[0]->Current()); Magazine replacement=r.magazine;r.muzzle.magazine=&replacement;assert(!seeds[0]->Current());r.muzzle.magazine=&r.magazine; r.prefab.name="replacement-box";assert(!seeds[0]->Current());} for(int fault=0;fault<16;fault++){Rig r;Entity other;Slot replacement;Well wrong;wrong.type=2; if(fault==0)r.root.complete=false; if(fault==1)r.root.allowed={&r.root,&r.gun}; if(fault==2)r.muzzle.magazine=nullptr; if(fault==3)r.loaded.prefab=nullptr; if(fault==4)r.prefab.name=""; if(fault==5)r.muzzle.kind=1; if(fault==6)r.magazine.well=nullptr; if(fault==7)r.magazine.well=&wrong; if(fault==8)r.magazine.capacity=0; if(fault==9)r.magazine.rounds=101; if(fault==10)r.storage.owner=&other; if(fault==11)r.magItem.slot=&replacement; if(fault==12)r.mount.gun=&other; if(fault==13)r.gunSlot.attached=&other; if(fault==14)r.weapon.muzzles.resize(9,&r.muzzle); if(fault==15)r.magazine.rounds=-1; Array seeds;ERR_MountedMagazineSeed::Capture(&r.root,0,seeds);assert(seeds.Count()==0);} {Rig r;Array seeds;ERR_MountedMagazineSeed::Capture(&r.root,6,seeds);assert(seeds.Count()==0);seeds.resize(48,nullptr);ERR_MountedMagazineSeed::Capture(&r.root,0,seeds);assert(seeds.Count()==48);} {Rig a,b;Array seeds;ERR_MountedMagazineSeed::Capture(&a.root,0,seeds);ERR_MountedMagazineSeed::Capture(&b.root,3,seeds);assert(seeds.Count()==2);} } ''') print('PASS: actual admission seeds use exact installed loaded prefab, reject replacement/foreign/projectile paths and preserve bounded immutable identity') service=D/'ERR_SupplyConvoyService.c' raw=service.read_text() assert raw.index('CaptureMountedStock(supply)') < raw.index('for (int i = 0; i < 8; i++)') assert raw.index('task.MagazinesIssued = true;',raw.index('protected void IssueMagazines')) < raw.index('IssueMountedStock(task, inventory, issued,') assert 'ref array MountedStock' in (D/'ERR_SupplyConvoyTactics.c').read_text() code='\n'.join(body(service,x) for x in ['protected bool MountedStockOwner(', 'protected void CaptureMountedStock(', 'protected int IssueMountedStock(', 'protected void IssueMagazines(']) code=re.sub(r'//[^\n]*','',code).replace('protected ','').replace('null','nullptr').replace('foreach (','for (').replace('array<','Array<') for old,new in { 'ERR_HQ.Cast(m_Mode.Command())':'m_Mode->Command()', 'InventoryStorageManagerComponent.Cast(task.Vehicles[1].Entity.FindComponent(InventoryStorageManagerComponent))':'task->Vehicles[1]->Entity->inventory', 'BaseWeaponComponent.Cast(item.FindComponent(BaseWeaponComponent))':'item->weapon', 'existing.FindComponent(BaseMagazineComponent)':'existing->magazine', }.items():code=code.replace(old,new) for typ in ['ERR_SupplyConvoyTask','ERR_HQ','ERR_ConvoyVehicle','ERR_ForceRecord','InventoryStorageManagerComponent','ERR_MountedMagazineSeed','ERR_ConvoyCargoCallback','BaseWeaponComponent','BaseMuzzleComponent']: code=re.sub(r'\b'+typ+r' (?=\w)',typ+'* ',code) code=code.replace('Array', 'Array') for name in ['m_Mode','task','vehicle','hq','record','inventory','seed','load','operation','item','weaponOperation','weapon','muzzle']: code=re.sub(r'\b'+name+r'\.',name+'->',code) for call in ['Forces()','GetPrefabData()']:code=code.replace(call+'.',call+'->') code=code.replace('->Receipt.','->Receipt->').replace('Vehicles[index].','Vehicles[index]->').replace('Vehicles[1].','Vehicles[1]->').replace('Vehicles[seed->VehicleIndex].','Vehicles[seed->VehicleIndex]->') for ns in ['ERR_MountedMagazineSeed','ERR_Inventory','EStoragePurpose','ERR_HQ','string']:code=code.replace(ns+'.',ns+'::') code=code.replace('int existingMagazines;', 'int existingMagazines=0;').replace('int issued;', 'int issued=0;') run(r''' #include #include #include #include struct string:std::string{using std::string::string;string(std::string s):std::string(s){}bool IsEmpty(){return empty();}templatestatic string Format(T...){return "event";}};using ResourceName=string; templatestruct Array:std::vector{using std::vector::vector;int Count(){return this->size();}void Insert(T t){this->push_back(t);}void Clear(){this->clear();}bool Contains(T t){return std::find(this->begin(),this->end(),t)!=this->end();}int Find(T t){auto f=std::find(this->begin(),this->end(),t);return f==this->end()?-1:f-this->begin();}void Remove(int i){this->erase(this->begin()+i);}}; struct Entity;using IEntity=Entity*;struct InventoryStorageManagerComponent;struct BaseWeaponComponent; struct Prefab{string name;string GetPrefabName(){return name;}}; struct Entity{InventoryStorageManagerComponent* inventory=nullptr;BaseWeaponComponent* weapon=nullptr;bool magazine=false;Prefab prefab;Prefab* GetPrefabData(){return &prefab;}}; struct BaseMuzzleComponent{string resource="rifle-mag";string GetDefaultMagazineOrProjectileName(){return resource;}}; struct BaseWeaponComponent{Array muzzles;void GetMuzzlesList(Array& out){out=muzzles;}}; struct Group{int id=0;IEntity bound=nullptr;bool valid=true;}; struct ERR_ForceRecord{int Id=0;};struct Ledger{Arrayrecords;ERR_ForceRecord* FindGroup(Group* g){return g&&g->idid]:nullptr;}}; struct ERR_HQ{static void Event(string,string){}bool ValidateBoundVehicle(Group* g,IEntity e){return g&&g->valid&&g->bound==e;}}; struct Mode{Ledger ledger;ERR_HQ hq;Ledger* Forces(){return &ledger;}ERR_HQ* Command(){return &hq;}}; struct ERR_ConvoyVehicle{int Index=0;bool Registered=true,Released=false,crew=true;IEntity Entity=nullptr;struct Group* Group=nullptr;bool CrewValid(Mode*){return crew;}}; struct Receipt{bool Consumed=true;ArrayRecords={0,1,2,3,4,5};string SourceId="convoy";}; struct ERR_ConvoyCargoCallback{string Prefab;bool Finished=true,Succeeded=true;}; struct ERR_MountedMagazineSeed{IEntity Root=nullptr;int VehicleIndex=0;string Prefab="PKM-box";bool valid=true;bool Current(){return valid;}static inline int captures=0;static void Capture(IEntity,int,Array&){captures++;}}; struct ERR_SupplyConvoyTask{bool Ready=true,Stopped=false,MagazinesIssued=false,CargoIssued=true;float Deadline=100;struct Receipt receipt;struct Receipt* Receipt=&receipt;ArrayVehicles;ArrayCargo;ArrayMountedStock;ArrayCargoBefore;}; struct EStoragePurpose{static const int PURPOSE_DEPOSIT=1;}; struct InventoryStorageManagerComponent{IEntity owner=nullptr;Arrayitems;Arrayrequests;bool accept=true,inlineDone=false;Entity spawned;IEntity GetOwner(){return owner;} bool TrySpawnPrefabToStorage(string p,void*,int,int,ERR_ConvoyCargoCallback* cb){requests.Insert(p);cb->Finished=inlineDone;if(inlineDone){spawned.magazine=true;items.Insert(&spawned);}return accept;}}; struct ERR_Inventory{static void Items(InventoryStorageManagerComponent* i,Array& items){items=i->items;}}; struct Service{Mode* m_Mode; '''+code+r''' }; struct Fixture{Mode mode;Service service{&mode};ERR_SupplyConvoyTask task;InventoryStorageManagerComponent inventory;Arrayroots{6},cargo{8},extra{129};Arraygroups{6};Arrayvehicles{6};Arrayweapons{8};BaseMuzzleComponent muzzle;Arraycallbacks{8};Arrayseeds{9}; Fixture(){mode.ledger.records.resize(6);for(int i=0;i<6;i++){groups[i].id=i;groups[i].bound=&roots[i];vehicles[i].Index=i;vehicles[i].Entity=&roots[i];vehicles[i].Group=&groups[i];task.Vehicles.Insert(&vehicles[i]);mode.ledger.records[i].Id=i;} roots[1].inventory=&inventory;inventory.owner=&roots[1]; for(int i=0;i<8;i++){cargo[i].prefab.name="weapon"+std::to_string(i);cargo[i].weapon=&weapons[i];weapons[i].muzzles={&muzzle};callbacks[i].Prefab=cargo[i].prefab.name;task.Cargo.Insert(&callbacks[i]);inventory.items.Insert(&cargo[i]);} for(int i=0;i<9;i++){seeds[i].Root=&roots[0];seeds[i].Prefab="box"+std::to_string(i);task.MountedStock.Insert(&seeds[i]);}} }; int main(){ {Fixture f;f.service.IssueMagazines(&f.task,0);assert(f.task.MagazinesIssued&&f.inventory.requests.Count()==64&&f.task.Cargo.Count()==72&&f.task.MountedStock.Count()==0); for(int i=0;i<48;i++)assert(f.inventory.requests[i]=="rifle-mag");for(int i=48;i<64;i++)assert(f.inventory.requests[i]=="box"+std::to_string((i-48)/2)); f.service.IssueMagazines(&f.task,99999);assert(f.inventory.requests.Count()==64);} {Fixture f;f.callbacks[0].Finished=false;f.service.IssueMagazines(&f.task,0);assert(!f.task.MagazinesIssued&&f.inventory.requests.Count()==0);f.callbacks[0].Finished=true;f.service.IssueMagazines(&f.task,1);assert(f.inventory.requests.Count()==64);} for(int missing=0;missing<2;missing++){Fixture f; if(missing==0)f.callbacks[0].Finished=false;else f.task.Cargo[0]=nullptr; f.service.IssueMagazines(&f.task,30100); assert(f.task.MagazinesIssued&&f.inventory.requests.Count()==42&&f.task.MountedStock.Count()==0); for(auto request:f.inventory.requests){assert(request=="rifle-mag");} f.callbacks[0].Finished=true;f.task.Cargo[0]=&f.callbacks[0]; f.service.IssueMagazines(&f.task,99999);assert(f.inventory.requests.Count()==42);} {Fixture f;f.inventory.accept=false;f.service.IssueMagazines(&f.task,0);assert(f.inventory.requests.Count()==64);for(auto cb:f.task.Cargo){assert(cb->Finished);}f.service.IssueMagazines(&f.task,99999);assert(f.inventory.requests.Count()==64);} {Fixture f;f.inventory.inlineDone=true;f.service.IssueMagazines(&f.task,0);assert(f.inventory.requests.Count()==64);} {Fixture f;f.service.IssueMountedStock(&f.task,&f.inventory,80,8,20);assert(f.inventory.requests.Count()==8);} //96 existing+attempts {Fixture f;int total=f.service.IssueMountedStock(&f.task,&f.inventory,48,0,79);assert(total==49&&f.inventory.requests.Count()==1);} //128allitems {Fixture f;f.task.Cargo.resize(127,&f.callbacks[0]);assert(f.service.IssueMountedStock(&f.task,&f.inventory,48,0,8)==49&&f.task.Cargo.Count()==128);} {Fixture f;for(auto& seed:f.seeds){seed.Prefab="same";}assert(f.service.IssueMountedStock(&f.task,&f.inventory,48,0,8)==50);} for(int bad=0;bad<8;bad++){Fixture f; if(bad==0)f.vehicles[1].crew=false;if(bad==1)f.groups[1].valid=false;if(bad==2)f.mode.ledger.records[1].Id=9; if(bad==3)f.task.Ready=false;if(bad==4)f.task.Receipt->Consumed=false; if(bad==5)for(auto& seed:f.seeds)seed.valid=false; if(bad==6)f.task.Vehicles[0]=&f.vehicles[3];if(bad==7)f.groups[0].valid=false; assert(f.service.IssueMountedStock(&f.task,&f.inventory,48,0,8)==48&&f.inventory.requests.Count()==0);} {Fixture f;f.inventory.items.clear();for(auto& e:f.extra){f.inventory.items.Insert(&e);}f.service.IssueMagazines(&f.task,0); assert(f.task.MagazinesIssued&&f.inventory.requests.Count()==0&&f.task.MountedStock.Count()==0&&f.task.CargoBefore.Count()==0);} {Fixture f;f.service.CaptureMountedStock(&f.task);assert(ERR_MountedMagazineSeed::captures==6);f.groups[1].valid=false;f.service.CaptureMountedStock(&f.task);assert(ERR_MountedMagazineSeed::captures==6);} } '''.replace(';if(', ';\n if(').replace(';for(', ';\n for(')) print('PASS: actual primary-before-mounted one-shot batch, shared96/128 caps, physical snapshot headroom, original ownership, callback refusal and admission pinning') lookup=body(D/'ERR_HQ.c','bool ValidateBoundVehicle(SCR_AIGroup group, IEntity vehicle)') lookup=lookup.replace('Replication.','Replication::').replace('null','nullptr') for typ in ['SCR_AIGroup','IEntity','ERR_HQUnit']:lookup=re.sub(r'\b'+typ+r' (?=\w)',typ+'* ',lookup) lookup=lookup.replace('unit.','unit->').replace('StatusSampler.','StatusSampler->') run(r''' #include #include struct Replication{static inline bool server=true;static bool IsServer(){return server;}}; struct SCR_AIGroup{};struct IEntity{}; struct Sampler{SCR_AIGroup* group;IEntity* root;bool valid=true;int calls=0;bool OwnsRoster(SCR_AIGroup* g){return g==group;}bool ValidateBoundVehicle(IEntity* r){calls++;return valid&&root==r;}}; struct ERR_HQUnit{SCR_AIGroup* Group;Sampler* StatusSampler;}; templatestruct Array:std::vector{using std::vector::vector;int Count(){return this->size();}}; struct HQ{bool m_Mode=true;Arraym_Units; '''+lookup+r''' }; int main(){SCR_AIGroup group,other;IEntity root,replacement;Sampler sampler{&group,&root};ERR_HQUnit unit{&group,&sampler};HQ h;h.m_Units={nullptr,&unit}; assert(h.ValidateBoundVehicle(&group,&root)&&!h.ValidateBoundVehicle(&group,&replacement)&&sampler.root==&root); assert(!h.ValidateBoundVehicle(&other,&root));sampler.valid=false;assert(!h.ValidateBoundVehicle(&group,&root));sampler.valid=true; int calls=sampler.calls;Replication::server=false;assert(!h.ValidateBoundVehicle(&group,&root)&&sampler.calls==calls);Replication::server=true; h.m_Units.assign(256,nullptr);h.m_Units.push_back(&unit);assert(!h.ValidateBoundVehicle(&group,&root)&&sampler.calls==calls); } ''') print('PASS: actual bounded HQ query validates only existing original binding without admission or replacement lookup')