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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

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

namespace XFEEDToolBox.Core.Rendering;

public sealed record GalaxyOriginalMilkyWayTexture(string Name,string OriginalName,int Width,int Height,int PayloadOffset,int PayloadBytes,
    IReadOnlyList<GalaxyOriginalSpriteMip> Mips);

/// <summary>Exact BC1 cloud atlas and the original colour/height textures.</summary>
public sealed class GalaxyOriginalMilkyWayResources
{
    private readonly byte[] payload;
    public ReadOnlyMemory<byte> Payload=>payload;
    public IReadOnlyList<GalaxyOriginalMilkyWayTexture> Textures {get;}
    public IReadOnlyList<int> AtlasTiles {get;}
    public const int AtlasColumns=3,AtlasRows=5;
    internal GalaxyOriginalMilkyWayResources(JsonElement metadata,byte[] data)
    {
        const string hash="c2755a034d7eb251220ef83b8534eea346218f1d428c1b87d1cdb74a3e2abaaa";
        if(data.Length!=2324480||metadata.GetProperty("payloadSha256").GetString()!=hash||Convert.ToHexStringLower(SHA256.HashData(data))!=hash||
           metadata.GetProperty("atlasColumns").GetInt32()!=AtlasColumns||metadata.GetProperty("atlasRows").GetInt32()!=AtlasRows)
            throw new InvalidDataException("原银河背景纹理校验失败。");
        payload=data;
        Textures=Array.AsReadOnly(metadata.GetProperty("textures").EnumerateArray().Select(t=>new GalaxyOriginalMilkyWayTexture(
            t.GetProperty("name").GetString()!,t.GetProperty("originalName").GetString()!,t.GetProperty("width").GetInt32(),t.GetProperty("height").GetInt32(),
            t.GetProperty("payloadOffset").GetInt32(),t.GetProperty("payloadBytes").GetInt32(),
            Array.AsReadOnly(JsonSerializer.Deserialize<GalaxyOriginalSpriteMip[]>(t.GetProperty("mips"),ToolboxSettings.JsonOptions)!))).ToArray());
        AtlasTiles=Array.AsReadOnly(metadata.GetProperty("atlasTiles").EnumerateArray().Select(t=>t.GetInt32()).ToArray());
        if(Textures.Count!=4||AtlasTiles.Count!=15||Textures.Sum(t=>t.PayloadBytes)!=data.Length||
           Textures.Any(t=>t.PayloadOffset<0||t.PayloadOffset+t.PayloadBytes>data.Length||t.Mips[^1].Offset+t.Mips[^1].Size!=t.PayloadBytes))
            throw new InvalidDataException("原银河背景纹理布局无效。");
    }
}

public static class GalaxyOriginalMilkyWay
{
    private static readonly Lazy<GalaxyOriginalMilkyWayResources> reference=new(Read);
    public static GalaxyOriginalMilkyWayResources Reference=>reference.Value;
    private static GalaxyOriginalMilkyWayResources Read()
    {
        var assembly=typeof(GalaxyOriginalMilkyWay).Assembly;
        using var jsonStream=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-milky-way.json")!;
        using var json=JsonDocument.Parse(jsonStream);
        using var stream=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-milky-way.bc1.gz")!;
        using var gzip=new GZipStream(stream,CompressionMode.Decompress);var payload=new byte[2324480];gzip.ReadExactly(payload);
        if(gzip.ReadByte()!=-1)throw new InvalidDataException("原银河背景纹理数据超出范围。");
        return new(json.RootElement,payload);
    }
}