Anime Studio:支持米哈游游戏的资源分析工具

Anime Studio:支持米哈游游戏的资源分析工具

项目描述

Anime Studio 是一个基于 .NET 平台开发的专业游戏资源分析工具,专门用于解析和提取米哈游系列游戏(原神、星穹铁道、绝区零等)的资源文件。该项目是 Razmoth 原始 AssetStudio 的现代化分支,整合了多个社区的修复和改进,提供了对最新游戏版本的完整支持。

功能特性

  • 多游戏支持:完整支持原神、星穹铁道、绝区零等米哈游系列游戏
  • 多种文件格式:支持 Unity Assets、Bundle、加密包等多种文件格式解析
  • 资源预览:可预览模型、纹理、音频、动画等游戏资源
  • 资源导出:支持将资源导出为常见格式(JSON、MessagePack、XML等)
  • 暗色主题:提供舒适的暗色界面主题
  • 资源浏览器:改进的资源浏览和筛选功能
  • SHA256哈希:为资源文件提供完整性校验
  • 差异对比:支持同时加载两个资源地图并进行差异分析
  • UnityCN密钥管理:内置 UnityCN 加密密钥管理器

安装指南

系统要求

  • .NET 8.0 或 .NET 9.0 运行时
  • Windows 7 或更高版本
  • 至少 2GB 可用内存

下载安装

推荐下载 Anime Studio for .NET 9

或下载 Anime Studio for .NET 8

  1. 下载对应的 ZIP 文件包
  2. 解压到任意目录
  3. 运行 AnimeStudio.exe 即可使用

依赖项

项目依赖以下核心库:

  • MessagePack(序列化)
  • Newtonsoft.Json(JSON处理)
  • ZstdSharp(压缩解压)
  • Brotli(压缩解压)

使用说明

基本使用

// 初始化资源管理器
var assetsManager = new AssetsManager();
assetsManager.Game = GameType.GI; // 设置游戏类型

// 加载游戏文件
assetsManager.LoadFiles("path/to/game/files");

// 处理资源文件
foreach (var assetFile in assetsManager.assetsFileList)
{
    foreach (var obj in assetFile.Objects)
    {
        // 处理游戏对象
        if (obj is Texture2D texture)
        {
            // 导出纹理
            texture.Dump("output/path");
        }
    }
}

资源地图功能

// 加载资源地图
var result = ResourceMap.FromFile("asset_map.bin");
if (result > 0)
{
    var entries = ResourceMap.GetEntries();
    
    // 筛选特定类型的资源
    var textures = entries.Where(e => e.Type == ClassIDType.Texture2D);
    
    foreach (var texture in textures)
    {
        Console.WriteLine($"Texture: {texture.Name}, Path: {texture.Container}");
    }
}

资源索引管理

// 加载资源索引
ResourceIndex.FromFile("index.json");

// 获取资源容器信息
var container = ResourceIndex.GetContainer(assetId, pathHash);
if (!string.IsNullOrEmpty(container))
{
    Console.WriteLine($"Asset container: {container}");
}

核心代码

资源管理器核心类

public class AssetsManager
{
    public Game Game;
    public bool Silent = false;
    public bool SkipProcess = false;
    public bool ResolveDependencies = false;        
    public string SpecifyUnityVersion;
    public CancellationTokenSource tokenSource = new CancellationTokenSource();
    public List<SerializedFile> assetsFileList = new List<SerializedFile>();

    /// <summary>
    /// 加载并处理游戏资源文件
    /// </summary>
    /// <param name="files">资源文件路径数组</param>
    public void LoadFiles(params string[] files)
    {
        if (Silent)
        {
            Logger.Silent = true;
            Progress.Silent = true;
        }

        var path = files[0];
        // 预处理分割文件
        ImportHelper.MergeSplitAssets(Path.GetDirectoryName(path));
        
        // 加载文件到管理器
        foreach (var file in files)
        {
            try
            {
                var fileReader = new FileReader(file);
                switch (fileReader.FileType)
                {
                    case FileType.AssetsFile:
                        assetsFileList.Add(new SerializedFile(fileReader, this));
                        break;
                    case FileType.BundleFile:
                        // 处理Bundle文件
                        break;
                    case FileType.WebFile:
                        // 处理Web文件
                        break;
                }
            }
            catch (Exception e)
            {
                Logger.Error($"Error loading file {file}", e);
            }
        }
    }
}

游戏资源枚举定义

/// <summary>
/// Unity 资源类型枚举
/// 官方 Class ID 参考: https://docs.unity3d.com/Manual/ClassIDReference.html
/// </summary>
public enum ClassIDType
{
    UnknownType = -1,
    Object = 0,
    GameObject = 1,
    Component = 2,
    Transform = 4,
    Texture2D = 28,
    Material = 21,
    Mesh = 43,
    Shader = 48,
    TextAsset = 49,
    AudioClip = 83,
    AnimationClip = 74,
    Animator = 91,
    // ... 其他资源类型
}

资源条目数据结构

[MessagePackObject]
public record AssetEntry
{
    [Key(0)]
    public string Name { get; set; }          // 资源名称
    
    [Key(1)]
    public string Container { get; set; }     // 容器路径
    
    [Key(2)]
    public string Source { get; set; }        // 源文件
    
    [Key(3)]
    public long PathID { get; set; }          // 路径ID
    
    [Key(4)]
    public ClassIDType Type { get; set; }     // 资源类型
    
    [Key(5)]
    public string SHA256Hash { get; set; }    // SHA256哈希值

    /// <summary>
    /// 使用正则表达式过滤器匹配资源条目
    /// </summary>
    public bool Matches(Dictionary<string, Regex> filters)
    {
        var matches = new List<bool>();
        foreach(var filter in filters)
        {
            matches.Add(filter.Key switch
            {
                string value when value.Equals(nameof(Name), StringComparison.OrdinalIgnoreCase) 
                    => filter.Value.IsMatch(Name),
                string value when value.Equals(nameof(Container), StringComparison.OrdinalIgnoreCase) 
                    => filter.Value.IsMatch(Container),
                // ... 其他属性匹配
                _ => throw new NotImplementedException()
            });
        }
        return matches.Count(x => x == true) == filters.Count;
    }
}

压缩解压工具类

/// <summary>
/// 提供多种压缩格式的解压支持
/// 包括 LZ4、LZMA、Zstd、Brotli 等
/// </summary>
public static class ImportHelper
{
    /// <summary>
    /// 合并分割的资源文件
    /// </summary>
    public static void MergeSplitAssets(string path, bool allDirectories = false)
    {
        Logger.Verbose($"Processing split assets (.splitX) prior to loading files...");
        var splitFiles = Directory.GetFiles(path, "*.split0", 
            allDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
        
        foreach (var splitFile in splitFiles)
        {
            var destFile = Path.GetFileNameWithoutExtension(splitFile);
            var destPath = Path.GetDirectoryName(splitFile);
            var destFull = Path.Combine(destPath, destFile);
            
            if (!File.Exists(destFull))
            {
                var splitParts = Directory.GetFiles(destPath, destFile + ".split*");
                using (var destStream = File.Create(destFull))
                {
                    for (int i = 0; i < splitParts.Length; i++)
                    {
                        var splitPart = destFull + ".split" + i;
                        using (var sourceStream = File.OpenRead(splitPart))
                        {
                            sourceStream.CopyTo(destStream);
                        }
                    }
                }
            }
        }
    }
}

更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)

公众号二维码

公众号二维码

posted @ 2025-10-17 16:23  qife  阅读(7)  评论(0)    收藏  举报