增加登录时自动存档同步功能

This commit is contained in:
ALIENJACK\alien 2025-08-18 17:20:45 +08:00
parent 3c04d26c50
commit 15c64ae655
7 changed files with 154 additions and 15 deletions

View File

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using UnityEngine;
using static AxibugEmuOnline.Client.HttpAPI;
using static AxibugEmuOnline.Client.Manager.LogManager;
using static AxibugEmuOnline.Client.SaveFile;
namespace AxibugEmuOnline.Client.ClientCore
{

View File

@ -81,6 +81,8 @@ namespace AxibugEmuOnline.Client.Manager
App.roomMgr.SendGetRoomList();
App.log.Info("获取在线玩家列表");
App.user.Send_GetUserList();
//开始同步存档
App.SavMgr.StartSyncSlot();
Eventer.Instance.PostEvent(EEvent.OnLoginSucceed);
}

View File

@ -2,7 +2,11 @@
using AxibugEmuOnline.Client.Tools;
using AxibugProtobuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEngine;
using SyncingFileRecord = System.Collections.Generic.Dictionary<AxibugProtobuf.RomPlatformType, System.Collections.Generic.Dictionary<int, System.Collections.Generic.HashSet<AxibugEmuOnline.Client.SaveFile.SyncingFiles>>>;
namespace AxibugEmuOnline.Client
{
@ -86,20 +90,7 @@ namespace AxibugEmuOnline.Client
{
byte[] saveOrderData = new byte[4];
//FileStream streaming = System.IO.File.OpenRead(FilePath);
//int res = streaming.Read(saveOrderData, 0, 4);
//if (res != 4) //无效的存档文件
//{
// IsEmpty = true;
// File.Delete(FilePath);
//}
//else
//{
// Sequecen = BitConverter.ToUInt32(saveOrderData, 0);
//}
//streaming.Dispose();
int res = AxiIO.File.ReadBytesToArr(FilePath, saveOrderData,0,4);
int res = AxiIO.File.ReadBytesToArr(FilePath, saveOrderData, 0, 4);
if (res < 4) //无效的存档文件
{
IsEmpty = true;
@ -232,6 +223,129 @@ namespace AxibugEmuOnline.Client
}
private void SetSavingFlag()
{
SyncingFilesUtility.Add(this);
}
private void ClearSavingFlag()
{
SyncingFilesUtility.Remove(this);
}
public static class SyncingFilesUtility
{
static SyncingFileRecord m_syncFiles = new SyncingFileRecord();
public static void ReadFromPlayprefs()
{
var jsonStr = AxiPlayerPrefs.GetString("SYNCING_SAVE");
if (string.IsNullOrEmpty(jsonStr)) return;
var temp = JsonUtility.FromJson<SyncingFilesList>(jsonStr);
if (temp.List == null || temp.List.Count == 0) return;
foreach (var file in temp.List)
{
Add(file);
}
}
public static void ContinueSync()
{
var allFiles = m_syncFiles.Values.SelectMany(v => v.Values).SelectMany(v => v);
foreach (var file in allFiles)
{
var savFile = App.SavMgr.GetSaveFile(file.romID, file.platform, file.slotIndex);
savFile.TrySync();
}
}
public static void Add(SaveFile savFile)
{
SyncingFiles file = new SyncingFiles { romID = savFile.RomID, platform = savFile.EmuPlatform, slotIndex = savFile.SlotIndex };
Add(file);
}
private static void Add(SyncingFiles file)
{
if (!m_syncFiles.TryGetValue(file.platform, out var mapper))
{
mapper = new Dictionary<int, HashSet<SyncingFiles>>();
m_syncFiles.Add(file.platform, mapper);
}
if (!mapper.TryGetValue(file.romID, out var syncingTables))
{
syncingTables = new HashSet<SyncingFiles>();
mapper[file.romID] = syncingTables;
}
if (syncingTables.Add(file))
{
WritePlayerprefs();
}
}
public static void Remove(SaveFile savFile)
{
SyncingFiles file = new SyncingFiles { romID = savFile.RomID, platform = savFile.EmuPlatform, slotIndex = savFile.SlotIndex };
if (!m_syncFiles.TryGetValue(file.platform, out var mapper))
{
return;
}
if (!mapper.TryGetValue(savFile.RomID, out var syncingTables))
{
return;
}
if (syncingTables.Remove(file))
{
WritePlayerprefs();
}
}
private static void WritePlayerprefs()
{
var allFiles = m_syncFiles.Values.SelectMany(v => v.Values).SelectMany(v => v);
var temp = new SyncingFilesList { List = new List<SyncingFiles>(allFiles) };
var jsonStr = JsonUtility.ToJson(temp);
AxiPlayerPrefs.SetString("SYNCING_SAVE", jsonStr);
}
}
[Serializable]
class SyncingFilesList
{
[SerializeField]
public List<SyncingFiles> List;
}
[Serializable]
public struct SyncingFiles
{
public int romID;
public RomPlatformType platform;
public int slotIndex;
public override int GetHashCode()
{
return HashCode.Combine(romID, platform, slotIndex);
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (obj.GetHashCode() != GetHashCode()) return false;
return true;
}
}
[StructLayout(LayoutKind.Explicit, Size = 24)]
struct Header
{

View File

@ -1,5 +1,6 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Tools;
using System;
namespace AxibugEmuOnline.Client
{
@ -26,6 +27,13 @@ namespace AxibugEmuOnline.Client
m_sequece = (uint)netData.Sequence;
m_downloadTask = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavUrl}");
m_downloadTaskImg = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavImgUrl}");
Host.SetSavingFlag();
}
public override void OnExit(SimpleFSM<SaveFile>.State nextState)
{
Host.ClearSavingFlag();
}
public override void OnUpdate()
@ -52,5 +60,6 @@ namespace AxibugEmuOnline.Client
FSM.ChangeState<SyncedState>();
}
}
}
}

View File

@ -6,6 +6,10 @@ namespace AxibugEmuOnline.Client
{
public class SyncedState : SimpleFSM<SaveFile>.State
{
public override void OnEnter(SimpleFSM<SaveFile>.State preState)
{
Host.ClearSavingFlag();
}
}
}
}

View File

@ -17,10 +17,13 @@ namespace AxibugEmuOnline.Client
}
Host.GetSavData(out byte[] savData, out byte[] screenData);
Host.CloudAPI.SendUpLoadGameSav(Host.RomID, Host.SlotIndex, Host.Sequecen, savData, screenData);
Host.SetSavingFlag();
}
public override void OnExit(SimpleFSM<SaveFile>.State nextState)
{
Host.ClearSavingFlag();
Host.CloudAPI.OnUploadedSavData -= Api_OnUploadedSavData;
}

View File

@ -13,6 +13,12 @@ namespace AxibugEmuOnline.Client
Dictionary<int, SaveFile[]> m_saveFileDict = new Dictionary<int, SaveFile[]>();
public void StartSyncSlot()
{
SaveFile.SyncingFilesUtility.ReadFromPlayprefs();
SaveFile.SyncingFilesUtility.ContinueSync();
}
public void Update()
{
foreach (var saveFiles in m_saveFileDict.Values)
@ -35,7 +41,7 @@ namespace AxibugEmuOnline.Client
return result;
}
SaveFile GetSaveFile(int romID, RomPlatformType platform, int slotIndex)
public SaveFile GetSaveFile(int romID, RomPlatformType platform, int slotIndex)
{
if (!m_saveFileDict.TryGetValue(romID, out SaveFile[] files))
{