local RedEnvelopRain_Model = {} local private = {} local activity_red_envelope_rain_pb = require("Proto/activity_red_envelope_rain_pb") local EventSystem = require('Event/EventSystem') local BatchReqInterval = 0.5 local GetRedEnvelopeMaxNum = DataSheetManager.ConstData:GetDataByID("GetRedEnvelopeMaxNum").IntValue local RedEnvelopeRainDuration = DataSheetManager.ConstData:GetDataByID("RedEnvelopeRainDuration").IntValue RedEnvelopRain_Model.EnvelopeRainRankType = { YesterdayRank = activity_red_envelope_rain_pb.YesterdayRank, -- 昨日榜单 TodayRank = activity_red_envelope_rain_pb.TodayRank, -- 今日榜单 AllRank = activity_red_envelope_rain_pb.AllRank, -- 总榜 } RedEnvelopRain_Model.EnvelopeRainRankRewardType = { TodayRank = 1, -- 今日榜单奖励 AllRank = 2, -- 总榜单奖励 } RedEnvelopRain_Model.EnvelopeType = { Small = activity_red_envelope_rain_pb.Small, -- 小红包 Big = activity_red_envelope_rain_pb.Big, -- 大红包 } -- 排序(充值金额大 > 充值时间早 > acid) local function SortRank(a, b) local infoA = private.rankInfoDic[a.rankType][a.acid] local infoB = private.rankInfoDic[b.rankType][b.acid] if infoA.addGoldNum == infoB.addGoldNum then if infoA.lastAddTime == infoB.lastAddTime then return infoA.acid < infoB.acid else return infoA.lastAddTime < infoB.lastAddTime end else return infoA.addGoldNum > infoB.addGoldNum end end function RedEnvelopRain_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageUpdateRedEnvelopeRainReward, private.UpdateRedEnvelopeRainRewardResp) NetManager.RegisterMsgCB(MessageEnums.MessageGetRedEnvelopeRainRank, private.GetRedEnvelopeRainRankResp) NetManager.RegisterMsgCB(MessageEnums.MessageG2CPushRedEnvelopeRainRank, private.G2CPushRedEnvelopeRainRank) private.rankAcidDic = {} -- K为EnvelopeRainRankType,V为{acid=XXX, rankType = XXX}结构。用于排序 private.rankInfoDic = {} -- K为EnvelopeRainRankType,V为InfoDic,其中K为Acid,V为RedEnvelopeRainRankInfo结构。主要使用数据的使用 private.myRankInfoDic = {} -- K为EnvelopeRainRankType,V为RedEnvelopeRainRankInfo结构。 private.allGoldNum = 0 -- 奖池金额 private.shardLen = 0 -- 参与服务器数量 -- 活动开始时红包的数据 private.bigEnvelopeInfo = {} private.smallEnvelopeInfo = {} private.remainSecond = 0 -- 活动剩余秒数 private.residueDrawTimes = 0 -- 今日活动剩余抽取次数 -- 批量请求领取暂存数据 private.bigEnvelopeIds = {} private.smallEnvelopeIds = {} end ---------- Start 协议相关 Start ---------- -- 开始(初始化)红包雨,红包内容(全量) function RedEnvelopRain_Model.UpdateRedEnvelopeRainRewardReq() if LevelManager.IsTown and not MDL.Loading.GetIsLoadingState() and not AuxUtil.InTimeline() and not UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIMoviePanel) then if MDL.Unlock.IsServerUnlock(MDL.Unlock.FunctionType.RedEnvelopeRain) then local msg = activity_red_envelope_rain_pb.UpdateRedEnvelopeRainRewardReq() msg.activityId = CTL.RedEnvelopRain.GetCurOpenRedEnvelopRainActivityId() NetManager.SendMessage(MessageEnums.MessageUpdateRedEnvelopeRainReward, msg) end else CTL.RedEnvelopRain.BeginLevel() -- 2秒后进行重试 end end function private.UpdateRedEnvelopeRainRewardResp(msgResp) if msgResp.Resp.Code == 0 then -- 大红包 table.clearArray(private.bigEnvelopeInfo) for _, info in ipairs(msgResp.bigEnvelopeInfo) do table.insert(private.bigEnvelopeInfo, info) end -- 小红包 table.clearArray(private.smallEnvelopeInfo) for _, info in ipairs(msgResp.smallEnvelopeInfo) do table.insert(private.smallEnvelopeInfo, info) end -- 进入活动剩余抽取次数 private.residueDrawTimes = GetRedEnvelopeMaxNum - msgResp.drawTimes -- 剩余秒数 private.remainSecond = msgResp.remainSecond -- 根据状态打开界面 if (#private.bigEnvelopeInfo > 0 or #private.smallEnvelopeInfo > 0) and private.residueDrawTimes > 0 then -- 超过30秒打开倒计时界面,否则直接打开下落红包界面 if private.remainSecond > RedEnvelopeRainDuration then if UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIRedEnvelopeRainCountDown) then EventSystem.Dispatch(EventID.RedEnvelope_RefreshCountDown) else UIManager.OpenAndPushAll(Const_UI_Lua.UIEnum.UIRedEnvelopeRainCountDown) end else if UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIRedEnvelopeRainStart) then EventSystem.Dispatch(EventID.RedEnvelope_StartCountDown) else UIManager.OpenAndPushAll(Const_UI_Lua.UIEnum.UIRedEnvelopeRainStart) end end end end end -- 获取红包雨指定榜单信息(全量) function RedEnvelopRain_Model.GetRedEnvelopeRainRankReq(rankType, isNeedBroad) local activityId = CTL.RedEnvelopRain.GetCurOpenRedEnvelopRainActivityId() if activityId and type(activityId) == "number" then local msg = activity_red_envelope_rain_pb.GetRedEnvelopeRainRankReq() msg.activityId = activityId msg.rankType = rankType msg.isNeedBroad = isNeedBroad NetManager.SendMessage(MessageEnums.MessageGetRedEnvelopeRainRank, msg) end end function private.GetRedEnvelopeRainRankResp(msgResp) if msgResp.Resp.Code == 0 and msgResp.isNeedBroad then -- 先设置一次自身数据,之后在设置排行数据的时候,根据排行信息更新一下 local rankType = msgResp.rankType private.myRankInfoDic[rankType] = {index = msgResp.myRankInfo.Index, addGoldNum = msgResp.myRankInfo.addGoldNum} -- 设置排行数据 private.SetRankDataByRankType(rankType, msgResp.allPlayerInfo) -- 再根据下发的排行数据,更新一下自身排行信息(防止服务器自身数据和 排行榜数据不一致) local myAcid = BattleDataGetter.GetAcID() local acidList, infoDic = private.GetRankDataTableByRankType(rankType) for index, acidTb in ipairs(acidList) do if myAcid == acidTb.acid then local myInfo = private.myRankInfoDic[rankType] myInfo.index = index myInfo.addGoldNum = infoDic[myAcid].addGoldNum end end -- 设置奖池金额(总榜没有奖池) if rankType ~= RedEnvelopRain_Model.EnvelopeRainRankType.AllRank then private.allGoldNum = msgResp.goldNum end private.shardLen = msgResp.shardLen -- 触发事件 刷新列表 EventSystem.Dispatch(EventID.RedEnvelope_RefreshRankList) end end -- 打包红包列表 function RedEnvelopRain_Model.ReceiveRedEnvelopReward(envelopId) if private.residueDrawTimes <= 0 then return end -- 设置剩余抽取次数 private.residueDrawTimes = private.residueDrawTimes - 1 local info = private.GetInfoByEnvelopId(envelopId) if not info then return end -- 客户端预表现奖励 CTL.Tips.AddImageTip(info.rewardId, info.rewardNum) if info.envelopType == RedEnvelopRain_Model.EnvelopeType.Small then table.insert(private.smallEnvelopeIds, envelopId) elseif info.envelopType == RedEnvelopRain_Model.EnvelopeType.Big then table.insert(private.bigEnvelopeIds, envelopId) end if not private.timerHandle then private.timerHandle = TimerUtil.Interval(private.C2GReceiveRedEnvelopReward, BatchReqInterval, 1) end EventSystem.Dispatch(EventID.RedEnvelope_RefreshResidueDrawTimes) end -- 领取红包协议(C2G) function private.C2GReceiveRedEnvelopReward() local msg = activity_red_envelope_rain_pb.C2GReceiveRedEnvelopReward() msg.activityId = CTL.RedEnvelopRain.GetCurOpenRedEnvelopRainActivityId() for _, id in ipairs(private.bigEnvelopeIds) do table.insert(msg.bigEnvelopeIds, id) end table.clearArray(private.bigEnvelopeIds) for _, id in ipairs(private.smallEnvelopeIds) do table.insert(msg.smallEnvelopeIds, id) end table.clearArray(private.smallEnvelopeIds) private.timerHandle = nil NetManager.SendMessage(MessageEnums.MessageC2GReceiveRedEnvelopReward, msg) end -- 红包雨榜单信息(增量G2C) function private.G2CPushRedEnvelopeRainRank(msg) local rankType = msg.rankType local acidList, infoDic = private.GetRankDataTableByRankType(rankType) -- 先处理移除信息 for _, acid in ipairs(msg.delPlayerInfo) do infoDic[acid] = nil for i, acidTb in ipairs(acidList) do if acidTb.acid == acid then table.remove(acidList, i) break end end end -- 再处理新增信息 for _, info in ipairs(msg.addPlayerInfo) do if not infoDic[info.acid] then table.insert(acidList, {acid = info.acid, rankType = rankType}) end infoDic[info.acid] = info end -- 排序 table.sort(acidList, SortRank) -- 设置奖池金额(总榜没有奖池) if rankType ~= RedEnvelopRain_Model.EnvelopeRainRankType.AllRank then private.allGoldNum = msg.goldNum end private.shardLen = msg.shardLen -- 触发事件 刷新列表 EventSystem.Dispatch(EventID.RedEnvelope_RefreshRankList) end ------------ End 协议相关 End ------------ ------------ Start 数据获取相关 Start ------------ function RedEnvelopRain_Model.GetShardLen() return private.shardLen end function RedEnvelopRain_Model.GetAllGoldNum() return private.allGoldNum end function RedEnvelopRain_Model.GetRankInfoNumByRankType(rankType) local acidList = private.rankAcidDic[rankType] if acidList then return #acidList else return 0 end end function RedEnvelopRain_Model.ResetRankInfoIterator(rankType) private.enumNextRankInfoIndex = 1 private.enumRankType = rankType end function RedEnvelopRain_Model.EnumRankInfoIterator() local acidList = private.rankAcidDic[private.enumRankType] local data = acidList[private.enumNextRankInfoIndex] if data then private.enumNextRankInfoIndex = private.enumNextRankInfoIndex + 1 return private.rankInfoDic[data.rankType][data.acid] else return nil end end function RedEnvelopRain_Model.GetMyRankInfoByRankType(rankType) return private.myRankInfoDic[rankType] end function RedEnvelopRain_Model.GetRemainSecond() return private.remainSecond end function RedEnvelopRain_Model.GetResidueDrawTimes() return private.residueDrawTimes end function RedEnvelopRain_Model.GetEnvelopeInfo() return private.bigEnvelopeInfo, private.smallEnvelopeInfo end -------------- End 数据获取相关 End -------------- ------------ Start 处理模块数据(私有方法) Start ------------ function private.GetRankDataTableByRankType(rankType) local acidList = private.rankAcidDic[rankType] if not acidList then acidList = {} private.rankAcidDic[rankType] = acidList end local infoDic = private.rankInfoDic[rankType] if not infoDic then infoDic = {} private.rankInfoDic[rankType] = infoDic end return acidList, infoDic end function private.SetRankDataByRankType(rankType, allPlayerInfo) local acidList, infoDic = private.GetRankDataTableByRankType(rankType) -- info直接清空 table.clear(infoDic) -- acidList 使用table复用防止table频繁创建 for i, info in ipairs(allPlayerInfo) do local acidTb = acidList[i] if acidTb then acidTb.acid = info.acid acidTb.rankType = rankType else table.insert(acidList, {acid = info.acid, rankType = rankType}) end infoDic[info.acid] = info end for i = #allPlayerInfo + 1, #acidList do table.remove(acidList) end -- 排序 table.sort(acidList, SortRank) end function private.GetInfoByEnvelopId(envelopId) for _, info in ipairs(private.bigEnvelopeInfo) do if info.envelopId == envelopId then return info end end for _, info in ipairs(private.smallEnvelopeInfo) do if info.envelopId == envelopId then return info end end return nil end -------------- End 处理模块数据(私有方法) End -------------- return RedEnvelopRain_Model