251 lines
9.9 KiB
C#
251 lines
9.9 KiB
C#
|
|
|||
|
using Newtonsoft.Json;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Reflection;
|
|||
|
using System.Xml.Linq;
|
|||
|
using UnityEngine;
|
|||
|
using static Animancer.Validate;
|
|||
|
using static Unity.VisualScripting.Member;
|
|||
|
|
|||
|
namespace Ether
|
|||
|
{
|
|||
|
public abstract class SaveBase<T> : Singleton<T> where T : new()
|
|||
|
{
|
|||
|
public SaveBase()
|
|||
|
{
|
|||
|
SaveSystem.Inst.Regist(this);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public abstract class SaveBase
|
|||
|
{
|
|||
|
public SaveBase()
|
|||
|
{
|
|||
|
SaveSystem.Inst.Regist(this);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class SaveSystem : Singleton<SaveSystem>
|
|||
|
{
|
|||
|
public int SaveArchiveNum = 5;
|
|||
|
public Dictionary<int, ArchiveData> AllSaveArchive
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
Dictionary<int, ArchiveData> allSaveArchive = new Dictionary<int, ArchiveData>();
|
|||
|
|
|||
|
for (int i = 0; i < SaveArchiveNum; i++)
|
|||
|
{
|
|||
|
string path = string.Format(PathConst.SaveArchiveDataPath, i);
|
|||
|
if (!ES3.FileExists(string.Format(PathConst.SaveArchiveDataPath, i)))
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
ArchiveData archiveData = ES3.Load<ArchiveData>("SaveArchive", string.Format(PathConst.SaveArchiveDataPath, i));
|
|||
|
if (archiveData != null)
|
|||
|
{
|
|||
|
allSaveArchive.Add(i, archiveData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return allSaveArchive;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private List<object> allSaveInst = new List<object>();
|
|||
|
|
|||
|
public void Regist(object savaBase)
|
|||
|
{
|
|||
|
allSaveInst.Add(savaBase);
|
|||
|
}
|
|||
|
|
|||
|
public void UnRegist(object savaBase)
|
|||
|
{
|
|||
|
allSaveInst.Remove(savaBase);
|
|||
|
}
|
|||
|
|
|||
|
public bool LoadArchive(int saveIndex, Action<bool> callback = null)
|
|||
|
{
|
|||
|
if (AllSaveArchive.TryGetValue(saveIndex, out ArchiveData archiveData))
|
|||
|
{
|
|||
|
foreach (object source in allSaveInst)
|
|||
|
{// 获取对象的类型
|
|||
|
Type type = source.GetType();
|
|||
|
|
|||
|
// 存储字段、属性和方法的值
|
|||
|
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|||
|
.Where(f => f.GetCustomAttribute<SaveAttribute>() != null);
|
|||
|
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|||
|
.Where(p => p.GetCustomAttribute<SaveAttribute>() != null);
|
|||
|
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|||
|
.Where(m => m.GetCustomAttribute<SaveAttribute>() != null);
|
|||
|
|
|||
|
// 打印出带有Attribute的成员的名称和值
|
|||
|
foreach (var field in fields)
|
|||
|
{
|
|||
|
//object value = field.GetValue(source);
|
|||
|
//Debug.LogError($"Field: {field.Name}, Value: {value}");
|
|||
|
// 存储field.GetValue(source)的值
|
|||
|
object value = archiveData.ArchiveDic[field.Name];
|
|||
|
Type tempType = field.FieldType;
|
|||
|
|
|||
|
if (value is JObject valueObj)
|
|||
|
{
|
|||
|
if (tempType.IsGenericType && tempType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
|
|||
|
{
|
|||
|
// 直接调用 ToObject 方法,并指定目标泛型类型
|
|||
|
var deserializedValue = valueObj.ToObject(tempType, JsonSerializer.CreateDefault());
|
|||
|
field.SetValue(source, deserializedValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
field.SetValue(source, valueObj.ToObject(tempType));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (tempType == typeof(int) && value.GetType() == typeof(long))
|
|||
|
{
|
|||
|
value = Convert.ToInt32(value);
|
|||
|
}
|
|||
|
field.SetValue(source, value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
foreach (var property in properties)
|
|||
|
{
|
|||
|
object value = archiveData.ArchiveDic[property.Name];
|
|||
|
Type tempType = property.PropertyType;
|
|||
|
|
|||
|
if (value is JObject valueObj)
|
|||
|
{
|
|||
|
if (tempType.IsGenericType && tempType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
|
|||
|
{
|
|||
|
// 直接调用 ToObject 方法,并指定目标泛型类型
|
|||
|
var deserializedValue = valueObj.ToObject(tempType, JsonSerializer.CreateDefault());
|
|||
|
property.SetValue(source, deserializedValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
property.SetValue(source, valueObj.ToObject(tempType));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (tempType == typeof(int) && value.GetType() == typeof(long))
|
|||
|
{
|
|||
|
value = Convert.ToInt32(value);
|
|||
|
}
|
|||
|
property.SetValue(source, value);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
foreach (var method in methods)
|
|||
|
{
|
|||
|
//Debug.LogError($"Method: {method.Name}");
|
|||
|
// 存储方法的引用或返回值
|
|||
|
// 注意:方法的调用可能需要参数,这里只是获取方法的引用
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
string sceneSavePath = string.Format(PathConst.SaveArchiveScenePath, saveIndex);
|
|||
|
ES3.DeleteFile("TempSceneSave.es3");
|
|||
|
ES3.CopyFile(sceneSavePath, "TempSceneSave.es3");
|
|||
|
|
|||
|
callback?.Invoke(true);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
callback?.Invoke(false);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public bool SaveArchive(int saveIndex, Action<bool> callback = null)
|
|||
|
{
|
|||
|
ArchiveData archiveData = saveIndex < AllSaveArchive.Count ? AllSaveArchive[saveIndex] : new ArchiveData() { Id = saveIndex, Time = DateTime.Now };
|
|||
|
|
|||
|
foreach (object source in allSaveInst)
|
|||
|
{
|
|||
|
// 获取对象的类型
|
|||
|
Type type = source.GetType();
|
|||
|
|
|||
|
// 存储字段、属性和方法的值
|
|||
|
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|||
|
.Where(f => f.GetCustomAttribute<SaveAttribute>() != null);
|
|||
|
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|||
|
.Where(p => p.GetCustomAttribute<SaveAttribute>() != null);
|
|||
|
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|||
|
.Where(m => m.GetCustomAttribute<SaveAttribute>() != null);
|
|||
|
|
|||
|
// 打印出带有Attribute的成员的名称和值
|
|||
|
foreach (var field in fields)
|
|||
|
{
|
|||
|
object value = field.GetValue(source);
|
|||
|
//Debug.LogError($"Field: {field.Name}, Value: {value}");
|
|||
|
// 存储field.GetValue(source)的值
|
|||
|
if (!archiveData.ArchiveDic.TryAdd(field.Name, value))
|
|||
|
{
|
|||
|
archiveData.ArchiveDic[field.Name] = value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
foreach (var property in properties)
|
|||
|
{
|
|||
|
object value = property.GetValue(source);
|
|||
|
//Debug.LogError($"Property: {property.Name}, Value: {value}");
|
|||
|
// 存储property.GetValue(source)的值
|
|||
|
if (!archiveData.ArchiveDic.TryAdd(property.Name, value))
|
|||
|
{
|
|||
|
archiveData.ArchiveDic[property.Name] = value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
foreach (var method in methods)
|
|||
|
{
|
|||
|
//Debug.LogError($"Method: {method.Name}");
|
|||
|
// 存储方法的引用或返回值
|
|||
|
// 注意:方法的调用可能需要参数,这里只是获取方法的引用
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ES3.Save("SaveArchive", archiveData, string.Format(PathConst.SaveArchiveDataPath, saveIndex));
|
|||
|
string sceneSavePath = string.Format(PathConst.SaveArchiveScenePath, saveIndex);
|
|||
|
ES3.DeleteFile(sceneSavePath);
|
|||
|
ES3.CopyFile("TempSceneSave.es3", sceneSavePath);
|
|||
|
|
|||
|
//Debug.LogError(JsonTools.ToJson(archiveData));
|
|||
|
//FileTools.WriteFileForJson(string.Format(PathConst.SaveArchivePath, saveIndex), archiveData, isFormat: true);
|
|||
|
|
|||
|
callback?.Invoke(true);
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class ArchiveData
|
|||
|
{
|
|||
|
public int Id;
|
|||
|
public DateTime Time;
|
|||
|
public Dictionary<object, object> ArchiveDic = new Dictionary<object, object>();
|
|||
|
|
|||
|
public void SaveData(object key, object value)
|
|||
|
{
|
|||
|
ArchiveDic.TryAdd(key, value);
|
|||
|
}
|
|||
|
|
|||
|
public object GetData(object key)
|
|||
|
{
|
|||
|
if (ArchiveDic.ContainsKey(key))
|
|||
|
{
|
|||
|
return ArchiveDic[key];
|
|||
|
}
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|