c1_lua/lua/app/common/data_manager.lua
2025-05-25 19:19:05 +08:00

573 lines
17 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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")
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()
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.heroes_equips)
self.EquipData:initGifts(data.act_weapon_armor_gift)
self.SkinData:init(data.bag.skins)
-- HeroData要在EquipData、SkinData之后初始化依赖它们的属性数据
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)
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) -- 每日特惠
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, true)
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