415 lines
No EOL
16 KiB
Lua
415 lines
No EOL
16 KiB
Lua
XGachaManagerCreator = function()
|
||
local GET_GACHA_DATA_INTERVAL = 15
|
||
local XGachaManager = {}
|
||
local GachaRewardInfos = {}
|
||
local GachaProbShows = {}
|
||
local GachaLogList = {}
|
||
local LastGetGachaRewardInfoTimes = {}
|
||
local CurCountOfAll = 0
|
||
local MaxCountOfAll = 0
|
||
local IsInfinite = false
|
||
local ParseToTimestamp = XTime.ParseToTimestamp
|
||
|
||
-- 卡池组状态
|
||
-- Key:number OrganizeId
|
||
-- Value:Table { gachaId = XGachaConfigs.OrganizeGachaStatus }
|
||
local GachaOrganizeStatus = {}
|
||
|
||
local METHOD_NAME = {
|
||
GetGachaInfo = "GetGachaInfoRequest",
|
||
Gacha = "GachaRequest",
|
||
GetGachaOrganizeInfo = "GetGachaOrganizeInfoRequest",
|
||
}
|
||
|
||
function XGachaManager.Init()
|
||
XGachaManager.SetGachaRewardInfo()
|
||
XGachaManager.SetGachaProbShowInfo()
|
||
end
|
||
|
||
function XGachaManager.GetGachaRewardInfoById(gaChaId)
|
||
local gachaCfg = XGachaConfigs.GetGachas()
|
||
MaxCountOfAll = 0
|
||
CurCountOfAll = 0
|
||
IsInfinite = false
|
||
local groupIdList = {}
|
||
for _, groupId in pairs(gachaCfg[gaChaId].GroupId) do
|
||
table.insert(groupIdList, groupId)
|
||
end
|
||
|
||
local list = {}
|
||
for _, v in pairs(GachaRewardInfos) do
|
||
for _, groupId in pairs(groupIdList) do
|
||
if v.GroupId == groupId then
|
||
table.insert(list, v)
|
||
break
|
||
end
|
||
end
|
||
|
||
end
|
||
for _, v in pairs(list) do
|
||
if v.RewardType == XGachaConfigs.RewardType.NotCount then
|
||
IsInfinite = true
|
||
end
|
||
MaxCountOfAll = MaxCountOfAll + v.UsableTimes
|
||
CurCountOfAll = CurCountOfAll + (v.UsableTimes - v.CurCount)
|
||
end
|
||
|
||
table.sort(list, function(a, b)
|
||
if a.Priority == b.Priority then
|
||
return a.Id < b.Id
|
||
else
|
||
return a.Priority > b.Priority
|
||
end
|
||
end)
|
||
return list
|
||
end
|
||
|
||
function XGachaManager.GetGachaProbShowById(gaChaId)
|
||
local gachaProbShowInfo = GachaProbShows[gaChaId]
|
||
if gachaProbShowInfo then
|
||
table.sort(gachaProbShowInfo, function(a, b)
|
||
if a.IsRare == b.IsRare then
|
||
return a.Id < b.Id
|
||
else
|
||
return a.IsRare == XGachaConfigs.RareType.Rare
|
||
end
|
||
end)
|
||
else
|
||
XLog.Error("ProbShows's Data Is Null By GachaId :"..gaChaId)
|
||
end
|
||
|
||
return gachaProbShowInfo
|
||
end
|
||
|
||
function XGachaManager.GetCurCountOfAll()
|
||
return CurCountOfAll
|
||
end
|
||
|
||
function XGachaManager.GetMaxCountOfAll()
|
||
return MaxCountOfAll
|
||
end
|
||
|
||
function XGachaManager.GetIsInfinite()
|
||
return IsInfinite
|
||
end
|
||
|
||
function XGachaManager.GetGachaLogById(gachaId)
|
||
return GachaLogList[gachaId] or {}
|
||
end
|
||
|
||
---
|
||
---@param notCheckDraw boolean 是否检测活动研发功能开启,true:不检测,false:检测
|
||
function XGachaManager.CheckGachaIsOpenById(id, IsShowText, notCheckDraw)
|
||
if IsShowText then
|
||
if not notCheckDraw and not XFunctionManager.DetectionFunction(XFunctionManager.FunctionName.ActivityDrawCard) then
|
||
return false
|
||
end
|
||
else
|
||
if not notCheckDraw and not XFunctionManager.JudgeCanOpen(XFunctionManager.FunctionName.ActivityDrawCard) then
|
||
return false
|
||
end
|
||
end
|
||
|
||
local gachaCfg = XGachaConfigs.GetGachas()
|
||
|
||
if not gachaCfg[id] then
|
||
XLog.Error("GachaId Is Not Exist :"..id)
|
||
return false
|
||
end
|
||
|
||
local nowTime = XTime.GetServerNowTimestamp()
|
||
local startTime = ParseToTimestamp(gachaCfg[id].StartTimeStr)
|
||
local endTime = ParseToTimestamp(gachaCfg[id].EndTimeStr)
|
||
local IsClose = nowTime > endTime
|
||
local IsNotOpen = startTime > nowTime
|
||
if IsShowText and IsNotOpen then
|
||
local str = CS.XTextManager.GetText("GachaIsNotOpen", gachaCfg[id].StartTimeStr, gachaCfg[id].EndTimeStr)
|
||
XUiManager.TipMsg(str)
|
||
end
|
||
if IsShowText and IsClose then
|
||
XUiManager.TipText("GachaIsClose")
|
||
end
|
||
return (not IsClose) and (not IsNotOpen)
|
||
end
|
||
|
||
---
|
||
--- 检测扭蛋组是否开启
|
||
function XGachaManager.CheckGachaOrganizeIsOpen(organizeId, isShowText)
|
||
local startTimeStr, endTimeStr = XGachaConfigs.GetOrganizeTime(organizeId)
|
||
if not startTimeStr or not endTimeStr then
|
||
return false
|
||
end
|
||
|
||
local nowTime = XTime.GetServerNowTimestamp()
|
||
local startTime = ParseToTimestamp(startTimeStr)
|
||
local endTime = ParseToTimestamp(endTimeStr)
|
||
|
||
local IsNotOpen = startTime > nowTime
|
||
if isShowText and IsNotOpen then
|
||
local str = CS.XTextManager.GetText("GachaIsNotOpen", startTimeStr, endTimeStr)
|
||
XUiManager.TipMsg(str)
|
||
end
|
||
|
||
local IsClose = nowTime > endTime
|
||
if isShowText and IsClose then
|
||
XUiManager.TipText("GachaIsClose")
|
||
end
|
||
|
||
return (not IsClose) and (not IsNotOpen)
|
||
end
|
||
|
||
function XGachaManager.UpdateGachaRewardInfo(gridInfoList)
|
||
for _, v in pairs(gridInfoList or {}) do
|
||
if GachaRewardInfos[v.Id] then
|
||
GachaRewardInfos[v.Id].CurCount = GachaRewardInfos[v.Id].UsableTimes - v.Times
|
||
end
|
||
end
|
||
end
|
||
|
||
function XGachaManager.UpdateGachaLog(gachaId, logList)
|
||
GachaLogList = GachaLogList or {}
|
||
GachaLogList[gachaId] = logList
|
||
end
|
||
|
||
function XGachaManager.SetGachaRewardInfo()
|
||
local gachaRewardCfg = XGachaConfigs.GetGachaReward()
|
||
for id, reward in pairs(gachaRewardCfg) do
|
||
GachaRewardInfos[id] = {}
|
||
for k, v in pairs(reward) do
|
||
GachaRewardInfos[id][k] = v
|
||
end
|
||
GachaRewardInfos[id].CurCount = GachaRewardInfos[id].UsableTimes
|
||
end
|
||
end
|
||
|
||
function XGachaManager.SetGachaProbShowInfo()
|
||
local gachaProbShowCfg = XGachaConfigs.GetGachaProbShows()
|
||
for _, probShow in pairs(gachaProbShowCfg) do
|
||
GachaProbShows[probShow.GachaId] = GachaProbShows[probShow.GachaId] or {}
|
||
table.insert(GachaProbShows[probShow.GachaId],probShow)
|
||
end
|
||
end
|
||
|
||
function XGachaManager.GetGachaRewardInfoRequest(gaChaId, cb)
|
||
local now = XTime.GetServerNowTimestamp()
|
||
if LastGetGachaRewardInfoTimes[gaChaId] and now - LastGetGachaRewardInfoTimes[gaChaId] <= GET_GACHA_DATA_INTERVAL then
|
||
cb()
|
||
return
|
||
end
|
||
XNetwork.Call(METHOD_NAME.GetGachaInfo, { Id = gaChaId }, function(res)
|
||
if res.Code ~= XCode.Success then
|
||
XUiManager.TipCode(res.Code)
|
||
return
|
||
end
|
||
XGachaManager.UpdateGachaRewardInfo(res.GridInfoList)
|
||
XGachaManager.UpdateGachaLog(gaChaId, res.GachaRecordList)
|
||
LastGetGachaRewardInfoTimes[gaChaId] = XTime.GetServerNowTimestamp()
|
||
cb()
|
||
end)
|
||
end
|
||
|
||
|
||
function XGachaManager.DoGacha(gaChaId, count, cb, errorCb, organizeId)
|
||
XNetwork.Call(METHOD_NAME.Gacha, { Id = gaChaId, Times = count }, function(res)
|
||
if res.Code ~= XCode.Success then
|
||
XUiManager.TipCode(res.Code)
|
||
if errorCb then
|
||
errorCb()
|
||
end
|
||
return
|
||
end
|
||
XGachaManager.UpdateGachaRewardInfo(res.GridInfoList)
|
||
XGachaManager.UpdateGachaLog(gaChaId, res.GachaRecordList)
|
||
|
||
local newUnlockGachaId
|
||
if organizeId then
|
||
newUnlockGachaId = XGachaManager.DrawUpdateOrganizeStatus(organizeId, gaChaId)
|
||
end
|
||
|
||
if cb then
|
||
cb(res.RewardList, newUnlockGachaId)
|
||
end
|
||
end)
|
||
end
|
||
|
||
---
|
||
--- 在进入界面的时候请求'organizeId'卡池组里的已售罄池子,以及最新解锁的池子的奖励信息
|
||
function XGachaManager.GetGachaOrganizeInfoRequest(organizeId, cb)
|
||
XNetwork.Call(METHOD_NAME.GetGachaOrganizeInfo, { OrganizeId = organizeId }, function(res)
|
||
if res.Code ~= XCode.Success then
|
||
XUiManager.TipCode(res.Code)
|
||
return
|
||
end
|
||
|
||
XGachaManager.UpdateGachaRewardInfo(res.GridInfoList)
|
||
XGachaManager.UpdateGachaLog(res.CurrentId, res.GachaRecordList)
|
||
XGachaManager.OpenUpdateOrganizeStatus(organizeId, res.CurrentId, res.OutOfStockIdList)
|
||
if cb then
|
||
cb(res.CurrentId)
|
||
end
|
||
end)
|
||
end
|
||
|
||
|
||
--------------------------------------------Organize卡池状态相关------------------------------------------------------
|
||
|
||
---
|
||
--- 进入界面时更新卡池组的卡池状态
|
||
---
|
||
--- 'newestGachaId'为最新解锁的卡池Id,它前面的卡池状态为正常或售罄,后面的卡池状态为锁定
|
||
--- 'outSoldList'为已售罄卡池Id数组,这样就不用发送所有卡池的奖励信息,就能知道所有卡池的状态
|
||
function XGachaManager.OpenUpdateOrganizeStatus(organizeId, newestGachaId, outSoldList)
|
||
if not GachaOrganizeStatus[organizeId] then
|
||
GachaOrganizeStatus[organizeId] = {}
|
||
end
|
||
|
||
-- 设置已售罄卡池
|
||
for _, gachaId in ipairs(outSoldList) do
|
||
if not GachaOrganizeStatus[organizeId][gachaId] then
|
||
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.SoldOut
|
||
end
|
||
|
||
-- 进入界面时,客户端缓存的售馨卡池与服务器下发的售罄卡池不同步
|
||
if GachaOrganizeStatus[organizeId][gachaId] ~= XGachaConfigs.OrganizeGachaStatus.SoldOut then
|
||
XLog.Error(string.format("XGachaManager.UpdateOrganizeGachaStatus函数错误,服务器下发的最新卡池Id为%s,卡池组%s的卡池%s状态与服务器不同步,客户端的为未售罄状态",
|
||
tostring(newestGachaId), tostring(organizeId), tostring(gachaId)))
|
||
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.SoldOut
|
||
end
|
||
end
|
||
|
||
local organizeGachaIdList = XGachaConfigs.GetOrganizeGahcaIdList(organizeId) -- organizeId组的所有gachaId数组,已根据Sort排序
|
||
local newestGachaIndex = XGachaConfigs.GetOrganizeIndex(organizeId, newestGachaId) -- 最新解锁卡池在organizeGachaIdList数组里的序号
|
||
if not newestGachaIndex then
|
||
return
|
||
end
|
||
-- 最新解锁卡池前面的卡池为已解锁或售罄,后面的为锁定
|
||
for index, gachaId in ipairs(organizeGachaIdList) do
|
||
if index <= newestGachaIndex then
|
||
if not GachaOrganizeStatus[organizeId][gachaId] then
|
||
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Normal
|
||
end
|
||
|
||
-- 进入界面时,客户端缓存的 newestGachaId卡池前面的卡池的状态 为锁定,说明状态与服务器不同步
|
||
if GachaOrganizeStatus[organizeId][gachaId] == XGachaConfigs.OrganizeGachaStatus.Lock then
|
||
XLog.Error(string.format("XGachaManager.UpdateOrganizeGachaStatus函数错误,服务器下发的最新卡池Id为%s,卡池组%s的卡池%s状态与服务器不同步,客户端的为上锁状态",
|
||
tostring(newestGachaId), tostring(organizeId), tostring(gachaId)))
|
||
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Normal
|
||
end
|
||
else
|
||
if not GachaOrganizeStatus[organizeId][gachaId] then
|
||
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Lock
|
||
end
|
||
|
||
-- 进入界面时,客户端缓存的 newestGachaId卡池后面的卡池的状态为正常,说明状态与服务器不同步
|
||
if GachaOrganizeStatus[organizeId][gachaId] == XGachaConfigs.OrganizeGachaStatus.Normal then
|
||
XLog.Error(string.format("XGachaManager.UpdateOrganizeGachaStatus函数错误,服务器下发的最新卡池Id为%s,卡池组%s的卡池%s状态与服务器不同步,客户端的为正常状态",
|
||
tostring(newestGachaId), tostring(organizeId), tostring(gachaId)))
|
||
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Lock
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
--- 抽卡后更新卡池组的卡池状态
|
||
--- 如果解锁了新卡池则返回该卡池Id
|
||
---@return number
|
||
function XGachaManager.DrawUpdateOrganizeStatus(organizeId, DrawingGachaId)
|
||
if not GachaOrganizeStatus[organizeId] then
|
||
XLog.Error(string.format("XGachaManager.DrawUpdateOrganizeStatus函数错误,卡池组%s的状态数据为空",
|
||
tostring(organizeId)))
|
||
GachaOrganizeStatus[organizeId] = {}
|
||
end
|
||
|
||
local isSoldOutRare = true -- 特殊奖励是否售罄
|
||
local isSoldOut = true -- 全部奖励是否售罄
|
||
local groupIdList = {}
|
||
|
||
-- 是否无限次数
|
||
if IsInfinite then
|
||
isSoldOut = false
|
||
else
|
||
-- 找出DrawingGachaId的奖励
|
||
local gachaCfg = XGachaConfigs.GetGachas()
|
||
for _, groupId in pairs(gachaCfg[DrawingGachaId].GroupId) do
|
||
table.insert(groupIdList, groupId)
|
||
end
|
||
|
||
for _, v in pairs(GachaRewardInfos) do
|
||
-- 是否属于DrawingGachaId的奖励组
|
||
for _, groupId in pairs(groupIdList) do
|
||
if v.GroupId == groupId and v.CurCount ~= 0 then
|
||
isSoldOut = false
|
||
if v.Rare then
|
||
isSoldOutRare = false
|
||
end
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if isSoldOut then
|
||
GachaOrganizeStatus[organizeId][DrawingGachaId] = XGachaConfigs.OrganizeGachaStatus.SoldOut
|
||
end
|
||
|
||
local isUnlockNext
|
||
if isSoldOutRare then
|
||
-- 是否解锁了新的卡池62504
|
||
local nextGachaStatus, nextGachaId = XGachaManager.GetOrganizeNextGachaStatus(organizeId, DrawingGachaId)
|
||
if nextGachaStatus and nextGachaId then
|
||
if nextGachaStatus == XGachaConfigs.OrganizeGachaStatus.Lock then
|
||
GachaOrganizeStatus[organizeId][nextGachaId] = XGachaConfigs.OrganizeGachaStatus.Normal
|
||
isUnlockNext = nextGachaId
|
||
end
|
||
end
|
||
end
|
||
return isUnlockNext
|
||
end
|
||
|
||
---
|
||
--- 获取''organizeId'卡池组内'gachaId'卡池的状态
|
||
function XGachaManager.GetOrganizeGachaStatus(organizeId, gachaId)
|
||
if not gachaId or gachaId == 0 then
|
||
return
|
||
end
|
||
if GachaOrganizeStatus[organizeId] then
|
||
if GachaOrganizeStatus[organizeId][gachaId] then
|
||
return GachaOrganizeStatus[organizeId][gachaId]
|
||
else
|
||
XLog.Error(string.format("XGachaManager.GetOrganizeGachaStatus函数错误,卡池%s的状态数据为空", gachaId))
|
||
end
|
||
else
|
||
XLog.Error(string.format("XGachaManager.GetOrganizeGachaStatus函数错误,卡池组%s的状态数据为空", organizeId))
|
||
end
|
||
return XGachaConfigs.OrganizeGachaStatus.Lock
|
||
end
|
||
|
||
---
|
||
--- 获取''organizeId'卡池组内'gachaId'前一个卡池的状态与Id
|
||
---
|
||
--- 如果'gachaId'是第一个卡池,则返回nil
|
||
function XGachaManager.GetOrganizePreGachaStatus(organizeId, gachaId)
|
||
local preGachaId = XGachaConfigs.GetOrganizePreGachaId(organizeId, gachaId)
|
||
local status = XGachaManager.GetOrganizeGachaStatus(organizeId, preGachaId)
|
||
if status then
|
||
return status, preGachaId
|
||
end
|
||
end
|
||
|
||
---
|
||
--- 获取''organizeId'卡池组内'gachaId'后一个卡池的状态与Id
|
||
---
|
||
--- 如果'gachaId'是最后一个卡池,则返回nil
|
||
function XGachaManager.GetOrganizeNextGachaStatus(organizeId, gachaId)
|
||
local nextGachaId = XGachaConfigs.GetOrganizeNextGachaId(organizeId, gachaId)
|
||
local status = XGachaManager.GetOrganizeGachaStatus(organizeId, nextGachaId)
|
||
if status then
|
||
return status, nextGachaId
|
||
end
|
||
end
|
||
--------------------------------------------------------------------------------------------------------------------
|
||
|
||
|
||
XGachaManager.Init()
|
||
return XGachaManager
|
||
end |