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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text.Json;

namespace XFEEDToolBox.Core.Galaxy;

public sealed record GalaxyNativeCommodityOption(uint Uid,string Name,string Category,int Kind,bool? PublisherEligible);
public sealed record GalaxyCommodityOptionsSnapshot(bool Available,IReadOnlyList<GalaxyNativeCommodityOption> Options,int UnresolvedCount)
{
    public bool Complete=>false;
}

public sealed partial class NativeGalaxyAccountCatalog
{
    public async Task<GalaxyCommodityOptionsSnapshot> ReadCommodityOptionsAsync(CancellationToken token=default)
    {
        var page=await pipe.CallAsync(new{op="galaxy.commodities",limit=16},token);
        if(!page.GetProperty("available").GetBoolean())return new(false,[],0);
        var generation=page.GetProperty("generation").GetUInt64();var total=page.GetProperty("total").GetInt32();var entity=page.GetProperty("entityId").GetString();var unresolved=page.GetProperty("unresolvedCount").GetInt32();
        if(generation==0||total is <0 or >4096||unresolved is <0 or >4096||string.IsNullOrEmpty(entity)||page.GetProperty("complete").GetBoolean())throw new InvalidDataException("原商品定义快照标识无效。");
        var result=new List<GalaxyNativeCommodityOption>();var ids=new HashSet<uint>();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||page.GetProperty("unresolvedCount").GetInt32()!=unresolved||page.GetProperty("complete").GetBoolean())throw new InvalidDataException("原商品定义读取期间来源发生变化。");
            var items=page.GetProperty("items");if(items.ValueKind!=JsonValueKind.Array||items.GetArrayLength()>16)throw new InvalidDataException("原商品定义分页无效。");
            foreach(var item in items.EnumerateArray())
            {
                var uid=item.GetProperty("uid").GetUInt32();var name=item.GetProperty("name").GetString();var category=item.GetProperty("category").GetString();var kind=item.GetProperty("kind").GetInt32();
                var eligibility=item.GetProperty("publisherEligible");bool? eligible=eligibility.ValueKind==JsonValueKind.Null?null:eligibility.GetBoolean();
                if(uid==uint.MaxValue||!ids.Add(uid)||string.IsNullOrWhiteSpace(name)||name.Length>256||name.Any(char.IsControl)||category is null||category.Length>256||category.Any(char.IsControl)||kind is not(1 or 2)||kind==1&&eligible!=true)throw new InvalidDataException("原商品定义条目无效。");
                result.Add(new(uid,name,category,kind,eligible));
            }
            offset+=items.GetArrayLength();var next=page.GetProperty("nextOffset");
            if(next.ValueKind==JsonValueKind.Null){if(offset!=total)throw new InvalidDataException("原商品定义缺失分页。");break;}
            if(items.GetArrayLength()==0||next.GetInt32()!=offset||offset>=total)throw new InvalidDataException("原商品定义分页顺序无效。");
            page=await pipe.CallAsync(new{op="galaxy.commodities",limit=16,offset,generation},token);
        }
        return new(true,result,unresolved);
    }
}