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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

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

namespace XFEEDToolBox.Plugin;

internal static unsafe partial class Navigation
{
    static readonly int[] GalaxyRouteChoiceCategories=[2,3,4,6,7,8,10];
    internal sealed record GalaxyRouteCategoryChoices(int categoryId,GalaxyRouteCheckboxChoice[]? choices,bool? affectsRoutePlotting);
    internal sealed record GalaxyRouteChoices(ulong tick,ulong contextSystemAddress,GalaxyRouteCategoryChoices[] categories);
    sealed partial record GalaxyCatalogueProfile {internal GalaxyRouteChoices? routeFilterChoices {get;init;}}

    static GalaxyRouteChoices? CopyGalaxyCatalogueRouteChoices(Snapshot frame,GalaxyServices services)
    {
        try
        {
            if(!Enabled()||!inGame||!frame.valid||frame.entity==0||owningThread==0||GetCurrentThreadId()!=owningThread)return null;
            var type=Read<uint>(image+0x5FDB224);var component=RegisteredComponent(services.registry,type);
            if(!CopyGameRouteOptions(component,image,out var main,out _))return null;
            var controller=Pointer(main+0x288);var result=new List<GalaxyRouteCategoryChoices>(7);
            foreach(var category in GalaxyRouteChoiceCategories)
            {
                var copied=DiscoverGalaxyRouteCheckboxState(main,image,category,out var state)&&state is not null;
                result.Add(new(category,copied?state!.choices:null,copied?state!.actualAffects:null));
            }
            var current=Current();
            if(!current.valid||current.entity!=frame.entity||current.referenceWorld!=frame.referenceWorld||
               Read<uint>(image+0x5FDB224)!=type||RegisteredComponent(services.registry,type)!=component||
               !CopyGameRouteOptions(component,image,out var confirmed,out _)||confirmed!=main||Pointer(main+0x288)!=controller)return null;
            return new(GetTickCount64(),frame.referenceWorld&0x007FFFFFFFFFFFFFUL,result.ToArray());
        }
        catch{return null;}
    }

    static JsonObject? GalaxyRouteChoicesDescription(GalaxyRouteChoices? source)
    {
        if(source is null)return null;
        var categories=new JsonArray();var bytes=0;
        foreach(var category in source.categories)
        {
            var rows=category.choices is null?null:new JsonArray(category.choices.Select(c=>(JsonNode?)Obj(("index",c.index),("settingsName",c.settingsName),("key",c.key),("selected",c.selected))).ToArray());
            var row=Obj(("categoryId",category.categoryId),("choices",rows),("affectsRoutePlotting",category.affectsRoutePlotting));
            var length=System.Text.Encoding.UTF8.GetByteCount(row.ToJsonString());
            // Optional choices cannot overflow the profile's36k point page or
            // defer basic LOD. A whole oversized category remains unknown.
            if(bytes+length>12000)row=Obj(("categoryId",category.categoryId),("choices",null),("affectsRoutePlotting",null));
            bytes+=System.Text.Encoding.UTF8.GetByteCount(row.ToJsonString());categories.Add((JsonNode)row);
        }
        return Obj(("scope","current-original-route-filter-choices"),("capturedAtTick",source.tick.ToString(CultureInfo.InvariantCulture)),
            ("contextSystemAddress",source.contextSystemAddress.ToString(CultureInfo.InvariantCulture)),("categories",categories));
    }
}