XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Buffers.Binary;
using System.Globalization;
using System.Text.Json.Nodes;
using static XFEEDToolBox.Plugin.JsonWire;

namespace XFEEDToolBox.Plugin;

internal static unsafe partial class Navigation
{
    internal sealed record GalaxyColonisationHighlight(ulong centreSystemAddress,int eligibilityStatus,float distanceSquared,float radiusSquared,float[] rawRgb);

    // 3B428E0 subtracts independently decoded float coordinates, not world
    // doubles relative to the catalogue origin. Preserve that rounding/order.
    static bool GalaxyColonisationRawPosition(byte[] compact,ulong address,out float x,out float y,out float z)
    {
        x=y=z=0;if(compact.Length!=0x48||address==0||address>=1UL<<55||BinaryPrimitives.ReadUInt64LittleEndian(compact)!=address)return false;
        var m=(int)(address&7);
        x=(float)((((address>>(30-2*m))<<m)&0x3FFF)*320+BinaryPrimitives.ReadUInt16LittleEndian(compact.AsSpan(0x42)))*.03125f;
        y=(float)((((address>>(17-m))<<m)&0x1FFF)*320+BinaryPrimitives.ReadUInt16LittleEndian(compact.AsSpan(0x44)))*.03125f;
        z=(float)((((address>>3)<<m)&0x3FFF)*320+BinaryPrimitives.ReadUInt16LittleEndian(compact.AsSpan(0x46)))*.03125f;
        return true;
    }

    static bool CopyGalaxyColonisationHighlight(nuint provider,nuint navigation,nuint candidate,nuint expectedImage,ulong address,int eligibilityStatus,out GalaxyColonisationHighlight? result)
    {
        result=null;if(provider<0x10000||candidate<0x10000||eligibilityStatus is <0 or >11)return false;
        try
        {
            var table=expectedImage+0x552D920;
            if(Pointer(provider)!=table||Pointer(table+0x20)!=expectedImage+0x3B3E650||Pointer(table+0x50)!=expectedImage+0x3B26B30||
                Pointer(provider+0x160)!=navigation)return false;
            var centreSlot=GalaxyPowerOuterCentreSlot(navigation,expectedImage);if(centreSlot==0)return false;
            var centre=Pointer(provider+0x178);
            // An absent/pending cached navigation object supplies no verified
            // centre. Do not turn its absence into a fabricated galaxy origin.
            if(centre<0x10000||Pointer(centreSlot)!=centre||Read<uint>(centre+0x20)!=2||!GalaxyColonisationLoadedObject(candidate,address))return false;
            var centreAddress=Read<ulong>(centre+0x28);var centreCompact=Pointer(centre+0x38);var candidateCompact=Pointer(candidate+0x38);
            if(centreCompact<0x10000||candidateCompact<0x10000)return false;
            var centreBytes=Platform.ReadBytes(centreCompact,0x48);var candidateBytes=Platform.ReadBytes(candidateCompact,0x48);
            if(!GalaxyColonisationRawPosition(centreBytes,centreAddress,out var cx,out var cy,out var cz)||
                !GalaxyColonisationRawPosition(candidateBytes,address,out var x,out var y,out var z))return false;
            var radius=Read<float>(provider+0x1A0);var colour=Platform.ReadBytes(provider+0x11C,12);
            if(!float.IsFinite(radius)||radius<0||colour.Length!=12)return false;
            var rgb=new float[3];for(var i=0;i<3;i++){rgb[i]=BinaryPrimitives.ReadSingleLittleEndian(colour.AsSpan(i*4));if(!float.IsFinite(rgb[i])||rgb[i]<0)return false;}
            var dx=x-cx;var dy=y-cy;var dz=z-cz;var distance=(dx*dx+dy*dy)+dz*dz;
            if(!float.IsFinite(distance)||Pointer(provider)!=table||Pointer(provider+0x160)!=navigation||Pointer(provider+0x178)!=centre||
                GalaxyPowerOuterCentreSlot(navigation,expectedImage)!=centreSlot||Pointer(centreSlot)!=centre||Read<uint>(centre+0x20)!=2||
                Read<ulong>(centre+0x28)!=centreAddress||Pointer(centre+0x38)!=centreCompact||!GalaxyColonisationLoadedObject(candidate,address)||
                Pointer(candidate+0x38)!=candidateCompact||Read<float>(provider+0x1A0)!=radius||
                !Platform.ReadBytes(provider+0x11C,12).AsSpan().SequenceEqual(colour)||
                !Platform.ReadBytes(centreCompact,0x48).AsSpan().SequenceEqual(centreBytes)||
                !Platform.ReadBytes(candidateCompact,0x48).AsSpan().SequenceEqual(candidateBytes))return false;
            result=new(centreAddress,eligibilityStatus,distance,radius,rgb);return true;
        }
        catch{result=null;return false;}
    }

    static bool TryReadGalaxyColonisationHighlight(GalaxyFilterContext context,GalaxyServices services,nuint candidate,ulong address,int eligibilityStatus,out GalaxyColonisationHighlight? result)
    {
        result=null;
        if(context.expectedImage!=image||context.thread==0||context.thread!=owningThread||GetCurrentThreadId()!=context.thread||
            GetTickCount64()-context.tick>500||services.registry<0x10000)return false;
        try
        {
            var mainComponent=RegisteredComponent(services.registry,Read<uint>(image+0x5FDB224));
            var navigation=RegisteredComponent(services.registry,Read<uint>(image+0x5F05DD4));
            if(!CopyGameRouteOptions(mainComponent,image,out var main,out _)||Read<int>(main+0x280)!=-1)return false;
            var type=Pointer(main+0x288);if(type<0x10028||Pointer(type)!=image+0x552D788)return false;
            var controller=type-0x28;if(Pointer(controller)!=image+0x552D5C0)return false;
            var block=Pointer(controller+0x3D0);var provider=Pointer(controller+0x3D8);
            if(block<0x10000||Read<int>(block+8)<=0||Read<int>(block+0xC)<=0||
                !CopyGalaxyColonisationHighlight(provider,navigation,candidate,image,address,eligibilityStatus,out var copied))return false;
            var frame=Current();
            if(!frame.valid||frame.entity!=context.entity||(frame.referenceWorld&0x007FFFFFFFFFFFFFUL)!=context.currentSystem||
                RegisteredComponent(services.registry,Read<uint>(image+0x5FDB224))!=mainComponent||
                RegisteredComponent(services.registry,Read<uint>(image+0x5F05DD4))!=navigation||
                !CopyGameRouteOptions(mainComponent,image,out var confirmed,out _)||confirmed!=main||Read<int>(main+0x280)!=-1||
                Pointer(main+0x288)!=type||Pointer(type)!=image+0x552D788||Pointer(controller)!=image+0x552D5C0||
                Pointer(controller+0x3D0)!=block||Pointer(controller+0x3D8)!=provider||Read<int>(block+8)<=0||Read<int>(block+0xC)<=0)return false;
            result=copied;return true;
        }
        catch{result=null;return false;}
    }

    static JsonObject? GalaxyColonisationHighlightDescription(GalaxyColonisationHighlight? value)=>value is null?null:Obj(
        ("source","original-colonisation-highlight"),("centreSystemAddress",value.centreSystemAddress.ToString(CultureInfo.InvariantCulture)),
        ("eligibilityStatus",value.eligibilityStatus),("distanceSquared",value.distanceSquared),("radiusSquared",value.radiusSquared),
        ("rawRgb",new JsonArray(value.rawRgb.Select(v=>(JsonNode?)JsonValue.Create(v)).ToArray())));
}