using System.IO.Compression;
using System.Security.Cryptography;
using System.Text.Json;
using XFEEDToolBox.Core.Models;
namespace XFEEDToolBox.Core.Rendering;
/// <summary>The exact original SimpleBillboardGlow alpha texture and padded BC4 mips.</summary>
public sealed class GalaxyOriginalTerritoryGlow
{
public const int Width=512,Height=512,MipCount=10,PayloadBytes=181248;
public const string PayloadSha256="61adefceaa631e66c4015df5c06b1d9fe154de86cb2d3be693a8be4be20208f9";
public static GalaxyOriginalTerritoryGlow Reference {get;}=Read();
public ReadOnlyMemory<byte> Payload {get;}
public IReadOnlyList<GalaxyOriginalSpriteMip> Mips {get;}
private GalaxyOriginalTerritoryGlow(JsonElement metadata,byte[] payload)
{
if(metadata.GetProperty("sourceFormat").GetInt32()!=101||metadata.GetProperty("nativeFormat").GetInt32()!=80||
metadata.GetProperty("format").GetString()!="BC4_UNorm"||metadata.GetProperty("width").GetInt32()!=Width||
metadata.GetProperty("height").GetInt32()!=Height||metadata.GetProperty("mipCount").GetInt32()!=MipCount||
payload.Length!=PayloadBytes||Convert.ToHexStringLower(SHA256.HashData(payload))!=PayloadSha256)
throw new InvalidDataException("原势力区域辉光纹理校验失败。");
var mips=JsonSerializer.Deserialize<GalaxyOriginalSpriteMip[]>(metadata.GetProperty("mips"),ToolboxSettings.JsonOptions)??[];
if(mips.Length!=MipCount)throw new InvalidDataException("原势力区域辉光层级无效。");
var end=0;
for(var level=0;level<MipCount;level++)
{
var mip=mips[level];var blocksX=Math.Max(1,((Width>>level)+3)/4);var blocksY=Math.Max(1,((Height>>level)+3)/4);
if(mip.Offset!=end||mip.Size!=mip.SliceBytes||mip.RowPitch<blocksX*8||mip.SliceBytes<mip.RowPitch*blocksY)
throw new InvalidDataException("原势力区域辉光布局无效。");
end=checked(end+mip.Size);
}
if(end!=payload.Length)throw new InvalidDataException("原势力区域辉光数据不完整。");
Payload=payload;Mips=Array.AsReadOnly(mips);
}
private static GalaxyOriginalTerritoryGlow Read()
{
var assembly=typeof(GalaxyOriginalTerritoryGlow).Assembly;
using var metadata=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-territory-glow.json")!;
using var json=JsonDocument.Parse(metadata);
using var source=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-territory-glow.bc4.gz")!;
using var gzip=new GZipStream(source,CompressionMode.Decompress);var payload=new byte[PayloadBytes];gzip.ReadExactly(payload);
if(gzip.ReadByte()!=-1)throw new InvalidDataException("原势力区域辉光数据超出范围。");
return new(json.RootElement,payload);
}
}
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text.Json;
using XFEEDToolBox.Core.Models;
namespace XFEEDToolBox.Core.Rendering;
/// <summary>The exact original SimpleBillboardGlow alpha texture and padded BC4 mips.</summary>
public sealed class GalaxyOriginalTerritoryGlow
{
public const int Width=512,Height=512,MipCount=10,PayloadBytes=181248;
public const string PayloadSha256="61adefceaa631e66c4015df5c06b1d9fe154de86cb2d3be693a8be4be20208f9";
public static GalaxyOriginalTerritoryGlow Reference {get;}=Read();
public ReadOnlyMemory<byte> Payload {get;}
public IReadOnlyList<GalaxyOriginalSpriteMip> Mips {get;}
private GalaxyOriginalTerritoryGlow(JsonElement metadata,byte[] payload)
{
if(metadata.GetProperty("sourceFormat").GetInt32()!=101||metadata.GetProperty("nativeFormat").GetInt32()!=80||
metadata.GetProperty("format").GetString()!="BC4_UNorm"||metadata.GetProperty("width").GetInt32()!=Width||
metadata.GetProperty("height").GetInt32()!=Height||metadata.GetProperty("mipCount").GetInt32()!=MipCount||
payload.Length!=PayloadBytes||Convert.ToHexStringLower(SHA256.HashData(payload))!=PayloadSha256)
throw new InvalidDataException("原势力区域辉光纹理校验失败。");
var mips=JsonSerializer.Deserialize<GalaxyOriginalSpriteMip[]>(metadata.GetProperty("mips"),ToolboxSettings.JsonOptions)??[];
if(mips.Length!=MipCount)throw new InvalidDataException("原势力区域辉光层级无效。");
var end=0;
for(var level=0;level<MipCount;level++)
{
var mip=mips[level];var blocksX=Math.Max(1,((Width>>level)+3)/4);var blocksY=Math.Max(1,((Height>>level)+3)/4);
if(mip.Offset!=end||mip.Size!=mip.SliceBytes||mip.RowPitch<blocksX*8||mip.SliceBytes<mip.RowPitch*blocksY)
throw new InvalidDataException("原势力区域辉光布局无效。");
end=checked(end+mip.Size);
}
if(end!=payload.Length)throw new InvalidDataException("原势力区域辉光数据不完整。");
Payload=payload;Mips=Array.AsReadOnly(mips);
}
private static GalaxyOriginalTerritoryGlow Read()
{
var assembly=typeof(GalaxyOriginalTerritoryGlow).Assembly;
using var metadata=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-territory-glow.json")!;
using var json=JsonDocument.Parse(metadata);
using var source=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-territory-glow.bc4.gz")!;
using var gzip=new GZipStream(source,CompressionMode.Decompress);var payload=new byte[PayloadBytes];gzip.ReadExactly(payload);
if(gzip.ReadByte()!=-1)throw new InvalidDataException("原势力区域辉光数据超出范围。");
return new(json.RootElement,payload);
}
}