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 bag = require "Bag" local design = require "Design" local Store = oo.class() --初始化商城礼包数据 function Store:Init() --StorePack_data.json local StorePack = skynet.server.gameConfig.StorePack --获取配置文件StorePack中的数据 --StorePrice_data.json local StorePrice = skynet.server.gameConfig.StorePrice --获取配置文件StorePrice中的数据 --House_data.json local House = skynet.server.gameConfig.House --获取配置文件House中的数据 self.TriggerGiftBag = skynet.server.gameConfig.SValue.triggerGiftBag --获取配置文件SValue中的数据 self.StorePack = {} --初始化礼包相关信息 for k , v in pairs(StorePack) do local count = v.id self.StorePack [ count ] = {} self.StorePack [ count ].storeId = v.id --礼包id self.StorePack [ count ].packType = v.packType --礼包类型 1常驻礼包 2限时礼包 3特殊礼包 4首充礼包 5非付费兑换礼包 6免费礼包 7功能触发礼包 self.StorePack [ count ].packUI = v.packUI --礼包界面 1-货币售卖 2-常规售卖 3-活动售卖 4-衣服售卖 self.StorePack [ count ].rewardId = v.rewardId --礼包对应的奖励id self.StorePack [ count ].packLimit = v.packLimit --礼包对应的购买次数 例 [1,2] (1:日限购 2:周限购 3:限购购买) 每日限购2次 if v.startTime==nil or v.startTime=='' then self.StorePack [ count ].startTime = 0 --礼包对应的生效时间 else self.StorePack [ count ].startTime = skynet.server.common:GetTime(v.startTime) end if v.endTime==nil or v.endTime=='' then self.StorePack [ count ].failureTime = 0 --礼包对应的失效时间 else self.StorePack [ count ].failureTime = skynet.server.common:GetTime(v.endTime) end self.StorePack [ count ].packGift = v.packGift --礼包赠礼 0=每次购买赠送 1=首次购买赠送 [赠礼类型,奖励id] --找得到的礼包进行赋值 找不到的礼包赋值为0 self.StorePack [ count ].price = 0 for k2 ,v2 in pairs(StorePrice) do if v.id==v2.storePackId then self.StorePack [ count ].price = v2.price --礼包对应的价格 end end self.StorePack [ count ].packExchange = v.packExchange --存储兑换礼包的相关信息 self.StorePack [ count ].icon = v.icon --存储礼包入口 self.StorePack [ count ].reward = skynet.server.gameConfig:AwardInfo(v.rewardId) --礼包对应的奖励信息 end self.House = {} --存储功能触发礼包的相关信息 for k ,v in pairs(House) do local houseId = v.id self.House [ houseId ] = {} self.House [ houseId ].id = houseId --户型对应的id self.House [ houseId ].unlockPack = v.unlockPack --户型对应的解锁礼包 self.House [ houseId ].packValid = v.packValid --对应礼包的有效时间 end end --玩家礼包数据初始化 function Store:InitData( player ) --重置商城红点 skynet.server.msgTips:Reset(player , 27) skynet.server.msgTips:Reset(player , 28) skynet.server.msgTips:Reset(player , 29) skynet.server.msgTips:Reset(player , 30) --9级开启商城 判断是否是第一次加载 if player.gameData.level >= skynet.server.gameConfig.SValue.storeUnlockLvl and next(player.gameData.storePack.storePackInfo)==nil then log.info("第一次加载商城") for k ,v in pairs(self.StorePack) do --如果是功能触发礼包需要判断是否满足条件 if 7==v.packType then --满足购买了对应户型的条件 进行添加触发礼包 for k1 , v1 in pairs(player.gameData.house) do if v1.status>=3 and next(self.House[v1.id].unlockPack)~=nil then --添加该礼包 for k2 ,v2 in pairs(self.House[v1.id].unlockPack) do if v2==v.storeId then local count = v.storeId player.gameData.storePack.storePackInfo[ count ] = {} player.gameData.storePack.storePackInfo[ count ].storeId = v.storeId --礼包id player.gameData.storePack.storePackInfo[ count ].buyTimes = 0 --玩家购买的次数 player.gameData.storePack.storePackInfo[ count ].historyBuyTimes = 0 --玩家历史购买次数 player.gameData.storePack.storePackInfo[ count ].buyStatus = false --玩家是否购买该礼包 付费成功 改为true ; 发放奖励后 改为false player.gameData.storePack.storePackInfo[ count ].packLimit = v.packLimit --礼包对应的购买次数 例 [1,2] (1:日限购 2:周限购 3:限购购买) 每日限购2次 player.gameData.storePack.storePackInfo[ count ].look = false --玩家是否看过该礼包(配合限时礼包) --同时添加该礼包的存在时间 player.gameData.storePack.storePackInfo[ count ].startTime = os.time() player.gameData.storePack.storePackInfo[ count ].failureTime = skynet.server.common:GetAfterSomeHour(self.House[v1.id].packValid) player.gameData.storePack.storePackInfo[ count ].IsShow = true --是否继续展示packLimit[0] = 3 ,即限制购买的礼包 默认为true self:SendIconPackToUser(player) end end end end else local count = v.storeId player.gameData.storePack.storePackInfo[ count ] = {} player.gameData.storePack.storePackInfo[ count ].storeId = v.storeId --礼包id player.gameData.storePack.storePackInfo[ count ].buyTimes = 0 --玩家购买的次数 player.gameData.storePack.storePackInfo[ count ].historyBuyTimes = 0 --玩家历史购买次数 player.gameData.storePack.storePackInfo[ count ].buyStatus = false --玩家是否购买该礼包 付费成功 改为true ; 发放奖励后 改为false player.gameData.storePack.storePackInfo[ count ].packLimit = v.packLimit --礼包对应的购买次数 例 [1,2] (1:日限购 2:周限购 3:限购购买) 每日限购2次 if v.startTime>0 then player.gameData.storePack.storePackInfo[ count ].look = false --玩家是否看过该礼包(配合限时礼包) else player.gameData.storePack.storePackInfo[ count ].look = true --普通礼包不用该字段 end player.gameData.storePack.storePackInfo[ count ].IsShow = true --是否继续展示packLimit[0] = 3 ,即限制购买的礼包 默认为true end end elseif player.gameData.level >= skynet.server.gameConfig.SValue.storeUnlockLvl and next(player.gameData.storePack.storePackInfo)~=nil then log.info("第n次加载商城") for k ,v in pairs(self.StorePack) do --判断该礼包是否应该添加给该玩家 local isExist = false for k1 , v1 in pairs(player.gameData.storePack.storePackInfo) do if v.storeId==v1.storeId then isExist = true break end end --将该礼包赋值给该玩家 if not isExist and 7~=v.packType then local count = v.storeId player.gameData.storePack.storePackInfo[ count ] = {} player.gameData.storePack.storePackInfo[ count ].storeId = v.storeId --礼包id player.gameData.storePack.storePackInfo[ count ].buyTimes = 0 --玩家购买的次数 player.gameData.storePack.storePackInfo[ count ].historyBuyTimes = 0 --玩家历史购买次数 player.gameData.storePack.storePackInfo[ count ].buyStatus = false --玩家是否购买该礼包 付费成功 改为true ; 发放奖励后 改为false player.gameData.storePack.storePackInfo[ count ].packLimit = v.packLimit --礼包对应的购买次数 例 [1,2] (1:日限购 2:周限购 3:限购购买) 每日限购2次 if v.startTime>0 then player.gameData.storePack.storePackInfo[ count ].look = false --玩家是否看过该礼包(配合限时礼包) else player.gameData.storePack.storePackInfo[ count ].look = true --普通礼包不用该字段 end player.gameData.storePack.storePackInfo[ count ].IsShow = true --是否继续展示packLimit[0] = 3 ,即限制购买的礼包 默认为true elseif not isExist and 7==v.packType then --满足购买了对应户型的条件 进行添加对应礼包 for k1 , v1 in pairs(player.gameData.house) do if v1.status>=3 and next(self.House[v1.id].unlockPack)~=nil then --添加该礼包 for k2 ,v2 in pairs(self.House[v1.id].unlockPack) do if v2==v.storeId then local count = v.storeId player.gameData.storePack.storePackInfo[ count ] = {} player.gameData.storePack.storePackInfo[ count ].storeId = v.storeId --礼包id player.gameData.storePack.storePackInfo[ count ].buyTimes = 0 --玩家购买的次数 player.gameData.storePack.storePackInfo[ count ].historyBuyTimes = 0 --玩家历史购买次数 player.gameData.storePack.storePackInfo[ count ].buyStatus = false --玩家是否购买该礼包 付费成功 改为true ; 发放奖励后 改为false player.gameData.storePack.storePackInfo[ count ].packLimit = v.packLimit --礼包对应的购买次数 例 [1,2] (1:日限购 2:周限购 3:限购购买) 每日限购2次 player.gameData.storePack.storePackInfo[ count ].look = false --玩家是否看过该礼包(配合限时礼包) --同时添加该礼包的存在时间 player.gameData.storePack.storePackInfo[ count ].startTime = os.time() player.gameData.storePack.storePackInfo[ count ].failureTime = skynet.server.common:GetAfterSomeHour(self.House[v1.id].packValid) player.gameData.storePack.storePackInfo[ count ].IsShow = true --是否继续展示packLimit[0] = 3 ,即限制购买的礼包 默认为true self:SendIconPackToUser(player) end end end end --满足购买了对应商城礼包的条件 进行添加触发礼包 local triggeredGiftBagTime = skynet.server.gameConfig.SValue.triggeredGiftBagTime --被触发的超优礼包id,持续时间(分钟) if v.storeId==triggeredGiftBagTime[1] then for k1 ,v1 in pairs(player.gameData.storePack.storePackInfo) do for k2 ,v2 in pairs(self.TriggerGiftBag) do if v1.storeId==v2 and v1.buyTimes>0 then local count = triggeredGiftBagTime[1] player.gameData.storePack.storePackInfo[ count ] = {} player.gameData.storePack.storePackInfo[ count ].storeId = triggeredGiftBagTime[1] --礼包id player.gameData.storePack.storePackInfo[ count ].buyTimes = 0 --玩家购买的次数 player.gameData.storePack.storePackInfo[ count ].historyBuyTimes = 0 --玩家历史购买次数 player.gameData.storePack.storePackInfo[ count ].buyStatus = false --玩家是否购买该礼包 付费成功 改为true ; 发放奖励后 改为false player.gameData.storePack.storePackInfo[ count ].packLimit = self.StorePack[triggeredGiftBagTime[1]].packLimit --礼包对应的购买次数 例 [1,2] (1:日限购 2:周限购 3:限购购买) 每日限购2次 player.gameData.storePack.storePackInfo[ count ].look = false --玩家是否看过该礼包(配合限时礼包) --同时添加该礼包的存在时间 player.gameData.storePack.storePackInfo[ count ].startTime = os.time() player.gameData.storePack.storePackInfo[ count ].failureTime = skynet.server.common:GetAfterSomeHour(triggeredGiftBagTime[2]) player.gameData.storePack.storePackInfo[ count ].IsShow = true --是否继续展示packLimit[0] = 3 ,即限制购买的礼包 默认为true self:SendIconPackToUser(player) end end end end end end end --如果有免费礼包可以获取则 商城显示红点 for k , v in pairs(self.StorePack) do if v.packType==6 then for k1 , v1 in pairs(player.gameData.storePack.storePackInfo) do --找到对应礼包 判断是否可以领取 if v.storeId==v1.storeId and v1.buyTimes==0 then if v.packUI==1 then skynet.server.msgTips:Add(player , 27) elseif v.packUI==2 then skynet.server.msgTips:Add(player , 28) elseif v.packUI==3 then skynet.server.msgTips:Add(player , 29) elseif v.packUI==4 then skynet.server.msgTips:Add(player , 30) end break end end end end --如果有限时礼包未查看 商城显示红点 local nowTime = os.time() for k , v in pairs(player.gameData.storePack.storePackInfo) do if v.look==false and v.IsShow then for k1 , v1 in pairs(self.StorePack) do if v.storeId==v1.storeId and nowTime>=v1.startTime then if v1.packUI==1 then skynet.server.msgTips:Add(player , 27) elseif v1.packUI==2 then skynet.server.msgTips:Add(player , 28) elseif v1.packUI==3 then skynet.server.msgTips:Add(player , 29) elseif v1.packUI==4 then skynet.server.msgTips:Add(player , 30) end end end end end end --商城显示 function Store:Show( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SStoreShow", c2sData.data )) local packUI = c2sData.data.packUI local data = {} data.packUI = packUI data.storeInfos = {} local nowTime = os.time() for k , v in pairs(self.StorePack) do --将满足条件的礼包进行显示 if v.packUI==packUI and nowTime>=v.startTime then --获取玩家对应的礼包数据 for k1 ,v1 in pairs(player.gameData.storePack.storePackInfo) do if v.storeId==v1.storeId and v1.look and v1.IsShow then if v1.failureTime==nil and v.failureTime==0 then table.insert(data.storeInfos , {storeId=v.storeId , buyTimes=v1.buyTimes , failureTime = v.failureTime , redDot = false}) elseif v1.failureTime==nil and v.failureTime~=0 and nowTime<=v.failureTime then table.insert(data.storeInfos , {storeId=v.storeId , buyTimes=v1.buyTimes , failureTime = v.failureTime , redDot = false}) elseif v1.failureTime~=nil and nowTime<=v1.failureTime then table.insert(data.storeInfos , {storeId=v.storeId , buyTimes=v1.buyTimes , failureTime = v1.failureTime , redDot = false}) end elseif v.storeId==v1.storeId and not v1.look and v1.IsShow then if v1.failureTime==nil and v.failureTime==0 then table.insert(data.storeInfos , {storeId=v.storeId , buyTimes=v1.buyTimes , failureTime = v.failureTime , redDot = true}) elseif v1.failureTime==nil and v.failureTime~=0 and nowTime<=v.failureTime then table.insert(data.storeInfos , {storeId=v.storeId , buyTimes=v1.buyTimes , failureTime = v.failureTime , redDot = true}) elseif v1.failureTime~=nil and nowTime<=v1.failureTime then table.insert(data.storeInfos , {storeId=v.storeId , buyTimes=v1.buyTimes , failureTime = v1.failureTime , redDot = true}) end self:DelRedDot(player , packUI) --修改玩家对应礼包的读取状态 v1.look=true end end end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_StoreShow") s2cData.data = assert(pb.encode("S2CStoreShow", data)) end --商城购买 function Store:Buy( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SStoreBuy", c2sData.data )) local storeId = c2sData.data.storeId local buyCount = c2sData.data.buyCount if buyCount<0 then buyCount = -buyCount end local data = {} data.storeInfo = {} data.buyCount = buyCount --判断是否进行发放物品 local nowTime = os.time() for k ,v in pairs(self.StorePack) do if v.storeId==storeId and nowTime >= v.startTime then log.info("找到对应的礼包" .. skynet.server.common:TableToString(v)) if v.price>0 and next(v.packExchange) == nil then --判断礼包是不是付费礼包 if player.gameData.storePack.storePackInfo[storeId]~=nil and player.gameData.storePack.storePackInfo[storeId].buyStatus then --if true then --判断该礼包有没有额外奖励 if next(v.packGift)~=nil then --将该礼包的奖励信息返回给客户端 并给该玩家增加对应的物品 for k1 ,v1 in pairs(player.gameData.storePack.storePackInfo) do --判断购买次数是否有限制 if v1.storeId==storeId and next(v1.packLimit)==nil then if v.packGift[ 1 ]==0 then --每次购买赠送 player:GiveReward(v.rewardId,buyCount) elseif v.packGift[ 1 ]==1 and player.gameData.storePack.storePackInfo[storeId].historyBuyTimes==0 then --首次购买赠送 player:GiveReward(v.rewardId,buyCount) end --原本应获取的物品 player:GiveReward(v.rewardId,buyCount) --修改玩家对应礼包的购买次数 self:ChangeBuyTimes( player , storeId) break elseif v1.storeId==storeId and v1.packLimit[2]-v1.buyTimes>=buyCount then --限制数-已购买数 >= 购买数 if v.packGift[ 1 ]==0 then --每次购买赠送 player:GiveReward(v.rewardId,buyCount) elseif v.packGift[ 1 ]==1 and player.gameData.storePack.storePackInfo[storeId].historyBuyTimes==0 then --首次购买赠送 player:GiveReward(v.rewardId,buyCount) end --原本应获取的物品 player:GiveReward(v.rewardId,buyCount) --修改玩家对应礼包的购买次数 self:ChangeBuyTimes( player , storeId) break elseif v1.storeId==storeId and v1.packLimit[2]-v1.buyTimes < buyCount then s2cData.code=errorInfo.ErrorCode.StorePackBuyError break end end else --将该礼包的奖励信息返回给客户端 并给该玩家增加对应的物品 for k1 ,v1 in pairs(player.gameData.storePack.storePackInfo) do if v1.storeId==storeId and next(v1.packLimit)==nil then --无限制 player:GiveReward(v.rewardId,buyCount) --修改玩家对应礼包的购买次数 self:ChangeBuyTimes( player , storeId) break elseif v1.storeId==storeId and v1.packLimit[2]-v1.buyTimes>=buyCount then --有限制 player:GiveReward(v.rewardId,buyCount) --修改玩家对应礼包的购买次数 self:ChangeBuyTimes( player , storeId) break elseif v1.storeId==storeId and v1.packLimit[2]-v1.buyTimes < buyCount then s2cData.code=errorInfo.ErrorCode.StorePackBuyError break end end end --发放奖励后将状态修改为false player.gameData.storePack.storePackInfo[storeId].buyStatus = false break else s2cData.code=errorInfo.ErrorCode.StorePackBuyError end elseif next(v.packExchange) ~= nil then --判断是不是兑换礼包 --判断该礼包是否是无限制的 if next(v.packLimit)~=nil then for k1 ,v1 in pairs(player.gameData.storePack.storePackInfo) do --判断是否还可以购买 if v.packLimit[ 2 ] - v1.buyTimes >=buyCount and v1.storeId==storeId then --先扣除玩家货币 local isSuccess = player:MoneyChange(v.packExchange[1] , -v.packExchange[2]*buyCount) --再增加对应的物品 if isSuccess~=false then player:GiveReward(v.rewardId,buyCount) self:ChangeBuyTimes( player , storeId ,buyCount) else s2cData.code=errorInfo.ErrorCode.StorePackBuyError end break end end else for k1 ,v1 in pairs(player.gameData.storePack.storePackInfo) do if v1.storeId==storeId then --先扣除玩家货币 local isSuccess = player:MoneyChange(v.packExchange[1] , -v.packExchange[2]*buyCount) --再增加对应的物品 if isSuccess~=false then player:GiveReward(v.rewardId,buyCount) self:ChangeBuyTimes( player , storeId ,buyCount) else s2cData.code=errorInfo.ErrorCode.StorePackBuyError end break end end end elseif v.packType==6 then --判断是不是免费礼包 --判断该礼包是否是无限制的 if next(v.packLimit)~=nil then for k1 ,v1 in pairs(player.gameData.storePack.storePackInfo) do if v1.storeId==storeId then --判断是否还可以购买 if v.packLimit[ 2 ]-v1.buyTimes >= buyCount then player:GiveReward(v.rewardId,buyCount) self:ChangeBuyTimes( player , storeId ,buyCount) --消除红点 self:DelRedDot( player , v.packUI) else s2cData.code=errorInfo.ErrorCode.StorePackBuyError end break end end end end break elseif v.storeId==storeId then s2cData.code=errorInfo.ErrorCode.StorePackBuyError break end end for k ,v in pairs(player.gameData.storePack.storePackInfo) do if storeId==v.storeId then data.storeInfo = {storeId=storeId , buyTimes=v.buyTimes , failureTime = v.failureTime ,redDot = false} end end --判断购买的礼包是否会触发相应礼包 for k , v in pairs(self.TriggerGiftBag) do if storeId==v then self:InitData(player) --主动推送一下对应礼包的packUI的信息 local c2sData1 = {} local s2cData1 = {} local showData = {} showData.packUI = self.StorePack[skynet.server.gameConfig.SValue.triggeredGiftBagTime[1]].packUI c2sData1.data = assert(pb.encode("C2SStoreShow", showData)) self:Show(player , c2sData1 , s2cData1) local data1 = assert(pb.decode("S2CStoreShow", s2cData1.data)) skynet.server.gameServer:SendMsgToUser(player.userId, "CMD_S2C_StoreShow", data1) end end --判断购买的礼包是否达到购买限制 若达到则不进行商城展示了 for k , v in pairs(player.gameData.storePack.storePackInfo) do if storeId == v.storeId and v.packLimit[1] == 3 and v.buyTimes>=v.packLimit [2] then v.IsShow = false end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_StoreBuy") s2cData.data = assert(pb.encode("S2CStoreBuy", data)) end --主动推送含有icon的可购买礼包 function Store:SendIconPackToUser( player ) local data = {} data.storeInfos ={} --找到该玩家还可以购买含有icon的所有礼包 for k , v in pairs(self.StorePack) do if v.icon ~= nil and v.icon~="" then for k1 , v1 in pairs(player.gameData.storePack.storePackInfo) do if v.storeId==v1.storeId and not v1.look and v1.buyTimes 0 then player:MoneyChange( dataType.MoneyType_Coin , cfgReward.coin ) log.info(string.format("玩家 %d 发放金币 %d" , player.userId,cfgReward.coin )) end if cfgReward.mapCoin > 0 then player:MoneyChange( dataType.MoneyType_Map , cfgReward.mapCoin ) log.info(string.format("玩家 %d 发放地图币 %d" , player.userId,cfgReward.mapCoin )) end if cfgReward.voluteCoin > 0 then player:MoneyChange( dataType.MoneyType_Volute , cfgReward.voluteCoin ) log.info(string.format("玩家 %d 发放蜗壳 %d" , player.userId,cfgReward.voluteCoin )) end --增加礼包中的物品奖励 if buyCount~=nil then for k ,v in pairs(reward) do --判断是不是抽奖卷 若是则直接增加,不通过礼包增加 if dataType.GoodsType_Prop == v.type then if ticket1 == v.id then player.gameData.design.ticket1 = player.gameData.design.ticket1 + buyCount*v.count elseif ticket2 == v.id then player.gameData.design.ticket2 = player.gameData.design.ticket2 + buyCount*v.count elseif ticket3 == v.id then player.gameData.design.ticket3 = player.gameData.design.ticket3 + buyCount*v.count end else skynet.server.bag:AddGoods(player , v.type , v.id , buyCount*v.count) end end else for k ,v in pairs(reward) do --判断是不是抽奖卷 若是则直接增加,不通过礼包增加 if dataType.GoodsType_Prop == v.type then if ticket1 == v.id then player.gameData.design.ticket1 = player.gameData.design.ticket1 + v.count elseif ticket2 == v.id then player.gameData.design.ticket2 = player.gameData.design.ticket2 + v.count elseif ticket3 == v.id then player.gameData.design.ticket3 = player.gameData.design.ticket3 + v.count end else skynet.server.bag:AddGoods(player , v.type , v.id , v.count) end end end end --修改玩家对应礼包的购买次数 function Store:ChangeBuyTimes( player , storeId , buyCount) for k ,v in pairs(player.gameData.storePack.storePackInfo) do if v.storeId==storeId and buyCount==nil then player.gameData.storePack.storePackInfo[storeId].buyTimes=player.gameData.storePack.storePackInfo[storeId].buyTimes+1 player.gameData.storePack.storePackInfo[storeId].historyBuyTimes=player.gameData.storePack.storePackInfo[storeId].historyBuyTimes+1 elseif v.storeId==storeId and buyCount~=nil then player.gameData.storePack.storePackInfo[storeId].buyTimes=player.gameData.storePack.storePackInfo[storeId].buyTimes+buyCount player.gameData.storePack.storePackInfo[storeId].historyBuyTimes=player.gameData.storePack.storePackInfo[storeId].historyBuyTimes+buyCount end end end --消除红点 function Store:DelRedDot( player , packUI) --消除红点 if packUI==1 then skynet.server.msgTips:Reduce(player , 27) elseif packUI==2 then skynet.server.msgTips:Reduce(player , 28) elseif packUI==3 then skynet.server.msgTips:Reduce(player , 29) elseif packUI==4 then skynet.server.msgTips:Reduce(player , 30) end end skynet.server.store = Store return Store