将以下小文件合并到相关核心类中,减少文件数量并保持职责清晰: - SaveSnapshotSummary -> SaveSnapshot - SnapshotProviderIds + SnapshotBootstrap -> SnapshotRegistry - SnapshotSectionDeserializer -> SnapshotRestore - SnapshotSerializer -> SnapshotPersistence 同步更新 SnapshotService 与 YarnVariableStorage 的调用点。
102 lines
3.9 KiB
C#
102 lines
3.9 KiB
C#
using System.IO;
|
||
using AibisDream.Utility;
|
||
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
using UnityEngine;
|
||
|
||
namespace AibisDream.SaveSystem
|
||
{
|
||
/// <summary>
|
||
/// 快照与磁盘的边界:序列化、读写 JSON 文件、检测旧档格式。
|
||
/// <para>
|
||
/// P2 起,业务存档统一通过 <see cref="SlotManager"/> 写入槽位目录;
|
||
/// 本类保留按路径读写的低级接口,供旧档兼容、迁移和外部调试使用。
|
||
/// </para>
|
||
/// </summary>
|
||
public static class SnapshotPersistence
|
||
{
|
||
private static readonly JsonSerializerSettings Settings = new()
|
||
{
|
||
TypeNameHandling = TypeNameHandling.None,
|
||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
||
NullValueHandling = NullValueHandling.Ignore
|
||
};
|
||
|
||
/// <summary>P1 自测落盘:<c>SnapshotTestPath/latest_snapshot.json</c>(P2 迁移源)。</summary>
|
||
public static string GetTestFilePath()
|
||
{
|
||
return Path.Combine(ConstRef.SnapshotTestPath, ConstRef.SnapshotTestFileName);
|
||
}
|
||
|
||
/// <summary>将快照序列化并写入指定槽位。</summary>
|
||
public static void SaveToSlot(int slotIndex, SaveSnapshot snapshot)
|
||
{
|
||
SlotManager.SaveToSlot(slotIndex, snapshot, null);
|
||
}
|
||
|
||
/// <summary>从指定槽位读取快照。</summary>
|
||
public static SaveSnapshot LoadFromSlot(int slotIndex)
|
||
{
|
||
return SlotManager.LoadSnapshot(slotIndex);
|
||
}
|
||
|
||
/// <summary>将快照序列化为 JSON 字符串。</summary>
|
||
public static string Serialize(SaveSnapshot snapshot)
|
||
{
|
||
snapshot.schemaVersion = SaveSnapshotSchema.CurrentVersion;
|
||
return JsonConvert.SerializeObject(snapshot, Formatting.Indented, Settings);
|
||
}
|
||
|
||
/// <summary>从 JSON 字符串反序列化为快照。</summary>
|
||
public static SaveSnapshot Deserialize(string json)
|
||
{
|
||
var snapshot = JsonConvert.DeserializeObject<SaveSnapshot>(json, Settings);
|
||
if (snapshot != null && snapshot.schemaVersion != SaveSnapshotSchema.CurrentVersion)
|
||
{
|
||
Debug.LogWarning(
|
||
$"[SnapshotPersistence] schemaVersion {snapshot.schemaVersion} != {SaveSnapshotSchema.CurrentVersion},按当前结构读取。");
|
||
}
|
||
|
||
return snapshot;
|
||
}
|
||
|
||
/// <summary>将快照序列化并写入 path(自动补 .json 后缀)。</summary>
|
||
public static void Save(SaveSnapshot snapshot, string pathWithoutExtension)
|
||
{
|
||
var json = Serialize(snapshot);
|
||
var path = JsonUtil.FormatAsJsonPath(pathWithoutExtension);
|
||
var dir = Path.GetDirectoryName(path);
|
||
if (!string.IsNullOrEmpty(dir))
|
||
{
|
||
Directory.CreateDirectory(dir);
|
||
}
|
||
|
||
File.WriteAllText(path, json);
|
||
}
|
||
|
||
/// <summary>从 path 读取并反序列化为 <see cref="SaveSnapshot"/>。</summary>
|
||
public static SaveSnapshot Load(string pathWithoutExtension)
|
||
{
|
||
var json = File.ReadAllText(JsonUtil.FormatAsJsonPath(pathWithoutExtension));
|
||
return Deserialize(json);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否为旧 StorageSystem 格式(含 systemData、无 schemaVersion)。
|
||
/// 此类文件应走 <see cref="SaveRestoreOrchestrator"/> 的 legacy 分支。
|
||
/// </summary>
|
||
public static bool IsLegacyFormat(string savePath)
|
||
{
|
||
var json = File.ReadAllText(JsonUtil.FormatAsJsonPath(savePath));
|
||
var jobj = JObject.Parse(json);
|
||
return jobj.Value<int?>("schemaVersion") == null && jobj["systemData"] != null;
|
||
}
|
||
|
||
/// <summary>读取旧格式存档根 JObject,供 legacy 还原使用。</summary>
|
||
public static JObject ReadLegacySaveRoot(string savePath)
|
||
{
|
||
return JsonUtil.ReadJObject(savePath);
|
||
}
|
||
}
|
||
}
|