// *********************************************************************** // Assembly : Game // Author : Kimch // Created : 2020-12-01 // Description : // Last Modified By : // Last Modified On : // *********************************************************************** // // // *********************************************************************** using CodeStage.AntiCheat.ObscuredTypes; using F; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace G { /// /// 存档功能 /// public class ArchiveProxy : F.GameProxy { [System.Serializable] public class ArchiveInfo { /// /// /// public string deviceId; /// /// /// public int timestamp; /// /// /// public string playerName; /// /// 角色等级 /// public int playerGrade; /// /// 最大通关数 /// public int completedLevel; /// /// /// public int combatValue; /// /// /// public bool compress = true; /// /// /// public bool isGuest; /// /// /// public string appVersion; /// /// /// public int version; /// /// /// public bool isCheat; public override string ToString() { return JsonUtility.ToJson(this); } public bool FromString(string text) { if (string.IsNullOrEmpty(text)) { return false; } try { JsonUtility.FromJsonOverwrite(text, this); return true; } catch { return false; } } } [System.Serializable] public class UserInfo { public bool god_rank; } #region Field /// /// /// private Archive _archive; /// /// /// private ArchiveInfo _archiveInfo; /// /// /// private UserInfo _userInfo; private bool _isLoaded; #endregion #region Property public override int priority => int.MaxValue; public string autoUploadArchiveMessage { get; private set; } /// /// 有本地存档 /// public bool hasLocal { get; private set; } /// /// /// public bool isCheckCloud { get; private set; } public string deviceId { get { var result = PlayerPrefs.GetString("sx_d_id"); if (string.IsNullOrEmpty(result)) { result = SystemInfo.deviceUniqueIdentifier; if (result == null || result.Length < 10) { result = "sx_did_" + Launch.Timestamp.ToString(); } PlayerPrefs.SetString("sx_d_id", result); PlayerPrefs.Save(); } return result; } } /// /// /// public UserInfo userInfo { get { return _userInfo; } } #endregion #region API /// Gets the int. public int GetInt(string key, int defaultValue = 0) { return _archive != null ? _archive.GetInt(key, defaultValue) : defaultValue; } /// /// 加密 /// /// /// /// public int GetInt(int key, int defaultValue = 0) { return _archive != null ? _archive.GetInt(key, defaultValue) : defaultValue; } /// /// 获取列表 /// /// /// 不会为空 public List GetIntList(string key) { return _archive?.GetIntList(key); } /// /// 获取列表 /// /// /// 不会为空 public List GetIntList(int key) { return _archive?.GetIntList(key); } /// Sets the int. public void SetInt(string key, int value) { _archive?.SetInt(key, value); } public void SetInt(int key, int value) { _archive?.SetInt(key, value); } /// /// /// /// /// public void SetIntList(string key, List value) { _archive?.SetIntList(key, value); } /// /// /// /// /// public void SetIntList(int key, List value) { _archive?.SetIntList(key, value); } /// /// /// /// public void RemoveIntList(string key) { _archive?.RemoveIntList(key); } /// /// /// /// public void RemoveIntList(int key) { _archive?.RemoveIntList(key); } public string GetString(string key, string defaultValue = null) { return _archive?.GetString(key, defaultValue); } public string GetString(int key, string defaultValue = null) { return _archive?.GetString(key, defaultValue); } public List GetStringList(string key) { return _archive?.GetStringList(key); } public List GetStringList(int key) { return _archive?.GetStringList(key); } public void SetString(string key, string value) { _archive?.SetString(key, value); } public void SetString(int key, string value) { _archive?.SetString(key, value); } /// Sets the int. public void SetStringList(string key, List value) { _archive?.SetStringList(key, value); } public void SetStringList(int key, List value) { _archive?.SetStringList(key, value); } public void RemoveString(string key) { _archive?.RemoveString(key); } public void RemoveString(int key) { _archive?.RemoveString(key); } #endregion #region Method /// /// /// /// /// /// 通过游客方式登录 LOGIN_TYPE_VISITOR = 1, 通过OneSdk方式登录 = 100 /// // 正常登陆 NormalLogin = 1,// 账号绑定 AccountBind = 2,// 切换账号 SwitchAccount = 3, public void OnSDKLogin(string openId, string openToken, int loginType, int loginInvokeMode) { _archiveInfo = new ArchiveInfo(); if (loginType == 1) { _archiveInfo.isGuest = true; _archive = Archive.Create(deviceId, ""); } else { _archiveInfo.isGuest = false; _archive = Archive.Create(deviceId, openId); } this.hasLocal = _archive.Load(); _isLoaded = true; } /// /// 服务器登录成功 处理存档逻辑 /// public void OnServerLogin(int loginMode) { //正常登陆 if (loginMode == 1) { Debug.Log("正常登陆 CheckAndDownload"); CheckAndDownload(OnLoginAccount); } //帐号绑订 else if (loginMode == 2) { Debug.Log("帐号绑订 Upload"); Upload(false, OnBindAccount); } //帐号切换 else if (loginMode == 3) { Debug.Log("帐号切换 Download"); Download(OnSwitchAccount); } } /// /// /// /// /// private void OnLoginAccount(int error, string message) { Debug.Log("正常登陆 CheckAndDownload 回调 " + error); if (error == ErrorCode.SUCCESS) { isCheckCloud = true; _lastUploadTime = 180f; } else { UI.MessageBox.ShowMessage("同步存档失败", "确定重新同步存档?", () => { CheckAndDownload(OnLoginAccount); }); } } /// /// 绑定帐号 /// /// /// private void OnBindAccount(int error, string message) { if (error != ErrorCode.SUCCESS) { UI.MessageBox.ShowMessage("上传存档失败", "确定重新上传存档?", () => { Upload(false, OnBindAccount); }); } } /// /// 切换帐号 /// /// /// private void OnSwitchAccount(int error, string message) { if (error != ErrorCode.SUCCESS) { UI.MessageBox.ShowMessage("下载存档失败", "确定重新下载存档?", () => { Download(OnSwitchAccount); }); } else { GameWorld.Instance.ReloadGame(); } } /// /// /// /// public string GetUploadText() { return _archive.ToBase64Text(true); } /// /// /// /// public string GetUploadInfo() { _archiveInfo.deviceId = deviceId; _archiveInfo.playerName = PlayerProxy.Instance.nickName; _archiveInfo.playerGrade = PlayerProxy.Instance.grade; _archiveInfo.completedLevel = LevelProxy.Instance.currentCompletedLevel; _archiveInfo.combatValue = PlayerProxy.Instance.combatValue; _archiveInfo.timestamp = Launch.Timestamp; _archiveInfo.appVersion = Application.version; _archiveInfo.version = Archive.VERSION; _archiveInfo.compress = true; _archiveInfo.isCheat = _archive.CheckAnti(Archive.VERSION); if (_archiveInfo.isCheat) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "使用第三方工具,可能会导致封号"); } return _archiveInfo.ToString(); } /// /// for gm /// /// public void LoadServerText(ArchiveInfo archiveInfo, string text) { var netArchive = Archive.Create(deviceId); netArchive.FromBase64Text(text, archiveInfo.compress); var old = _archive; _archive = netArchive; old.Dispose(); hasLocal = true; GameWorld.Instance.ReloadGame(); } /// /// /// /// bool GetServerData(object data, out string archiveInfoData, out string archiveData) { archiveInfoData = null; archiveData = null; if (data is IList archives && archives.Count > 0) { for (int i = 0; i < archives.Count; i++) { var archive = archives.GetDictionary(i); if (archive != null) { var name = archive.GetString("name"); if (name == "archive_info") { archiveInfoData = archive.GetString("data"); } else if (name == "archive") { archiveData = archive.GetString("data"); } else if (name == "user_info") { _userInfo = JsonUtility.FromJson(archive.GetString("data")); } } } return true; } return false; } /// /// /// /// /// public bool CheckOnline(Callback3 callback) { return AntiCheatProxy.Instance.CheckCheat((error, message) => { if (error == ErrorCode.SUCCESS) ServerProxy.Instance.DownloadArchive(new string[] { "archive_info" }, callback); }); } /// /// 检查并下载 /// /// /// public bool CheckAndDownload(Callback2 callback) { if (!hasLocal) { Download(callback); } else { Check(callback); } return true; } /// /// 第一次检查 /// /// /// public bool Check(Callback2 callback) { ServerProxy.Instance.DownloadArchive(new string[] { "user_info", "archive_info", "archive" }, (error, msg, data) => { if (error == 0) { if (GetServerData(data, out string archiveInfoData, out string archiveData)) { // 是否是新号 if (_archiveInfo.FromString(archiveInfoData)) { bool diffDevice = _archiveInfo.deviceId != deviceId; if (diffDevice) { _archive.FromBase64Text(archiveData, _archiveInfo.compress); } if (!GlobalUtils.IsSmallVersion(_archiveInfo.appVersion, Application.version)) Upload(diffDevice, callback); else UploadBackup(diffDevice, archiveInfoData, archiveData, callback); } else { _archive.FromBase64Text("", _archiveInfo.compress); Upload(true, callback); } } else { callback?.Invoke(0, ""); } } else { callback?.Invoke(error, msg); } }); return true; } /// /// 下载存档 /// /// /// public void Download(Callback2 callback) { //本地没有存档 ServerProxy.Instance.DownloadArchive(new string[] { "archive_info", "archive" }, (error, msg, data) => { if (error == 0) { GetServerData(data, out string archiveInfoData, out string archiveData); if (!string.IsNullOrEmpty(archiveInfoData)) _archiveInfo.FromString(archiveInfoData); _archive.FromBase64Text(archiveData, _archiveInfo.compress); hasLocal = true; GetUploadInfo(); } callback?.Invoke(error, msg); }); } /// /// 上传存档 /// /// 1 上传正常 0 只上传信息 /// /// public void Upload(bool onlyUploadInfo, Callback2 callback) { string uploadInfo = GetUploadInfo(); string uploadText = null; if (!onlyUploadInfo) { uploadText = GetUploadText(); } ServerProxy.Instance.UploadArchive(uploadInfo, uploadText, null, null, (error, message) => { if (error == ErrorCode.SUCCESS) { message = "上次保存时间:\n" + System.DateTime.Now.ToString(); } callback?.Invoke(error, message); }); } /// /// /// /// public void UploadBackup(bool onlyUploadInfo, string archiveInfo2, string archive2, Callback2 callback) { string uploadInfo = GetUploadInfo(); string uploadText = null; if (!onlyUploadInfo) { uploadText = GetUploadText(); } ServerProxy.Instance.UploadArchive(uploadInfo, uploadText, archiveInfo2, archive2, callback); } public void UploadImmediate() { _lastUploadTime = 0.1f; } /// /// 保存 /// public void Save() { if (AntiCheatProxy.Instance.isCheatMemory) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "修改内存会导致帐号异常"); Debug.LogError("修改内存会导致帐号异常" + $"uid={UserProxy.AccountID}"); return; } if (_archive != null) _archive.Save(); } /// /// 清除帐号 /// public void Delete() { if (_archive != null) _archive.Delete(); _archive = null; } float _lastUploadTime = -1f; void AutoUpload() { if (_lastUploadTime > 0f) { _lastUploadTime -= Time.deltaTime; if (_lastUploadTime <= 0f) { if (!GlobalVar.IsBattling) { if (!AntiCheatProxy.Instance.isCheat) { Upload(false, OnAutoUpload); _lastUploadTime = 100f; } else if (AntiCheatProxy.Instance.isCheatTime) { autoUploadArchiveMessage = "当前时间异常"; _lastUploadTime = 10f; } else if (AntiCheatProxy.Instance.isCheatMemory) { autoUploadArchiveMessage = "修改内存会导致帐号异常"; _lastUploadTime = float.MaxValue; } } else { _lastUploadTime = 1f; } } } } /// /// /// /// /// private void OnAutoUpload(int error, string message) { if (error == ErrorCode.SUCCESS) { autoUploadArchiveMessage = "上次保存时间:\n" + System.DateTime.Now.ToString(); } else { autoUploadArchiveMessage = "自动同步失败"; } } float _lastUpdateTime = -1f; void AutoSave() { _lastUpdateTime += Time.deltaTime; if (_lastUpdateTime > 5f) { _lastUpdateTime = 0f; if (!GlobalVar.IsBattling) Save(); return; } } #endregion #region Unity && Proxy public static ArchiveProxy Instance; // Use this for initialization private void Awake() { Instance = this; KPlatform.ApplicationFocusEvent += this.OnApplicationFocusEvent; } private void LateUpdate() { AutoSave(); AutoUpload(); } private void OnApplicationFocusEvent(bool focus) { if (!focus) Save(); } #endregion } }