using System.Runtime.InteropServices; namespace XFEEDToolBox.Plugin; internal static unsafe partial class Navigation { static uint mockRouteFlags,mockRouteCalculations; static bool mockRouteReject; [UnmanagedCallersOnly] static void MockRouteDestination(nuint obj,int index,ulong* destination,ulong* body,long* market,long* settlement,byte cluster,byte surface) { if(index==0)mockRouteFlags|=1;if(*destination==9007199254740995)mockRouteFlags|=2;if(*body==0x200&&*market==-1&&*settlement==-1&&cluster==0&&surface==0)mockRouteFlags|=4;if(!mockRouteReject)Write(obj+0x148,*destination); } [UnmanagedCallersOnly] static void MockRouteCalculate(nuint obj,int index){++mockRouteCalculations;if(index==0&&Read(obj+0x148)==9007199254740995)mockRouteFlags|=8;} static uint RouteArgumentsSelfTest() { var memory=Platform.Allocate(4096);if(memory==0)return 0;try{ var route=memory;var table=route+1024;Write(route,table);Write(table+0x30,(nuint)(delegate* unmanaged)&MockRouteDestination);Write(table+0x38,(nuint)(delegate* unmanaged)&MockRouteCalculate); mockRouteFlags=mockRouteCalculations=0;mockRouteReject=false;uint passed=0;if(InvokeGameRoute(route,9007199254740995))passed|=1;if(mockRouteFlags==15)passed|=2;if(mockRouteCalculations==1&&Read(route+0x148)==9007199254740995)passed|=4;mockRouteReject=true; if(!InvokeGameRoute(route,42))passed|=8;if(mockRouteCalculations==1&&Read(route+0x148)==9007199254740995)passed|=16;return passed; }finally{mockRouteReject=false;Platform.Free(memory);} } static uint OutwardThrottleSelfTest() { var position=new Vector(1,0,0);var outward=new Vector(1,0,0);var tangent=new Vector(0,1,0);var inward=new Vector(-1,0,0);uint passed=0; if(OutwardChargingMotion(position,outward,tangent,true,false))passed|=1;if(!OutwardChargingMotion(position,inward,tangent,true,false))passed|=2;if(!OutwardChargingMotion(position,outward,inward,true,false))passed|=4;if(!OutwardChargingMotion(position,outward,tangent,false,false))passed|=8;if(!OutwardChargingMotion(position,outward,tangent,true,true))passed|=16;return passed; } static uint CommitGateSelfTest() { var saved=CurrentFsd();try{ var observed=new FsdObservation{state=3,duration=15,clock=14};lock(fsdObservationLock)fsdObservation=observed;var command=new Lease{throttle=1,interlock=true};uint passed=0;if(CommandAxes(command)[0]==1)passed|=1; observed.clock=14.75f;lock(fsdObservationLock)fsdObservation=observed;if(CommandAxes(command)[0]==0)passed|=2;command.permitJump=true;if(CommandAxes(command)[0]==1)passed|=4;command.permitJump=false;observed.clock=15;lock(fsdObservationLock)fsdObservation=observed;if(CommandAxes(command)[0]==0)passed|=8;command.interlock=false;if(CommandAxes(command)[0]==1)passed|=16;return passed; }finally{lock(fsdObservationLock)fsdObservation=saved;} } static uint ApplicationAxesSelfTest() { uint passed=0;using var document=JsonDocument.Parse("[-1,0.5,1]");var axes=ApplicationSteeringAxes(document.RootElement);if(axes[0]==-1&&axes[1]==.5f&&axes[2]==1)passed|=1; static bool Rejects(string text){using var value=JsonDocument.Parse(text);try{ApplicationSteeringAxes(value.RootElement);}catch{return true;}return false;} if(Rejects("[0,0]"))passed|=2;if(Rejects("[0,0,1.0001]"))passed|=4;if(Rejects("[0,\"0\",0]"))passed|=8;if(Rejects("[0,null,0]"))passed|=16;return passed; } [UnmanagedCallersOnly] static ulong MockFsdResult(nuint obj,float dt)=>(ulong)obj^(ulong)(dt*1000)^0x87AFC311; static uint FsdReturnSelfTest() { var saved=originalFsd;var beforeGame=inGame;try{originalFsd=(nuint)(delegate* unmanaged)&MockFsdResult;inGame=false;uint passed=0;var fn=(delegate* unmanaged)&FsdHook; if(fn(0x12345678,.125f)==(0x12345678UL^(ulong)(.125f*1000)^0x87AFC311))passed|=1;if(fn(0x87654321,.5f)==(0x87654321UL^(ulong)(.5f*1000)^0x87AFC311))passed|=2;return passed; }finally{originalFsd=saved;inGame=beforeGame;} } static uint ActorSelectionSelfTest() { var memory=Platform.Allocate(8192);if(memory==0)return 0;try{var owner=memory;var rows=owner+4096;Write(owner+0x970,3UL);Write(owner+0x978,rows); void Set(uint i,byte kind,int ticket){Write(rows+i*0x1C0+0x190,kind);Write(rows+i*0x1C0+0x1B8,ticket);}uint passed=0;Set(0,3,0);Set(1,0,1);Set(2,2,2);if(ControlledActor(owner)==rows+2*0x1C0)passed|=1;Set(2,2,-1);if(ControlledActor(owner)==rows+0x1C0)passed|=2;Set(1,0,-1);if(ControlledActor(owner)==rows)passed|=4;Set(0,3,-1);if(ControlledActor(owner)==0)passed|=8;Write(owner+0x970,33UL);if(ControlledActor(owner)==0)passed|=16;Write(owner+0x970,0UL);if(ControlledActor(owner)==0)passed|=32;return passed; }finally{Platform.Free(memory);} } static uint ThrottleControlSelfTest() { if(!InputOwnershipDiagnosticSelfTest()||!PhysicalBindingRegistrySelfTest()||!PhysicalInputPolicySelfTest()||!PhysicalInputContextSelfTest())return 0; uint passed=0;var request=new Lease{throttle=1};if(CommandAxes(request)[0]==1)passed|=1;request.throttle=0;request.axes[3]=.2f;if(CommandAxes(request)[0]==0&&CommandAxes(request)[3]==.2f)passed|=2;request.throttle=-1;request.axes[0]=.12f;if(CommandAxes(request)[0]==.12f)passed|=4; var keyboard=new XFEEDToolBox.Core.Navigation.ManualTakeoverKeyboardPolicy();if(keyboard.Evaluate(1000,true)=="")passed|=8; keyboard.Key(0x57,true,1010,true);keyboard.Key(0x57,false,1030,true);if(keyboard.Evaluate(3000,true)=="")passed|=16; keyboard.Reset();keyboard.Key(0x53,true,4000,true);if(keyboard.Evaluate(5000,true)==""&&keyboard.Evaluate(5001,true)=="physical-key-S-held")passed|=32; var old=new Snapshot{valid=true,sequence=100,tick=1000,entity=42,life=0x123400,inputRoot=0x567800};var latest=new Snapshot{valid=true,sequence=110,tick=1180,entity=42,life=0x123400,inputRoot=0x567800};if(ReferenceUsable(old,latest,1190)&&!ReferenceUsable(old,latest,1201))passed|=64;latest.entity=43;if(!ReferenceUsable(old,latest,1190))passed|=128;return passed; } static uint FsdCancellationSelfTest() { var memory=Platform.Allocate(16384);if(memory==0)return 0;var beforeOwned=fsdOwned;var beforeOverride=overridden;var beforePulseAt=fsdLastPulseAt;var beforeCount=fsdPulseCount;var beforeMode=fsdOwnedMode; Lease beforeLease;FsdLease beforeFsdLease;lock(leaseLock){beforeLease=lease;beforeFsdLease=fsdLease;} try{ var root=memory;var life=root+4096;var fsd=root+8192;var frame=new Snapshot{inputRoot=root,life=life,fsd=fsd,entity=42,heat=root+12288};Write(frame.heat+0x188,.42f);Write(life+0xC0,8u);Write(life+0xB0,42UL);Write(fsd+0x398,root+0x60);Write(fsd+0x758,(byte)3);fsdOwned=true;fsdLastPulseAt=0;fsdOwnedMode=1; uint passed=0;var pulse=PrepareFsdPulse(frame,fsd);if(pulse.applied&&Read(root+0x60+0xBE)==1)passed|=1;Write(fsd+0x758,(byte)2);FinishFsdPulse(ref pulse);if(Read(root+0x60+0xBE)==0&&!fsdOwned)passed|=2;fsdOwned=true;fsdLastPulseAt=0;if(!PrepareFsdPulse(frame,fsd).applied)passed|=4; Write(fsd+0x758,(byte)3);var yielded=true; foreach(var offset in new nuint[]{0xBD,0xBE,0xBF}) { for(nuint button=0xBD;button<=0xBF;button++)Write(root+0x60+button,(byte)0); Write(root+0x60+offset,(byte)1);fsdOwned=true;overridden=false;fsdLastPulseAt=0; lock(leaseLock){lease.expires=777;fsdLease.expires=888;} var originalButton=PrepareFsdPulse(frame,fsd); yielded&=!originalButton.applied&&Read(root+0x60+offset)==1&&!overridden&&fsdOwned; lock(leaseLock)yielded&=lease.expires==777&&fsdLease.expires==888; } if(yielded)passed|=8; for(nuint button=0xBD;button<=0xBF;button++)Write(root+0x60+button,(byte)0); fsdLastPulseAt=0;pulse=PrepareFsdPulse(frame,fsd);Write(life+0xB0,43UL);FinishFsdPulse(ref pulse);if(Read(root+0x60+0xBE)==1)passed|=16; Write(life+0xB0,42UL);Write(root+0x60+0xBE,(byte)0);fsdOwned=true;fsdLastPulseAt=0;fsdOwnedMode=3;pulse=PrepareFsdPulse(frame,fsd);if(pulse.applied&&Read(root+0x60+0xBF)==1&&Read(root+0x60+0xBE)==0)passed|=32;Write(fsd+0x758,(byte)2);FinishFsdPulse(ref pulse);if(Read(root+0x60+0xBF)==0&&!fsdOwned)passed|=64;return passed; }finally{lock(leaseLock){lease=beforeLease;fsdLease=beforeFsdLease;}fsdOwned=beforeOwned;overridden=beforeOverride;fsdLastPulseAt=beforePulseAt;fsdPulseCount=beforeCount;fsdOwnedMode=beforeMode;Platform.Free(memory);} } static uint TargetLookupSelfTest() { var memory=Platform.Allocate(8192);if(memory==0)return 0;try{var navigation=memory;var storage=navigation+1024;var a=navigation+2048;var b=navigation+4096;Write(navigation+0x2C0,2UL);Write(navigation+0x2C8,4UL);Write(navigation+0x2D0,storage);Write(storage,(byte)9);Write(storage+8,11);Write(storage+16,a);Write(storage+8+3*16,22);Write(storage+16+3*16,b);Write(a+0x20,42UL);Write(a+0x188,2u);Write(b+0x20,43UL);Write(b+0x188,2u); uint passed=0;if(TargetKey(navigation,42,out var key)&&key==11)passed|=1;if(!TargetKey(navigation,44,out key)&&!TargetKey(navigation,0,out key))passed|=2;Write(b+0x20,42UL);if(!TargetKey(navigation,42,out key))passed|=4;Write(b+0x184,1u);if(TargetKey(navigation,42,out key)&&key==11)passed|=8;Write(navigation+0x2C8,3UL);if(!TargetKey(navigation,42,out key))passed|=16;Write(navigation+0x2C8,4UL);Write(navigation+0x2C0,3UL);if(!TargetKey(navigation,42,out key))passed|=32;return passed; }finally{Platform.Free(memory);} } static uint ComponentLookupSelfTest() { var memory=Platform.Allocate(16384);if(memory==0)return 0;try{var root=memory;var metadata=root+256;var slots=root+512;var array=root+8192;var pose=root+15000;Write(root+0x10,metadata);Write(root+0x18,array);Write(metadata+0x18,227UL);Write(metadata+0x30,slots);Write(slots+162*16,42UL);Write(array+42*8,pose);uint passed=0; if(RegisteredComponent(root,162)==pose)passed|=1;if(RegisteredComponent(root,0)==0&&RegisteredComponent(root,100000)==0)passed|=2;Write(slots+162*16,227UL);if(RegisteredComponent(root,162)==0)passed|=4;Write(slots+162*16,ulong.MaxValue);if(RegisteredComponent(root,162)==0)passed|=8;Write(slots+162*16,42UL);Write(root+0x10,(nuint)0);if(RegisteredComponent(root,162)==0)passed|=16;Write(root+0x10,metadata);Write(metadata+0x30,(nuint)0);if(RegisteredComponent(root,162)==0)passed|=32;return passed; }finally{Platform.Free(memory);} } static uint ObserverSelfTest() { var target=Platform.Allocate(4096);if(target==0)return 0;var observers=new nuint[3];try{ Platform.WriteBytes(target,[0x48,0x89,0xC8,0x48,0x31,0xD0,0x4C,0x31,0xC0,0x4C,0x31,0xC8,0x90,0x90,0xC3]); Platform.WriteBytes(target+64,[0xF3,0x0F,0x58,0xC1,0xF3,0x0F,0x58,0xC2,0xF3,0x0F,0x58,0xC3,0x90,0x90,0xC3]);Platform.WriteBytes(target+128,[0x48,0x89,0xC8,0x48,0x11,0xD0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xC3]); var callback=new List{0x31,0xC0,0x31,0xC9,0x31,0xD2,0x45,0x31,0xC0,0x45,0x31,0xC9,0x45,0x31,0xD2,0x45,0x31,0xDB};for(var i=0;i<6;i++)callback.AddRange([0x66,0x0F,0xEF,(byte)(0xC0+i*9)]);callback.Add(0xC3);Platform.WriteBytes(target+256,callback.ToArray()); var caller=new List{0x48,0x83,0xEC,0x28,0xB9,3,0,0,0,0xBA,4,0,0,0,0xF9,0x48,0xB8};caller.AddRange(BitConverter.GetBytes((ulong)(target+128)));caller.AddRange([0xFF,0xD0,0x48,0x83,0xC4,0x28,0xC3]);Platform.WriteBytes(target+512,caller.ToArray());Platform.Protect(target,4096,0x20,out _);Platform.FlushCode(target,4096); var status=Platform.HookInitialize();if(status!=0&&status!=1)return 0;uint passed=0;for(var i=0;i<3;i++){observers[i]=Platform.Observer(target+256,out _,target+(nuint)i*64);if(observers[i]!=0)Platform.HookEnable(target+(nuint)i*64);} if(observers[0]!=0&&Call(target,0x123456789ABC,0xF1234,0x11223344,0x22334455)==(0x123456789ABCUL^0xF1234UL^0x11223344UL^0x22334455UL))passed|=1; if(observers[1]!=0&&Math.Abs(CallFloat(target+64,F32(1.25f),F32(2.5f),F32(4),F32(8))-15.75f)<.0001f)passed|=2;if(observers[2]!=0&&Call(target+512)==8)passed|=4;return passed; }finally{for(var i=0;i<3;i++)if(observers[i]!=0){Platform.HookDisable(target+(nuint)i*64);Platform.HookRemove(target+(nuint)i*64);Platform.FreeObserver(observers[i]);}Platform.Free(target);} } static uint OverlayLifetimeSelfTest() { var memory=Platform.Allocate(8192);if(memory==0)return 0;try{var root=memory;var life=root+4096;var physics=life+512; InputOverlay Make(){Write(root,(nuint)0x12345678);Write(life+0xC0,8u);Write(life+0xB0,42UL);Write(physics+0x3B0,root+0x60);var result=new InputOverlay{root=root,vtable=0x12345678,life=life,physics=physics,entity=42,applied=true};for(var i=0;i<6;i++){result.previous[i]=.01f;result.written[i]=.05f;Write(root+0x70+(nuint)i*0x10,.05f);}return result;} uint passed=0;var overlay=Make();Restore(ref overlay);var restored=true;for(var i=0;i<6;i++)restored&=Read(root+0x70+(nuint)i*0x10)==.01f;if(restored)passed|=1; overlay=Make();Write(root+0x70,.08f);Restore(ref overlay);if(Read(root+0x70)==.08f&&Read(root+0x80)==.01f)passed|=2;overlay=Make();Write(life+0xB0,43UL);Restore(ref overlay);if(Read(root+0x70)==.05f)passed|=4;overlay=Make();Write(physics+0x3B0,root+0x100);Restore(ref overlay);if(Read(root+0x70)==.05f)passed|=8; overlay=Make();Platform.Protect(memory,4096,1,out var before);Restore(ref overlay);Platform.Protect(memory,4096,before,out _);if(Read(root+0x70)==.05f)passed|=16;return passed; }finally{Platform.Free(memory);} } static uint ShipHealthSelfTest() { var recovery=XFEEDToolBox.Core.Navigation.ShipDamageRecoveryPolicy.Observe(false,true,0,100,120); for(ulong at=140;at<3120;at+=20){recovery=XFEEDToolBox.Core.Navigation.ShipDamageRecoveryPolicy.Observe(recovery.Emergency,false,recovery.StableSince,at-20,at);if(!recovery.Emergency)return 0;} if(XFEEDToolBox.Core.Navigation.ShipDamageRecoveryPolicy.Observe(recovery.Emergency,false,recovery.StableSince,3100,3120).Emergency)return 0; var a=new Snapshot{healthValid=true,entity=7,life=0x123400,hullFraction=1,shieldKnown=true};var b=a;uint result=0;if(!HealthDamageEmergency(a,b))result|=1;a.shieldFraction=.01;b.shieldFraction=0;if(HealthDamageEmergency(a,b))result|=2;a.shieldFraction=b.shieldFraction=1;a.hullFraction=.501;b.hullFraction=.5;if(HealthDamageEmergency(a,b))result|=4;b.hullFraction=.499;if(HealthDamageEmergency(a,b))result|=8;a.hullFraction=b.hullFraction=.4;if(!HealthDamageEmergency(a,b))result|=16;a.hullFraction=1;b.hullFraction=.99;a.shieldFraction=b.shieldFraction=0;if(HealthDamageEmergency(a,b))result|=32;b.entity=8;if(!HealthDamageEmergency(a,b))result|=64;b.entity=7;a.healthValid=false;if(!HealthDamageEmergency(a,b))result|=128;return result; } static uint LocalTargetsSelfTest() { byte* nav=stackalloc byte[0x500];byte* fsd=stackalloc byte[0x500];byte* storage=stackalloc byte[64];byte* text=stackalloc byte[64];byte* record=stackalloc byte[0x200];new Span(nav,0x500).Clear();new Span(fsd,0x500).Clear();new Span(storage,64).Clear();new Span(text,64).Clear();new Span(record,0x200).Clear();var n=(nuint)nav;var r=(nuint)record;var s=(nuint)storage; Write(n+0x2C0,1UL);Write(n+0x2C8,8UL);Write(n+0x2D0,s);Write(n+0x38C,4);storage[0]=1;Write(s+8,4);Write(s+16,r);Write(r+0x188,1u);Write(r+0x184,12u);Write(r+0x20,99UL);Write(r+0x130,123u);Write(r+0x140,(nuint)text);Write((nuint)text,9UL);text[0x14]=14;"Station"u8.CopyTo(new Span(text+0x15,7));text[0x1c]=15; var frame=new Snapshot{fsd=(nuint)fsd,referenceWorld=20};Write(frame.fsd+0x338,n);var control=new Lease{local=true,localKey=4,localBody=99,localKind=12,localMarket=123,world=20};uint result=0; if(LocalControlMatches(control,frame))result|=1;Write(r+0x188,2u);if(!LocalControlMatches(control,frame))result|=2;Write(r+0x188,1u);control.localKind=14;if(!LocalControlMatches(control,frame))result|=4;control.localKind=12;control.localMarket=124;if(!LocalControlMatches(control,frame))result|=8;control.localMarket=123;control.localBody=98;if(!LocalControlMatches(control,frame))result|=16;control.localBody=99;frame.referenceWorld=21;if(!LocalControlMatches(control,frame))result|=32;frame.referenceWorld=20; if(ReadLocalIdentity(r,4,out var a)){var b=a;byte* name=a.name;if(System.Text.Encoding.UTF8.GetString(name,7)=="Station"){b.name[0]=(byte)'X';if(!SameLocal(a,b))result|=64;}}text[0x16]=0;if(!ReadLocalIdentity(r,4,out _))result|=128;return result; } static uint LocalEntityDirectorySelfTest() { byte* context=stackalloc byte[0x200];byte* player=stackalloc byte[0x200];byte* station=stackalloc byte[0x200];byte* storage=stackalloc byte[0x200];new Span(context,0x200).Clear();new Span(player,0x200).Clear();new Span(station,0x200).Clear();new Span(storage,0x200).Clear();var c=(nuint)context;var p=(nuint)player;var t=(nuint)station;var s=(nuint)storage; Write(c+0x148,2UL);Write(c+0x150,8UL);Write(c+0x158,s);storage[0]=3;Write(s+8,7UL);Write(s+16,p);Write(s+24,88UL);Write(s+32,t);Write(p+0xC0,8u);Write(p+0xB0,7UL);Write(t+0xC0,8u);Write(t+0xB0,88UL);uint result=0; if(LocalEntityFromDirectory(c,p,7,88)==t)result|=1;if(LocalEntityFromDirectory(c,p,7,89)==0)result|=2;Write(t+0xC0,7u);if(LocalEntityFromDirectory(c,p,7,88)==0)result|=4;Write(t+0xC0,8u);Write(t+0xB0,89UL);if(LocalEntityFromDirectory(c,p,7,88)==0)result|=8;Write(t+0xB0,88UL);Write(s+16,t);if(LocalEntityFromDirectory(c,p,7,88)==0)result|=16;Write(s+16,p);Write(c+0x148,9UL);if(LocalEntityFromDirectory(c,p,7,88)==0)result|=32;Write(c+0x148,2UL);Write(c+0x150,7UL);if(LocalEntityFromDirectory(c,p,7,88)==0)result|=64;Write(c+0x150,8UL);storage[0]=1;if(LocalEntityFromDirectory(c,p,7,88)==0)result|=128;return result; } static uint StellarSpeedSelfTest() { uint result=0;if(Math.Abs(StellarCruiseThrottle(.6f,30000,2e9,1e9,-.7)-.6f)<1e-6)result|=1;if(StellarCruiseThrottle(.6f,12000000,2e9,1e9,0)==0)result|=2;if(StellarCruiseThrottle(.6f,9000000,2e9,1e9,0)==.25f)result|=4;if(StellarCruiseThrottle(.6f,2000000,1.16e9,1e9,-1)==0)result|=8;if(StellarCruiseThrottle(.6f,0,1.14e9,1e9,0)==0)result|=16;if(StellarCruiseThrottle(.6f,double.PositiveInfinity,2e9,1e9,0)==0)result|=32;if(Math.Abs(StellarCruiseThrottle(.6f,20000000,4e9,1e9,0)-.6f)<1e-6)result|=64;if(Math.Abs(StellarCruiseThrottle(.6f,30000,1.14e9,1e9,1)-.6f)<1e-6)result|=128;return result; } #if PLUGIN_NAVIGATION static uint RunTest(Func test){try{return test();}catch{return 0;}} [UnmanagedCallersOnly(EntryPoint="XFENavigationObserverSelfTest")]internal static uint ExportObserverSelfTest()=>RunTest(ObserverSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationSessionMenuSelfTest")]internal static uint ExportSessionMenuSelfTest()=>RunTest(SessionMenuSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationShipHealthSelfTest")]internal static uint ExportShipHealthSelfTest()=>RunTest(ShipHealthSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationLocalTargetsSelfTest")]internal static uint ExportLocalTargetsSelfTest()=>RunTest(LocalTargetsSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationLocalEntityDirectorySelfTest")]internal static uint ExportLocalEntityDirectorySelfTest()=>RunTest(LocalEntityDirectorySelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationReferenceGeometrySelfTest")]internal static uint ExportReferenceGeometrySelfTest()=>RunTest(ReferenceGeometrySelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationScoopGeometrySelfTest")]internal static uint ExportScoopGeometrySelfTest()=>RunTest(ScoopGeometrySelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationHeatNormalizationSelfTest")]internal static uint ExportHeatNormalizationSelfTest()=>RunTest(HeatNormalizationSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationOverlayLifetimeSelfTest")]internal static uint ExportOverlayLifetimeSelfTest()=>RunTest(OverlayLifetimeSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationComponentLookupSelfTest")]internal static uint ExportComponentLookupSelfTest()=>RunTest(ComponentLookupSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationFsdCancellationSelfTest")]internal static uint ExportFsdCancellationSelfTest()=>RunTest(FsdCancellationSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationThrottleControlSelfTest")]internal static uint ExportThrottleControlSelfTest()=>RunTest(ThrottleControlSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationTargetLookupSelfTest")]internal static uint ExportTargetLookupSelfTest()=>RunTest(TargetLookupSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationActorSelectionSelfTest")]internal static uint ExportActorSelectionSelfTest()=>RunTest(ActorSelectionSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationFsdReturnSelfTest")]internal static uint ExportFsdReturnSelfTest()=>RunTest(FsdReturnSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationApplicationAxesSelfTest")]internal static uint ExportApplicationAxesSelfTest()=>RunTest(ApplicationAxesSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationCommitGateSelfTest")]internal static uint ExportCommitGateSelfTest()=>RunTest(CommitGateSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationOutwardThrottleSelfTest")]internal static uint ExportOutwardThrottleSelfTest()=>RunTest(OutwardThrottleSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationRouteArgumentsSelfTest")]internal static uint ExportRouteArgumentsSelfTest()=>RunTest(RouteArgumentsSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationAdaptiveMotionSelfTest")]internal static uint ExportAdaptiveMotionSelfTest()=>RunTest(AdaptiveMotionSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationStellarSpeedSelfTest")]internal static uint ExportStellarSpeedSelfTest()=>RunTest(StellarSpeedSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationCommerceSelfTest")]internal static uint ExportCommerceSelfTest()=>RunTest(CommerceProtocolSelfTest); [UnmanagedCallersOnly(EntryPoint="XFENavigationInterfaceProtocolSelfTest")]internal static uint ExportInterfaceProtocolSelfTest()=>RunTest(InterfaceProtocolSelfTest); #endif } #if PLUGIN_NAVIGATION internal static unsafe class NavigationExports { static bool standaloneEnabled=true; static uint Run(Func test){try{return test();}catch{return 0;}} [UnmanagedCallersOnly(EntryPoint="XFENavigationStart")]internal static uint Start(){try{return Navigation.Initialize(()=>standaloneEnabled)?1u:0u;}catch{return 0;}} [UnmanagedCallersOnly(EntryPoint="XFENavigationGetAbiVersion")]internal static uint Abi()=>1; [UnmanagedCallersOnly(EntryPoint="XFENavigationDeactivate")]internal static void Deactivate(){standaloneEnabled=false;Navigation.Deactivate();} } #endif