namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
internal sealed class GalaxyPowerActivityContext
{
internal nuint expectedImage,service,owner;
internal ulong tick,entity,currentSystem;
internal uint thread;
internal int optionCount;
internal Dictionary<int,int> indices=[];
}
// Evidence RVAs refer to pinned 6891: 3B1CFA0, 1412900, 14121E0,
// 1412A90 and 1414100. Current vtables below are verified ED5A addresses
// from the shared compatibility ledger and existing PowerOptions reader.
// This port calls no getter: 1414100 writes the original last-key cache.
static bool GalaxyPowerActivitySource(nuint service,nuint expectedImage,nuint owner)
{
try
{
return service>=0x10058&&owner>=0x10000&&Pointer(service)==expectedImage+0x51BB600&&
Pointer(service-0x58)==expectedImage+0x51BB4D0&&Pointer(service-0x50)==expectedImage+0x51BB500&&
Pointer(service-0x48)==owner&&Read<byte>(service+0x308)==1&&Read<byte>(service+0x309)==1&&
Read<byte>(service+0x30A)==1&&Read<byte>(service+0x30C)==0;
}
catch{return false;}
}
static bool TryCreateGalaxyPowerActivityContext(Snapshot frame,GalaxyServices services,out GalaxyPowerActivityContext result)
{
result=new();
if(!Enabled()||!inGame||!frame.valid||frame.entity==0||owningThread==0||GetCurrentThreadId()!=owningThread||services.registry<0x10000)return false;
try
{
var service=RegisteredComponent(services.registry,Read<uint>(image+0x5F3C524));
if(service<0x10058)return false;
var owner=Pointer(service-0x48);
if(!GalaxyPowerActivitySource(service,image,owner)||!CopyGalaxyPowerOptions(service-0x58,owner,image,out var options)||options.Length==0)return false;
var indices=new Dictionary<int,int>(options.Length);
foreach(var option in options)if(!indices.TryAdd(option.internalPowerId,option.index))return false;
if(!GalaxyPowerActivitySource(service,image,owner))return false;
result=new(){expectedImage=image,service=service,owner=owner,tick=GetTickCount64(),entity=frame.entity,
currentSystem=frame.referenceWorld&0x007FFFFFFFFFFFFFUL,thread=owningThread,optionCount=options.Length,indices=indices};
return result.currentSystem!=0;
}
catch{return false;}
}
static uint GalaxyPowerActivityPairHash(ulong address,uint mode)
{
unchecked
{
var hash=mode*0x1001;hash=((hash>>22)^hash)*0x11;hash=((hash>>9)^hash)*0x401;
hash=((hash>>2)^hash)*0x81;hash^=hash>>12;
return (uint)GalaxyFactHash(address)^(hash<<16|hash>>16);
}
}
// Original open-address layouts: metadata stride180/alignment16;
// unoccupied counters stride10/alignment8; controlled pairs stride18/alignment8.
// A valid empty counter table means original getter zero. A missing metadata
// record remains unknown, even though the game getter has a fallback record.
static bool GalaxyPowerActivityFind(nuint map,ulong address,int mode,int stride,int alignment,out nuint node)
{
node=0;
try
{
var count=Read<ulong>(map+8);var capacity=Read<ulong>(map+0x10);var storage=Pointer(map+0x18);
if(count>1_048_576||capacity>2_097_152||count>capacity||capacity!=0&&(capacity&(capacity-1))!=0)return false;
if(count==0)return Read<ulong>(map+8)==0&&Read<ulong>(map+0x10)==capacity&&Pointer(map+0x18)==storage;
if(capacity==0||storage<0x10000)return false;
var rows=storage+(nuint)(((capacity>>3)+(ulong)alignment-1)&~((ulong)alignment-1));
var hash=mode<0?GalaxyFactHash(address):GalaxyPowerActivityPairHash(address,(uint)mode);
var slot=hash&(capacity-1);var ended=false;
for(ulong step=0;step<Math.Min(capacity,4096UL);step++)
{
var bits=Read<ulong>(storage+(nuint)(slot>>6)*8);
if((bits&(1UL<<(int)(slot&63)))==0){ended=true;break;}
var at=rows+(nuint)slot*(nuint)stride;
if(Read<ulong>(at)==address&&(mode<0||Read<uint>(at+8)==mode)){node=at;ended=true;break;}
slot=(slot+1)&(capacity-1);
}
if(!ended||Read<ulong>(map+8)!=count||Read<ulong>(map+0x10)!=capacity||Pointer(map+0x18)!=storage){node=0;return false;}
return true;
}
catch{node=0;return false;}
}
static int GalaxyPowerActivityCounterMode(int action,bool allPowers,ulong ownerIndex,int selectedIndex)
=>allPowers?action==2?0:1:(ownerIndex==(ulong)selectedIndex)==(action!=4)?0:1;
static bool CopyGalaxyPowerActivityCounter(nuint service,nuint expectedImage,nuint owner,ulong address,
bool allPowers,int selectedIndex,int optionCount,int actionId,out float? recentActivity)
{
recentActivity=null;
if(address==0||address>=0x80000000000000UL||actionId is <1 or >5||optionCount is <1 or >128||
!allPowers&&(selectedIndex<0||selectedIndex>=optionCount)||!GalaxyPowerActivitySource(service,expectedImage,owner))return false;
try
{
if(!GalaxyPowerActivityFind(service+0x3C0,address,-1,0x180,16,out var node))return false;
if(node==0)return true;
var metadata=node+0x10;var ownerIndex=Read<ulong>(metadata);var state=Read<int>(metadata+0xC);
if(state<0||state>65535||state!=0&&ownerIndex>=(ulong)optionCount)return false;
float value;
if(actionId==5)value=Read<float>(metadata+0x124);
else if(state==0)
{
if(!GalaxyPowerActivityFind(service+0x3218,address,-1,0x10,8,out var counter))return false;
value=counter==0?0:Read<float>(counter+8);
}
else
{
var mode=GalaxyPowerActivityCounterMode(actionId,allPowers,ownerIndex,selectedIndex);
if(!GalaxyPowerActivityFind(service+0x3240,address,mode,0x18,8,out var counter))return false;
value=counter==0?0:Read<float>(counter+0x14);
}
if(!float.IsFinite(value)||value<0||!GalaxyPowerActivitySource(service,expectedImage,owner)||
Read<ulong>(node)!=address||Read<ulong>(metadata)!=ownerIndex||Read<int>(metadata+0xC)!=state)return false;
recentActivity=value;return true;
}
catch{return false;}
}
static bool TryReadGalaxyPowerActivityCounter(GalaxyPowerActivityContext context,ulong address,
bool allPowers,int actualInternalId,int actionId,out float? recentActivity)
{
recentActivity=null;
if(!Enabled()||!inGame||context.thread==0||context.thread!=owningThread||GetCurrentThreadId()!=context.thread||
GetTickCount64()-context.tick>500||context.expectedImage!=image)return false;
var frame=Current();
if(!frame.valid||frame.entity!=context.entity||(frame.referenceWorld&0x007FFFFFFFFFFFFFUL)!=context.currentSystem)return false;
var index=-1;
if(allPowers?actualInternalId!=-1:!context.indices.TryGetValue(actualInternalId,out index))return false;
return CopyGalaxyPowerActivityCounter(context.service,context.expectedImage,context.owner,address,
allPowers,index,context.optionCount,actionId,out recentActivity);
}
}
namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
internal sealed class GalaxyPowerActivityContext
{
internal nuint expectedImage,service,owner;
internal ulong tick,entity,currentSystem;
internal uint thread;
internal int optionCount;
internal Dictionary<int,int> indices=[];
}
// Evidence RVAs refer to pinned 6891: 3B1CFA0, 1412900, 14121E0,
// 1412A90 and 1414100. Current vtables below are verified ED5A addresses
// from the shared compatibility ledger and existing PowerOptions reader.
// This port calls no getter: 1414100 writes the original last-key cache.
static bool GalaxyPowerActivitySource(nuint service,nuint expectedImage,nuint owner)
{
try
{
return service>=0x10058&&owner>=0x10000&&Pointer(service)==expectedImage+0x51BB600&&
Pointer(service-0x58)==expectedImage+0x51BB4D0&&Pointer(service-0x50)==expectedImage+0x51BB500&&
Pointer(service-0x48)==owner&&Read<byte>(service+0x308)==1&&Read<byte>(service+0x309)==1&&
Read<byte>(service+0x30A)==1&&Read<byte>(service+0x30C)==0;
}
catch{return false;}
}
static bool TryCreateGalaxyPowerActivityContext(Snapshot frame,GalaxyServices services,out GalaxyPowerActivityContext result)
{
result=new();
if(!Enabled()||!inGame||!frame.valid||frame.entity==0||owningThread==0||GetCurrentThreadId()!=owningThread||services.registry<0x10000)return false;
try
{
var service=RegisteredComponent(services.registry,Read<uint>(image+0x5F3C524));
if(service<0x10058)return false;
var owner=Pointer(service-0x48);
if(!GalaxyPowerActivitySource(service,image,owner)||!CopyGalaxyPowerOptions(service-0x58,owner,image,out var options)||options.Length==0)return false;
var indices=new Dictionary<int,int>(options.Length);
foreach(var option in options)if(!indices.TryAdd(option.internalPowerId,option.index))return false;
if(!GalaxyPowerActivitySource(service,image,owner))return false;
result=new(){expectedImage=image,service=service,owner=owner,tick=GetTickCount64(),entity=frame.entity,
currentSystem=frame.referenceWorld&0x007FFFFFFFFFFFFFUL,thread=owningThread,optionCount=options.Length,indices=indices};
return result.currentSystem!=0;
}
catch{return false;}
}
static uint GalaxyPowerActivityPairHash(ulong address,uint mode)
{
unchecked
{
var hash=mode*0x1001;hash=((hash>>22)^hash)*0x11;hash=((hash>>9)^hash)*0x401;
hash=((hash>>2)^hash)*0x81;hash^=hash>>12;
return (uint)GalaxyFactHash(address)^(hash<<16|hash>>16);
}
}
// Original open-address layouts: metadata stride180/alignment16;
// unoccupied counters stride10/alignment8; controlled pairs stride18/alignment8.
// A valid empty counter table means original getter zero. A missing metadata
// record remains unknown, even though the game getter has a fallback record.
static bool GalaxyPowerActivityFind(nuint map,ulong address,int mode,int stride,int alignment,out nuint node)
{
node=0;
try
{
var count=Read<ulong>(map+8);var capacity=Read<ulong>(map+0x10);var storage=Pointer(map+0x18);
if(count>1_048_576||capacity>2_097_152||count>capacity||capacity!=0&&(capacity&(capacity-1))!=0)return false;
if(count==0)return Read<ulong>(map+8)==0&&Read<ulong>(map+0x10)==capacity&&Pointer(map+0x18)==storage;
if(capacity==0||storage<0x10000)return false;
var rows=storage+(nuint)(((capacity>>3)+(ulong)alignment-1)&~((ulong)alignment-1));
var hash=mode<0?GalaxyFactHash(address):GalaxyPowerActivityPairHash(address,(uint)mode);
var slot=hash&(capacity-1);var ended=false;
for(ulong step=0;step<Math.Min(capacity,4096UL);step++)
{
var bits=Read<ulong>(storage+(nuint)(slot>>6)*8);
if((bits&(1UL<<(int)(slot&63)))==0){ended=true;break;}
var at=rows+(nuint)slot*(nuint)stride;
if(Read<ulong>(at)==address&&(mode<0||Read<uint>(at+8)==mode)){node=at;ended=true;break;}
slot=(slot+1)&(capacity-1);
}
if(!ended||Read<ulong>(map+8)!=count||Read<ulong>(map+0x10)!=capacity||Pointer(map+0x18)!=storage){node=0;return false;}
return true;
}
catch{node=0;return false;}
}
static int GalaxyPowerActivityCounterMode(int action,bool allPowers,ulong ownerIndex,int selectedIndex)
=>allPowers?action==2?0:1:(ownerIndex==(ulong)selectedIndex)==(action!=4)?0:1;
static bool CopyGalaxyPowerActivityCounter(nuint service,nuint expectedImage,nuint owner,ulong address,
bool allPowers,int selectedIndex,int optionCount,int actionId,out float? recentActivity)
{
recentActivity=null;
if(address==0||address>=0x80000000000000UL||actionId is <1 or >5||optionCount is <1 or >128||
!allPowers&&(selectedIndex<0||selectedIndex>=optionCount)||!GalaxyPowerActivitySource(service,expectedImage,owner))return false;
try
{
if(!GalaxyPowerActivityFind(service+0x3C0,address,-1,0x180,16,out var node))return false;
if(node==0)return true;
var metadata=node+0x10;var ownerIndex=Read<ulong>(metadata);var state=Read<int>(metadata+0xC);
if(state<0||state>65535||state!=0&&ownerIndex>=(ulong)optionCount)return false;
float value;
if(actionId==5)value=Read<float>(metadata+0x124);
else if(state==0)
{
if(!GalaxyPowerActivityFind(service+0x3218,address,-1,0x10,8,out var counter))return false;
value=counter==0?0:Read<float>(counter+8);
}
else
{
var mode=GalaxyPowerActivityCounterMode(actionId,allPowers,ownerIndex,selectedIndex);
if(!GalaxyPowerActivityFind(service+0x3240,address,mode,0x18,8,out var counter))return false;
value=counter==0?0:Read<float>(counter+0x14);
}
if(!float.IsFinite(value)||value<0||!GalaxyPowerActivitySource(service,expectedImage,owner)||
Read<ulong>(node)!=address||Read<ulong>(metadata)!=ownerIndex||Read<int>(metadata+0xC)!=state)return false;
recentActivity=value;return true;
}
catch{return false;}
}
static bool TryReadGalaxyPowerActivityCounter(GalaxyPowerActivityContext context,ulong address,
bool allPowers,int actualInternalId,int actionId,out float? recentActivity)
{
recentActivity=null;
if(!Enabled()||!inGame||context.thread==0||context.thread!=owningThread||GetCurrentThreadId()!=context.thread||
GetTickCount64()-context.tick>500||context.expectedImage!=image)return false;
var frame=Current();
if(!frame.valid||frame.entity!=context.entity||(frame.referenceWorld&0x007FFFFFFFFFFFFFUL)!=context.currentSystem)return false;
var index=-1;
if(allPowers?actualInternalId!=-1:!context.indices.TryGetValue(actualInternalId,out index))return false;
return CopyGalaxyPowerActivityCounter(context.service,context.expectedImage,context.owner,address,
allPowers,index,context.optionCount,actionId,out recentActivity);
}
}