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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.IO.Compression;
using System.Numerics;
using System.Security.Cryptography;
using System.Text.Json;
using XFEEDToolBox.Core.Models;

namespace XFEEDToolBox.Core.Rendering;

/// <summary>Exact SectorLine diffuse texture, including the eight authored pattern rows.</summary>
public sealed class GalaxyOriginalGridTexture
{
    public const int Width=512,Height=512,MipCount=10,PayloadBytes=353280;
    public const string PayloadSha256="218423e603214f4957bfbc49cab9d91c22f088acdc01a845b079864e589b68bb";
    public static GalaxyOriginalGridTexture Reference {get;}=Read();
    public ReadOnlyMemory<byte> Payload {get;}
    public IReadOnlyList<GalaxyOriginalSpriteMip> Mips {get;}
    // Original3AB44E0 writes rendercfg+98 through the named scalar wrappers.
    // Keep the shader's Radius,RadiusFar,Range,RangeFar order explicit.
    public Vector4 AuthoredFade {get;}
    private GalaxyOriginalGridTexture(JsonElement metadata,byte[] payload)
    {
        if(metadata.GetProperty("sourceFormat").GetInt32()!=107||metadata.GetProperty("nativeFormat").GetInt32()!=98||
           metadata.GetProperty("format").GetString()!="BC7_UNorm"||metadata.GetProperty("width").GetInt32()!=Width||
           metadata.GetProperty("height").GetInt32()!=Height||metadata.GetProperty("mipCount").GetInt32()!=MipCount||
           metadata.GetProperty("viewportSlot").GetInt32()!=8||metadata.GetProperty("configurationLabel").GetString()!="SectorLine"||
           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 columns=Math.Max(1,((Width>>level)+3)/4);var rows=Math.Max(1,((Height>>level)+3)/4);
            if(mip.Offset!=end||mip.Size!=mip.SliceBytes||mip.RowPitch<columns*16||mip.SliceBytes<mip.RowPitch*rows)
                throw new InvalidDataException("原银河网格线条布局无效。");
            end=checked(end+mip.Size);
        }
        if(end!=payload.Length)throw new InvalidDataException("原银河网格线条数据不完整。");
        var fade=metadata.GetProperty("runtimeFadeVector").GetProperty("namedValues");
        AuthoredFade=new(fade.GetProperty("gAlphaFadeRadius").GetSingle(),fade.GetProperty("gAlphaFadeRadiusFar").GetSingle(),
            fade.GetProperty("gAlphaFadeRange").GetSingle(),fade.GetProperty("gAlphaFadeRangeFar").GetSingle());
        if(!float.IsFinite(AuthoredFade.X+AuthoredFade.Y+AuthoredFade.Z+AuthoredFade.W)||AuthoredFade.X<=0||AuthoredFade.Y<=0)
            throw new InvalidDataException("原银河网格淡出参数无效。");
        Payload=payload;Mips=Array.AsReadOnly(mips);
    }
    private static GalaxyOriginalGridTexture Read()
    {
        var assembly=typeof(GalaxyOriginalGridTexture).Assembly;
        using var metadata=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-grid-line.json")!;
        using var json=JsonDocument.Parse(metadata);
        using var source=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-grid-line.bc7.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);
    }
}