This commit is contained in:
2024-10-16 00:03:41 +08:00
commit 897058435c
5033 changed files with 1009728 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 263939c973da4ba78fe5d43131ab5bfa
timeCreated: 1716804995

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: caf09ddb7d054bb6a13286dcbb868301
timeCreated: 1716882147

View File

@@ -0,0 +1,10 @@
namespace Framework.Save
{
public interface ISaveData
{
public string SaveKey { get; }
void Save ();
bool Load ();
void Delete ();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e2417200c5fe4d7f944ee29585b174b7
timeCreated: 1716805005

View File

@@ -0,0 +1,7 @@
namespace Framework.Save
{
public interface ISaveGroup : ISaveData
{
public string GroupKey { get; }
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 887bb4869230464ea1aea6c91361aec9
timeCreated: 1716806649

View File

@@ -0,0 +1,120 @@
using FJson;
using Framework.Utils.SingletonTemplate;
namespace Framework.Save
{
public class SaveDataController : MgrBase<SaveDataController>
{
private LiteDictionary<string , SaveGroup> _saveGroups = new LiteDictionary<string , SaveGroup> ();
private string _userID;
protected override void OnCreateMge ()
{
SaveConfig config = SaveConfig.CreateConfig ();
#if UNITY_EDITOR
config._saveSerializer = new SaveSerializerJson ();
config._saveHandler = new SaveHandlerFileStream ();
config.hasHashName = false;
#else
config._saveSerializer = new SaveSerializerJsonEncrypt ();
config._saveHandler = new SaveHandlerQuickFileStream ();
#endif
config._saveHandler.Init ();
this.SetConfig (config);
}
public void SetConfig (SaveConfig config)
{
SaveManager.Instance.SetConfig (Save.SaveData.PersistentData , config);
}
public void SetUserID (string userID)
{
this._userID = userID;
this._saveGroups = new LiteDictionary<string, SaveGroup> ();
}
public bool HasSave (ISaveData saveData)
{
return SaveManager.Instance.HasSave (Save.SaveData.PersistentData , this._userID + saveData.SaveKey);
}
public void DeleteData (ISaveData saveData)
{
if (HasSave (saveData))
{
SaveManager.Instance.DeleteSave (Save.SaveData.PersistentData , this._userID + saveData.SaveKey);
}
}
public void SaveData (ISaveData saveData)
{
SaveManager.Instance.Save (Save.SaveData.PersistentData , saveData , this._userID + saveData.SaveKey);
}
public T LoadData<T> (string saveKey)
{
if (SaveManager.Instance.HasSave (Save.SaveData.PersistentData , this._userID + saveKey))
{
return SaveManager.Instance.Load<T> (Save.SaveData.PersistentData , this._userID + saveKey);
}
return default;
}
public object LoadData (ISaveData saveData)
{
if (SaveManager.Instance.HasSave (Save.SaveData.PersistentData , this._userID + saveData.SaveKey))
{
return SaveManager.Instance.Load<object> (Save.SaveData.PersistentData , this._userID + saveData.SaveKey);
}
return default;
}
internal void SaveDataToGroup (ISaveGroup saveGroup)
{
CheckSaveGroup (saveGroup.GroupKey);
var group = this._saveGroups[saveGroup.GroupKey];
group.SaveData (saveGroup);
SaveData (group);
}
internal bool LoadDataFromGroup<T> (ISaveGroup saveGroup) where T : ISaveGroup
{
if (this._saveGroups.ContainsKey (saveGroup.GroupKey))
this._saveGroups.Remove (saveGroup.GroupKey);
var group = CheckSaveGroup (saveGroup.GroupKey);
return group.LoadData (saveGroup.SaveKey , (T)saveGroup);
}
private SaveGroup CheckSaveGroup (string groupName)
{
if (!this._saveGroups.ContainsKey (groupName))
{
var group = new SaveGroup ();
if (SaveManager.Instance.HasSave (Save.SaveData.PersistentData , this._userID + groupName))
{
var saveGroup = LoadData<object> (groupName);
FJsonUtility.Convert<SaveGroup> (saveGroup , group);
}
group._saveKey = groupName;
this._saveGroups[groupName] = group;
}
return this._saveGroups[groupName];
}
public void DeleteGroupData <T> (GroupPersistentData<T> groupPersistentData) where T : ISaveGroup, new ()
{
var groupName = groupPersistentData.GroupKey;
if (this._saveGroups.ContainsKey (groupName))
{
var group = this._saveGroups[groupName];
group.DeleteData(groupPersistentData);
this._saveGroups[groupName] = group;
SaveData (group);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 56ef41d5cf924813aa83980b88a2f801
timeCreated: 1716805437

View File

@@ -0,0 +1,66 @@
using FJson;
using FJson.Core;
namespace Framework.Save
{
internal class SaveGroup : ISaveGroup
{
[FSerialize] internal LiteDictionary<string, JsonObject> _saveDataArray = new LiteDictionary<string, JsonObject> ();
[FSerialize] internal string _saveKey;
string ISaveData. SaveKey => this._saveKey;
public string GroupKey => this._saveKey;
public SaveGroup ()
{
}
public void Save ()
{
SaveDataController.Instance.SaveData (this);
}
public bool Load ()
{
var data = SaveDataController.Instance.LoadData (this);
if (data != null)
{
FJsonUtility.Convert<SaveGroup> ( data,this);
return true;
}
return false;
}
public void SaveData (ISaveData saveData)
{
if (this._saveDataArray == null)
{
this._saveDataArray = new LiteDictionary<string, JsonObject> ();
}
this._saveDataArray[saveData.SaveKey] = FJsonUtility.ToJsonObject(saveData);
}
public bool LoadData<T> (string saveKey , T target) where T : ISaveData
{
if (_saveDataArray != null && this._saveDataArray.TryGetValue ( saveKey, out var data))
{
FJsonUtility.Convert<T> (data , target);
return true;
}
return false;
}
public void Delete ()
{
this._saveDataArray?.Clear ();
}
public void DeleteData (ISaveData saveData)
{
if (this._saveDataArray != null && this._saveDataArray.ContainsKey (saveData.SaveKey))
{
this._saveDataArray.Remove (saveData.SaveKey);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 60a74de868394b8799ee3e60fb2cb32f
timeCreated: 1716805718

View File

@@ -0,0 +1,22 @@

namespace Framework.Save
{
/// <summary>
/// 按组持久化单元(按组读写)
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class GroupPersistentData<T> : ISaveGroup where T : ISaveGroup , new()
{
public virtual string SaveKey => this.GetType ().FullName;
public abstract string GroupKey { get; }
public void Save () => SaveDataController.Instance.SaveDataToGroup (this);
public bool Load ()
{
return SaveDataController.Instance.LoadDataFromGroup<T> (this);
}
public void Delete () => SaveDataController.Instance.DeleteGroupData (this);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 76ed2d42b79142d5862db90f5415cfb1
timeCreated: 1716812696

View File

@@ -0,0 +1,28 @@
using FJson;
namespace Framework.Save
{
/// <summary>
/// 持久化单元(单独读写存储)
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class SinglePersistentData<T> : ISaveData where T : ISaveData , new()
{
public virtual string SaveKey => this.GetType ().FullName;
public virtual void Save () => SaveDataController.Instance.SaveData (this);
public virtual bool Load ()
{
var data = SaveDataController.Instance.LoadData (this);
if (data != null)
{
FJsonUtility.Convert<T> (data , this);
return true;
}
return false;
}
public void Delete () => SaveDataController.Instance.DeleteData (this);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 05079d1c84134b67ba6d8af1e1e75939
timeCreated: 1716805144

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 44eacfb08d634af3ad80597933c5f792
timeCreated: 1581932615

View File

@@ -0,0 +1,12 @@
namespace Framework.Save.Interface
{
public interface ISaveHandler
{
void Init();
void WriteData(string path , string name, byte[] bytes);
byte[] ReadData(string path , string name);
bool HasPath(string path , string name);
void Dispose();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e593669ea2b2443084b9e25bd0b848b9
timeCreated: 1581932538

View File

@@ -0,0 +1,10 @@
using System;
namespace Framework.Save.Interface
{
public interface ISaveSerializer
{
byte[] Serialize(object obj);
T Deserialize<T>(byte[] value);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 75dae824b16e4dd692b110363a40de21
timeCreated: 1581932348

View File

@@ -0,0 +1,67 @@
using System.Collections.Generic;
using Framework.Save.Interface;
using Framework.Utils;
namespace Framework.Save
{
public class SaveConfig
{
public bool hasHashName = true;
/// <summary>
/// 存储根目录
/// </summary>
public string RootPath;
internal ISaveHandler _saveHandler;
internal ISaveSerializer _saveSerializer;
private SaveConfig() { }
public static SaveConfig CreateConfig(string rootPath = null , bool hasHashName = true)
{
if (string.IsNullOrEmpty(rootPath))
rootPath = FileHelper.UnityRootPath + "/save";
var config = new SaveConfig();
config.RootPath = rootPath;
config.hasHashName = hasHashName;
config._saveHandler = new SaveHandlerFileStream();
config._saveSerializer = new SaveSerializerJson();
#if !UNITY_EDITOR
config._saveSerializer = new SaveSerializerCommonJson();
#endif
return config;
}
public SaveConfig SetDataHandler(ISaveHandler saveHandler)
{
_saveHandler?.Dispose();
this._saveHandler = saveHandler;
this._saveHandler?.Init();
return this;
}
public SaveConfig SetSerializer(ISaveSerializer serializer)
{
this._saveSerializer = serializer;
return this;
}
public string HashName(object saveGroup, string table = "")
{
if (hasHashName)
{
var name = saveGroup + table;
return name.GetHashCode().ToString();
}
return saveGroup.ToString() + $"_{table}";
}
public void Release()
{
_saveHandler?.Dispose();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc6b2aaf5e7e6e949a7a2e9905e2e084
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,241 @@
using System;
using System.Collections.Generic;
using Framework.Save.Interface;
using Framework.Utils;
using UnityEngine;
using Object = System.Object;
namespace Framework.Save
{
public class SaveControl<SaveType> where SaveType : Enum
{
public SaveConfig BaseConfig { get; private set; }
public Dictionary<SaveType, SaveConfig> SaveConfigs;
private Dictionary<SaveType, Dictionary<string, byte[]>> _bytesCaches;
public SaveControl()
{
SaveConfigs = new Dictionary<SaveType, SaveConfig>();
this._bytesCaches = new Dictionary<SaveType, Dictionary<string, byte[]>>();
this.BaseConfig = SaveConfig.CreateConfig();
}
public void SetConfig(SaveType saveType, SaveConfig saveConfig)
{
if (SaveConfigs.TryGetValue(saveType, out var config))
{
config.Release();
}
SaveConfigs[saveType] = saveConfig;
}
public bool HasConfig(SaveType saveType)
{
return SaveConfigs.ContainsKey(saveType);
}
#region ---------------------------------------------------------------
/// <summary>
/// 是否有指定存档
/// </summary>
/// <param name="saveGroup"></param>
/// <param name="table"></param>
/// <returns></returns>
public bool HasSave(SaveType saveGroup, string table = "")
{
var config = GetConfig(saveGroup);
return config._saveHandler.HasPath(config.RootPath, config.HashName(saveGroup.ToString(), table));
}
public SaveConfig GetConfig(SaveType saveType)
{
if (SaveConfigs.TryGetValue(saveType, out var config))
{
return config;
}
return this.BaseConfig;
}
/// <summary>
/// 删除指定存档文件
/// </summary>
/// <param name="saveGroup"></param>
/// <param name="table"></param>
public void DeleteSave(SaveType saveGroup, string table = "")
{
var config = GetConfig(saveGroup);
FileHelper.DeleteFile(config.RootPath, config.HashName(saveGroup.ToString(), table));
this.ClearCache(saveGroup, table);
}
/// <summary>
/// 数据存档
/// </summary>
/// <param name="saveGroup"></param>
/// <param name="value"></param>
/// <param name="table"></param>
public void Save(SaveType saveGroup, object value, string table = "")
{
var config = GetConfig(saveGroup);
//序列化数据
var bytes = config._saveSerializer.Serialize(value);
if (this._bytesCaches.ContainsKey(saveGroup) && this._bytesCaches[saveGroup].ContainsKey(table))
this._bytesCaches[saveGroup][table] = bytes;
config._saveHandler.WriteData(config.RootPath, config.HashName(saveGroup.ToString(), table), bytes);
}
/// <summary>
/// 数据加载
/// </summary>
/// <param name="saveGroup"></param>
/// <param name="table"></param>
public T Load<T>(SaveType saveGroup, string table = "")
{
try
{
var config = GetConfig(saveGroup);
var bytes = config._saveHandler.ReadData(config.RootPath, config.HashName(saveGroup.ToString(), table));
if (bytes != null)
{
return config._saveSerializer.Deserialize<T>(bytes);
}
return default;
}
catch (Exception e)
{
Debug.LogError($"数据加载失败: {saveGroup}_{table}" + e);
return default;
}
}
#endregion
/// <summary>
/// 快速存储,只会将数据序列化到缓存中(内存)需要手动调用Flush方法将数据写入到磁盘
/// </summary>
/// <param name="saveGroup"></param>
/// <param name="value"></param>
/// <param name="table"></param>
/// <param name="serializer"></param>
public void QuickSave(SaveType saveGroup, object value, string table = "")
{
if (value == null)
{
return;
}
if (!this._bytesCaches.ContainsKey(saveGroup))
{
this._bytesCaches[saveGroup] = new Dictionary<string, byte[]>();
}
var config = GetConfig(saveGroup);
var bytes = config._saveSerializer.Serialize(value);
this._bytesCaches[saveGroup][table] = bytes;
}
/// <summary>
/// 快速加载,将会优先从缓存读取数据,如果缓存区没有数据则尝试从磁盘中读取指定数据并缓存
/// </summary>
/// <param name="saveGroup"></param>
/// <param name="table"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T QuickLoad<T>(SaveType saveGroup, string table = "")
{
byte[] obytes = null;
var config = GetConfig(saveGroup);
if (!this._bytesCaches.ContainsKey(saveGroup) || !this._bytesCaches[saveGroup].ContainsKey(table))
{
this._bytesCaches[saveGroup] = new Dictionary<string, byte[]>();
obytes = config._saveHandler.ReadData(config.RootPath, config.HashName(saveGroup.ToString(), table));
this._bytesCaches[saveGroup][table] = obytes;
}
else
{
obytes = this._bytesCaches[saveGroup][table];
}
byte[] bytes = new byte[obytes.Length];
obytes.CopyTo(bytes, 0);
return config._saveSerializer.Deserialize<T>(bytes);
// return default;
}
/// <summary>
/// 将指定缓存写入到磁盘
/// </summary>
/// <param name="saveType"></param>
public void Flush(SaveType saveType)
{
if (this._bytesCaches.TryGetValue(saveType, out var bytesMap))
{
var keys = bytesMap.Keys;
foreach (var key in keys)
{
this.Flush(saveType, key);
}
}
}
/// <summary>
/// 将指定缓存内容写入到磁盘
/// </summary>
/// <param name="saveType"></param>
/// <param name="table"></param>
public void Flush(SaveType saveType, string table )
{
if (this._bytesCaches.ContainsKey(saveType) && this._bytesCaches[saveType].ContainsKey(table))
{
var config = GetConfig(saveType);
Debug.Log("写入数据: " + saveType + table);
config._saveHandler.WriteData(config.RootPath, config.HashName(saveType, table),
this._bytesCaches[saveType][table]);
}
}
/// <summary>
/// 将缓存区所有数据写入到磁盘
/// </summary>
public void FlushAll()
{
foreach (var cachesKey in this._bytesCaches.Keys)
{
this.Flush(cachesKey);
}
}
public void ClearCache(SaveType saveType)
{
this._bytesCaches.Remove(saveType);
}
public void ClearCache(SaveType saveType, string table)
{
if (this._bytesCaches.TryGetValue(saveType, out var cach))
{
cach.Remove(table);
}
}
public void ClearCacheAll()
{
this._bytesCaches.Clear();
}
public void Release()
{
this.FlushAll();
this.ClearCacheAll();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: efbc7eba16e542f9b91246d9050db5b8
timeCreated: 1581935135

View File

@@ -0,0 +1,15 @@
namespace Framework.Save
{
public enum SaveData
{
Game,
System,
GM,
Temp1,
Temp2,
Scene,
Data,
PersistentData,
Cache
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 86ca46d8fcfb4d6ebdbf683c9f22d589
timeCreated: 1582121860

View File

@@ -0,0 +1,39 @@
using Framework.Save.Interface;
using Framework.Utils;
using UnityEngine;
namespace Framework.Save
{
/// <summary>
/// 基于FileStream的方式读写数据
/// </summary>
public class SaveHandlerFileStream : ISaveHandler
{
public void Init()
{
}
public void WriteData(string path, string name, byte[] value)
{
if (value != null)
{
FileHelper.WriteFile(path , name , value);
}
}
public byte[] ReadData(string path, string name)
{
var bytes = FileHelper.ReadFile(path, name);
return bytes;
}
public bool HasPath(string path, string name)
{
return FileHelper.CheckPath(path + "/" + name);
}
public void Dispose()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 43f86d69ccc9478a9e8e697277b3b2ee
timeCreated: 1582041404

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Framework.Save.Interface;
using Framework.Utils;
namespace Framework.Save
{
/// <summary>
/// 快速存储,适用于数据文件数量少,但对数据文件读写频繁的情况。
/// </summary>
public class SaveHandlerQuickFileStream : ISaveHandler
{
private class FileNode
{
public byte[] Cache;
public readonly string Path;
public readonly string Name;
public string FullName => Path + "/" + Name;
public string FullNameTemp => Path + "/" + Name + ".temp";
public FileNode(string path, string name)
{
this.Path = path;
this.Name = name;
FileHelper.CreateDirectory(Path);
}
public void Close()
{
File.Delete(FullNameTemp);
}
public byte[] Read()
{
if (Cache != null)
{
return Cache;
}
if (HasPath())
{
using ( var stream = new FileStream(this.Path + "/" + this.Name, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
var length = (int) stream.Length;
Cache = new byte[length];
var read = stream.Read(Cache, 0, length);
if (read == length) return Cache;
}
Cache = null;
return null;
}
return null;
}
public void Write(byte[] bytes)
{
Cache = bytes;
try
{
var stream = new FileStream(FullNameTemp, FileMode.Create, FileAccess.ReadWrite,
FileShare.ReadWrite);
stream.Write(Cache, 0, Cache.Length);
stream.Flush();
stream.Close();
stream.Dispose();
}
catch (Exception e)
{
if (File.Exists(FullNameTemp))
{
File.Delete(FullNameTemp);
}
return;
}
File.Copy(FullNameTemp , FullName , true);
}
public bool HasPath()
{
return FileHelper.CheckPath(Path + "/" + Name);
}
}
private Dictionary<string,FileNode> _fileNodes ;
public void Init()
{
_fileNodes = new Dictionary<string, FileNode>();
}
public void WriteData(string path, string name, byte[] bytes)
{
var fileNode = GetFileNode(path, name);
fileNode.Write(bytes);
}
public byte[] ReadData(string path, string name)
{
var fileNode = GetFileNode(path, name);
return fileNode.Read();
}
public bool HasPath(string path, string name)
{
var fileNode = GetFileNode(path, name);
return fileNode.HasPath();
}
private FileNode GetFileNode(string path, string name)
{
var key = path + "/" + name;
if (_fileNodes.TryGetValue(key, out var node))
{
return node;
}
node = new FileNode(path, name);
_fileNodes.Add(key, node);
return node;
}
public void Dispose()
{
foreach (var fileNodesValue in _fileNodes.Values)
{
fileNodesValue.Close();
}
_fileNodes.Clear();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 26e4f710c926423e93bd930f024c1853
timeCreated: 1684242182

View File

@@ -0,0 +1,27 @@
using System;
using Framework.Utils;
using Framework.Utils.SingletonTemplate;
namespace Framework.Save
{
public class SaveManager : SingletonBase<SaveControl<SaveData>, SaveManager>
{
protected override void OnInit()
{
_instance.BaseConfig.RootPath = FileHelper.UnityRootPath + "/system";
// _instance.Config.SetSerializer(new SaveSerializerJson());
// return;
#if UNITY_EDITOR
_instance.BaseConfig.hasHashName = false;
_instance.BaseConfig.SetSerializer(new SaveSerializerJson());
// _instance.Config.SetSerializer(new SaveSerializerCommonJson());
#else
_instance.BaseConfig.SetSerializer(new SaveSerializerCommonJson());
#endif
_instance.SetConfig(SaveData.Cache,
SaveConfig.CreateConfig($"{FileHelper.UnityRootPath}/cache", false)
.SetSerializer(new SaveSerializerBytes()));
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8cc730ace44947d48537651e656eae43
timeCreated: 1582120542

View File

@@ -0,0 +1,21 @@
using Framework.Save.Interface;
namespace Framework.Save
{
public class SaveSerializerBytes : ISaveSerializer
{
public byte[] Serialize(object obj)
{
if (obj is byte[])
{
return (byte[])obj;
}
return null;
}
public T Deserialize<T>(byte[] value)
{
return (T)((object)value);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 871953917f7e47c880476525f5378d11
timeCreated: 1681737518

View File

@@ -0,0 +1,35 @@
using System;
using FJson;
using Framework.Utils;
using UnityEngine;
namespace Framework.Save
{
public class SaveSerializerCommonJson : SaveSerializerJsonEncrypt
{
public override T Deserialize<T>(byte[] value)
{
if (value != null)
{
try
{
//尝试直接解析
var json = FileHelper.ArrayByteUtf8ToString(value);
//如果解析成功
var op = FJsonUtility.ToObject<T>(json);
if (op != null)
{
// // 重新写入,并转换为加密数据
// this.Serialize(op);
return op;
}
}
catch (Exception e)
{
// ignored
}
}
return base.Deserialize<T>(value);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ecd4585823154347bef6b0d2efe1ae47
timeCreated: 1658738774

View File

@@ -0,0 +1,29 @@
using System;
using FJson;
using Framework.Save.Interface;
using Framework.Utils;
using UnityEngine;
namespace Framework.Save
{
public class SaveSerializerJson : ISaveSerializer
{
public byte[] Serialize(object obj)
{
var json = FJsonUtility.ToJson(obj);
return FileHelper.StringToArrayByteUtf8(json);
}
public T Deserialize<T>(byte[] value)
{
if (value != null)
{
var json = FileHelper.ArrayByteUtf8ToString(value);
var op = FJsonUtility.ToObject<T>(json);
return op;
}
return default;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d1a9eb41984e4407ba71af8f23452ef9
timeCreated: 1581933052

View File

@@ -0,0 +1,45 @@
using System;
using FJson;
using Framework.Save.Interface;
using Framework.Utils;
using UnityEngine;
namespace Framework.Save
{
public class SaveSerializerJsonEncrypt : ISaveSerializer
{
private static readonly byte[] EncryptMaps = {0x16 , 0x12 , 0x15 , 0xf1 , 0xd5 , 0x01 , 0x18 , 0x00, 0xf2 , 0x10 , 0xf6 , 0xf7 , 0xf9};
public virtual byte[] Serialize(object obj)
{
var json = FJsonUtility.ToJson(obj);
var tBytes = FileHelper.StringToArrayByteUtf8(json);
this.reverseBytes(0 , tBytes);
return tBytes;
}
public virtual T Deserialize<T>(byte[] value)
{
if (value == null)
return default;
this.reverseBytes(0 , value);
var json = FileHelper.ArrayByteUtf8ToString(value);
var deserialize = FJsonUtility.ToObject<T>(json);
return deserialize;
}
public void reverseBytes(int index, byte[] arr) {
int j = arr.Length - 1;
int el = EncryptMaps.Length;
byte temp;
while (index<j) {
//替换
temp = arr[index];
arr[index] = (byte)(arr[j] ^ EncryptMaps[index % el]);
arr[j] = (byte)(temp ^ EncryptMaps[index % el]);
index++;
j--;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f5019769583c4c68ade7e68d1f0d4ba8
timeCreated: 1582122140