648 lines
28 KiB
Lua
648 lines
28 KiB
Lua
local skynet = require "skynet"
|
||
local oo = require "Class"
|
||
local log = require "Log"
|
||
local pb = require "pb"
|
||
local dataType = require "DataType"
|
||
local errorInfo = require "ErrorInfo"
|
||
local redisKeyUrl = require "RedisKeyUrl"
|
||
local activity = require "Activity"
|
||
local json =require "json"
|
||
local ActivityBindBox = oo.class()
|
||
|
||
ActivityBindBox.ActivityType = dataType.ActivityType_BindBox
|
||
|
||
ActivityBindBox.ActivityStatus_No = 0 --未开启活动
|
||
ActivityBindBox.ActivityStatus_Yes = 1 --已开启活动
|
||
ActivityBindBox.RefreshType_AD = 1 --广告刷新
|
||
ActivityBindBox.RefreshType_Daily = 2 --每日免费刷新
|
||
ActivityBindBox.RefreshType_Ticket = 3 --刷新券刷新
|
||
ActivityBindBox.RefreshType_VoluteCoin = 4 --蜗壳币刷新
|
||
ActivityBindBox.InitNormalBoxMax = 50 --初始NPC普通盲盒数量 测试数据之后记得调回去 200 100 50
|
||
ActivityBindBox.InitSmartBoxMax = 20 --初始NPC精致盲盒数量
|
||
ActivityBindBox.InitSurpriseBoxMax = 5 --初始NPC惊喜盲盒数量
|
||
|
||
--服务器活动状态
|
||
ActivityBindBox.activityStatus = ActivityBindBox.ActivityStatus_No
|
||
ActivityBindBox.activityId = 0
|
||
ActivityBindBox.refreshTime = 0
|
||
ActivityBindBox.refreshBoxRatio = {}
|
||
ActivityBindBox.normalBox = {}
|
||
ActivityBindBox.smartBox = {}
|
||
ActivityBindBox.surpriseBox = {}
|
||
ActivityBindBox.checkPrice = {}
|
||
ActivityBindBox.freeRefreshDaily = 0
|
||
ActivityBindBox.adRefreshDaily = 0
|
||
ActivityBindBox.currencyRefresh = {}
|
||
ActivityBindBox.couponRefresh = 0
|
||
ActivityBindBox.minimumStorage = 0
|
||
|
||
--构造函数(将活动注册到activity管理类中)
|
||
function ActivityBindBox:Init()
|
||
|
||
end
|
||
|
||
--活动关闭,服务器状态更新
|
||
local function CloseActivity()
|
||
local redisKey = string.format( redisKeyUrl.GameServerActivityBindBoxHash )
|
||
--删除redis中当期初始化标识并重置服务器中的活动状态
|
||
skynet.server.redis:hdel( redisKey , "isInitBoxMarket" )
|
||
ActivityBindBox.activityStatus = ActivityBindBox.ActivityStatus_No --当前活动状态
|
||
ActivityBindBox.activityId = 0 --当前活动id
|
||
ActivityBindBox.refreshTime = 0 --配置的盲盒市场刷新间隔
|
||
ActivityBindBox.refreshBoxRatio = {} --配置的盲盒档次比例 {1,2,3}
|
||
ActivityBindBox.normalBox = {} --闲置盲盒内容 { quality , count }
|
||
ActivityBindBox.smartBox = {} --精致盲盒内容
|
||
ActivityBindBox.surpriseBox = {} --惊喜盲盒内容
|
||
ActivityBindBox.checkPrice = {} --家具查看价格 { quality , priceType , price }
|
||
ActivityBindBox.freeRefreshDaily = 0 --每日免费刷新次数
|
||
ActivityBindBox.adRefreshDaily = 0 --每日广告刷新次数
|
||
ActivityBindBox.currencyRefresh = {} --单次刷新货币消耗 self.currencyRefresh.priceType self.currencyRefresh.price
|
||
ActivityBindBox.couponRefresh = 0 --单次刷新刷新券消耗
|
||
ActivityBindBox.minimumStorage = 0 --玩家参与活动的家具数门槛
|
||
end
|
||
|
||
--活动服务器数据初始化(服务器重启时也要保证条件满足时调用此方法,防止活动信息丢失)
|
||
local function ActivityInit(activityId)
|
||
if activityId == 0 then
|
||
--关闭活动状态
|
||
if ActivityBindBox.activityStatus == ActivityBindBox.ActivityStatus_Yes then
|
||
ActivityBindBox.activityStatus = ActivityBindBox.ActivityStatus_No
|
||
end
|
||
return
|
||
end
|
||
--如果已经开启则不需要执行后续逻辑
|
||
if ActivityBindBox.activityStatus == ActivityBindBox.ActivityStatus_Yes and ActivityBindBox.activityId == activityId then
|
||
return
|
||
end
|
||
log.info("==========================盲盒初始化执行==================")
|
||
--从redis中取出活动信息,如果是新一期则清理上一期数据,并重新生成新的初始数据
|
||
--由一台游戏服处理初始化数据,其他服只需要更新自身状态即可
|
||
local redisKey = string.format( redisKeyUrl.GameServerActivityBindBoxHash )
|
||
local returnValue = skynet.server.redis:hsetnx( redisKey , "isInitBoxMarket" , true )
|
||
local bindBoxCfg = skynet.server.gameConfig:GetCurCfg("BoxChange", activityId)
|
||
--将活动配置加载至服务器
|
||
ActivityBindBox:ServerInit( activityId ,bindBoxCfg )
|
||
|
||
log.info("==========================盲盒初始化执行==================returnValue:",returnValue)
|
||
if 0 == returnValue then
|
||
--返回0,表示有其它服务器处理了数据
|
||
return
|
||
end
|
||
|
||
--清空上一期的盲盒信息
|
||
skynet.server.redis:del( redisKeyUrl.GameServerActivityBindBoxNoramlSet )
|
||
skynet.server.redis:del( redisKeyUrl.GameServerActivityBindBoxDelicateSet )
|
||
skynet.server.redis:del( redisKeyUrl.GameServerActivityBindBoxWonderSet )
|
||
|
||
--初始化盲盒市场的npc盲盒逻辑
|
||
local furnitureCfg = skynet.server.gameConfig:GetAllCfg("Furniture")
|
||
|
||
--将Furniture表中家具根据规则筛选出3类可被随机的集合
|
||
local normalFurniture , smartFurniture , wonderFurniture = {} , {} , {}
|
||
for k, v in pairs(furnitureCfg) do
|
||
if v.shopType == 1 and v.quality == 1 and v.level >= 20 and v.level <= 60 then
|
||
table.insert(normalFurniture,v)
|
||
elseif (v.shopType == 3 and v.quality == 2 and v.level >= 20 and v.level <= 60) or v.suitType == 1 or v.suitType == 9 or v.suitType == 14 or v.suitType == 37 then
|
||
table.insert(smartFurniture,v)
|
||
elseif (v.shopType == 10 and v.quality == 3 and v.suitType == 0 ) or v.suitType == 32 then
|
||
table.insert(wonderFurniture,v)
|
||
end
|
||
end
|
||
|
||
--如果数量不够,则填补一些随机生成的系统盲盒 暂定普通盲盒200个,精致盲盒100个,惊喜盲盒50个
|
||
local boxRatio = {}
|
||
local box = {}
|
||
local data = {}
|
||
--生成系统普通盲盒
|
||
for k , v in pairs(bindBoxCfg.normalBox) do
|
||
local arr = skynet.server.common:Split(v , "_")
|
||
arr[1],arr[2] = tonumber(arr[1]),tonumber(arr[2])
|
||
table.insert(boxRatio,{ quality = arr[1] , count = arr[2] })
|
||
end
|
||
|
||
for i=1,ActivityBindBox.InitNormalBoxMax,1 do
|
||
box = {}
|
||
data = {}
|
||
data.quality = 1
|
||
data.box = {}
|
||
for k, v in pairs(boxRatio) do
|
||
if v.quality == 1 then
|
||
ActivityBindBox:RandomItem( box , v.count , normalFurniture )
|
||
elseif v.quality == 2 then
|
||
ActivityBindBox:RandomItem( box , v.count , smartFurniture )
|
||
elseif v.quality == 3 then
|
||
ActivityBindBox:RandomItem( box , v.count , wonderFurniture )
|
||
end
|
||
end
|
||
data.id = "npcNormal:"..i
|
||
data.box = box
|
||
local datajson = json:encode(data)
|
||
skynet.server.redis:sadd( redisKeyUrl.GameServerActivityBindBoxNoramlSet ,datajson)
|
||
end
|
||
--生成系统精致盲盒
|
||
boxRatio = {}
|
||
for k , v in pairs(bindBoxCfg.smartBox) do
|
||
local arr = skynet.server.common:Split(v , "_")
|
||
arr[1],arr[2] = tonumber(arr[1]),tonumber(arr[2])
|
||
table.insert(boxRatio,{ quality = arr[1] , count = arr[2] })
|
||
end
|
||
for i=1,ActivityBindBox.InitSmartBoxMax,1 do
|
||
box = {}
|
||
data = {}
|
||
data.quality = 2
|
||
data.box = {}
|
||
for k, v in pairs(boxRatio) do
|
||
if v.quality == 1 then
|
||
ActivityBindBox:RandomItem( box , v.count , normalFurniture )
|
||
elseif v.quality == 2 then
|
||
ActivityBindBox:RandomItem( box , v.count , smartFurniture )
|
||
elseif v.quality == 3 then
|
||
ActivityBindBox:RandomItem( box , v.count , wonderFurniture )
|
||
end
|
||
end
|
||
data.id = "npcSmart:"..i
|
||
data.box = box
|
||
local datajson = json:encode(data)
|
||
skynet.server.redis:sadd( redisKeyUrl.GameServerActivityBindBoxDelicateSet ,datajson)
|
||
end
|
||
--生成系统惊喜盲盒
|
||
boxRatio = {}
|
||
for k , v in pairs(bindBoxCfg.surpriseBox) do
|
||
local arr = skynet.server.common:Split(v , "_")
|
||
arr[1],arr[2] = tonumber(arr[1]),tonumber(arr[2])
|
||
table.insert(boxRatio,{ quality = arr[1] , count = arr[2] })
|
||
end
|
||
for i=1,ActivityBindBox.InitSurpriseBoxMax,1 do
|
||
box = {}
|
||
data = {}
|
||
data.quality = 3
|
||
data.box = {}
|
||
for k, v in pairs(boxRatio) do
|
||
if v.quality == 1 then
|
||
ActivityBindBox:RandomItem( box , v.count , normalFurniture )
|
||
elseif v.quality == 2 then
|
||
ActivityBindBox:RandomItem( box , v.count , smartFurniture )
|
||
elseif v.quality == 3 then
|
||
ActivityBindBox:RandomItem( box , v.count , wonderFurniture )
|
||
end
|
||
end
|
||
data.id = "npcSurprise:"..i
|
||
data.box = box
|
||
local datajson = json:encode(data)
|
||
skynet.server.redis:sadd( redisKeyUrl.GameServerActivityBindBoxWonderSet ,datajson)
|
||
end
|
||
|
||
end
|
||
|
||
--服务器活动初始化
|
||
function ActivityBindBox:ServerInit( activityId , bindBoxCfg )
|
||
self.activityStatus = ActivityBindBox.ActivityStatus_Yes
|
||
self.activityId = activityId --当期id
|
||
self.refreshTime = bindBoxCfg.refreshTime * 60 --刷新时间(秒)
|
||
for i, v in pairs(bindBoxCfg.refreshBoxRatio) do
|
||
table.insert(self.refreshBoxRatio,tonumber(v)) --单次刷新盲盒档次比例
|
||
end
|
||
for i, v in pairs(bindBoxCfg.normalBox) do
|
||
local info = skynet.server.common:Split(v, "_")
|
||
info[1], info[2] = tonumber(info[1]), tonumber(info[2])
|
||
table.insert(self.normalBox, { quality = info[1] , count = info[2] }) --闲置盲盒内容[稀有度_数量]
|
||
end
|
||
for i, v in pairs(bindBoxCfg.smartBox) do
|
||
local info = skynet.server.common:Split(v, "_")
|
||
info[1], info[2] = tonumber(info[1]), tonumber(info[2])
|
||
table.insert(self.smartBox, { quality = info[1] , count = info[2] }) --精致盲盒内容[稀有度_数量]
|
||
end
|
||
for i, v in pairs(bindBoxCfg.surpriseBox) do
|
||
local info = skynet.server.common:Split(v, "_")
|
||
info[1], info[2] = tonumber(info[1]), tonumber(info[2])
|
||
table.insert(self.surpriseBox, { quality = info[1] , count = info[2] }) --惊喜盲盒内容[稀有度_数量]
|
||
end
|
||
for i, v in pairs(bindBoxCfg.checkPrice) do
|
||
local info = skynet.server.common:Split(v, "_")
|
||
info[1], info[2] = tonumber(info[1]), tonumber(info[2])
|
||
table.insert(self.checkPrice, { quality = i, priceType = info[1] , price = info[2] }) --家具查看价格[货币种类_消耗数量](普通,稀有,罕见,星耀)
|
||
end
|
||
|
||
local currencyRefresh = skynet.server.common:Split(bindBoxCfg.currencyRefresh, "_") --单次刷新货币消耗[货币种类_消耗数量]
|
||
currencyRefresh[1], currencyRefresh[2] = tonumber(currencyRefresh[1]), tonumber(currencyRefresh[2])
|
||
self.currencyRefresh.priceType = currencyRefresh[1]
|
||
self.currencyRefresh.price = currencyRefresh[2]
|
||
|
||
self.freeRefreshDaily = bindBoxCfg.freeRefreshDaily --每日免费刷新次数
|
||
self.adRefreshDaily = bindBoxCfg.adRefreshDaily --每日广告刷新次数
|
||
self.couponRefresh = bindBoxCfg.couponRefresh --单次刷新刷新券消耗
|
||
self.minimumStorage = bindBoxCfg.minimumStorage --玩家参与置换的仓库家具最低值
|
||
end
|
||
|
||
function ActivityBindBox:LoginInitData( player )
|
||
--判断模块是否开启
|
||
if not player:IsUnlockSystem( dataType.UnlockSystem_ActivityBindBox ) then
|
||
return
|
||
end
|
||
|
||
--获取开启的活动
|
||
local activityId = activity:GetActivityInfo(player, self.ActivityType)
|
||
if activityId == 0 then
|
||
return
|
||
end
|
||
|
||
if (player.gameData.activity[self.ActivityType] == nil or next(player.gameData.activity[self.ActivityType]) == nil) then
|
||
self:InitData( player )
|
||
else
|
||
if player.gameData.activity[self.ActivityType].curId ~= activityId then
|
||
self:InitData( player )
|
||
else
|
||
self:ResetDailyData( player )
|
||
end
|
||
end
|
||
--红点
|
||
self:CheckTips(player)
|
||
end
|
||
|
||
--初始化玩家数据
|
||
function ActivityBindBox:InitData( player )
|
||
player.gameData.activity[self.ActivityType] = {}
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
activityBindBox.curId = 0
|
||
--历史购买盲盒id列表
|
||
activityBindBox.historyIds = {}
|
||
--当前市场内盲盒列表
|
||
activityBindBox.boxList = {}
|
||
--待领取盲盒
|
||
activityBindBox.waitForGet = {}
|
||
--上次刷新时间
|
||
activityBindBox.lastRefreshTime = 0
|
||
--每日免费刷新次数
|
||
activityBindBox.freeRefreshDaily = 0
|
||
--每日广告刷新次数
|
||
activityBindBox.adRefreshDaily = 0
|
||
--活动期间上传盲盒数量
|
||
activityBindBox.exchangeNum = 0
|
||
|
||
activityBindBox.curId = self.activityId
|
||
activityBindBox.freeRefreshDaily = self.freeRefreshDaily
|
||
activityBindBox.adRefreshDaily = self.adRefreshDaily
|
||
end
|
||
|
||
--重置需要每日刷新的数据
|
||
function ActivityBindBox:ResetDailyData( player )
|
||
--获取开启的活动
|
||
local activityId = activity:GetActivityInfo(player, self.ActivityType)
|
||
if activityId == 0 then
|
||
return
|
||
end
|
||
if player.gameData.activity[self.ActivityType] == nil or next(player.gameData.activity[self.ActivityType]) == nil or player.gameData.activity[self.ActivityType].curId ~= activityId then
|
||
self:InitData( player )
|
||
end
|
||
local todayGain = player.gameData.todayGain
|
||
if not todayGain.bindBoxDaily then
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
activityBindBox.freeRefreshDaily = self.freeRefreshDaily
|
||
activityBindBox.adRefreshDaily = self.adRefreshDaily
|
||
todayGain.bindBoxDaily = true
|
||
end
|
||
end
|
||
|
||
--盲盒展示
|
||
--message BindBoxInfo
|
||
--{
|
||
-- int32 id = 1; //物品id
|
||
-- int32 quality = 2; //稀有度
|
||
-- bool canView = 3; //是否揭露
|
||
-- int32 index =4; //物品索引
|
||
--}
|
||
--
|
||
--message BindBox
|
||
--{
|
||
-- int32 id = 1; //盲盒id
|
||
-- int32 quality = 2; //盲盒品质 1-闲置盲盒 2-精致盲盒 3-惊喜盲盒
|
||
-- repeated BindBoxInfo box = 3; //盲盒物品
|
||
--}
|
||
|
||
function ActivityBindBox:Show( player , c2sData , s2cData )
|
||
local data = {}
|
||
data.boxes = {}
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
--判断是否需要刷新展示盲盒
|
||
if skynet.GetTime() - activityBindBox.lastRefreshTime >= self.refreshTime then
|
||
activityBindBox.boxList = {}
|
||
for i, v in pairs(self.refreshBoxRatio) do
|
||
self:GetNewBox ( player , i , v )
|
||
end
|
||
activityBindBox.lastRefreshTime = skynet.GetTime()
|
||
--红点
|
||
skynet.server.msgTips:ReduceAll(player , 126)
|
||
elseif ( activityBindBox.boxList == nil or next(activityBindBox.boxList) == nil ) and ( activityBindBox.historyIds == nil or next(activityBindBox.historyIds) == nil ) then
|
||
activityBindBox.boxList = {}
|
||
for i, v in pairs(self.refreshBoxRatio) do
|
||
self:GetNewBox ( player , i , v )
|
||
end
|
||
activityBindBox.lastRefreshTime = skynet.GetTime()
|
||
end
|
||
data.boxes = activityBindBox.boxList
|
||
data.refreshTime = self.refreshTime + activityBindBox.lastRefreshTime
|
||
data.adRefreshCount = activityBindBox.adRefreshDaily
|
||
data.freeRefreshCount = activityBindBox.freeRefreshDaily
|
||
data.boxWaitForGet = activityBindBox.waitForGet
|
||
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityBindBoxShow")
|
||
s2cData.data = assert(pb.encode("S2CActivityBindBoxShow", data))
|
||
end
|
||
|
||
--盲盒刷新 //刷新类型 1-广告刷新 2-每日免费刷新 3-刷新券刷新 4-蜗壳币刷新
|
||
function ActivityBindBox:Refresh( player , c2sData , s2cData )
|
||
c2sData.data = assert(pb.decode("C2SActivityBindBoxReFresh", c2sData.data))
|
||
local refreshType = c2sData.data.refreshType
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
local data = {}
|
||
data.isSuc = true
|
||
data.boxes = {}
|
||
data.refreshTime = 0
|
||
--判断刷新类型
|
||
if refreshType == self.RefreshType_AD then
|
||
if activityBindBox.adRefreshDaily <= 0 then
|
||
data.isSuc = false
|
||
s2cData.code = errorInfo.ErrorCode.TodayMaxLimit
|
||
else
|
||
activityBindBox.adRefreshDaily = activityBindBox.adRefreshDaily - 1
|
||
end
|
||
elseif refreshType == self.RefreshType_Daily then
|
||
if activityBindBox.freeRefreshDaily <= 0 then
|
||
data.isSuc = false
|
||
s2cData.code = errorInfo.ErrorCode.TodayMaxLimit
|
||
else
|
||
activityBindBox.freeRefreshDaily = activityBindBox.freeRefreshDaily - 1
|
||
end
|
||
elseif refreshType == self.RefreshType_Ticket then
|
||
if skynet.server.bag:GetGoodsCount(player, dataType.GoodsType_Prop, 4) >= self.couponRefresh then
|
||
skynet.server.bag:RemoveGoods(player , dataType.GoodsType_Prop, 4 , self.couponRefresh)
|
||
else
|
||
data.isSuc = false
|
||
s2cData.code = errorInfo.ErrorCode.NoEnoughProp
|
||
end
|
||
elseif refreshType == self.RefreshType_VoluteCoin then
|
||
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_146" )
|
||
if not player:MoneyChange( self.currencyRefresh.priceType , -self.currencyRefresh.price , eventId ) then
|
||
data.isSuc = false
|
||
s2cData.code = errorInfo.ErrorCode.NoEnoughMoney
|
||
end
|
||
end
|
||
--成功刷新
|
||
if data.isSuc then
|
||
activityBindBox.boxList = {}
|
||
for i, v in pairs(self.refreshBoxRatio) do
|
||
self:GetNewBox ( player , i , v )
|
||
end
|
||
activityBindBox.lastRefreshTime = skynet.GetTime()
|
||
data.boxes = activityBindBox.boxList
|
||
data.refreshTime = self.refreshTime + activityBindBox.lastRefreshTime
|
||
data.adRefreshCount = activityBindBox.adRefreshDaily
|
||
data.freeRefreshCount = activityBindBox.freeRefreshDaily
|
||
end
|
||
|
||
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityBindBoxReFresh")
|
||
s2cData.data = assert(pb.encode("S2CActivityBindBoxReFresh", data))
|
||
end
|
||
|
||
--获取新盲盒 data = { id = i , quality = 1 , box = {{ id = id , quality = quality },{ id = id , quality = quality },{ id = id , quality = quality } } }
|
||
function ActivityBindBox:GetNewBox( player , quality , count)
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
local data = {}
|
||
local haveExchange = false
|
||
--local result = {}
|
||
local redisKey
|
||
|
||
--根据需要的盲盒稀有度从redis中随机取对应数量的盲盒出来
|
||
if quality == 1 then
|
||
redisKey = redisKeyUrl.GameServerActivityBindBoxNoramlSet
|
||
elseif quality == 2 then
|
||
redisKey = redisKeyUrl.GameServerActivityBindBoxDelicateSet
|
||
elseif quality == 3 then
|
||
redisKey = redisKeyUrl.GameServerActivityBindBoxWonderSet
|
||
end
|
||
|
||
data = skynet.server.redis:srandmember( redisKey , count)
|
||
|
||
--拆箱
|
||
for i, v in pairs(data) do
|
||
haveExchange = false
|
||
local box = json:decode(v)
|
||
--判重
|
||
for k, v1 in pairs(activityBindBox.historyIds) do
|
||
if box.id == v1 then
|
||
haveExchange = true
|
||
break
|
||
end
|
||
end
|
||
--如果购买过则重新开一个箱子
|
||
if haveExchange then
|
||
box = self:ReGetOneBox ( player , redisKey )
|
||
end
|
||
--将盲盒内容处理成客户端需要的形式返回(每个盲盒内的物品类添加一个是否展示的标记),方便展示
|
||
local cacheBox = {}
|
||
for i, v in pairs(box.box) do
|
||
table.insert(cacheBox ,{ id = v.id , quality = v.quality , canView = false , index = i })
|
||
end
|
||
--table.insert(result,{ id = box.id , quality = box.quality , box = cacheBox })
|
||
--这里默认boxList已经初始化,直接添加即可,可以减少遍历操作
|
||
table.insert(activityBindBox.boxList,{ id = tostring(box.id) , quality = box.quality , box = cacheBox , isBuy = false })
|
||
end
|
||
--return result
|
||
end
|
||
|
||
--重新获取一个盲盒
|
||
function ActivityBindBox:ReGetOneBox( player , redisKey )
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
local data = {}
|
||
local haveExchange = false
|
||
local result = {}
|
||
data = skynet.server.redis:srandmember( redisKey , 1)
|
||
|
||
--拆箱 此处只会有一个box
|
||
for i, v in pairs(data) do
|
||
haveExchange = false
|
||
local box = json:decode(v)
|
||
--判重
|
||
for k, v1 in pairs(activityBindBox.historyIds) do
|
||
if box.id == v1 then
|
||
haveExchange = true
|
||
break
|
||
end
|
||
end
|
||
--如果购买过则重新开一个箱子
|
||
if haveExchange then
|
||
box = self:ReGetOneBox ( player , redisKey )
|
||
end
|
||
result = box
|
||
end
|
||
return result
|
||
end
|
||
|
||
--盲盒物品揭露
|
||
function ActivityBindBox:PeekBox( player , c2sData , s2cData )
|
||
c2sData.data = assert(pb.decode("C2SActivityBindBoxPeek", c2sData.data))
|
||
local boxId = c2sData.data.boxId
|
||
local index = c2sData.data.index
|
||
local data = {}
|
||
data.isSuc = false
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
local box = {}
|
||
for i, v in pairs(activityBindBox.boxList) do
|
||
--寻找对应id的盲盒
|
||
if v.id == boxId then
|
||
for i2, v2 in pairs(v.box) do
|
||
--根据数据表中配置的品质对应的揭露价格去扣除对应货币,返回状态
|
||
if v2.index == index then
|
||
if not v2.canView then
|
||
local price =self.checkPrice[v2.quality]
|
||
if price ~= nil then
|
||
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_146" )
|
||
if not player:MoneyChange( price.priceType , -price.price , eventId ) then
|
||
s2cData.code = errorInfo.ErrorCode.NoEnoughMoney
|
||
else
|
||
data.isSuc = true
|
||
v2.canView = true
|
||
box = v
|
||
end
|
||
end
|
||
else
|
||
s2cData.code = errorInfo.ErrorCode.AlreadyGet
|
||
end
|
||
break
|
||
end
|
||
end
|
||
break
|
||
end
|
||
end
|
||
if not data.isSuc and (s2cData.code == nil or s2cData.code == '') then
|
||
s2cData.code = errorInfo.ErrorCode.NoGoodsID
|
||
end
|
||
data.boxInfo = box
|
||
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityBindBoxPeek")
|
||
s2cData.data = assert(pb.encode("S2CActivityBindBoxPeek", data))
|
||
end
|
||
|
||
|
||
--盲盒置换
|
||
function ActivityBindBox:Exchange( player , c2sData , s2cData )
|
||
c2sData.data = assert(pb.decode("C2SActivityBindBoxExchange", c2sData.data))
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
local data = {}
|
||
data.isSuc = false
|
||
local boxId = c2sData.data.boxId
|
||
local uploadBox = c2sData.data.box
|
||
--先判断活动开启状态和上传的盲盒家具数量是否足够
|
||
local canBuy = true
|
||
if self.activityStatus == self.ActivityStatus_No then
|
||
canBuy = false
|
||
s2cData.code = errorInfo.ErrorCode.ActivityClosed
|
||
else
|
||
for i, v in pairs(uploadBox) do
|
||
if skynet.server.bag:GetGoodsCount(player, dataType.GoodsType_Furniture, v.id) <= 0 then
|
||
canBuy = false
|
||
s2cData.code = errorInfo.ErrorCode.NoExistGoodsInBag
|
||
break
|
||
end
|
||
end
|
||
end
|
||
--都足够的情况下这些家具各移除1个
|
||
if canBuy then
|
||
local box = {}
|
||
for i, v in pairs(uploadBox) do
|
||
skynet.server.bag:RemoveGoods(player , dataType.GoodsType_Furniture, v.id , 1)
|
||
table.insert( box,{ id = v.id , quality = v.quality } )
|
||
end
|
||
--移除后将盲盒打包上传至redis中,供其他玩家获取,
|
||
for i, v in pairs(activityBindBox.boxList) do
|
||
if boxId == v.id then
|
||
--修改盲盒购买状态,并且将id添加到历史购买列表中防止再次刷到
|
||
v.isBuy = true
|
||
table.insert(activityBindBox.historyIds,boxId)
|
||
activityBindBox.waitForGet = v
|
||
--装箱上传redis
|
||
local cache = {}
|
||
cache.quality = v.quality
|
||
cache.box = {}
|
||
cache.id = player.account .. ':' .. activityBindBox.exchangeNum
|
||
cache.box = box
|
||
local datajson = json:encode(cache)
|
||
if v.quality == 1 then
|
||
skynet.server.redis:sadd( redisKeyUrl.GameServerActivityBindBoxNoramlSet ,datajson)
|
||
elseif v.quality == 2 then
|
||
skynet.server.redis:sadd( redisKeyUrl.GameServerActivityBindBoxDelicateSet ,datajson)
|
||
elseif v.quality == 2 then
|
||
skynet.server.redis:sadd( redisKeyUrl.GameServerActivityBindBoxWonderSet ,datajson)
|
||
end
|
||
--上传后更新交易数 ,将自己的盲盒id添加进历史交易记录中防止刷新到自己的盲盒
|
||
activityBindBox.exchangeNum = activityBindBox.exchangeNum + 1
|
||
table.insert(activityBindBox.historyIds,cache.id)
|
||
--红点
|
||
skynet.server.msgTips:Add(player , 125)
|
||
end
|
||
end
|
||
end
|
||
data.boxWaitForGet = activityBindBox.waitForGet
|
||
data.boxes = activityBindBox.boxList
|
||
data.refreshTime = self.refreshTime + activityBindBox.lastRefreshTime
|
||
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityBindBoxExchange")
|
||
s2cData.data = assert(pb.encode("S2CActivityBindBoxExchange", data))
|
||
end
|
||
|
||
--领取盲盒内容
|
||
function ActivityBindBox:GetReward( player , c2sData , s2cData )
|
||
c2sData.data = assert(pb.decode("C2SActivityBindBoxGet", c2sData.data))
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
local data = {}
|
||
if activityBindBox.waitForGet ~= nil and next(activityBindBox.waitForGet) ~= nil then
|
||
data.boxGet = skynet.server.common:DeepCopy( activityBindBox.waitForGet )
|
||
for i, v in pairs(activityBindBox.waitForGet.box) do
|
||
skynet.server.bag:AddGoodsNoExp(player, dataType.GoodsType_Furniture, v.id, 1 ,true)
|
||
end
|
||
--领取完成后清空该字段
|
||
activityBindBox.waitForGet = {}
|
||
--红点逻辑
|
||
skynet.server.msgTips:ReduceAll(player , 125)
|
||
end
|
||
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityBindBoxGet")
|
||
s2cData.data = assert(pb.encode("S2CActivityBindBoxGet", data))
|
||
end
|
||
|
||
--红点逻辑
|
||
function ActivityBindBox:CheckTips(player)
|
||
skynet.server.msgTips:Reset( player , 126 )
|
||
skynet.server.msgTips:Reset( player , 125 )
|
||
local activityBindBox = player.gameData.activity[self.ActivityType]
|
||
--刷新时间
|
||
if skynet.GetTime() - activityBindBox.lastRefreshTime >= self.refreshTime then
|
||
skynet.server.msgTips:Add(player , 126)
|
||
end
|
||
--待领取盲盒
|
||
if activityBindBox.waitForGet ~= nil and next(activityBindBox.waitForGet) ~= nil then
|
||
skynet.server.msgTips:Add(player , 125)
|
||
end
|
||
end
|
||
|
||
--封装随机家具BOX
|
||
function ActivityBindBox:RandomItem( box , count , pool )
|
||
if count > 1 then
|
||
--用作判重,防止一个盲盒中出现重复家具
|
||
local lastIndexs = {}
|
||
local index
|
||
for i = 1,count do
|
||
index = math.random( 1, #pool)
|
||
while ( lastIndexs[index] ~= nil ) do
|
||
index = math.random( 1, #pool)
|
||
end
|
||
table.insert(box,{ id = pool[index].id , quality = pool[index].quality })
|
||
lastIndexs[index] = 1
|
||
end
|
||
else
|
||
local index = math.random( 1, #pool)
|
||
table.insert(box,{ id = pool[index].id , quality = pool[index].quality })
|
||
end
|
||
end
|
||
|
||
--注册活动
|
||
activity:RegisterInitHandler(ActivityInit,"盲盒活动",ActivityBindBox.ActivityType)
|
||
activity:RegisterCloeseHandler(CloseActivity,"盲盒活动",ActivityBindBox.ActivityType)
|
||
skynet.server.activityBindBox = ActivityBindBox
|
||
return ActivityBindBox |