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;

namespace XFEEDToolBox.Core.Galaxy;

public sealed record GalaxyFleetItem(int Id,uint ShipId,long SystemAddress);
public sealed record GalaxyFleetSnapshot(bool Available,uint? CurrentShipId,IReadOnlyList<GalaxyFleetItem> Ships)
{
    public bool Complete=>false;
}
public sealed record GalaxyFleetMapTarget(int Id,uint ShipId,long SystemAddress,string Label);

public sealed partial class NativeGalaxyAccountCatalog
{
    public async Task<GalaxyFleetSnapshot> ReadFleetAsync(CancellationToken token=default)
    {
        var page=await pipe.CallAsync(new{op="galaxy.fleet",limit=96},token);
        if(!page.GetProperty("available").GetBoolean())return new(false,null,[]);
        var generation=page.GetProperty("generation").GetUInt64();var total=page.GetProperty("total").GetInt32();var entity=page.GetProperty("entityId").GetString();
        uint? Current(JsonElement p)
        {
            var value=p.GetProperty("currentShipId");if(value.ValueKind==JsonValueKind.Null)return null;
            if(!value.TryGetUInt32(out var id)||id==uint.MaxValue)throw new InvalidDataException("原游戏当前飞船 ID 无效。");return id;
        }
        var current=Current(page);
        if(generation==0||total is <0 or >4096||string.IsNullOrEmpty(entity))throw new InvalidDataException("原游戏飞船快照标识无效。");
        var ships=new List<GalaxyFleetItem>();var offset=0;
        while(true)
        {
            token.ThrowIfCancellationRequested();
            if(!page.GetProperty("available").GetBoolean()||page.GetProperty("generation").GetUInt64()!=generation||page.GetProperty("entityId").GetString()!=entity||page.GetProperty("total").GetInt32()!=total||Current(page)!=current)
                throw new InvalidDataException("原游戏飞船快照已变化,请重试。");
            var rows=page.GetProperty("items");if(rows.ValueKind!=JsonValueKind.Array||rows.GetArrayLength()>96||offset+rows.GetArrayLength()>total)throw new InvalidDataException("原游戏飞船分页无效。");
            foreach(var row in rows.EnumerateArray())
            {
                var id=row.GetProperty("id").GetInt32();var shipId=row.GetProperty("shipId").GetUInt32();
                if(id!=ships.Count+1||shipId==uint.MaxValue||current==shipId||!long.TryParse(row.GetProperty("systemAddress").GetString(),NumberStyles.None,CultureInfo.InvariantCulture,out var address)||address<=0||address>=1L<<55)
                    throw new InvalidDataException("原游戏飞船条目无效。");
                // AS id is the original filtered one-based ordinal, never a
                // ship ID or a Galactic address. Preserve repeated systems.
                ships.Add(new(id,shipId,address));
            }
            offset+=rows.GetArrayLength();if(offset==total)break;if(rows.GetArrayLength()==0)throw new InvalidDataException("原游戏飞船分页未继续。");
            page=await pipe.CallAsync(new{op="galaxy.fleet",generation,offset,limit=96},token);
        }
        return new(true,current,ships);
    }
}