feat: add cross-engine platform services

This commit is contained in:
2026-09-05 02:33:55 +08:00
parent 1bfb99d4c3
commit 0030f5b794
10 changed files with 171 additions and 42 deletions
+34 -13
View File
@@ -4,7 +4,9 @@ using System.IO;
using System.Threading;
using Cysharp.Threading.Tasks;
using Newtonsoft.Json.Linq;
#if UNITY_5_3_OR_NEWER
using UnityEngine;
#endif
namespace ShrinkDataSaver
{
@@ -141,7 +143,7 @@ namespace ShrinkDataSaver
}
catch (Exception e)
{
Debug.LogWarning($"[ShrinkDataSaver] 读取元数据失败 slot_{slotIndex}: {e.Message}");
ShrinkDataSaverPlatform.Warning($"[ShrinkDataSaver] 读取元数据失败 slot_{slotIndex}: {e.Message}");
}
}
@@ -200,7 +202,11 @@ namespace ShrinkDataSaver
}
};
#if UNITY_5_3_OR_NEWER
if (options.Screenshot || options.CaptureScreenshot)
#else
if (options.Screenshot != null || options.CaptureScreenshot)
#endif
{
packet.Meta.ScreenshotBase64 = await CaptureScreenshotAsync(options, ct);
}
@@ -223,7 +229,7 @@ namespace ShrinkDataSaver
throw new InvalidOperationException($"关键模块 '{module.Key}' 序列化失败: {e.Message}", e);
}
Debug.LogError($"[ShrinkDataSaver] 模块 '{module.Key}' 序列化失败(已跳过): {e.Message}");
ShrinkDataSaverPlatform.Error($"[ShrinkDataSaver] 模块 '{module.Key}' 序列化失败(已跳过): {e.Message}");
}
}
@@ -252,7 +258,7 @@ namespace ShrinkDataSaver
ModuleNames = moduleNames.ToArray(),
Timestamp = timestamp
});
Debug.Log($"[ShrinkDataSaver] 槽位 {slotIndex} 已保存。({moduleNames.Count} 个模块)");
ShrinkDataSaverPlatform.Info($"[ShrinkDataSaver] 槽位 {slotIndex} 已保存。({moduleNames.Count} 个模块)");
}
catch (Exception e)
{
@@ -293,13 +299,13 @@ namespace ShrinkDataSaver
}
catch (Exception e)
{
Debug.LogError($"[ShrinkDataSaver] 反序列化模块 '{module.Key}' 失败: {e.Message}");
ShrinkDataSaverPlatform.Error($"[ShrinkDataSaver] 反序列化模块 '{module.Key}' 失败: {e.Message}");
}
}
_loadedSlot = slotIndex;
_storedPlaytime = packet.Meta.PlaytimeSeconds;
_sessionStart = Time.realtimeSinceStartup;
_sessionStart = (float)ShrinkDataSaverPlatform.TimeSeconds;
await PersistRecentSlotIndexAsync(slotIndex, ct);
OnLoadCompleted?.Invoke(new LoadCompletedEventArgs
@@ -309,7 +315,7 @@ namespace ShrinkDataSaver
Version = packet.Meta.SaveVersion,
Timestamp = timestamp
});
Debug.Log($"[ShrinkDataSaver] 槽位 {slotIndex} 已加载。(v{packet.Meta.SaveVersion}, {moduleNames.Count} 个模块)");
ShrinkDataSaverPlatform.Info($"[ShrinkDataSaver] 槽位 {slotIndex} 已加载。(v{packet.Meta.SaveVersion}, {moduleNames.Count} 个模块)");
}
catch (Exception e)
{
@@ -344,7 +350,7 @@ namespace ShrinkDataSaver
}
OnDeleteCompleted?.Invoke(new SlotDeletedEventArgs { SlotIndex = slotIndex });
Debug.Log($"[ShrinkDataSaver] 槽位 {slotIndex} 已删除。");
ShrinkDataSaverPlatform.Info($"[ShrinkDataSaver] 槽位 {slotIndex} 已删除。");
}
public static float GetMinAutoSaveInterval()
@@ -355,7 +361,7 @@ namespace ShrinkDataSaver
{
if (cfg.AutoSaveIntervalSeconds > 0f)
{
min = Mathf.Min(min, cfg.AutoSaveIntervalSeconds);
min = Math.Min(min, cfg.AutoSaveIntervalSeconds);
hasAny = true;
}
}
@@ -406,7 +412,11 @@ namespace ShrinkDataSaver
throw new ArgumentOutOfRangeException(nameof(slotIndex), "槽位索引不能为负数。");
}
#if UNITY_5_3_OR_NEWER
var max = ShrinkDataSaverSettings.Instance.maxSlots;
#else
var max = ShrinkDataSaverPlatform.MaxSlots;
#endif
if (max > 0 && slotIndex >= max)
{
throw new ArgumentOutOfRangeException(nameof(slotIndex), $"超出最大槽位数 ({max})。");
@@ -529,7 +539,7 @@ namespace ShrinkDataSaver
if (!string.Equals(candidatePath, primaryPath, StringComparison.Ordinal))
{
Debug.LogWarning($"[ShrinkDataSaver] 槽位 {slotIndex} 主文件损坏或缺失,已从备份恢复:{candidatePath}");
ShrinkDataSaverPlatform.Warning($"[ShrinkDataSaver] 槽位 {slotIndex} 主文件损坏或缺失,已从备份恢复:{candidatePath}");
await _storage.WriteAsync(primaryPath, bytes, ct);
}
@@ -538,7 +548,7 @@ namespace ShrinkDataSaver
catch (Exception ex)
{
lastError = ex;
Debug.LogWarning($"[ShrinkDataSaver] 读取槽位副本失败:{candidatePath} / {ex.Message}");
ShrinkDataSaverPlatform.Warning($"[ShrinkDataSaver] 读取槽位副本失败:{candidatePath} / {ex.Message}");
}
}
@@ -612,7 +622,7 @@ namespace ShrinkDataSaver
if (!string.Equals(candidatePath, primaryPath, StringComparison.Ordinal))
{
Debug.LogWarning($"[ShrinkDataSaver] 槽位 {slotIndex} 主文件损坏或缺失,已从备份恢复:{candidatePath}");
ShrinkDataSaverPlatform.Warning($"[ShrinkDataSaver] 槽位 {slotIndex} 主文件损坏或缺失,已从备份恢复:{candidatePath}");
await _storage.WriteAsync(primaryPath, bytes, ct);
}
@@ -621,7 +631,7 @@ namespace ShrinkDataSaver
catch (Exception ex)
{
lastError = ex;
Debug.LogWarning($"[ShrinkDataSaver] 加载槽位副本失败:{candidatePath} / {ex.Message}");
ShrinkDataSaverPlatform.Warning($"[ShrinkDataSaver] 加载槽位副本失败:{candidatePath} / {ex.Message}");
}
}
@@ -633,10 +643,11 @@ namespace ShrinkDataSaver
throw new FileNotFoundException($"槽位 {slotIndex} 不存在。");
}
private static float GetCurrentPlaytime() => _loadedSlot < 0 ? 0f : _storedPlaytime + (Time.realtimeSinceStartup - _sessionStart);
private static float GetCurrentPlaytime() => _loadedSlot < 0 ? 0f : _storedPlaytime + ((float)ShrinkDataSaverPlatform.TimeSeconds - _sessionStart);
private static async UniTask<string> CaptureScreenshotAsync(SaveOptions options, CancellationToken ct)
{
#if UNITY_5_3_OR_NEWER
var tex = options.Screenshot;
if (!tex && options.CaptureScreenshot)
{
@@ -668,6 +679,16 @@ namespace ShrinkDataSaver
}
return Convert.ToBase64String(tex.EncodeToJPG(75));
#else
var pngBytes = options.Screenshot;
if (pngBytes == null && options.CaptureScreenshot)
{
var provider = ShrinkDataSaverPlatform.Screenshots ??
throw new InvalidOperationException("Screenshot capture was requested but no platform provider is configured.");
pngBytes = await provider.CapturePngAsync(ct);
}
return pngBytes == null ? string.Empty : Convert.ToBase64String(pngBytes);
#endif
}
}
}