using System.Collections.Generic; using System.IO; using System.Linq; using AibisDream.Utility; using Newtonsoft.Json; using UnityEngine; namespace AibisDream.SaveSystem { /// /// 存档槽位目录与文件路径工具。 /// public static class SlotDirectory { public static string GetSlotPath(int slotIndex) { return Path.Combine(ConstRef.SaveFilePath, $"{ConstRef.SaveSlotDirPrefix}{slotIndex}"); } public static string GetSnapshotPath(int slotIndex) { return Path.Combine(GetSlotPath(slotIndex), $"{ConstRef.SaveSnapshotFileName}.json"); } public static string GetMetaPath(int slotIndex) { return Path.Combine(GetSlotPath(slotIndex), $"{ConstRef.SaveMetaFileName}.json"); } public static string GetThumbnailPath(int slotIndex) { return Path.Combine(GetSlotPath(slotIndex), $"{ConstRef.SaveThumbnailFileName}.png"); } public static string GetLatestSlotIndexPath() { return Path.Combine(ConstRef.SaveFilePath, $"{ConstRef.LatestSlotFileName}.json"); } public static bool Exists(int slotIndex) { return File.Exists(GetMetaPath(slotIndex)); } public static IEnumerable EnumerateExistingSlots() { if (!Directory.Exists(ConstRef.SaveFilePath)) { yield break; } for (var i = SlotIndex.Auto; i <= SlotIndex.ManualEnd; i++) { if (Exists(i)) { yield return i; } } } public static void EnsureSlotDirectory(int slotIndex) { Directory.CreateDirectory(GetSlotPath(slotIndex)); } } /// /// 槽位文件原子写工具。 /// 先写入临时文件,再重命名为最终文件,避免写入过程中崩溃导致存档损坏。 /// public static class SlotAtomicWriter { public static void WriteJson(T obj, string finalPath) { var json = JsonConvert.SerializeObject(obj, Formatting.Indented); WriteText(json, finalPath); } public static void WriteText(string text, string finalPath) { var tempPath = finalPath + ".tmp"; var dir = Path.GetDirectoryName(finalPath); if (!string.IsNullOrEmpty(dir)) { Directory.CreateDirectory(dir); } File.WriteAllText(tempPath, text); CommitTempFile(tempPath, finalPath); } public static void WriteBytes(byte[] data, string finalPath) { if (data == null) { return; } var tempPath = finalPath + ".tmp"; var dir = Path.GetDirectoryName(finalPath); if (!string.IsNullOrEmpty(dir)) { Directory.CreateDirectory(dir); } File.WriteAllBytes(tempPath, data); CommitTempFile(tempPath, finalPath); } private static void CommitTempFile(string tempPath, string finalPath) { if (File.Exists(finalPath)) { File.Delete(finalPath); } File.Move(tempPath, finalPath); } } }