79 lines
3.7 KiB
C#
79 lines
3.7 KiB
C#
using UnityEditor;
|
||
using UnityEngine;
|
||
using System.IO;
|
||
using Ichni.RhythmGame.Beatmap;
|
||
|
||
namespace Ichni.Editor
|
||
{
|
||
public class IchniProjectDecryptor : EditorWindow
|
||
{
|
||
[MenuItem("Tools/Ichni/Decrypt Exported Project")]
|
||
public static void ShowWindow()
|
||
{
|
||
// 打开文件夹选择面板,让用户选择被加密(导出)的工程文件夹
|
||
string exportFolderPath = EditorUtility.OpenFolderPanel("Select Exported Project Folder", Application.streamingAssetsPath + "/Export", "");
|
||
|
||
if (string.IsNullOrEmpty(exportFolderPath)) return;
|
||
|
||
string projectName = new DirectoryInfo(exportFolderPath).Name;
|
||
|
||
// 选择要输出解密后的工程文件夹(默认为 Projects 文件夹下的同名文件夹)
|
||
string saveFolderPath = EditorUtility.SaveFolderPanel("Select Output Directory for Decrypted Project", Application.streamingAssetsPath + "/Projects", projectName);
|
||
|
||
if (string.IsNullOrEmpty(saveFolderPath)) return;
|
||
|
||
// 确保输出文件夹存在
|
||
if (!Directory.Exists(saveFolderPath))
|
||
{
|
||
Directory.CreateDirectory(saveFolderPath);
|
||
}
|
||
|
||
bool success = true;
|
||
|
||
// 分别解密并转存四个主要配置/谱面文件
|
||
success &= DecryptAndSave<ProjectInformation_BM>("ProjectInformation", exportFolderPath + "/ProjectInfo.bytes", saveFolderPath + "/ProjectInfo.json");
|
||
success &= DecryptAndSave<SongInformation_BM>("SongInformation", exportFolderPath + "/SongInfo.bytes", saveFolderPath + "/SongInfo.json");
|
||
success &= DecryptAndSave<BeatmapContainer_BM>("Beatmap", exportFolderPath + "/Beatmap.bytes", saveFolderPath + "/Beatmap.json");
|
||
success &= DecryptAndSave<CommandScripts_BM>("CommandScripts", exportFolderPath + "/CommandScripts.bytes", saveFolderPath + "/CommandScripts.json");
|
||
|
||
if (success)
|
||
{
|
||
EditorUtility.DisplayDialog("Decryption Complete", $"Project '{projectName}' has been successfully decrypted and saved to:\n{saveFolderPath}", "OK");
|
||
}
|
||
else
|
||
{
|
||
EditorUtility.DisplayDialog("Decryption Finished with Warnings", $"Project '{projectName}' decryption finished, but some files might be missing or failed to decode. Check Console for details.", "OK");
|
||
}
|
||
|
||
// 刷新 AssetDatabase
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private static bool DecryptAndSave<T>(string key, string inputPath, string outputPath)
|
||
{
|
||
if (!File.Exists(inputPath))
|
||
{
|
||
Debug.LogWarning($"[IchniDecryptor] Missing encrypted file, skipping: {inputPath}");
|
||
return true; // 允许部分文件缺失(例如可能没有CommandScripts)
|
||
}
|
||
|
||
try
|
||
{
|
||
// 使用导出的加密配置进行读取
|
||
T data = ES3.Load<T>(key, inputPath, ProjectManager.ExportSettings);
|
||
|
||
// 使用明文保存配置转存为 JSON
|
||
ES3.Save<T>(key, data, outputPath, ProjectManager.SaveSettings);
|
||
|
||
Debug.Log($"[IchniDecryptor] Successfully decrypted: {Path.GetFileName(inputPath)} -> {Path.GetFileName(outputPath)}");
|
||
return true;
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError($"[IchniDecryptor] Failed to decrypt {Path.GetFileName(inputPath)}: {e.Message}\n{e.StackTrace}");
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|