namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
internal readonly record struct GalaxyServiceFact(ushort mask,bool defaulted);
// ED5A, paired old1DD2560/5242560/+50=1E22170. No original getter is called.
static bool GalaxyServiceSource(nuint source,nuint expectedImage)
{
if(source<0x10058)return false;
var table=Pointer(source);
return table==expectedImage+0x5242530&&Pointer(source-0x58)==expectedImage+0x52423E8&&
Pointer(source-0x50)==expectedImage+0x5242430&&Pointer(table)==expectedImage+0x1E110C0&&
Pointer(table+8)==expectedImage+0x201130&&Pointer(table+0x50)==expectedImage+0x1E220B0;
}
static ushort GalaxyServiceMask(ReadOnlySpan<byte> summary)
{
if(summary.Length!=6)throw new ArgumentException("Original service summary requires six bytes.");
ushort mask=0;
// Exact3B26860 jump table, independent of original Settings34.
for(var index=0;index<4;index++)if(summary[2]==index+1)mask|=(ushort)(1<<index);
for(var index=4;index<6;index++)if(summary[3]==index-3)mask|=(ushort)(1<<index);
if(summary[1]!=0)mask|=1<<6;
if(summary[0]!=0)mask|=1<<7;
if(summary[4]!=0)mask|=1<<8;
if(summary[5]!=0)mask|=1<<9;
return mask;
}
static bool CopyGalaxyServiceFacts(nuint source,nuint expectedImage,ulong address,out GalaxyServiceFact? result)
{
result=null;
if(address==0||address>=1UL<<55)return false;
try
{
if(!GalaxyServiceSource(source,expectedImage))return false;
// Actual1E22170 uses644BD0 on interface+118. Map+8=count,
// +10=capacity, +18=bit storage; records are16bytes, key+0,
// six-byte summary+8. Initial zero-capacity has no published table.
var map=source+0x118;var count=Read<ulong>(map+8);var capacity=Read<ulong>(map+0x10);var storage=Pointer(map+0x18);
if(count==0&&capacity==0&&storage==0)return true;
if(capacity is <8 or >1_048_576||(capacity&(capacity-1))!=0||count>=capacity||storage<0x10000)return false;
var rows=storage+(nuint)(((capacity>>3)+7)&~7UL);var slot=GalaxyFactHash(address)&(capacity-1);
var found=(nuint)0;var ended=false;var bitAddress=(nuint)0;ulong observedBits=0;
var maximum=(int)Math.Min(count+1,4096UL);
for(var attempt=0;attempt<maximum;attempt++,slot=(slot+1)&(capacity-1))
{
bitAddress=storage+(nuint)(slot>>6)*8;observedBits=Read<ulong>(bitAddress);
if((observedBits&(1UL<<(int)(slot&63)))==0){ended=true;break;}
if(count==0)return false;
var row=rows+(nuint)slot*16;
if(Read<ulong>(row)==address){found=row;ended=true;break;}
}
if(!ended)return false;
var bytes=found==0?null:Platform.ReadBytes(found+8,6);
if(!GalaxyServiceSource(source,expectedImage)||Read<ulong>(map+8)!=count||Read<ulong>(map+0x10)!=capacity||
Pointer(map+0x18)!=storage||Read<ulong>(bitAddress)!=observedBits)return false;
if(found!=0&&(Read<ulong>(found)!=address||!Platform.ReadBytes(found+8,6).AsSpan().SequenceEqual(bytes)))return false;
// A stable missing-key result is exactly the six zero bytes written
// by original1E22170, not a public-catalogue absence inference.
result=new(bytes is null?(ushort)0:GalaxyServiceMask(bytes),found==0);return true;
}
catch{result=null;return false;}
}
static bool TryReadGalaxyServiceFacts(GalaxyFilterContext context,nuint registry,ulong address,out GalaxyServiceFact? result)
{
result=null;
if(!Enabled()||!inGame||context.expectedImage!=image||context.thread==0||context.thread!=owningThread||
GetCurrentThreadId()!=context.thread||GetTickCount64()-context.tick>500||registry<0x10000)return false;
var frame=Current();
if(!frame.valid||frame.entity!=context.entity||(frame.referenceWorld&0x007FFFFFFFFFFFFFUL)!=context.currentSystem)return false;
try
{
var source=RegisteredComponent(registry,Read<uint>(image+0x5F856E8));
if(!CopyGalaxyServiceFacts(source,image,address,out var copied)||
RegisteredComponent(registry,Read<uint>(image+0x5F856E8))!=source)return false;
result=copied;return true;
}
catch{return false;}
}
}
namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
internal readonly record struct GalaxyServiceFact(ushort mask,bool defaulted);
// ED5A, paired old1DD2560/5242560/+50=1E22170. No original getter is called.
static bool GalaxyServiceSource(nuint source,nuint expectedImage)
{
if(source<0x10058)return false;
var table=Pointer(source);
return table==expectedImage+0x5242530&&Pointer(source-0x58)==expectedImage+0x52423E8&&
Pointer(source-0x50)==expectedImage+0x5242430&&Pointer(table)==expectedImage+0x1E110C0&&
Pointer(table+8)==expectedImage+0x201130&&Pointer(table+0x50)==expectedImage+0x1E220B0;
}
static ushort GalaxyServiceMask(ReadOnlySpan<byte> summary)
{
if(summary.Length!=6)throw new ArgumentException("Original service summary requires six bytes.");
ushort mask=0;
// Exact3B26860 jump table, independent of original Settings34.
for(var index=0;index<4;index++)if(summary[2]==index+1)mask|=(ushort)(1<<index);
for(var index=4;index<6;index++)if(summary[3]==index-3)mask|=(ushort)(1<<index);
if(summary[1]!=0)mask|=1<<6;
if(summary[0]!=0)mask|=1<<7;
if(summary[4]!=0)mask|=1<<8;
if(summary[5]!=0)mask|=1<<9;
return mask;
}
static bool CopyGalaxyServiceFacts(nuint source,nuint expectedImage,ulong address,out GalaxyServiceFact? result)
{
result=null;
if(address==0||address>=1UL<<55)return false;
try
{
if(!GalaxyServiceSource(source,expectedImage))return false;
// Actual1E22170 uses644BD0 on interface+118. Map+8=count,
// +10=capacity, +18=bit storage; records are16bytes, key+0,
// six-byte summary+8. Initial zero-capacity has no published table.
var map=source+0x118;var count=Read<ulong>(map+8);var capacity=Read<ulong>(map+0x10);var storage=Pointer(map+0x18);
if(count==0&&capacity==0&&storage==0)return true;
if(capacity is <8 or >1_048_576||(capacity&(capacity-1))!=0||count>=capacity||storage<0x10000)return false;
var rows=storage+(nuint)(((capacity>>3)+7)&~7UL);var slot=GalaxyFactHash(address)&(capacity-1);
var found=(nuint)0;var ended=false;var bitAddress=(nuint)0;ulong observedBits=0;
var maximum=(int)Math.Min(count+1,4096UL);
for(var attempt=0;attempt<maximum;attempt++,slot=(slot+1)&(capacity-1))
{
bitAddress=storage+(nuint)(slot>>6)*8;observedBits=Read<ulong>(bitAddress);
if((observedBits&(1UL<<(int)(slot&63)))==0){ended=true;break;}
if(count==0)return false;
var row=rows+(nuint)slot*16;
if(Read<ulong>(row)==address){found=row;ended=true;break;}
}
if(!ended)return false;
var bytes=found==0?null:Platform.ReadBytes(found+8,6);
if(!GalaxyServiceSource(source,expectedImage)||Read<ulong>(map+8)!=count||Read<ulong>(map+0x10)!=capacity||
Pointer(map+0x18)!=storage||Read<ulong>(bitAddress)!=observedBits)return false;
if(found!=0&&(Read<ulong>(found)!=address||!Platform.ReadBytes(found+8,6).AsSpan().SequenceEqual(bytes)))return false;
// A stable missing-key result is exactly the six zero bytes written
// by original1E22170, not a public-catalogue absence inference.
result=new(bytes is null?(ushort)0:GalaxyServiceMask(bytes),found==0);return true;
}
catch{result=null;return false;}
}
static bool TryReadGalaxyServiceFacts(GalaxyFilterContext context,nuint registry,ulong address,out GalaxyServiceFact? result)
{
result=null;
if(!Enabled()||!inGame||context.expectedImage!=image||context.thread==0||context.thread!=owningThread||
GetCurrentThreadId()!=context.thread||GetTickCount64()-context.tick>500||registry<0x10000)return false;
var frame=Current();
if(!frame.valid||frame.entity!=context.entity||(frame.referenceWorld&0x007FFFFFFFFFFFFFUL)!=context.currentSystem)return false;
try
{
var source=RegisteredComponent(registry,Read<uint>(image+0x5F856E8));
if(!CopyGalaxyServiceFacts(source,image,address,out var copied)||
RegisteredComponent(registry,Read<uint>(image+0x5F856E8))!=source)return false;
result=copied;return true;
}
catch{return false;}
}
}