namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
private sealed record DisabledPhysicalContext(string name,nuint entry,nuint nameHeader,nuint graph,nuint nodes,uint nodeCount,
nuint layers,ulong layerCount,byte[] metadata);
private sealed record DisabledPhysicalContexts(nuint registry,nuint buckets,ulong capacity,ulong count,DisabledPhysicalContext[] entries);
private static readonly string[] PhysicalFlightContexts=["Bindings_Flight","Bindings_Flight_Cruising","Bindings_Flight_Landing","Bindings_FreeCameraShipControls","Bindings_Mouse"];
// Current pinned 8F0BA0: entry+28/+30 is the priority-layer array. With
// every layer's +18 occupancy empty, execution takes 8F0D76, clears +38,
// and never calls 4C91960. These checks require both empty layers and an
// already cleared VM; absence of a named button alone is never neutral.
private static bool TryReadDisabledPhysicalContext(nuint entry,string expected,out DisabledPhysicalContext value)
{
value=null!;
if(!PhysicalBindingHeap(entry))return false;
var header=Pointer(entry+8);
if(!TryReadPhysicalBindingName(header,out var name)||!name.Equals(expected,StringComparison.OrdinalIgnoreCase))return false;
var metadata=Platform.ReadBytes(entry+0x10,0x30);var graph=Pointer(entry+0x10);
if(!PhysicalBindingHeap(graph))return false;
var nodes=Pointer(graph);var nodeCount=Read<uint>(graph+8);
var count=Read<ulong>(entry+0x28);var layers=Pointer(entry+0x30);
if(!PhysicalBindingHeap(nodes)||nodeCount is 0 or >4096||count>256||count>0&&!PhysicalBindingHeap(layers)||Pointer(entry+0x38)!=0)return false;
var raw=count==0?[]:Platform.ReadBytes(layers,checked((int)count*32));
for(var index=0;index<(int)count;index++)if(System.Buffers.Binary.BinaryPrimitives.ReadUInt64LittleEndian(raw.AsSpan(index*32+0x18,8))!=0)return false;
if(Pointer(entry+8)!=header||!metadata.AsSpan().SequenceEqual(Platform.ReadBytes(entry+0x10,0x30))
||Pointer(graph)!=nodes||Read<uint>(graph+8)!=nodeCount
||raw.Length>0&&!raw.AsSpan().SequenceEqual(Platform.ReadBytes(layers,raw.Length)))return false;
value=new(name,entry,header,graph,nodes,nodeCount,layers,count,metadata);return true;
}
private static bool DisabledPhysicalContextUnchanged(DisabledPhysicalContext before)
=>TryReadDisabledPhysicalContext(before.entry,before.name,out var after)&&before.nameHeader==after.nameHeader
&&before.graph==after.graph&&before.nodes==after.nodes&&before.nodeCount==after.nodeCount
&&before.layers==after.layers&&before.layerCount==after.layerCount&&before.metadata.AsSpan().SequenceEqual(after.metadata);
private static bool DisabledPhysicalContextsUnchanged(DisabledPhysicalContexts before)
=>Pointer(before.registry+0x78)==before.buckets&&Read<ulong>(before.registry+0x80)==before.capacity
&&Read<ulong>(before.registry+0x90)==before.count&&before.entries.Length==PhysicalFlightContexts.Length
&&before.entries.All(DisabledPhysicalContextUnchanged);
private static bool TryCaptureDisabledPhysicalContexts(nuint registry,out DisabledPhysicalContexts proof)
{
proof=null!;
if(!TryReadPhysicalBindingMap(registry,out _))return false;
var buckets=Pointer(registry+0x78);var capacity=Read<ulong>(registry+0x80);var count=Read<ulong>(registry+0x90);
if(!PhysicalBindingHeap(buckets)||capacity is 0 or >8192||count is 0 or >4096)return false;
var entries=new List<DisabledPhysicalContext>();var seen=new HashSet<nuint>();
for(nuint index=0;index<(nuint)capacity;index++)
{
var head=buckets+index*8;var item=Pointer(head);
while(item!=head)
{
if(!PhysicalBindingHeap(item)||item>=buckets&&item<buckets+(nuint)capacity*8||!seen.Add(item)||(ulong)seen.Count>count
||!TryReadPhysicalBindingName(Pointer(item+8),out var name))return false;
var expected=PhysicalFlightContexts.FirstOrDefault(value=>value.Equals(name,StringComparison.OrdinalIgnoreCase));
if(expected is not null)
{
if(entries.Any(value=>value.name.Equals(expected,StringComparison.OrdinalIgnoreCase))
||!TryReadDisabledPhysicalContext(item,expected,out var entry))return false;
entries.Add(entry);
}
item=Pointer(item);
}
}
if((ulong)seen.Count!=count||entries.Count!=PhysicalFlightContexts.Length)return false;
proof=new(registry,buckets,capacity,count,entries.ToArray());return DisabledPhysicalContextsUnchanged(proof);
}
private static bool DisabledPhysicalContextConfirmed(ulong initialSequence,ulong initialTick,ulong sequence,ulong now)
=>sequence>initialSequence&&now>=initialTick&&now-initialTick>=50;
private static bool PhysicalInputContextSelfTest()
{
var memory=Platform.Allocate(4096);if(memory==0)return false;
try
{
var entry=memory;var header=memory+256;var graph=memory+512;var nodes=memory+768;var layers=memory+1024;
var name="Bindings_Flight";Write(header,(ulong)name.Length);Write(header+8,(ulong)name.Length);Write(header+0x10,1);
System.Text.Encoding.ASCII.GetBytes(name).AsSpan().CopyTo(new Span<byte>((void*)(header+0x14),name.Length));Write(header+0x14+(nuint)name.Length,(byte)0);
Write(entry+8,header);Write(entry+0x10,graph);Write(graph,nodes);Write(graph+8,1u);
Write(entry+0x28,2UL);Write(entry+0x30,layers);Write(entry+0x38,(nuint)0);
Write(layers+0x18,0UL);Write(layers+0x38,0UL);
if(!TryReadDisabledPhysicalContext(entry,name,out var disabled)||!DisabledPhysicalContextUnchanged(disabled))return false;
// A newly admitted layer invalidates even before its VM exists.
Write(layers+0x38,1UL);if(DisabledPhysicalContextUnchanged(disabled))return false;Write(layers+0x38,0UL);
// A retained VM is not accepted during the original teardown.
Write(entry+0x38,memory+2048);if(DisabledPhysicalContextUnchanged(disabled))return false;Write(entry+0x38,(nuint)0);
Write(entry+0x10,graph+8);if(DisabledPhysicalContextUnchanged(disabled))return false;Write(entry+0x10,graph);
if(TryReadDisabledPhysicalContext(entry,"Bindings_Mouse",out _)||DisabledPhysicalContextConfirmed(1,100,1,200)
||DisabledPhysicalContextConfirmed(1,100,2,149)||!DisabledPhysicalContextConfirmed(1,100,2,150))return false;
return DisabledPhysicalContextUnchanged(disabled);
}
catch{return false;}
finally{Platform.Free(memory);}
}
}
namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
private sealed record DisabledPhysicalContext(string name,nuint entry,nuint nameHeader,nuint graph,nuint nodes,uint nodeCount,
nuint layers,ulong layerCount,byte[] metadata);
private sealed record DisabledPhysicalContexts(nuint registry,nuint buckets,ulong capacity,ulong count,DisabledPhysicalContext[] entries);
private static readonly string[] PhysicalFlightContexts=["Bindings_Flight","Bindings_Flight_Cruising","Bindings_Flight_Landing","Bindings_FreeCameraShipControls","Bindings_Mouse"];
// Current pinned 8F0BA0: entry+28/+30 is the priority-layer array. With
// every layer's +18 occupancy empty, execution takes 8F0D76, clears +38,
// and never calls 4C91960. These checks require both empty layers and an
// already cleared VM; absence of a named button alone is never neutral.
private static bool TryReadDisabledPhysicalContext(nuint entry,string expected,out DisabledPhysicalContext value)
{
value=null!;
if(!PhysicalBindingHeap(entry))return false;
var header=Pointer(entry+8);
if(!TryReadPhysicalBindingName(header,out var name)||!name.Equals(expected,StringComparison.OrdinalIgnoreCase))return false;
var metadata=Platform.ReadBytes(entry+0x10,0x30);var graph=Pointer(entry+0x10);
if(!PhysicalBindingHeap(graph))return false;
var nodes=Pointer(graph);var nodeCount=Read<uint>(graph+8);
var count=Read<ulong>(entry+0x28);var layers=Pointer(entry+0x30);
if(!PhysicalBindingHeap(nodes)||nodeCount is 0 or >4096||count>256||count>0&&!PhysicalBindingHeap(layers)||Pointer(entry+0x38)!=0)return false;
var raw=count==0?[]:Platform.ReadBytes(layers,checked((int)count*32));
for(var index=0;index<(int)count;index++)if(System.Buffers.Binary.BinaryPrimitives.ReadUInt64LittleEndian(raw.AsSpan(index*32+0x18,8))!=0)return false;
if(Pointer(entry+8)!=header||!metadata.AsSpan().SequenceEqual(Platform.ReadBytes(entry+0x10,0x30))
||Pointer(graph)!=nodes||Read<uint>(graph+8)!=nodeCount
||raw.Length>0&&!raw.AsSpan().SequenceEqual(Platform.ReadBytes(layers,raw.Length)))return false;
value=new(name,entry,header,graph,nodes,nodeCount,layers,count,metadata);return true;
}
private static bool DisabledPhysicalContextUnchanged(DisabledPhysicalContext before)
=>TryReadDisabledPhysicalContext(before.entry,before.name,out var after)&&before.nameHeader==after.nameHeader
&&before.graph==after.graph&&before.nodes==after.nodes&&before.nodeCount==after.nodeCount
&&before.layers==after.layers&&before.layerCount==after.layerCount&&before.metadata.AsSpan().SequenceEqual(after.metadata);
private static bool DisabledPhysicalContextsUnchanged(DisabledPhysicalContexts before)
=>Pointer(before.registry+0x78)==before.buckets&&Read<ulong>(before.registry+0x80)==before.capacity
&&Read<ulong>(before.registry+0x90)==before.count&&before.entries.Length==PhysicalFlightContexts.Length
&&before.entries.All(DisabledPhysicalContextUnchanged);
private static bool TryCaptureDisabledPhysicalContexts(nuint registry,out DisabledPhysicalContexts proof)
{
proof=null!;
if(!TryReadPhysicalBindingMap(registry,out _))return false;
var buckets=Pointer(registry+0x78);var capacity=Read<ulong>(registry+0x80);var count=Read<ulong>(registry+0x90);
if(!PhysicalBindingHeap(buckets)||capacity is 0 or >8192||count is 0 or >4096)return false;
var entries=new List<DisabledPhysicalContext>();var seen=new HashSet<nuint>();
for(nuint index=0;index<(nuint)capacity;index++)
{
var head=buckets+index*8;var item=Pointer(head);
while(item!=head)
{
if(!PhysicalBindingHeap(item)||item>=buckets&&item<buckets+(nuint)capacity*8||!seen.Add(item)||(ulong)seen.Count>count
||!TryReadPhysicalBindingName(Pointer(item+8),out var name))return false;
var expected=PhysicalFlightContexts.FirstOrDefault(value=>value.Equals(name,StringComparison.OrdinalIgnoreCase));
if(expected is not null)
{
if(entries.Any(value=>value.name.Equals(expected,StringComparison.OrdinalIgnoreCase))
||!TryReadDisabledPhysicalContext(item,expected,out var entry))return false;
entries.Add(entry);
}
item=Pointer(item);
}
}
if((ulong)seen.Count!=count||entries.Count!=PhysicalFlightContexts.Length)return false;
proof=new(registry,buckets,capacity,count,entries.ToArray());return DisabledPhysicalContextsUnchanged(proof);
}
private static bool DisabledPhysicalContextConfirmed(ulong initialSequence,ulong initialTick,ulong sequence,ulong now)
=>sequence>initialSequence&&now>=initialTick&&now-initialTick>=50;
private static bool PhysicalInputContextSelfTest()
{
var memory=Platform.Allocate(4096);if(memory==0)return false;
try
{
var entry=memory;var header=memory+256;var graph=memory+512;var nodes=memory+768;var layers=memory+1024;
var name="Bindings_Flight";Write(header,(ulong)name.Length);Write(header+8,(ulong)name.Length);Write(header+0x10,1);
System.Text.Encoding.ASCII.GetBytes(name).AsSpan().CopyTo(new Span<byte>((void*)(header+0x14),name.Length));Write(header+0x14+(nuint)name.Length,(byte)0);
Write(entry+8,header);Write(entry+0x10,graph);Write(graph,nodes);Write(graph+8,1u);
Write(entry+0x28,2UL);Write(entry+0x30,layers);Write(entry+0x38,(nuint)0);
Write(layers+0x18,0UL);Write(layers+0x38,0UL);
if(!TryReadDisabledPhysicalContext(entry,name,out var disabled)||!DisabledPhysicalContextUnchanged(disabled))return false;
// A newly admitted layer invalidates even before its VM exists.
Write(layers+0x38,1UL);if(DisabledPhysicalContextUnchanged(disabled))return false;Write(layers+0x38,0UL);
// A retained VM is not accepted during the original teardown.
Write(entry+0x38,memory+2048);if(DisabledPhysicalContextUnchanged(disabled))return false;Write(entry+0x38,(nuint)0);
Write(entry+0x10,graph+8);if(DisabledPhysicalContextUnchanged(disabled))return false;Write(entry+0x10,graph);
if(TryReadDisabledPhysicalContext(entry,"Bindings_Mouse",out _)||DisabledPhysicalContextConfirmed(1,100,1,200)
||DisabledPhysicalContextConfirmed(1,100,2,149)||!DisabledPhysicalContextConfirmed(1,100,2,150))return false;
return DisabledPhysicalContextUnchanged(disabled);
}
catch{return false;}
finally{Platform.Free(memory);}
}
}