c1_lua/lua/app/common/data_manager.lua
2025-09-26 15:41:46 +08:00

500 lines
16 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("HeroDataOther", "app/userdata/hero/hero_data_other")
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("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("ShopData", "app/userdata/shop/shop_data")
self:initManager("SummonData", "app/userdata/summon/summon_data")
self:initManager("AIHelperData", "app/userdata/game_setting/ai_helper_data")
self:initManager("TalentData", "app/userdata/talent/talent_data")
self:initManager("GiftPopData", "app/userdata/gift_pop/gift_pop_data")
self:initManager("PaymentData", "app/userdata/payment/payment_data")
self:initManager("FundLevelData", "app/userdata/fund_level/fund_level_data")
self:initManager("SignWeekData", "app/userdata/sign/sign_week_data")
self:initManager("SignMonthData", "app/userdata/sign/sign_month_data")
self:initManager("ChapterFundData", "app/userdata/chapter_fund/chapter_fund_data")
self:initManager("ActSevenDayData", "app/userdata/activity/act_seven_day/act_seven_day_data")
-- 冲刺活动
self:initManager("ActTimeData", "app/userdata/activity/act_time_data")
self:initManager("ActSprintData", "app/userdata/activity/act_sprint/act_sprint_data")
self:initManager("ActSprintSummonDataAll", "app/userdata/activity/act_sprint/act_sprint_summon_data_all")
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 = {}
for _, v in pairs(self._cacheManager) do
v:clear()
end
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.formations)
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.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.ShopData:init()
-- self.ShopData:refreshChapterShop(data.mall_chapter)
-- self.ShopData:refreshCoreSoulShop(data.soul)
self.ShopData:refreshDailyShop(data.mall_daily_store)
-- self.ShopData:refreshGoldShop(data.mall_gold)
-- self.ShopData:refreshEmblemShop(data.mall_mythic_store)
-- self.ShopData:initVit(data.energy_limit)
-- self.ShopData:initThirdPayOrder(data.third_pay)
-- self.ShopData:initThirdPayGiftOrder(data.third_pay)
-- 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.FundLevelData:initData(data.fund) -- levelGiftData要放到PaymentData后面因为要处理数据
self.ChapterFundData:initData(data.chapter_fund)
self.SignWeekData:initData(data.sign)
self.SignMonthData:initData(data.sign_30)
-- 活动要在礼包后初始化
self.ActTimeData:init(data.activities) -- 全活动时间, after PlayerData
self.ActivityData:initExchangeData(data.activity_exchange)
self.ActivityData:initTaskData(data.activity_task)
self.ActSprintData:init(data.activity_rush_exchange)
self.ActSevenDayData:initData(data.seven_days, true)
-- self.ActSprintSummonDataAll:initTaskData(data.activity_score_task, data.activity_task)
-- 商店礼包都初始化完了后检查一下每日红点
-- self.ShopData:checkShopDiscountRedPoint()
-- self.ShopData:checkLoginPopInfo() -- 需要写在shopdata所有初始化之后
self.SummonData:init(data.summon_data.summons)
self.AIHelperData:init(nil, true)
-- 任务数据最后初始化,依赖其他模块的数据
self.TaskData:init()
self:scheduleGlobal()
self:checkDataBind()
ModuleManager.ArenaManager:reqArenaInfo()
-- 写在最后防止某些数据还未初始化就被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
if EDITOR_MODE then
Logger.logHighlight("==========================================================")
Logger.logHighlight("本地显示日期:" .. Time:formatTimeYMD())
Logger.logHighlight("当前时间戳:" .. Time:getServerTime())
Logger.logHighlight("本日时间戳:" .. Time:getDayBeginTimeStamp() .. "-" .. Time:getDayOverTimeStamp())
Logger.logHighlight("本周时间戳:" ..
Time:getWeekBeginTimeStamp() .. "-" .. Time:getWeekOverTimeStamp() .. " 当前处于本周第" .. Time:getDayofWeek() .. "")
Logger.logHighlight("本月时间戳:" ..
Time:getMonthBeginTimeStamp() ..
"-" .. Time:getMonthOverTimeStamp() .. " 当前处于本月第" .. Time:getDayofMonth() .. "")
Logger.logHighlight("==========================================================")
end
self.crossDayTS = Time:getDayOverTimeStamp()
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 and GFunc.IsGotServerTime() then
self.crossDayTS = Time:getDayOverTimeStamp()
self.weekOverTime = Time:getWeekOverTimeStamp()
self.monthOverTime = Time:getMonthOverTimeStamp()
self.loginCount = self.loginCount + 1
-- 跨天先刷新活动时间
DataManager.ActTimeData:refreshActTime(true)
Logger.logHighlight("跨天===========================================================================")
if self.crossDayCallbacks then
for i, info in ipairs(self.crossDayCallbacks) do
if info.func and info.open then
info.func()
end
end
-- DataManager.GiftPopData:activeLoginPopGift()
end
self:doCrossDay()
-- 登录天数
ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.LOGIN_NUM)
self:tryOpenModules() -- 开服天数限制的
EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.CROSS_DAY)
-- 重置
if self.timeEveryDayCallbacks then
for k, v in ipairs(self.timeEveryDayCallbacks) do
v.triggerToday = false
end
end
end
-- 每日特定时间消息
if self.timeEveryDayCallbacks then
local timeToday = Time:getDayBeginTimeStamp(Time:getServerTime() + 1)
local passTime = Time:getServerTime() - timeToday
for k, v in ipairs(self.timeEveryDayCallbacks) do
if not v.triggerToday and v.func and v.open and passTime > v.time then
v.triggerToday = true
v.func()
end
end
end
end, 1)
end
function DataManager:doCrossDay()
local delayTime = math.random(1, 10000) / 1000
SchedulerManager:performWithDelayGlobal(function()
ModuleManager.MaincityManager:reqPassDay()
end, delayTime)
end
function DataManager:onCrossDay(info)
if info.activities then
self.ActTimeData:init(info.activities) -- 全活动时间, after PlayerData
end
if info.door then
self.DoorData:init(info.door)
end
if info.mall_daily_store then
self.ShopData:refreshDailyShop(info.mall_daily_store)
end
if info.elemental_dungeon then
self.ElementData:init(info.elemental_dungeon)
end
if info.dispatch then
self.DispatchData:init(info.dispatch)
end
end
function DataManager:registerTimeEveryDayFunc(bindId, time, func)
if not bindId or not time or not func then
return
end
if not self.timeEveryDayCallbacks then
self.timeEveryDayCallbacks = {}
end
local timeToday = Time:getDayBeginTimeStamp(Time:getServerTime() + 1)
local passTime = Time:getServerTime() - timeToday
for i, info in ipairs(self.timeEveryDayCallbacks) do
if info.bindId == bindId then
self.timeEveryDayCallbacks[i].func = func
self.timeEveryDayCallbacks[i].time = time
self.timeEveryDayCallbacks[i].triggerToday = passTime > time
self.timeEveryDayCallbacks[i].open = true
return
end
end
table.insert(self.timeEveryDayCallbacks, {
bindId = bindId,
func = func,
time = time,
triggerToday = passTime > time,
open = true
})
end
function DataManager:unRegisterTimeEveryDayFunc(bindId)
if not bindId then
return
end
if not self.timeEveryDayCallbacks then
return
end
for i, info in ipairs(self.timeEveryDayCallbacks) do
if info.bindId == bindId then
self.timeEveryDayCallbacks[i].open = false
return
end
end
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
return DataManager