using System.Runtime.InteropServices;
using System.Text;
namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
static uint GalaxyAllegianceDefinitionsSelfTest()
{
var memory=Platform.Allocate(0x30000);if(memory==0)return 0;
try
{
var expectedImage=memory+0x20000-0x51BBA70;var owner=memory+0x1000;var source=owner+0x58;
Write(owner,expectedImage+0x51BB940);Write(owner+8,expectedImage+0x51BB970);
Write(source,expectedImage+0x51BBA70);Write(source+8,expectedImage+0x51BBB60);
var slots=new(nuint offset,nuint function)[]{(0,0x140EA90),(0x18,0x140F240),(0x20,0x140EC60),(0x48,0x1410000),(0x50,0x140FE60)};
foreach(var (offset,function) in slots)Write(expectedImage+0x51BBA70+offset,expectedImage+function);
var offsets=new nuint[]{0x80,0xA8,0xC8,0xE8,0x108,0x128};var node=memory+0x4000;var control=memory+0x5000;var definition=memory+0x6000;var text=memory+0x7000;
void Reset()
{
for(var i=0;i<offsets.Length;i++)
{
var map=source+offsets[i];var buckets=memory+0x8000+(nuint)i*0x100;
Write(map,buckets);Write(map+8,17UL);Write(map+0x18,0UL);
for(nuint n=0;n<17;n++)Write(buckets+n*8,buckets+n*8);
}
}
void Put(ulong id,string key,int mapIndex=0)
{
Reset();var map=source+offsets[mapIndex];var buckets=Pointer(map);
var hash=mapIndex==5?GalaxyAllegianceLegacyHash((uint)id):GalaxyFactHash(id);var sentinel=buckets+(nuint)(hash%17)*8;
Write(map+0x18,1UL);Write(sentinel,node);Write(node,sentinel);Write(node+8,id);Write(node+0x10,control);Write(node+0x18,definition);
Write(control+0xC,1);Write(definition,id);Write(definition+8,text);Write(definition+0x18,(byte)1);
Write(text,(ulong)key.Length);Write(text+8,(ulong)key.Length);Write(text+0x10,1);Platform.WriteBytes(text+20,Encoding.UTF8.GetBytes(key+"\0"));
}
bool Copy(ulong id,out string? key)=>CopyGalaxyAllegianceKey(source,expectedImage,id,out key);
uint passed=0;var keys=new[]{"None","Federation","Empire","Alliance","Independent"};var all=true;
for(var i=0;i<keys.Length;i++){var id=9007199254740995UL+(ulong)i;Put(id,keys[i],i);all&=Copy(id,out var key)&&key==keys[i];}
if(all)passed|=1;
const ulong address=9007199254740995UL;Put(address,"Federation");
if(Copy(address,out var result)&&result=="Federation"&&Copy(address+(1UL<<32),out result)&&result is null)passed|=2;
Reset();if(Copy(ulong.MaxValue,out result)&&result=="None"&&Copy(123,out result)&&result is null)passed|=4;
Put(address,"Federation");Write(definition+0x18,(byte)0);
if(Copy(address,out result)&&result is null)passed|=8;
Put(address,"Federation");Write(control+0xC,0);
if(Copy(address,out result)&&result is null)passed|=16;
Put(address,"Some private faction");if(Copy(address,out result)&&result is null)passed|=32;
Put(address,"Empire",5);if(Copy(address,out result)&&result=="Empire")passed|=64;
if(Copy(address+(1UL<<32),out result)&&result is null)passed|=128;
Put(0,"Alliance");if(Copy(0,out result)&&result=="Alliance")passed|=256;
Put(address,"Federation");var tables=true;
foreach(var (at,table) in new[]{(owner,expectedImage+0x51BB940),(owner+8,expectedImage+0x51BB970),(source,expectedImage+0x51BBA70),(source+8,expectedImage+0x51BBB60)})
{Write(at,table+8);tables&=!Copy(address,out _);Write(at,table);}if(tables)passed|=512;
var getters=true;
foreach(var (offset,function) in slots)
{Write(expectedImage+0x51BBA70+offset,expectedImage+function+1);getters&=!Copy(address,out _);Write(expectedImage+0x51BBA70+offset,expectedImage+function);}if(getters)passed|=1024;
Put(address,"Federation");Write(node+8,address+1);Write(node,node);
if(!Copy(address,out _))passed|=2048;
Put(address,"Federation");Write(definition,address+1);
if(Copy(address,out result)&&result is null)passed|=4096;
Put(address,"Federation");Write(text+8,1UL);var strings=Copy(address,out result)&&result is null;
Put(address,"Federation");Write(text+0x10,0);strings&=Copy(address,out result)&&result is null;if(strings)passed|=8192;
Reset();Write(source+0x80+8,0UL);var malformed=!Copy(address,out _);
Reset();Write(source+0x80+0x18,4_000_001UL);malformed&=!Copy(address,out _);if(malformed)passed|=16384;
Put(address,"Independent");var before=Platform.ReadBytes(memory,0x30000);
if(Copy(address,out result)&&result=="Independent"&&!CopyGalaxyAllegianceKey(0,expectedImage,address,out _)&&
!CopyGalaxyAllegianceKey(source,expectedImage+8,address,out _)&&Platform.ReadBytes(memory,0x30000).AsSpan().SequenceEqual(before))passed|=32768;
return passed;
}
finally{Platform.Free(memory);}
}
#if PLUGIN_NAVIGATION
[UnmanagedCallersOnly(EntryPoint="XFENavigationGalaxyAllegianceDefinitionsSelfTest")]
internal static uint ExportGalaxyAllegianceDefinitionsSelfTest()=>RunTest(GalaxyAllegianceDefinitionsSelfTest);
#endif
}
using System.Runtime.InteropServices;
using System.Text;
namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
static uint GalaxyAllegianceDefinitionsSelfTest()
{
var memory=Platform.Allocate(0x30000);if(memory==0)return 0;
try
{
var expectedImage=memory+0x20000-0x51BBA70;var owner=memory+0x1000;var source=owner+0x58;
Write(owner,expectedImage+0x51BB940);Write(owner+8,expectedImage+0x51BB970);
Write(source,expectedImage+0x51BBA70);Write(source+8,expectedImage+0x51BBB60);
var slots=new(nuint offset,nuint function)[]{(0,0x140EA90),(0x18,0x140F240),(0x20,0x140EC60),(0x48,0x1410000),(0x50,0x140FE60)};
foreach(var (offset,function) in slots)Write(expectedImage+0x51BBA70+offset,expectedImage+function);
var offsets=new nuint[]{0x80,0xA8,0xC8,0xE8,0x108,0x128};var node=memory+0x4000;var control=memory+0x5000;var definition=memory+0x6000;var text=memory+0x7000;
void Reset()
{
for(var i=0;i<offsets.Length;i++)
{
var map=source+offsets[i];var buckets=memory+0x8000+(nuint)i*0x100;
Write(map,buckets);Write(map+8,17UL);Write(map+0x18,0UL);
for(nuint n=0;n<17;n++)Write(buckets+n*8,buckets+n*8);
}
}
void Put(ulong id,string key,int mapIndex=0)
{
Reset();var map=source+offsets[mapIndex];var buckets=Pointer(map);
var hash=mapIndex==5?GalaxyAllegianceLegacyHash((uint)id):GalaxyFactHash(id);var sentinel=buckets+(nuint)(hash%17)*8;
Write(map+0x18,1UL);Write(sentinel,node);Write(node,sentinel);Write(node+8,id);Write(node+0x10,control);Write(node+0x18,definition);
Write(control+0xC,1);Write(definition,id);Write(definition+8,text);Write(definition+0x18,(byte)1);
Write(text,(ulong)key.Length);Write(text+8,(ulong)key.Length);Write(text+0x10,1);Platform.WriteBytes(text+20,Encoding.UTF8.GetBytes(key+"\0"));
}
bool Copy(ulong id,out string? key)=>CopyGalaxyAllegianceKey(source,expectedImage,id,out key);
uint passed=0;var keys=new[]{"None","Federation","Empire","Alliance","Independent"};var all=true;
for(var i=0;i<keys.Length;i++){var id=9007199254740995UL+(ulong)i;Put(id,keys[i],i);all&=Copy(id,out var key)&&key==keys[i];}
if(all)passed|=1;
const ulong address=9007199254740995UL;Put(address,"Federation");
if(Copy(address,out var result)&&result=="Federation"&&Copy(address+(1UL<<32),out result)&&result is null)passed|=2;
Reset();if(Copy(ulong.MaxValue,out result)&&result=="None"&&Copy(123,out result)&&result is null)passed|=4;
Put(address,"Federation");Write(definition+0x18,(byte)0);
if(Copy(address,out result)&&result is null)passed|=8;
Put(address,"Federation");Write(control+0xC,0);
if(Copy(address,out result)&&result is null)passed|=16;
Put(address,"Some private faction");if(Copy(address,out result)&&result is null)passed|=32;
Put(address,"Empire",5);if(Copy(address,out result)&&result=="Empire")passed|=64;
if(Copy(address+(1UL<<32),out result)&&result is null)passed|=128;
Put(0,"Alliance");if(Copy(0,out result)&&result=="Alliance")passed|=256;
Put(address,"Federation");var tables=true;
foreach(var (at,table) in new[]{(owner,expectedImage+0x51BB940),(owner+8,expectedImage+0x51BB970),(source,expectedImage+0x51BBA70),(source+8,expectedImage+0x51BBB60)})
{Write(at,table+8);tables&=!Copy(address,out _);Write(at,table);}if(tables)passed|=512;
var getters=true;
foreach(var (offset,function) in slots)
{Write(expectedImage+0x51BBA70+offset,expectedImage+function+1);getters&=!Copy(address,out _);Write(expectedImage+0x51BBA70+offset,expectedImage+function);}if(getters)passed|=1024;
Put(address,"Federation");Write(node+8,address+1);Write(node,node);
if(!Copy(address,out _))passed|=2048;
Put(address,"Federation");Write(definition,address+1);
if(Copy(address,out result)&&result is null)passed|=4096;
Put(address,"Federation");Write(text+8,1UL);var strings=Copy(address,out result)&&result is null;
Put(address,"Federation");Write(text+0x10,0);strings&=Copy(address,out result)&&result is null;if(strings)passed|=8192;
Reset();Write(source+0x80+8,0UL);var malformed=!Copy(address,out _);
Reset();Write(source+0x80+0x18,4_000_001UL);malformed&=!Copy(address,out _);if(malformed)passed|=16384;
Put(address,"Independent");var before=Platform.ReadBytes(memory,0x30000);
if(Copy(address,out result)&&result=="Independent"&&!CopyGalaxyAllegianceKey(0,expectedImage,address,out _)&&
!CopyGalaxyAllegianceKey(source,expectedImage+8,address,out _)&&Platform.ReadBytes(memory,0x30000).AsSpan().SequenceEqual(before))passed|=32768;
return passed;
}
finally{Platform.Free(memory);}
}
#if PLUGIN_NAVIGATION
[UnmanagedCallersOnly(EntryPoint="XFENavigationGalaxyAllegianceDefinitionsSelfTest")]
internal static uint ExportGalaxyAllegianceDefinitionsSelfTest()=>RunTest(GalaxyAllegianceDefinitionsSelfTest);
#endif
}