--在线奖励活动 --db --[=[ human.db.OnlineRewardData = { haveTime = nil, --活动获得时间, 即首充时间 dailyData = { --每日数据,key为当前时间距离 haveTime 的天数 [1] = { [1] = nil, --记录当天某个档位奖励的领取情况, key 为档位,有记录表示已经领取了(不可领取和可领取两种状态不存db) [2] = nil, }, [2] = { [1] = nil, [2] = nil, }, } } ]=]-- local Msg = require("core.Msg") local Grid = require("bag.Grid") local Util = require("common.Util") local BagLogic = require("bag.BagLogic") local Broadcast = require("broadcast.Broadcast") local Lang = require("common.Lang") local onlineAardCfg = require("excel.onlineAward").onlineAward local YunYingLogic = require("yunying.YunYingLogic") local PanelDefine = require("broadcast.PanelDefine") local Timer = require("core.Timer") local ObjHuman = require("core.ObjHuman") --分钟转秒 local TIMEBASE = 60 --一天的秒数 local DAYSEC = 86400 --本活动日志标识 local LOGTYPE = "OnlineAwardLogic" --是否在线 -- IsOnline = false --活动ID local ACTID = 18001 --检查活动获得时间, 如果没有初始化则初始化 local function checkHaveTime(human) local OnlineRewardData = human.db.OnlineRewardData if not OnlineRewardData or not OnlineRewardData.haveTime then human.db.OnlineRewardData = human.db.OnlineRewardData or {} human.db.OnlineRewardData.haveTime = os.time() end end --计算当天到目前为止的总在线时长 local function calcTotalOnlineTime(human) local lastOnlineTime = human.db.onlineTimeDay or 0 local loginTime = human.db.lastLoginTime --可能存在玩家在线跨天情况,需要判断登录时间与当前时间是否属于同一天,如果不是, 那么在此活动中,当天的登录时间应该为当天0点 local now = os.time() if not Util.isSameDay(loginTime) then loginTime = Util.getDayStartTime(now) end local totalOnlineTime = now - loginTime + lastOnlineTime return totalOnlineTime end --获取当前时间距离startTime相差多少天 local function getDiffDay(startTime) local passDay = Util.diffDay(startTime) + 1 return passDay end --是否获得该活动 local function isHaveAct(human) local topupAcount = human.db.topupAcount if topupAcount and topupAcount > 0 then return true end return false end --是否结束 local function isOver(human) local OnlineRewardData = human.db.OnlineRewardData if not OnlineRewardData then return false end local targetDay = getDiffDay(OnlineRewardData.haveTime) local targetCfg = onlineAardCfg[targetDay] --配置错误或者已经超过配置里的天数了都不显示 if not targetCfg then return true end return false end --计算下一个未获得奖励需要的在线时间 local function calcLeftTime(human) local OnlineRewardData = human.db.OnlineRewardData local targetDay = getDiffDay(OnlineRewardData.haveTime) local targetCfg = onlineAardCfg[targetDay] if not targetCfg then return end local leftTime = 0 local totalNeedTime = 0 local timeCfg = targetCfg.onlineTimeVec local totalOnlineTime = calcTotalOnlineTime(human) for _, needTime in ipairs(timeCfg) do totalNeedTime = totalNeedTime + needTime * TIMEBASE if totalNeedTime > totalOnlineTime then leftTime = totalNeedTime - totalOnlineTime break end end return leftTime end --返回可领取奖励的index Vec local function getCanReceiveAwardVec(human, isRed) local OnlineRewardData = human.db.OnlineRewardData local dailyData = OnlineRewardData.dailyData local targetDay = getDiffDay(OnlineRewardData.haveTime) local targetCfg = onlineAardCfg[targetDay] local todayRecordData = dailyData and dailyData[targetDay] if not targetCfg then if not isRed then Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end return end --充值金额是否符合 local topupAcountDaily = human.db.topupAcountDaily if not topupAcountDaily or topupAcountDaily < targetCfg.needRecharge then if not isRed then Broadcast.sendErr(human, Lang.COMMON_DAY_RECHARGE_NOT_ENOUGH) end return end local totalNeedTime = 0 local cfgOnlineTimeVec = targetCfg.onlineTimeVec local totalOnlineTime = calcTotalOnlineTime(human) local len = 0 local awardIdxVec = {} for idx, needTime in ipairs(cfgOnlineTimeVec) do totalNeedTime = totalNeedTime + needTime * TIMEBASE if totalOnlineTime >= totalNeedTime and (not todayRecordData or not todayRecordData[idx]) then len = len + 1 awardIdxVec[len] = idx end end if len == 0 then return end return awardIdxVec end --定时器任务 local function timeFunc(human) if not ObjHuman.onlineNewUniqueTag[human.db.newUniqueTag] then return end -- if not IsOnline then -- return -- end local leftTime = calcLeftTime(human) if leftTime and leftTime > 0 then local now = os.time() local todayStartTi = Util.getDayStartTime(now) local nextDayStartTi = todayStartTi + DAYSEC --只有需要挂机时间 + 当前时间 < 下一天0点, 那么才加定时器 if leftTime + now < nextDayStartTi then Timer.addLater(leftTime, function () Query(human) --红点更新 YunYingLogic.updateIcon(YYInfo[ACTID], human, true) timeFunc(human) end) end end end --红点判断 function isRed(human, YYInfo, funcConfig) if not isHaveAct(human) then return false end if not getCanReceiveAwardVec(human, true) then return false end return true end --是否开启(外部调用) function isOpen(human) if not isHaveAct(human) then return false end if isOver(human) then return false end return true end --登录 function onLogin(human, actID) if not isHaveAct(human) then return end -- IsOnline = true checkHaveTime(human) timeFunc(human) end --下线 -- function onLogout(human, funcID, parameter, parameter2) -- IsOnline = false -- end --跨天 -- function updateDaily(human, funcID) -- checkHaveTime(human) -- end --新跨天函数,这里用新的跨天函数是因为ObjHuman.lua中 重置每日在线时间代码会晚于运营活动中的 updateDaily()执行 --这个活动中,会用到每日在线时间,所以需要重新定义一个跨天函数,在重置每日在线时间后再执行 function NewUpdateDaily(human) if not isHaveAct(human) then return end --if IsOnline then if isOver(human) then YunYingLogic.updateIcon(YYInfo[ACTID], human, true) return end --针对玩家在线跨天情况,下发一次最新数据 Query(human) timeFunc(human) --end end --充值 function onCharge(human, price) local OnlineRewardData = human.db.OnlineRewardData if not OnlineRewardData or not OnlineRewardData.haveTime then checkHaveTime(human) timeFunc(human) YunYingLogic.updateIcon(YYInfo[ACTID], human, true) end OnlineRewardData = human.db.OnlineRewardData local targetDay = getDiffDay(OnlineRewardData.haveTime) local targetCfg = onlineAardCfg[targetDay] --活动结束后玩家充值导致报错 if not targetCfg then return end local topupAcountDaily = human.db.topupAcountDaily if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then Query(human) end return true end --查询 function Query(human) if not isHaveAct(human) then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local OnlineRewardData = human.db.OnlineRewardData local dailyData = OnlineRewardData.dailyData local targetDay = getDiffDay(OnlineRewardData.haveTime) local targetCfg = onlineAardCfg[targetDay] local todayData = dailyData and dailyData[targetDay] if not targetCfg then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end local timeCfg = targetCfg.onlineTimeVec local awardCfg = targetCfg.awardVec if #timeCfg ~= #awardCfg then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end local len = 0 local totalNeedTime = 0 local totalOnlineTime = calcTotalOnlineTime(human) local msgRet = Msg.gc.GC_ONLINEAWARD_QUERY msgRet.leftTime = 0 msgRet.needRecharge = targetCfg.needRecharge msgRet.nowRecharge = human.db.topupAcountDaily or 0 msgRet.isReach = 0 local topupAcountDaily = human.db.topupAcountDaily if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then msgRet.isReach = 1 end msgRet.remainingDays = math.max(#onlineAardCfg - targetDay, 0) local msgAwardVec = msgRet.awardVec msgAwardVec[0] = 0 for idx, needTime in ipairs(timeCfg) do len = len + 1 msgAwardVec[len].state = 0 Grid.makeItem(msgAwardVec[len].itemInfo, awardCfg[idx][1], awardCfg[idx][2]) totalNeedTime = totalNeedTime + needTime * TIMEBASE if totalOnlineTime >= totalNeedTime then msgAwardVec[len].state = 1 if todayData and todayData[idx] then msgAwardVec[len].state = 2 end else if msgRet.leftTime == 0 then msgRet.leftTime = totalNeedTime - totalOnlineTime end end end msgAwardVec[0] = len Msg.send(msgRet, human.fd) end --领奖 function ClaimAward(human) if not isHaveAct(human) then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local awardIdxVec = getCanReceiveAwardVec(human) if not awardIdxVec then return end local OnlineRewardData = human.db.OnlineRewardData local targetDay = getDiffDay(OnlineRewardData.haveTime) OnlineRewardData.dailyData = OnlineRewardData.dailyData or {} OnlineRewardData.dailyData[targetDay] = OnlineRewardData.dailyData[targetDay] or {} local todayRecoedData = OnlineRewardData.dailyData[targetDay] local len = 0 local awardVec = {} local targetCfg = onlineAardCfg[targetDay] local awardCfg = targetCfg.awardVec for _, idx in ipairs(awardIdxVec) do len = len + 1 awardVec[len] = {awardCfg[idx][1], awardCfg[idx][2]} todayRecoedData[idx] = true end BagLogic.addItemList(human, awardVec, LOGTYPE) --下发数据更新 Query(human) --红点更新 YunYingLogic.updateIcon(YYInfo[ACTID], human, true) end