HomeServer/Server/AllServer/GameServer/Redeem.lua
2024-11-20 15:41:37 +08:00

211 lines
10 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local skynet = require "skynet"
local oo = require "Class"
local log = require "Log"
local pb = require "pb"
local redisKeyUrl = require "RedisKeyUrl"
local sqlUrl = require "SqlUrl"
local dataType = require "DataType"
local json =require "json"
local errorInfo = require "ErrorInfo"
local Redeem = oo.class()
Redeem.RedeemOpType_1 = 1 --获取兑换列表
Redeem.RedeemOpType_2 = 2 --查阅/领取奖品
Redeem.ExchangeType_First = 1 --初次兑换
Redeem.ExchangeType_Error = 2 --兑换异常再次尝试
Redeem.RedeemQueue={} --兑换码缓存队列
--[[
后台code
SUCCESS(200,"操作成功"),
REDEEM_CODE_NOT_NULL(601,"礼包ID或玩家ID不能为空"),
REDEEM_CODE_NOT_USE(602,"兑换码已停止使用"),
REDEEM_CODE_FULL_USE(603,"兑换码已全部兑换"),
REDEEM_CODE_TIME_FAILURE(604,"兑换码时间失效"),
REDEEM_CODE_PLAYER_USED(605,"该玩家已兑换"),
]]
function Redeem:Init()
end
--获取兑换历史
function Redeem:History( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SRedeemHistory", c2sData.data ))
local data = {}
data.historyInfo = {}
for k,v in pairs(player.gameData.redeem.redeemList) do
table.insert(data.historyInfo , { redeemCode = v.redeemCode , award = v.award , gainTime = v.gainTime})
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_RedeemHistory")
s2cData.data = assert(pb.encode("S2CRedeemHistory", data))
end
--兑换码领取奖励
function Redeem:Award( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SRedeemAward", c2sData.data ))
local data = {}
local redeemCode = c2sData.data.redeemCode
if not redeemCode then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local upperRedeemCode = string.upper(redeemCode) --将小写转化未大写
local hasHistory = false
--此处可以先遍历历史兑换码,省去数据库查询
for k,v in pairs(player.gameData.redeem.redeemList) do
if v.redeemCode == upperRedeemCode then
hasHistory = true
break
end
end
if hasHistory then
s2cData.code = errorInfo.ErrorCode.AlreadyGetRedeem
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
else
--判断是否有过兑换异常的记录
local exchangeStatus = self.ExchangeType_First
if next(player.gameData.redeem.redeemRequestList) ~= nil then
for k,v in pairs(player.gameData.redeem.redeemRequestList) do
if v.redeemCode == upperRedeemCode then
exchangeStatus = v.status
table.remove(player.gameData.redeem.redeemRequestList,k)
break
end
end
end
data.redeemCode = upperRedeemCode
local cgi = player.basicInfo.gameCgi
local channel = player.basicInfo.channel
local appVersion = player.basicInfo.appVersion
--向后端请求
local param = { giftId = upperRedeemCode, playerId = player.account, gameId = cgi, useChannel = channel , minVersion = appVersion , status = exchangeStatus }
local web = skynet.server.gameConfig.WebConfig.host .. ":" .. skynet.server.gameConfig.WebConfig.port
local url = skynet.server.common.redeemUrl
local status,body,isSuc = skynet.server.httpClient:PostJson( web , url , json:encode(param),"http")
if isSuc then
local newbody = json:decode(body)
if 200 == status and 200 == newbody.code then
--判断返回结果如果包含了兑换码信息则说明是特殊兑换码,特殊处理
if newbody.data.giftArticles ~= nil and next(newbody.data.giftArticles) ~= nil then
self:Bonus( player , upperRedeemCode , newbody.data.giftArticles , data)
--请求成功的时候将传回来的兑换码奖励信息存进缓存里,用作请求失败玩家的兑换补发依据(暂时只补偿特殊兑换码,可以保证一码对多,普通兑换码可能是一对一)
if newbody.data.redeemCodeModel.specialTag == 1 then
if not self.RedeemQueue[upperRedeemCode] then
self.RedeemQueue[upperRedeemCode] = newbody.data.giftArticles
end
end
else
self:Bonus( player , upperRedeemCode , newbody.data , data)
end
else
if 607 == newbody.code then
s2cData.code = errorInfo.ErrorCode.RedeemNoStart
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
elseif 605 == newbody.code then
s2cData.code = errorInfo.ErrorCode.AlreadyGetRedeem
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
elseif 604 == newbody.code then
s2cData.code = errorInfo.ErrorCode.RedeemOutDate
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
elseif 603 == newbody.code then
s2cData.code = errorInfo.ErrorCode.RedeemFullUse
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
elseif 602 == newbody.code then
s2cData.code = errorInfo.ErrorCode.NoRedeemID
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
end
end
else
--处理请求失败时的异常,从特殊兑换码缓存中取奖励内容,有的话直接发放对应奖励
if next(self.RedeemQueue)~=nil and self.RedeemQueue[upperRedeemCode]~=nil then
self:Bonus( player , upperRedeemCode , self.RedeemQueue[upperRedeemCode] , data)
else
--没有的话判断兑换码长度小于12时一般是特殊兑换码则返回兑换失败稍后重试
if #upperRedeemCode ~= 12 then
s2cData.code = errorInfo.ErrorCode.RedeemFullUse
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
else
s2cData.code = errorInfo.ErrorCode.RedeemFailed
s2cData.desc = errorInfo.ErrorMsg[s2cData.code]
table.insert(player.gameData.redeem.redeemRequestList,{ redeemCode = upperRedeemCode , status = self.ExchangeType_Error })
end
end
end
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_RedeemAward")
s2cData.data = assert(pb.encode("S2CRedeemAward", data))
end
--发放兑换奖励
function Redeem:Bonus( player , redeemCode , bonus , data )
data.award = {}
for k, v in pairs(bonus) do
local goodsType = skynet.server.common:AwardTypeStrToInt(v.articlesType)
--货币直接发放相应数量就行
if goodsType == dataType.GoodsType_Init or goodsType == dataType.GoodsType_RewardId then
if dataType.GoodsType_Coin == v.articlesId then
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_38")
player:MoneyChange( pb.enum("EnumGoodsType","Coin") , v.articlesNumber , eventId)
elseif dataType.GoodsType_Clovers == v.articlesId then
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_38")
player:MoneyChange( pb.enum("EnumGoodsType","Clovers") , v.articlesNumber , eventId )
elseif dataType.GoodsType_Volute == v.articlesId then
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_38")
player:MoneyChange( pb.enum("EnumGoodsType","VoluteCoin") , v.articlesNumber , eventId )
elseif dataType.GoodsType_Fragment == v.articlesId then
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_38")
player:MoneyChange( pb.enum("EnumGoodsType","Fragment") , v.articlesNumber , eventId )
elseif dataType.GoodsType_RewardId == goodsType then
local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_38")
player:GiveReward( v.articlesId , eventId )
end
elseif goodsType >= dataType.GoodsType_Furniture and goodsType <= dataType.GoodsType_End then
skynet.server.bag:AddGoods( player , goodsType , v.articlesId, v.articlesNumber )
end
if goodsType == dataType.GoodsType_Init then
table.insert( data.award , { type = v.articlesId , count = v.articlesNumber } )
else
table.insert( data.award , { type = goodsType , id = v.articlesId , count = v.articlesNumber } )
end
log.debug(string.format("玩家 %d 兑换码 %s 领取奖励 类型 %d ID %d 数量 %d" , player.userId , redeemCode , goodsType , v.articlesId , v.articlesNumber))
end
self:AddHistory( player , redeemCode , data.award )
end
--添加兑换码历史
function Redeem:AddHistory( player , redeemCode , award )
--插入到玩家兑换列表中
local curIndex = player.gameData.redeem.curIndex
player.gameData.redeem.redeemList[ curIndex ] = {}
player.gameData.redeem.redeemList[ curIndex ].redeemCode = redeemCode
player.gameData.redeem.redeemList[ curIndex ].award = award
player.gameData.redeem.redeemList[ curIndex ].gainTime = skynet.GetTime() -- skynet.server.common:GetStrTime(skynet.GetTime())
--玩家最多150条最近的兑换码记录
player.gameData.redeem.curIndex = player.gameData.redeem.curIndex + 1
if player.gameData.redeem.curIndex >= 150 then
player.gameData.redeem.curIndex = 1
end
end
--修复扩容兑换码游标问题
function Redeem:FixRedeemCursor( player )
if player.gameData.redeem.redeemList ~= nil and next(player.gameData.redeem.redeemList) ~= nil then
if #player.gameData.redeem.redeemList >= 30 then
player.gameData.redeem.curIndex = #player.gameData.redeem.redeemList + 1
end
end
end
skynet.server.redeem = Redeem
return Redeem