using System.Text.Json;
namespace XFEEDToolBox.Core.Galaxy;
/// <summary>Original State classification after its pseudo-unpopulated override.
/// Key and colour come from the actual State provider, independently of its
/// current selection and animation. A raw ID without a provider row stays unknown.</summary>
public sealed record GalaxyNativeStateFact(uint StateId,bool PseudoUnpopulated,bool Defaulted,string? Key,IReadOnlyList<float>? RawRgba)
{
public string? NormalizedKey=>string.IsNullOrWhiteSpace(Key)?null:GalaxyMapFilter.Normalize(Key) is{Length:>0} key?key:null;
public static GalaxyNativeStateFact? FromWire(JsonElement value)
{
if(value.ValueKind==JsonValueKind.Null)return null;
if(value.ValueKind!=JsonValueKind.Object||!value.TryGetProperty("stateId",out var id)||id.ValueKind!=JsonValueKind.Number||!id.TryGetUInt32(out var state))
throw new InvalidDataException("原状态分类编号无效。");
bool Flag(string name)
{
if(!value.TryGetProperty(name,out var flag)||flag.ValueKind is not(JsonValueKind.True or JsonValueKind.False))
throw new InvalidDataException("原状态分类来源无效。");
return flag.GetBoolean();
}
var pseudo=Flag("pseudoUnpopulated");var defaulted=Flag("defaulted");
if(pseudo&&state!=39||defaulted&&(state!=0||pseudo))throw new InvalidDataException("原状态分类来源不一致。");
if(!value.TryGetProperty("key",out var keyField)||keyField.ValueKind is not(JsonValueKind.String or JsonValueKind.Null))
throw new InvalidDataException("原状态分类键无效。");
var key=keyField.GetString();
if(key is not null&&(string.IsNullOrWhiteSpace(key)||key.Length>128||GalaxyMapFilter.Normalize(key).Length==0))
throw new InvalidDataException("原状态分类键无效。");
if(!value.TryGetProperty("rawRgba",out var colour))throw new InvalidDataException("原状态颜色回执缺失。");
float[]? rgba=null;
if(colour.ValueKind!=JsonValueKind.Null)
{
if(colour.ValueKind!=JsonValueKind.Array||colour.GetArrayLength()!=4||key is null)throw new InvalidDataException("原状态颜色回执无效。");
rgba=new float[4];var index=0;
foreach(var channel in colour.EnumerateArray())
{
if(channel.ValueKind!=JsonValueKind.Number||!channel.TryGetSingle(out var number)||!float.IsFinite(number)||number<0)
throw new InvalidDataException("原状态颜色通道无效。");
rgba[index++]=number;
}
}
if((key is null)!=(rgba is null))throw new InvalidDataException("原状态分类键与颜色来源不一致。");
return new(state,pseudo,defaulted,key,rgba);
}
}
public sealed partial record GalaxyNativeSystemFacts
{
public GalaxyNativeStateFact? State {get;init;}
public bool StateRequested {get;init;}
}
using System.Text.Json;
namespace XFEEDToolBox.Core.Galaxy;
/// <summary>Original State classification after its pseudo-unpopulated override.
/// Key and colour come from the actual State provider, independently of its
/// current selection and animation. A raw ID without a provider row stays unknown.</summary>
public sealed record GalaxyNativeStateFact(uint StateId,bool PseudoUnpopulated,bool Defaulted,string? Key,IReadOnlyList<float>? RawRgba)
{
public string? NormalizedKey=>string.IsNullOrWhiteSpace(Key)?null:GalaxyMapFilter.Normalize(Key) is{Length:>0} key?key:null;
public static GalaxyNativeStateFact? FromWire(JsonElement value)
{
if(value.ValueKind==JsonValueKind.Null)return null;
if(value.ValueKind!=JsonValueKind.Object||!value.TryGetProperty("stateId",out var id)||id.ValueKind!=JsonValueKind.Number||!id.TryGetUInt32(out var state))
throw new InvalidDataException("原状态分类编号无效。");
bool Flag(string name)
{
if(!value.TryGetProperty(name,out var flag)||flag.ValueKind is not(JsonValueKind.True or JsonValueKind.False))
throw new InvalidDataException("原状态分类来源无效。");
return flag.GetBoolean();
}
var pseudo=Flag("pseudoUnpopulated");var defaulted=Flag("defaulted");
if(pseudo&&state!=39||defaulted&&(state!=0||pseudo))throw new InvalidDataException("原状态分类来源不一致。");
if(!value.TryGetProperty("key",out var keyField)||keyField.ValueKind is not(JsonValueKind.String or JsonValueKind.Null))
throw new InvalidDataException("原状态分类键无效。");
var key=keyField.GetString();
if(key is not null&&(string.IsNullOrWhiteSpace(key)||key.Length>128||GalaxyMapFilter.Normalize(key).Length==0))
throw new InvalidDataException("原状态分类键无效。");
if(!value.TryGetProperty("rawRgba",out var colour))throw new InvalidDataException("原状态颜色回执缺失。");
float[]? rgba=null;
if(colour.ValueKind!=JsonValueKind.Null)
{
if(colour.ValueKind!=JsonValueKind.Array||colour.GetArrayLength()!=4||key is null)throw new InvalidDataException("原状态颜色回执无效。");
rgba=new float[4];var index=0;
foreach(var channel in colour.EnumerateArray())
{
if(channel.ValueKind!=JsonValueKind.Number||!channel.TryGetSingle(out var number)||!float.IsFinite(number)||number<0)
throw new InvalidDataException("原状态颜色通道无效。");
rgba[index++]=number;
}
}
if((key is null)!=(rgba is null))throw new InvalidDataException("原状态分类键与颜色来源不一致。");
return new(state,pseudo,defaulted,key,rgba);
}
}
public sealed partial record GalaxyNativeSystemFacts
{
public GalaxyNativeStateFact? State {get;init;}
public bool StateRequested {get;init;}
}