using System; using System.Collections.Generic; using System.IO; using UnityEngine; namespace Bansonic.datacheck { public class DataCheck : MonoBehaviour { [Header("Settings")] [Tooltip("是否在游戏启动时自动校验歌曲运行时存档")] public bool checkOnStart = true; private const string Salt = "bansonic2026@fudongyouxi"; private const string SongRuntimeCategory = "song_runtime"; private void Start() { if (!checkOnStart) { Debug.Log("[DataCheck] 自动校验已关闭。"); return; } ValidateSongRuntimeSaves(); } private void ValidateSongRuntimeSaves() { float startTime = Time.realtimeSinceStartup; string persistentPath = Application.persistentDataPath; string legacyRoot = persistentPath; int encryptedFileCount = SecureSaveVault.CountEncryptedFiles(SongRuntimeCategory); int legacyFileCount = 0; try { legacyFileCount = Directory.GetFiles(legacyRoot, "SongData_*.json", SearchOption.TopDirectoryOnly).Length; } catch (Exception ex) { Debug.LogWarning($"[DataCheck] 统计旧版歌曲存档失败: {ex.Message}"); } List loadedJsonList = SecureSaveVault.LoadAllRawJson(SongRuntimeCategory, legacyRoot, "SongData_*.json"); int totalFiles = Math.Max(encryptedFileCount + legacyFileCount, loadedJsonList.Count); int corruptedFiles = 0; for (int i = 0; i < loadedJsonList.Count; i++) { string json = loadedJsonList[i]; SongDataSerializable serializable; if (!SongData.VerifyJsonIntegrity(json, Salt, out serializable)) { corruptedFiles++; } } int envelopeFailedFiles = Math.Max(0, encryptedFileCount - loadedJsonList.Count + legacyFileCount); corruptedFiles += envelopeFailedFiles; float duration = Time.realtimeSinceStartup - startTime; Debug.Log($"[DataCheck] 歌曲存档校验完成。耗时: {duration:F4}s | 总文件: {totalFiles} | 异常/篡改: {corruptedFiles}"); if (corruptedFiles > 0) { Debug.LogWarning("[DataCheck] 检测到异常歌曲存档。安全存档层已阻止被破坏的数据继续参与读取。"); } else if (totalFiles > 0) { Debug.Log("[DataCheck] 所有歌曲运行时存档通过校验。"); } } } }