local DirectGift_Model = {} local private = {} local EventSystem = require('Event/EventSystem') local direct_gift_pb = require 'Proto.direct_gift_pb' DirectGift_Model.GiftStateEnum = { Invalid = -1, --已过期、失效 FutureOpen = 1, --未来开放的礼包 Locked = 2, --未解锁 Limited = 3, --到达限购次数 ShowLimited = 4,--到达限购次数并且展示售罄状态 Available = 5, --可购买 } DirectGift_Model.DirectGiftType = { Base = 0, --普通活动 Normal = 1, --福利界面常驻 StageUnlock = 2, --阶段解锁直购礼包 --待补充 } --[[ 以服务器发送过来的数据为准,服务器只会发过来当前可以买的礼包 礼包如果因为过了时间过期,服务器不会主动push,所以每个非永久礼包都会添加一个对应的计时器 过天或者购买后服务器会全量推送过来新数据 将每个礼包的所有所属信息都储存成 info = { activityId, 礼包所属活动实例ID giftId, 礼包在这个活动的礼包ID data, 礼包在相应静态活动表中的数据 info, 服务器发过来的礼包信息,包括相应的时间戳 state, 礼包的状态,对应GiftStateEnum枚举 } private.openDirectGiftList中存储可购买的 private.lockDirectGiftList中存储未解锁的\未来时间解锁的 已经过期的礼包不会存储 ]] function DirectGift_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageDirectGiftGetFreeAward, private.DirectGiftGetFreeAwardResp) EventSystem.Regist(EventID.TeamLevelUpdate, private.UpdateDirectGiftList) EventSystem.Regist(EventID.UI_Shop_Recharge, private.UpdateDirectGiftList) EventSystem.Regist(EventID.DirectGift_UpdateDirectGiftList, private.UpdateDirectGiftList) private.directGiftCountInfo = {} private.lockDirectGiftList = {} private.openDirectGiftList = {} private.tempList = {} --缓存用 end function DirectGift_Model.GetGiftTimeStamp(info) --如果有返还终止时间,以返还终止时间作为结束时间 if info.payBackShowEndTime and info.payBackShowEndTime > 0 then return info.startTime, info.payBackShowEndTime end return info.startTime, info.endTime end function DirectGift_Model.SetBuyingCountInfo(countInfos) private.directGiftCountInfo = {} for i, v in ipairs(countInfos) do if not private.directGiftCountInfo[v.activityID] then private.directGiftCountInfo[v.activityID] = {} end private.directGiftCountInfo[v.activityID][v.giftType] = v.giftCount end for type, typeGiftList in pairs(private.openDirectGiftList) do for i, v in pairs(typeGiftList) do local info = v.info local giftState = private.GetGiftStateEnumByInfo(info) if giftState == DirectGift_Model.GiftStateEnum.Available or giftState == DirectGift_Model.GiftStateEnum.ShowLimited then v.state = giftState else if giftState == DirectGift_Model.GiftStateEnum.Locked or giftState == DirectGift_Model.GiftStateEnum.FutureOpen then table.insert(private.lockDirectGiftList, v) end DirectGift_Model.RemoveGiftInfo(v.activityId, v.giftId) end end end for i, v in pairs(private.openDirectGiftList) do if i == DirectGift_Model.DirectGiftType.Normal then table.sort(v, private.SortDirectGift) else table.sort(v, private.SortActivityDirectGift) end end private.UpdateDirectGiftList() end function DirectGift_Model.GetGiftBuyingCount(activityId, giftId) if private.directGiftCountInfo[activityId] then return private.directGiftCountInfo[activityId][giftId] or 0 end return 0 end function DirectGift_Model.SetDirectGiftInfo(directGiftInfos) --与服务器约定,每次均为全量推送 --因为增量推送会导致热更时如果出现礼包时间往前调或者直接删掉无法判断并成功删除掉的问题 private.ClearDirectGiftInfo() local nowTime = UTL.Time.GetServerTimestamp() for i, v in ipairs(directGiftInfos) do local activityId = v.activityID local giftId = v.giftType local giftState = private.GetGiftStateEnumByInfo(v) if giftState ~= DirectGift_Model.GiftStateEnum.Invalid then local info = { activityId = activityId, giftId = giftId, data = MDL.OperationActivity.DirectGiftData[v.ActivityType]:GetDataByActivityID_HotPackageID(activityId, giftId), info = v, state = giftState, } local sheetData = info.data if giftState == DirectGift_Model.GiftStateEnum.Available or giftState == DirectGift_Model.GiftStateEnum.ShowLimited then local type = sheetData.HotPackageType if not private.openDirectGiftList[type] then private.openDirectGiftList[type] = {} end table.insert(private.openDirectGiftList[type], info) local timeType = sheetData.TimeType if timeType and timeType ~= MDL.OperationActivity.TimeType.Forever then local startTime, endTime = DirectGift_Model.GetGiftTimeStamp(info.info) if endTime - nowTime > 0 then CTL.DirectGift.AddGiftExpireTimer(activityId, giftId, endTime - nowTime) else DirectGift_Model.RemoveGiftInfo(activityId, giftId) end end CTL.DirectGift.RemoveGiftStartTimer(activityId, giftId) elseif giftState == DirectGift_Model.GiftStateEnum.Locked or giftState == DirectGift_Model.GiftStateEnum.FutureOpen then table.insert(private.lockDirectGiftList, info) local startTime, endTime = DirectGift_Model.GetGiftTimeStamp(info.info) local diffTime = startTime - nowTime --未来开启的增加定时器(小于1天得才加定时器) if diffTime > 0 and diffTime < UTL.Time.TotalSecondsOneDay and giftState == DirectGift_Model.GiftStateEnum.FutureOpen then CTL.DirectGift.AddGiftStartTimer(activityId, giftId, diffTime + 5) --延迟几秒刷新,保证正确性 end end end end for i, v in pairs(private.openDirectGiftList) do if i == DirectGift_Model.DirectGiftType.Normal then table.sort(v, private.SortDirectGift) else table.sort(v, private.SortActivityDirectGift) end end EventSystem.Dispatch(EventID.UI_DirectGift_GiftInfoUpdate) EventSystem.Dispatch(EventID.UI_PayMall_RefreshRedPoint) end function private.UpdateDirectGiftList() local nowTime = UTL.Time.GetServerTimestamp() for i = #private.lockDirectGiftList, 1, -1 do local info = private.lockDirectGiftList[i] local activityId = info.activityId local giftId = info.giftId local giftState = private.GetGiftStateEnumByInfo(info.info) info.state = giftState if giftState == DirectGift_Model.GiftStateEnum.Available then local type = info.data.HotPackageType if not private.openDirectGiftList[type] then private.openDirectGiftList[type] = {} end table.insert(private.openDirectGiftList[type], info) local timeType = info.data.TimeType if timeType and timeType ~= MDL.OperationActivity.TimeType.Forever then local startTime, endTime = DirectGift_Model.GetGiftTimeStamp(info.info) if endTime - nowTime > 0 then CTL.DirectGift.AddGiftExpireTimer(activityId, giftId, endTime - nowTime) else DirectGift_Model.RemoveGiftInfo(activityId, giftId) end end CTL.DirectGift.RemoveGiftStartTimer(activityId, giftId) table.remove(private.lockDirectGiftList, i) elseif giftState == DirectGift_Model.GiftStateEnum.Invalid then table.remove(private.lockDirectGiftList, i) end end for i, v in pairs(private.openDirectGiftList) do if i == DirectGift_Model.DirectGiftType.Normal then table.sort(v, private.SortDirectGift) else table.sort(v, private.SortActivityDirectGift) end end EventSystem.Dispatch(EventID.UI_PayMall_SaveCurrentShopTabIndex) --保存一下商城打开的页签 EventSystem.Dispatch(EventID.UI_DirectGift_GiftInfoUpdate) EventSystem.Dispatch(EventID.UI_PayMall_RefreshRedPoint) EventSystem.Dispatch(EventID.UI_PayMall_RefreshTab) end function private.ClearDirectGiftInfo() private.openDirectGiftList = {} private.lockDirectGiftList = {} private.tempList = {} CTL.DirectGift.ClearGiftExpireTimer() CTL.DirectGift.ClearGiftStartTimer() end --这里要循环套循环,之后看看有没有优化空间 --可以添加一个参数用来标识礼包类型,减少一个循环 function DirectGift_Model.RemoveGiftInfo(activityId, giftId) for key, giftList in pairs(private.openDirectGiftList) do for i, v in ipairs(giftList) do if v.activityId == activityId and v.giftId == giftId then table.remove(private.openDirectGiftList[key], i) CTL.DirectGift.RemoveGiftExpireTimer(activityId, giftId) EventSystem.Dispatch(EventID.UI_DirectGift_GiftInfoUpdate) return end end end EventSystem.Dispatch(EventID.UI_PayMall_RefreshRedPoint) end function DirectGift_Model.GetGiftInfo(activityId, giftId) for key, giftList in pairs(private.openDirectGiftList) do for i, v in ipairs(giftList) do if v.activityId == activityId and v.giftId == giftId then return v end end end end function DirectGift_Model.GetNormalDirectGiftEnumerator(welfareId) private.tempList = {} if private.openDirectGiftList[DirectGift_Model.DirectGiftType.Normal] then if welfareId then for i, v in ipairs(private.openDirectGiftList[DirectGift_Model.DirectGiftType.Normal]) do local tab = v.data.HotPackageTab if tab == welfareId then table.insert(private.tempList, v) end end else private.tempList = private.openDirectGiftList[DirectGift_Model.DirectGiftType.Normal] end end return ipairs(private.tempList) end function DirectGift_Model.GetDirectGiftEnumerator(type, activityId) --因为先按照activityId进行了从小到大的排序,所以遍历到的activityId大于要找的Id的时候就可以跳出循环了 --因为事先都排序了,所以按序取出来就是排好顺序的 private.tempList = {} if private.openDirectGiftList[type] then if activityId then for i, v in ipairs(private.openDirectGiftList[type]) do if v.activityId > activityId then break end if v.activityId == activityId then table.insert(private.tempList, v) end end else private.tempList = private.openDirectGiftList[type] end end return ipairs(private.tempList) end function DirectGift_Model.GetLockedDirectGiftEnumerator(type, activityId) --暂未排序 private.tempList = {} if private.lockDirectGiftList then if activityId then for i, v in ipairs(private.lockDirectGiftList) do if v.data.HotPackageType == type and v.activityId == activityId then table.insert(private.tempList, v) end end else private.tempList = private.lockDirectGiftList end end return ipairs(private.tempList) end function private.GetGiftStateEnumByInfo(info) local activityId = info.activityID local giftId = info.giftType local giftData = MDL.OperationActivity.DirectGiftData[info.ActivityType]:GetDataByActivityID_HotPackageID(activityId, giftId) if not giftData or giftData.TimeType == nil then return DirectGift_Model.GiftStateEnum.Invalid end local nowTime = UTL.Time.GetServerTimestamp() local startTime, endTime = DirectGift_Model.GetGiftTimeStamp(info) if (not endTime and not startTime) or nowTime >= endTime then return DirectGift_Model.GiftStateEnum.Invalid elseif nowTime >= startTime then if CTL.DirectGift.IsGiftUnlockToSee(giftData) then if DirectGift_Model.GetGiftBuyingCount(activityId, giftId) >= giftData.TimesLimit and giftData.LimitType ~= LuaConst.LimitBuyType.NoLimit then --返还类型的礼包特殊处理 if giftData.PayBackTime and giftData.PayBackTime > 0 then return DirectGift_Model.GiftStateEnum.ShowLimited end if giftData.SellOutDisplayType and giftData.SellOutDisplayType > 0 then return DirectGift_Model.GiftStateEnum.ShowLimited end local isSuccess, welfareData = false, nil if giftData.HotPackageTab then isSuccess, welfareData = DataSheetManager.DirectGiftOrder:TryGetDataByID(giftData.HotPackageTab) end if isSuccess and welfareData.GiftSellOutType == CTL.DirectGift.GiftSoldOutType.SoldOut then return DirectGift_Model.GiftStateEnum.ShowLimited else return DirectGift_Model.GiftStateEnum.Limited end else return DirectGift_Model.GiftStateEnum.Available end else return DirectGift_Model.GiftStateEnum.Locked end else return DirectGift_Model.GiftStateEnum.FutureOpen end end function private.SortActivityDirectGift(giftInfoA, giftInfoB) local activityIdA = giftInfoA.activityId local activityIdB = giftInfoB.activityId if activityIdA == activityIdB then return private.SortDirectGift(giftInfoA, giftInfoB) else return activityIdA < activityIdB end end function private.SortDirectGift(giftInfoA, giftInfoB) local giftStateA = giftInfoA.state local giftStateB = giftInfoB.state if giftStateA ~= giftStateB then return giftStateA > giftStateB --比较两个礼包的状态 else local sortA = giftInfoA.data.HotPackageRank local sortB = giftInfoB.data.HotPackageRank if sortA == sortB then local startTimeA, endTimeA = DirectGift_Model.GetGiftTimeStamp(giftInfoA.info) local startTimeB, endTimeB = DirectGift_Model.GetGiftTimeStamp(giftInfoB.info) if startTimeA and startTimeB then if startTimeA ~= startTimeB then return startTimeA > startTimeB --比较两个礼包开放时间 else return giftInfoA.giftId < giftInfoB.giftId end elseif startTimeA then return true elseif startTimeB then return false else return giftInfoA.giftId < giftInfoB.giftId end else return sortA > sortB end end end ---@public 游戏内货币购买直购礼包(包括领取免费奖励) ---服务器那边需要动以前的接口所以方法名先不改 function DirectGift_Model.DirectGiftGetFreeAwardReq(activityId, giftId, giftNum) local msg = direct_gift_pb.DirectGiftGetFreeAwardReq() msg.activityId = activityId msg.giftType = giftId msg.giftNum = giftNum or 1 NetManager.SendMessage(MessageEnums.MessageDirectGiftGetFreeAward, msg) end function private.DirectGiftGetFreeAwardResp(msgResp) end return DirectGift_Model