local DataManager = { initByServer = false } function DataManager:init() self.cdCallBack = {} self._cacheManager = {} self:initManager("GameSettingData", "app/userdata/game_setting/game_setting_data") self:initManager("PlayerData", "app/userdata/player/player_data") self:initManager("ChapterData", "app/userdata/chapter/chapter_data") self:initManager("DailyChallengeData", "app/userdata/daily_challenge/daily_challenge_data") self:initManager("DungeonData", "app/userdata/dungeon/dungeon_data") self:initManager("ArenaData", "app/userdata/arena/arena_data") self:initManager("CollectionData", "app/userdata/collection/collection_data") self:initManager("HeroData", "app/userdata/hero/hero_data") self:initManager("BagData", "app/userdata/bag/bag_data") self:initManager("EquipData", "app/userdata/equip/equip_data") self:initManager("SkinData", "app/userdata/skin/skin_data") self:initManager("BattleData", "app/userdata/battle/battle_data") self:initManager("BattlePVPData", "app/userdata/battle/battle_pvp_data") self:initManager("FormationData", "app/userdata/formation/formation_data") self:initManager("TutorialData", "app/userdata/tutorial/tutorial_data") self:initManager("MailData", "app/userdata/mail/mail_data") self:initManager("ActivityData", "app/userdata/activity/activity_data") self:initManager("GoldPigData", "app/userdata/activity/gold_pig/gold_pig_data") self:initManager("BountyData", "app/userdata/bounty/bounty_data") self:initManager("ArenaBountyData", "app/userdata/arena/arena_bounty_data") self:initManager("TaskData", "app/userdata/task/task_data") self:initManager("DailyTaskData", "app/userdata/task/daily_task_data") self:initManager("IdleData", "app/userdata/idle/idle_data") self:initManager("GrowthFundData", "app/userdata/fund/growth_fund_data") self:initManager("SevenDayData", "app/userdata/activity/seven_day/seven_day_data") self:initManager("ShopData", "app/userdata/shop/shop_data") self:initManager("SummonData", "app/userdata/summon/summon_data") self:initManager("FullMoonData", "app/userdata/activity/full_moon/full_moon_data") self:initManager("TournWaveData", "app/userdata/activity/tourn_wave/tourn_wave_data") self:initManager("TournArenaData", "app/userdata/activity/tourn_arena/tourn_arena_data") self:initManager("AIHelperData", "app/userdata/game_setting/ai_helper_data") self:initManager("HeroFundData", "app/userdata/activity/hero_fund/hero_fund_data") self:initManager("ActBossRushData", "app/userdata/activity/act_boss_rush/act_boss_rush_data") self:initManager("FourteenDayData", "app/userdata/activity/fourteen_day/fourteen_day_data") self:initManager("ActPvpData", "app/userdata/activity/act_pvp/act_pvp_data") self:initManager("TalentData", "app/userdata/talent/talent_data") end function DataManager:initManager(name, path) if self[name] then self._cacheManager[name] = self[name] end if (name == "BattleData" or name == "BattlePVPData") and self._cacheManager[name] then else self[name] = require(path):create() end end function DataManager:checkDataBind() local changeBindFunc = function(baseData, curBaseData) local data = baseData.data if data then local bindList = baseData.bindList if bindList then for fieldName, list in pairs(bindList) do for _, v in ipairs(list) do if v.binder.unBind then v.binder:unBind(baseData, fieldName) end if v.binder.bind then if baseData.data[fieldName] ~= curBaseData.data[fieldName] then v.binder:bind(curBaseData, fieldName, v.bindFunc, true) else v.binder:bind(curBaseData, fieldName, v.bindFunc) end end end end end baseData:clearBindAll() end end if self._cacheManager then -- 如果已经存在就检查一下绑定 for name, baseData in pairs(self._cacheManager) do if name == "BagData" then changeBindFunc(baseData.ItemData, self[name].ItemData) else if baseData ~= self[name] then changeBindFunc(baseData, self[name]) end end end end end function DataManager:clear() self.loginSuccess = false self.initWithServer = false if self.cacheTimer then SchedulerManager:unscheduleGlobal(self.cacheTimer) self.cacheTimer = nil end self.cdCallBack = {} self.PlayerData:clear() self.ChapterData:clear() self.DailyChallengeData:clear() self.DungeonData:clear() self.ArenaData:clear() self.CollectionData:clear() self.HeroData:clear() self.BagData:clear() self.EquipData:clear() self.SkinData:clear() self.FormationData:clear() self.ActivityData:clear() self.MailData:clear() self.GoldPigData:clear() self.BountyData:clear() self.ArenaBountyData:clear() self.DailyTaskData:clear() self.IdleData:clear() self.GrowthFundData:clear() self.SevenDayData:clear() self.ShopData:clear() self.SummonData:clear() self.FullMoonData:clear() self.TournWaveData:clear() self.TournArenaData:clear() -- 任务数据最后清理 self.TaskData:clear() self.AIHelperData:clear() self.HeroFundData:clear() self.ActBossRushData:clear() self.FourteenDayData:clear() self.ActPvpData:clear() self.TalentData:clear() ModuleManager.TaskManager:clear() self:clearTryOpenFunc() self.activityBountyLevelMap = nil end function DataManager:initWithServerData(data) self:init() Time:setServerTimeZone(0) Time:updateServerTime(data.now_ts) Time:updateServerTimeToday(data.today_ts) if EDITOR_MODE then Logger.logHighlight("initWithServerData") Logger.printTable(data) Logger.logHighlight("注册时间 : " .. Time:formatTimeYMDHMS(GFunc.formatTimeStep(data.stat.register_ts))) end self.registerTs = data.stat and data.stat.register_ts or Time:getServerTime() self.registerTs = GFunc.formatTimeStep(self.registerTs or Time:getServerTime()) self.todayFirstLogin = data.today_first_login self.PlayerData:init(data) self.ChapterData:init(data.chapter) self.DailyChallengeData:init(data.chapter_daily_challenge) self.DungeonData:initDungeonGold(data.chapter_gold_challenge) self.DungeonData:initDungeonShards(data.chapter_shards_challenge) self.FormationData:init(data.fight_info) self.EquipData:init(data.equip) self.SkinData:init(data.bag.skins) self.TalentData:init(data.talent) -- HeroData要在EquipData、SkinData、TalentData之后初始化,依赖它们的属性数据 self.HeroData:init(data.bag.heroes) self.BagData:init(data.bag) -- self.DungeonData:initDungeonWeapon(data.chapter_weapon_challenge) -- self.DungeonData:initDungeonArmor(data.chapter_armor_challenge) self.CollectionData:init(data.collection) self.TutorialData:init(data.guide) self.MailData:init(data.mail_info) self.GoldPigData:init(data.pig, true) self.BountyData:init(data.bounty) self.ArenaBountyData:init(data.arena_bounty) self.ArenaData:initGiftInfo(data.act_arena_gift, true) -- 任务要在BountyData之后初始化,依赖BountyData的数据 self.DailyTaskData:init(data.task_daily, data.task_achievement) self.IdleData:init(data.idle) self.SevenDayData:init(data.seven_day) self.ShopData:initBase() self.ShopData:initActGift(data.act) -- 礼包购买信息 self.ShopData:initMallDaily(data.mall_daily_store) -- 每日特惠 self.ShopData:initCommonDailyGoldGift(data.mall_idle and data.mall_idle.ad_count) -- 常驻金币礼包 self.ShopData:initGrowUpGift(data.act_grow_up_gift2) -- 成长礼包 self.ShopData:initLevelUpGift(data.act_level_up_gift) -- 助力/金币礼包 self.ShopData:initIntroductGift(data.act_introductory_gift) -- 入门礼包 -- 活动要在礼包后初始化 self.ActivityData:init() -- 商店礼包都初始化完了后检查一下每日红点 self.ShopData:checkShopDiscountRedPoint() self.ShopData:checkLoginPopInfo() -- 需要写在shopdata所有初始化之后 self.SummonData:init(data.summon_data.summons) self.AIHelperData:init(nil, true) -- 成长基金要在ShopData和PlayerDataBagData还有之后初始化,依赖这些数据 if data.fund then self.GrowthFundData:init(data.fund.funds) end self.HeroFundData:init(data.hero_fund) self.FourteenDayData:init(data.fourteen_bounty) -- 任务数据最后初始化,依赖其他模块的数据 self.TaskData:init() self:scheduleGlobal() self:checkDataBind() ModuleManager.ArenaManager:reqArenaInfo() self:dealOpenActivity(data.activities) -- 写在最后,防止某些数据还未初始化,就被bi访问报错 self.initWithServer = true end -- 是否首次登录 function DataManager:getIsFirstLogin() local nowTime = Time:getServerTime() local offset = nowTime - (self.registerTs or 0) if math.abs(offset) <= 10 and self:getIsTodayFirstLogin() then -- 允许误差 return true end return false end -- 是否在新号24小时内 function DataManager:getIsInCreate24Hour() local nowTime = Time:getServerTime() local passTime = nowTime - (self.registerTs or 0) return passTime < 86400 end function DataManager:getRegisterTs() return self.registerTs or 0 end function DataManager:getIsTodayFirstLogin() return self.todayFirstLogin or false end function DataManager:getIsInitWithServer() return self.initWithServer end function DataManager:registerDataCd(dataName) if not dataName then return end for k, v in ipairs(self.cdCallBack) do if v == dataName then return end end table.insert(self.cdCallBack, dataName) end function DataManager:unregisterDataCd(dataName) if not dataName then return end for k, v in ipairs(self.cdCallBack) do if v == dataName then table.remove(self.cdCallBack, k) break end end end function DataManager:registerCrossDayFunc(bindId, func) if not bindId or not func then return end if not self.crossDayCallbacks then self.crossDayCallbacks = {} end for i, info in ipairs(self.crossDayCallbacks) do if info.bindId == bindId then self.crossDayCallbacks[i].func = func self.crossDayCallbacks[i].open = true return end end table.insert(self.crossDayCallbacks,{ bindId = bindId, func = func, open = true }) end function DataManager:unregisterCrossDayFunc(bindId) if not bindId then return end if not self.crossDayCallbacks then return end for i, info in ipairs(self.crossDayCallbacks) do if info.bindId == bindId then self.crossDayCallbacks[i].open = false return end end end function DataManager:scheduleGlobal() if self.cacheTimer then return end self.crossDayTS = Time:getOverOfServerToday() self.cacheTimer = SchedulerManager:scheduleGlobal(function (inter) for k, v in ipairs(self.cdCallBack) do if self[v] and self[v].updateCd then self[v]:updateCd() end end if Time:getServerTime() > self.crossDayTS then self.crossDayTS = Time:getOverOfServerToday() if self.crossDayCallbacks then for i, info in ipairs(self.crossDayCallbacks) do if info.func and info.open then info.func() end end end ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_LOGIN_DAY) end end, 1) end function DataManager:tryOpenModules() if not self.tryOpenCallbacks then return end for k, v in pairs(self.tryOpenCallbacks) do v() end end function DataManager:registerTryOpenFunc(bindId, func) if not bindId or not func then return end if not self.tryOpenCallbacks then self.tryOpenCallbacks = {} end self.tryOpenCallbacks[bindId] = func end function DataManager:unregisterTryOpenFunc(bindId) if not bindId then return end if not self.tryOpenCallbacks then return end self.tryOpenCallbacks[bindId] = nil end function DataManager:clearTryOpenFunc() if not self.tryOpenCallbacks then return end for k, v in pairs(self.tryOpenCallbacks) do self.tryOpenCallbacks[k] = nil end end function DataManager:getSignInfo() local nowTime = Time:getServerTime() local lastSignTime = self.signInfo.latest_at // 1000 local todayBeginTime = nowTime - nowTime % 86400 local canSign = lastSignTime < todayBeginTime if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.SIGNIN) then canSign = false end return self.signInfo.count or 0, canSign, self.hasSigned end function DataManager:setSignCount(count) self.hasSigned = true self.signInfo.count = count self.signInfo.latest_at = Time:getServerTime() * 1000 --Logger.logHighlight("签到成功次数:"..count) end function DataManager:resetSignInInfo() self.hasSigned = false end function DataManager:setLoginSuccess(success) self.loginSuccess = success end function DataManager:getLoginSuccess() return self.loginSuccess end -- 获取建号时间 function DataManager:getCreatePlayerTime() return self.createPlayerTime or Time:getServerTime() end -- 记录sync了多少次数据,如果以后游戏中要回到登录界面,则此值应当被清除 function DataManager:markSyncDataCount() if not self.syncDataCount then self.syncDataCount = 1 else self.syncDataCount = self.syncDataCount + 1 end end function DataManager:getSyncDataCount() return self.syncDataCount or 0 end function DataManager:needDealGm() return self:getSyncDataCount() >= 2 end function DataManager:getManager(name, path) if self[name] then return self[name] end self[name] = require(path):create() return self[name] end ---- 缓存一下活动战令 function DataManager:getActivityBountyLevelByActId(actId) if not self.activityBountyLevelMap then self.activityBountyLevelMap = {} local cfg = ConfigManager:getConfig("activity_bounty_level") for id, info in pairs(cfg) do if info.act_id then if not self.activityBountyLevelMap[info.act_id] then self.activityBountyLevelMap[info.act_id] = {} end table.insert(self.activityBountyLevelMap[info.act_id], id) end end end return self.activityBountyLevelMap[actId] end ---- 缓存一下活动兑换商店 function DataManager:getActivityExchangeByActId(actId) if not self.activityExchangeMap then self.activityExchangeMap = {} local cfg = ConfigManager:getConfig("activity_exchange") for id, info in pairs(cfg) do if info.activity then if not self.activityExchangeMap[info.activity] then self.activityExchangeMap[info.activity] = {} end table.insert(self.activityExchangeMap[info.activity], id) end end end return self.activityExchangeMap[actId] end ---- 缓存一下活动排行榜 function DataManager:getActivityRankByActId(actId) if not self.activityRankMap then self.activityRankMap = {} local cfg = ConfigManager:getConfig("activity_rank") for id, info in pairs(cfg) do if info.act_id then if not self.activityRankMap[info.act_id] then self.activityRankMap[info.act_id] = {} end table.insert(self.activityRankMap[info.act_id], id) end end end return self.activityRankMap[actId] end function DataManager:dealOpenActivity(activityInfo) local curTime = Time:getServerTime() if not activityInfo then return end local newActivityList = {} local map = {} for _, info in ipairs(activityInfo) do if info.type then if not map[info.type] then map[info.type] = info else if map[info.type].start_at > info.start_at then map[info.type] = info end end end end for actType, info in pairs(map) do table.insert(newActivityList, info) end local dealTypeMap = {} for _, info in ipairs(newActivityList) do local startTime = GFunc.formatTimeStep(info.start_at) if startTime <= curTime and curTime <= GFunc.formatTimeStep(info.end_at) then local reqFunc = DataManager.activityOpenFunc[info.type] if reqFunc and not dealTypeMap[info.type] then dealTypeMap[info.type] = true reqFunc(info) end elseif startTime > curTime then local waitOpenFunc = DataManager.waitOpenActivity[info.type] if waitOpenFunc and not dealTypeMap[info.type] then dealTypeMap[info.type] = true waitOpenFunc(info) end end end end DataManager.activityOpenFunc = { [2] = function(params) DataManager.ActBossRushData:setActivityInfo(params) ModuleManager.ActBossRushManager:reqActData() end, [3] = function(params) DataManager.ActPvpData:setActivityId(params.id) DataManager.ActPvpData:setActivityInfo(params) DataManager.ActPvpData:init({}) -- 默认初始化 ModuleManager.ActPvpManager:reqActData() end, [4] = function(params) DataManager.FullMoonData:setActStatus(params) ModuleManager.FullMoonManager:reqActData() ModuleManager.FullMoonManager:initTimer() end, [5] = function(params) DataManager.TournWaveData:setActStatus(params) ModuleManager.TournWaveManager:reqActData() ModuleManager.TournWaveManager:initTimer() end, [6] = function(params) DataManager.TournArenaData:setActStatus(params) ModuleManager.TournArenaManager:reqActData() ModuleManager.TournArenaManager:initTimer() end, } DataManager.waitOpenActivity = { [2] = function(params) DataManager.ActBossRushData:init({activity_id = params.id}) -- 默认初始化 DataManager.ActBossRushData:setActivityInfo(params) end, [3] = function(params) DataManager.ActPvpData:setActivityId(params.id) DataManager.ActPvpData:setActivityInfo(params) DataManager.ActPvpData:init({}) -- 默认初始化 end, [4] = function(params) DataManager.FullMoonData:setActStatus(params) ModuleManager.FullMoonManager:initTimer() end, [5] = function(params) DataManager.TournWaveData:setActStatus(params) ModuleManager.TournWaveManager:initTimer() end, [6] = function(params) DataManager.TournArenaData:setActStatus(params) ModuleManager.TournArenaManager:initTimer() end, } return DataManager