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 GalaxyOriginalSpriteMip(int Offset,int SliceBytes,int Size,int RowPitch,int DepthPitch);

/// <summary>Exact original BC1 diffuse array; the original BackgroundStars shader is separate.</summary>
public sealed class GalaxyOriginalSpriteArray
{
    public const int Width=512,Height=512,Layers=28,MipCount=10;
    private readonly byte[] payload;
    public ReadOnlyMemory<byte> Payload=>payload;
    public IReadOnlyList<GalaxyOriginalSpriteMip> Mips {get;}
    public string SourceSha256 {get;}
    public string PayloadSha256 {get;}
    internal GalaxyOriginalSpriteArray(JsonElement metadata,byte[] data)
    {
        SourceSha256=metadata.GetProperty("sourceArchiveSha256").GetString()!;
        PayloadSha256=metadata.GetProperty("payloadSha256").GetString()!;
        if(metadata.GetProperty("width").GetInt32()!=Width||metadata.GetProperty("height").GetInt32()!=Height||
           metadata.GetProperty("layers").GetInt32()!=Layers||metadata.GetProperty("mipCount").GetInt32()!=MipCount||
           data.Length!=5074944||Convert.ToHexStringLower(SHA256.HashData(data))!=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 i=0;i<mips.Length;i++)
        {
            var mip=mips[i];var blockWidth=Math.Max(1,(Width>>i)+3>>2);var blockHeight=Math.Max(1,(Height>>i)+3>>2);
            if(mip.Offset!=end||mip.Size!=mip.SliceBytes*Layers||mip.RowPitch<blockWidth*8||mip.SliceBytes<mip.RowPitch*blockHeight)
                throw new InvalidDataException("原星图点纹理布局无效。");
            end=checked(end+mip.Size);
        }
        if(end!=data.Length)throw new InvalidDataException("原星图点纹理数据不完整。");
        payload=data;Mips=Array.AsReadOnly(mips);
    }
}

public static class GalaxyOriginalStarSprites
{
    public const int DefaultLayer=13;
    public static GalaxyOriginalSpriteArray Reference {get;}=Read();
    // Original Territory/Activities vtable+58 getter 3B32DD0; these are its
    // own state indices, not the public power-state string enumeration.
    public static int TerritoryLayer(int stateIndex)=>stateIndex switch{2=>16,3=>21,4=>18,5=>19,6=>22,7=>23,_=>15};
    private static GalaxyOriginalSpriteArray Read()
    {
        var assembly=typeof(GalaxyOriginalStarSprites).Assembly;
        using var metadata=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-star-sprites.json")!;
        using var json=JsonDocument.Parse(metadata);
        using var compressed=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-star-sprites.bc1.gz")!;
        using var gzip=new GZipStream(compressed,CompressionMode.Decompress);var data=new byte[5074944];gzip.ReadExactly(data);
        if(gzip.ReadByte()!=-1)throw new InvalidDataException("原星图点纹理数据超出范围。");
        return new(json.RootElement,data);
    }
}