import { PREVIEW } from "cc/env"; import { MainConfig } from "../../Launch/_MainConfig"; import { Director, director, sys } from "cc"; import { ESceneName } from "../const/GameEnum"; import FileManager from "../Framework/FileTools/FileManager"; import { Utils } from "../ExUtils/Utils"; import DataInstanceT from "../ExUtils/DataInstanceT"; import { TDAnalyticsMgr } from "../Mgr_Ge/TDAnalyticsMgr"; import { GEData } from "../Mgr_Ge/GeDifine"; import PlatformData from "../Platform/Data/PlatformData"; import { PlatformCommonDefine } from "../Platform/Common/PlatformCommonDefine"; export default class LocalStorage{ static readonly GAME_DATA_NAME: string = `${MainConfig.Name}-${`CatCat`}`; static readonly LoginKey:string = "LoginTime" static m_mapLocalData: { [key: string]: any } = {}; static mMapLocalDataJson: string = ``; /**标记更新*/ static mDirty: boolean = false; static mLoadComplete:boolean = false; static mReBuilding:boolean = false; //是否正在重新构建数据 /**是否分离Jsonstringify与localStorage */ static mStringifySplit: boolean = false; /**是否支持监听游戏关闭或者结束 暂未实现请自己在关闭游戏时进行处理 */ static mSupListen: boolean = false; static mDebugTime: boolean = false; /**时间记录 */ static time:number = 0; static frame:number = 0; static maxFrame:number = 5; private static isSaveing:boolean =false; private static saveTime: number = 0; private static mstime:number = 0; private static GameTime = 0; private static LastGameTime = 0; private static chekcTime = 30*1000; private static LoginDay:number = 0; private static mPlatformData:PlatformData; private static mLoginState:PlatformCommonDefine.LoginState; /**添加事件触发 */ static addEvent(){ this.mstime = Date.now(); this.LastGameTime = this.mstime; this.GameTime = this.mstime; director.targetOff(this) director.on(Director.EVENT_AFTER_DRAW, this.SaveGameData, this); } private static isNewUserKey:string = "NewUser"; private static _isNewUser:boolean = false; static get isNewUser():boolean{ return this._isNewUser; } static set isNewUser(value: boolean) { this.setItem(this.isNewUserKey, true, true); this._isNewUser = value; this.mDirty = true; } private static ADKey:string = "ADKey"; private static _ad_cnt: number = 0; static get ad_cnt() { return this._ad_cnt; } static set ad_cnt(value: number) { this._ad_cnt = value; this.setItem(this.ADKey, this._ad_cnt); } static InitServerGameData(_PlatformData:PlatformData,_loginState:PlatformCommonDefine.LoginState,callBack: Function) { this.mPlatformData = _PlatformData; this.mLoginState = _loginState; this.getServerData((json: string) => { this.InitGameData(json, callBack); // if (this.m_mapLocalData["_ShopData"] && this.m_mapLocalData["_ShopData"]["times"] < 0) { // this.m_mapLocalData["_ShopData"]["times"] = 50; // } if (this.m_mapLocalData["_TokenData"] && this.m_mapLocalData["_TokenData"]["Token"]["1"] < 0) { this.m_mapLocalData["_TokenData"]["Token"]["1"] = 3000000; } }) } /**初始化游戏缓存数据 */ static InitGameData(serverJson:string,callBack:Function) { /**获取本地数据 */ this.mMapLocalDataJson = sys.localStorage.getItem(this.GAME_DATA_NAME); if (!this.mMapLocalDataJson) { /**如果拥有服务器数据 */ if (serverJson) { let tampData = JSON.parse(serverJson) || {}; this.m_mapLocalData = tampData; this.saveTime = tampData.lastTime || 0; } else { this.mMapLocalDataJson = "{}"; this.m_mapLocalData = JSON.parse(this.mMapLocalDataJson) || {}; } } else { if (serverJson) { let tampData = JSON.parse(serverJson) || {}; this.saveTime = tampData.lastTime || 0; let templocalData = JSON.parse(this.mMapLocalDataJson) || {}; if(tampData["_GameData"] && tampData["_PassData"] && templocalData["_GameData"] && templocalData["_PassData"]){ const serverlevelid = tampData["_GameData"]["mLevelData"]["id"] + tampData["_PassData"]["passed_times"] * 21; const locallevelid = templocalData["_GameData"]["mLevelData"]["id"] + templocalData["_PassData"]["passed_times"] * 21; if(serverlevelid <= locallevelid){ ConsoleEx.Com("本地数据更新: " + serverlevelid + " <= " + locallevelid) this.m_mapLocalData = templocalData; } }else{ this.m_mapLocalData = tampData; } }else{ this.m_mapLocalData = JSON.parse(this.mMapLocalDataJson) || {}; } } this.time = Date.now(); let LoginTime = this.getItem(this.LoginKey); if (!LoginTime) { this.setItem(this.LoginKey, Date.now()); this.LoginDay = 1; } else { this.LoginDay = Math.floor((this.time - LoginTime) / 1000 / (24 * 60 * 60)) + 1; } let _time = Date.now() - this.time; this.time = 0; //判断时间差 if (_time > 50) { ConsoleEx.Error('数据读取时间过长', this.GAME_DATA_NAME, _time); } this._isNewUser = !this.getItem(this.isNewUserKey); this._ad_cnt = +this.getItem(this.ADKey) || 0; callBack && callBack(); } private static getServerData( Back: (str:string)=>void) { const platformData = this.mPlatformData; const loginState = this.mLoginState; let base = window["wx"] || window["tt"] || window["ks"]; if (!base || !platformData.appId || !loginState.openid) { !PREVIEW && ConsoleEx.Error("获取存档失败",base,platformData.appId,loginState.openid); Back && Back(null); return; } let data = { app_id: platformData.appId, open_id: loginState.openid, } base.request({ url: `https://game-api.lvzhouyouxi.com/user/game_data`, // 本地服务地址 method: 'GET', data: data, header: { 'Content-Type': 'application/json' }, success: (resp) => { console.log('*********************', resp) // console.warn("获取的存档数据", resp.data.game_data) Back && Back(resp.data.game_data); }, fail: (errString) => { console.error(errString); Back && Back(null); }, complete: (message) => { } }); } static CheckSaveServerData(Back?: (isError: boolean) => void) { if (this.saveTime < this.m_mapLocalData["lastTime"]) { this.saveServerData(Back); } else { Back && Back(true); } } static getCloudDiffTime() { return this.m_mapLocalData["lastTime"] - this.saveTime; } static saveServerData(Back: (isError:boolean)=>void) { if (this.isSaveing) { return; } this.isSaveing = true; const platformData = this.mPlatformData; const loginState = this.mLoginState; let base = window["wx"] || window["tt"] || window["ks"]; if (!base || !platformData.appId || !loginState.openid) { !PREVIEW && ConsoleEx.Error("存档失败",base,platformData.appId,loginState.openid); Back && Back(false); this.isSaveing = false; return; } if (!this.m_mapLocalData["lastTime"]) { this.m_mapLocalData["lastTime"] = Date.now(); } let time = this.m_mapLocalData["lastTime"]; let data = { app_id: platformData.appId, open_id: loginState.openid, game_data: this.mMapLocalDataJson, } let sync_time_start = Date.now(); base.request({ url: `https://game-api.lvzhouyouxi.com/user/game_data`, // 本地服务地址 method: 'POST', data: data, header: { 'Content-Type': 'application/json' }, success: (resp) => { console.log('*********************', resp) console.warn("保存存档数据", resp.data.game_data) this.saveTime = time; this.isSaveing = false; let sync_time = (Date.now() - sync_time_start) / 1000; sync_time = +sync_time.toFixed(2) TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.sync_data, {sync_time: sync_time}); Back && Back(true); }, fail: (errString) => { console.error(errString); Back && Back(false); this.isSaveing = false; }, complete: (message) => { } }); } static setLodingComplete(){ this.mLoadComplete = true; } static tryEventSend(){ this.mstime = Date.now(); if ((this.mstime - this.LastGameTime) >= this.chekcTime) { this.LastGameTime = this.mstime; let time = this.mstime - this.GameTime; let length = Math.floor(Utils.MathUtils.MsToFloat(time)); ConsoleEx.Log(`游玩时长:第${this.LoginDay}天 游玩时长:${length}`); // TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.play_time, { day: this.LoginDay, length: length }); } } /**保存游戏数据 */ static SaveGameData(dt:number) { this.tryEventSend(); if (!this.mLoadComplete) { return; } if (!this.mDirty) { return; } if (this.mReBuilding) { return; } /**处于新用户阶段 不保存数据 */ //if (this.isNewUser) { return; } // this.frame++; // if(this.frame 50) { ConsoleEx.Error('数据保存时间过长', this.GAME_DATA_NAME, _time); } this.mDirty = false; this.mDebugTime && ConsoleEx.Log(this.mMapLocalDataJson) } /**获取缓存数据 */ static getItem(key) { return this.m_mapLocalData[key] } /**设置缓存数据 */ static setItem(key: string, value: any, isSave: boolean = false) { this.m_mapLocalData[`${key}`] = value; this.mDirty = true; if (this.mStringifySplit || isSave) { this.m_mapLocalData["lastTime"] = Date.now(); this.mMapLocalDataJson = JSON.stringify(this.m_mapLocalData,null, 0) } isSave && (this.mDirty = false) isSave && this.saveData(); } /**保存数据 */ static saveData(){ sys.localStorage.setItem(this.GAME_DATA_NAME, this.mMapLocalDataJson) } /**重置所有数据 */ static reBuildAllData(){ DataInstanceT.ReBuildData(); DataInstanceT.initData(); DataInstanceT.initLogic(); } /**清除所有 */ static clearAll() { DataInstanceT.ClearData(); localStorage.clear(); this.m_mapLocalData = {}; this.mMapLocalDataJson = JSON.stringify(this.m_mapLocalData,null, 0) this.saveData(); } /**清除某个key的数据 */ static clearDataByKey(key: string) { delete this.m_mapLocalData[`${key}`]; this.mMapLocalDataJson = JSON.stringify(this.m_mapLocalData,null, 0) this.saveData(); } static readJsonFile(callback:Function){ FileManager.ins().mFileTools.openLocalFileCallBack((file) => { let data = null; if(file?.value){ data = file?.value; }else if(file?.json){ if(typeof file.json == "string"){ data = file.json; }else{ data = JSON.stringify(file.json); } } if(!data){ConsoleEx.Error("数据读取失败",file); return;} callback && callback(); let scene = director.getScene(); for (let i = 0; i < scene.children.length; i++) { const tNode = scene.children[i]; if (director.isPersistRootNode(tNode)) { director.removePersistRootNode(tNode) ConsoleEx.Log(tNode.name) } } LocalStorage.readJson(data); director.loadScene(ESceneName.Launch); }, ".json"); } static readJson(json:string){ this.clearAll(); this.mLoadComplete = false; this.mDirty = false; this.m_mapLocalData = JSON.parse(json) || {}; this.mMapLocalDataJson = JSON.stringify(this.m_mapLocalData,null, 0) this.saveData(); } static getSaveJson(){ return JSON.stringify(this.m_mapLocalData,null, 0); } static SaveToLocal(){ FileManager.ins().mFileTools.ProjectWriteStringToFile(LocalStorage.getSaveJson(),`${MainConfig.ZHName}${"存档"}.json`); } static getUserInfo(appId:string,openid:string){ let xhr: XMLHttpRequest = new XMLHttpRequest(); xhr.open('GET', `https://game-api.lvzhouyouxi.com/user/game_data?app_id=${appId}&open_id=${openid}`, true); xhr.onreadystatechange = () => { if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)) { if (xhr.responseText.length > 0) { let data = JSON.parse(xhr.responseText); let game_data = JSON.stringify(JSON.parse(data.game_data)) FileManager.ins().mFileTools.ProjectWriteStringToFile(game_data,`${appId}-${openid}.json`); } else { } } } xhr.onerror = () => { console.error("拉取存档错误"); } xhr.send(); } static setUserInfo(appId: string, openid: string,json:string) { let xhr: XMLHttpRequest = new XMLHttpRequest(); xhr.open('POST', `https://game-api.lvzhouyouxi.com/user/game_data`, true); xhr.setRequestHeader('Content-Type','application/json' ); xhr.onreadystatechange = () => { if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)) { if (xhr.responseText.length > 0) { let data = JSON.parse(xhr.responseText); ConsoleEx.Log("存档成功!",xhr.responseText) } else { } } } xhr.onerror = () => { console.error("存档错误"); } let data = { app_id: appId, open_id: openid, game_data: json, } xhr.send(JSON.stringify(data)); } } if (PREVIEW) { window['LocalStorage'] = LocalStorage; }