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);
}
}
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);
}
}