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

624 lines
19 KiB
Lua
Raw Permalink 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 dataType = require "DataType"
local errorInfo = require "ErrorInfo"
local activity = require "Activity"
local json =require "json"
local dataType = require "DataType"
local ActivitySignPack = oo.class()
ActivitySignPack.ActivityType = dataType.ActivityType_SignPack
--构造函数
function ActivitySignPack:Init()
end
-- 每次登录需要进行修改的数据
function ActivitySignPack:LoginInitData(player)
--判断模块是否开启
if not player:IsUnlockSystem( dataType.UnlockSystem_ActivitySignPack ) then
log.debug("限时签到模块未开启")
return
end
--活动结束
if self:CheckDataAndGetActivity(player) == nil then
--查询是否有补发需求
self:Reissue(player,0)
log.debug("限时签到活动已结束")
return
end
-- 处理红点
skynet.server.msgTips:Reset(player, 109)
--获取开启的活动
local activityId, startTime, endTime, id = activity:GetActivityInfo(player, ActivitySignPack.ActivityType)
--查询是否有补发需求{针对跨活动的情况}
self:Reissue(player,id)
log.debug("限时签到活动进行中")
end
--处理活动结束后补发奖励id活动id,全部检查传0
function ActivitySignPack:Reissue(player,id)
if player.gameData.SignPackMap == nil or not next(player.gameData.SignPackMap) then
return
end
local cfgActivitys = skynet.server.gameConfig:GetPlayerAllCfg(player, "Activity")
if cfgActivitys == nil then
return
end
--循环已经参加过的签到活动
for key, signPack in pairs(player.gameData.SignPackMap) do
if id ~= 0 and key == id then
log.debug("限时签到奖励补发,id ~= 0 and key == id")
break
end
--未参与过活动
if signPack == nil then
log.debug("限时签到奖励补发,signPack == nil")
break
end
local cfgActivity = nil
--获取配置
for _, cfgTemp in ipairs(cfgActivitys) do
if cfgTemp.id == key then
cfgActivity = cfgTemp
break
end
end
--是否存在活动
if cfgActivity == nil then
log.debug("限时签到奖励补发,cfgActivity == nil")
break
end
local startTime = skynet.server.common:GetTime(cfgActivity.startTime)
local endTime = skynet.server.common:GetTime(cfgActivity.endTime)
--未开始的活动,或者正在进行中的活动
if startTime > skynet.GetTime() or endTime > skynet.GetTime()then
log.debug("限时签到奖励补发,startTime >skynet.GetTime() or endTime<skynet.GetTime()")
break
end
--获取签到配置
local cfgSignPack = self:GetSignPackConfig(player,cfgActivity.activityId)
if cfgSignPack == nil then
log.debug("限时签到奖励补发,cfgSignPack == nil")
break
end
--判断是否全部领取,避免后续循环
if #cfgSignPack.normalReward == #signPack.normalRewardIds
and #cfgSignPack.payReward == #signPack.specialRewardIds then
log.debug("限时签到奖励补发,#cfgSignPack.normalReward == #signPack.normalRewardIds and #cfgSignPack.payReward == #signPack.specialRewardIds")
break
end
--当前活动登录天数
local curDay = math.ceil((signPack.LoginDate - skynet.server.common:GetTime(cfgActivity.startTime))/dataType.OneDaySec)
--邮件奖励
local award = {}
--普通奖励
for _, normalReward in ipairs(cfgSignPack.normalReward) do
--解析配置
local arr = skynet.server.common:Split(normalReward, "_")
local day=tonumber(arr[1])
local rewardid=tonumber(arr[2])
--判断是否已领取
for _, signDay in ipairs( signPack.normalRewardIds) do
if signDay==day then
log.debug("限时签到奖励补发,signDay==day")
goto coroutine
end
end
--是否可以领取
if curDay < day and not signPack.isBuySpecialReward then
log.debug("限时签到奖励补发,curDay < day and not signPack.isBuySpecialReward")
break
end
--以邮件形式发奖
local reward = skynet.server.playerLand:GetRewardInfo(player , rewardid)--对应的奖励信息
for _ ,v1 in pairs( reward ) do
table.insert(award , v1 )
end
--添加领取信息
table.insert(player.gameData.SignPackMap[key].normalRewardIds,day)
--跳出循环
::coroutine::
end
--是否购专属礼包
if signPack.isBuySpecialReward then
--专属奖励
for _, payReward in ipairs(cfgSignPack.payReward) do
--解析配置
local arr = skynet.server.common:Split(payReward, "_")
local day=tonumber(arr[1])
local rewardid=tonumber(arr[2])
--判断是否已领取
for _, signDay in ipairs(signPack.specialRewardIds) do
if signDay==day then
log.debug("限时签到奖励补发,signDay==day2")
goto coroutine
end
end
--以邮件形式发奖
local reward = skynet.server.playerLand:GetRewardInfo(player , rewardid)--对应的奖励信息
for _ ,v1 in pairs( reward ) do
table.insert(award , v1 )
end
--添加领取信息
table.insert(player.gameData.SignPackMap[key].specialRewardIds,day)
--跳出循环
::coroutine::
end
end
--是否需要补发奖励
if next(award) then
skynet.server.mail:AddNewMail( player , skynet.server.mail.MailType_Award,"签到奖励补发", "本次限时签到活动已经结束,小蜗们忘记领取的签到奖励已经通过邮件发放咯,请小蜗们及时领取~", award, true)
log.debug(string.format("玩家 %d 限时签到奖励补发", player.userId ))
end
end
end
--初始玩家数据,返回活动信息,
function ActivitySignPack:CheckDataAndGetActivity(player)
--默认空活动
local cfgSignPack = nil
if player==nil then
log.debug("限时签到CheckDataAndGetActivity player is nil")
return cfgSignPack
end
--判断等级是否开启
if not player:IsUnlockSystem( dataType.UnlockSystem_ActivitySignPack) then
log.debug("限时签到等级不足")
return cfgSignPack
end
--获取开启的活动
local activityId, startTime, endTime, id = activity:GetActivityInfo(player, ActivitySignPack.ActivityType)
--没有开启的活动
if activityId == 0 then
log.debug("限时签到未开启-未获取到有效的活动1")
return cfgSignPack
end
--初始化
if player.gameData.SignPackMap==nil then
player.gameData.SignPackMap={}
end
--获取活动配置
cfgSignPack=self:GetSignPackConfig(player,activityId)
--未获取到有效的活动
if cfgSignPack == nil then
log.debug("限时签到未开启-未获取到有效的活动2")
return cfgSignPack
end
--如果玩家已经存在活动不需要检查
if player.gameData.SignPackMap[id] then
player.gameData.SignPackMap[id].LoginDate = skynet.GetTime() --更新登录时间 补发奖励用
--删除过期活动,减少数据产生
local removeKeyList = {}
for exceedId, _ in pairs(player.gameData.SignPackMap) do
if exceedId ~= id then
table.insert(removeKeyList, exceedId)
end
end
if next(removeKeyList) then
for _, removeKey in ipairs(removeKeyList) do
player.gameData.SignPackMap[removeKey]=nil
end
end
return cfgSignPack
end
--存在活动初始化玩家数据
local playerActivitySignPack = {}
playerActivitySignPack.activityId = cfgSignPack.activityId
playerActivitySignPack.normalRewardIds = {} --普通奖励领取列表
playerActivitySignPack.specialRewardIds = {} --专属奖励领取列表
playerActivitySignPack.isBuySpecialReward = false --是否购买专属奖励
playerActivitySignPack.LoginDate = skynet.GetTime() --登录天数
--更新缓存
player.gameData.SignPackMap[id] = playerActivitySignPack
return cfgSignPack
end
--可领取奖励列表
function ActivitySignPack:GetConDrawReward(player)
--可领取奖励
local conNormalRewardIds={}
local conSpecialRewardIds={}
--不存在开启的活动
local cfgSignPack=self:CheckDataAndGetActivity(player)
--活动未开启
if cfgSignPack == nil then
log.debug("限时签到未开启-未获取到有效的活动")
return conNormalRewardIds,conSpecialRewardIds
end
--获取开启的活动
local activityId, startTime, endTime, id = activity:GetActivityInfo(player, ActivitySignPack.ActivityType)
--获取当前活动开启天数
local thenDay = self:GetActivityDay(player,id)
--循环普通奖励
for _, normalRewardItemStr in ipairs(cfgSignPack.normalReward) do
--解析配置
local arr = skynet.server.common:Split(normalRewardItemStr, "_")
local day=tonumber(arr[1])
local rewardId = tonumber(arr[2])
--空奖励 进入下一个循环
if rewardId == 0 then
goto coroutine
end
--判断天数
if day > thenDay then
goto coroutine
end
--检查配置
if #arr ~= 2 then
log.debug(string.format("限时签到配置错误 normalRewardItemStr%d",normalRewardItemStr))
goto coroutine
end
local isCon = false
--循环判断是否领取
for _, value in ipairs(player.gameData.SignPackMap[id].normalRewardIds) do
if value == day then
isCon = true
break
end
end
if not isCon then
table.insert(conNormalRewardIds,day)
end
::coroutine::
end
--专属奖励
if player.gameData.SignPackMap[id].isBuySpecialReward then
--循环专属奖励
for _, specialRewardItemStr in ipairs(cfgSignPack.payReward) do
--解析配置
local arr = skynet.server.common:Split(specialRewardItemStr, "_")
local day=tonumber(arr[1])
local rewardId = tonumber(arr[2])
--空奖励 直接进入下一个循环
if rewardId == 0 then
goto coroutine
end
--判断天数
if day > thenDay then
goto coroutine
end
--检查配置
if #arr ~= 2 then
log.debug(string.format("限时签到配置错误 specialRewardItemStr%d",specialRewardItemStr))
goto coroutine
end
local isCon = false
--循环判断是否领取
for _, value in ipairs(player.gameData.SignPackMap[id].specialRewardIds) do
if value == day then
isCon = true
break
end
end
if not isCon then
table.insert(conSpecialRewardIds,day)
end
::coroutine::
end
end
return conNormalRewardIds,conSpecialRewardIds
end
--获取签到当天天数 theActivityid 当前活动id
function ActivitySignPack:GetActivityDay(player,theActivityid)
--获取开启的活动
local activityId, startTime, endTime, id = activity:GetActivityInfo(player, ActivitySignPack.ActivityType)
if activityId == 0 or theActivityid ~= id then
return 0
end
local startTimeDate = os.date("*t", startTime)
--由于活动开启时间是10点这里统计时间设置成0点
local startTimeTemp=os.time({ year = startTimeDate.year, month = startTimeDate.month, day=startTimeDate.day, hour=0, min=0, sec=0 })
--计算当前是哪天
local day =math.ceil((skynet.GetTime()-startTimeTemp)/dataType.OneDaySec)
log.debug(string.format("获取限时签到天数 day:%d",day))
return day
end
--获取配置信息
function ActivitySignPack:GetSignPackConfig(player,activityId)
local cfSignPack=nil
--获取该活动的默认初始关卡
local cfSignPacks=skynet.server.gameConfig:GetPlayerAllCfg(player, "SignPack")
if cfSignPacks==nil then
log.debug("cfSignPacks is nil")
return cfSignPack
end
for index, value in pairs(cfSignPacks) do
if value.id==activityId then
cfSignPack=value
break
end
end
return cfSignPack
end
--是否付费签到
function ActivitySignPack:ChangeStore(player,storeId)
--检查显示是否开启
local cfgSignPack=self:CheckDataAndGetActivity(player)
if cfgSignPack == nil then
return
end
-- 活动不匹配
if cfgSignPack.packId ~= storeId then
return
end
--获取开启的活动
local activityId, startTime, endTime, id = activity:GetActivityInfo(player, ActivitySignPack.ActivityType)
--设置已付费
player.gameData.SignPackMap[id].isBuySpecialReward = true
-- 处理红点
local conNormalRewardIds,conSpecialRewardIds =self:GetConDrawReward(player)
if next(conNormalRewardIds) or next(conSpecialRewardIds) then
skynet.server.msgTips:Add(player,109)
end
end
--获取限时签到信息
function ActivitySignPack:Show( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SignPackShow", c2sData.data ))
s2cData.cmd = pb.enum("MsgType","CMD_S2S_ActivitySignPackShow")
local data = {}
--检查并且获取活动信息
local cfgSignPack=self:CheckDataAndGetActivity(player)
if cfgSignPack == nil then
s2cData.code = errorInfo.ErrorCode.ActivityClosed
return
end
--获取开启的活动
local activityId, startTime, endTime, id = activity:GetActivityInfo(player, ActivitySignPack.ActivityType)
local startDate=os.date("%Y-%m-%d",startTime)
local startTimeStamp=os.time({year=string.sub(startDate,1,4), month=string.sub(startDate,6,7), day=string.sub(startDate,9,10)})
local nowDate=os.date("%Y-%m-%d",skynet.GetTime())
local nowTimeStamp=os.time({year=string.sub(nowDate,1,4), month=string.sub(nowDate,6,7), day=string.sub(nowDate,9,10)})
data.openDay=math.floor((nowTimeStamp - startTimeStamp) / (24 * 60 * 60))+1
data.normalRewardIds=player.gameData.SignPackMap[id].normalRewardIds
data.specialRewardIds=player.gameData.SignPackMap[id].specialRewardIds
data.isBuySpecialReward=player.gameData.SignPackMap[id].isBuySpecialReward
--返回信息
s2cData.data = assert(pb.encode("S2SignPackShow", data))
end
--领取签到奖励(客户端)
function ActivitySignPack:DrawReward( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SignPackDrawReward", c2sData.data ))
s2cData.cmd = pb.enum("MsgType","CMD_S2S_ActivitySignPackDrawReward")
--参数 奖励类型 1 普通奖励 2 专属奖励
local rewardType = c2sData.data.rewardType
local day = c2sData.data.day
local data = {}
data.rewardType = rewardType
data.day = day
--获取可领取的奖励
local normalRewardIds,specialRewardIds=self:GetConDrawReward(player)
if rewardType == 1 and not next(normalRewardIds) then
s2cData.code = errorInfo.ErrorCode.NotGet
return
end
if rewardType == 2 and not next(specialRewardIds) then
s2cData.code = errorInfo.ErrorCode.NotGet
return
end
--获取开启的活动
local activityId, startTime, endTime, id = activity:GetActivityInfo(player, ActivitySignPack.ActivityType)
--获取活动配置
local cfgSignPack=self:GetSignPackConfig(player,activityId)
--是否可领取
local isConGet = false
local rewardId = tonumber(0)
--普通奖励
if rewardType == 1 then
--判断是否已经领取
for _, value in ipairs(player.gameData.SignPackMap[id].normalRewardIds) do
if value == day then
s2cData.code = errorInfo.ErrorCode.NotGet
return
end
end
--判断是否包含可领取奖励
for _, normalRewardId in ipairs(normalRewardIds) do
if normalRewardId == day then
isConGet = true
break
end
end
--查找奖励
for _, normalRewardItemStr in ipairs(cfgSignPack.normalReward) do
--解析配置
local arr = skynet.server.common:Split(normalRewardItemStr, "_")
if day == tonumber(arr[1]) then
rewardId = tonumber(arr[2])
break
end
end
--发奖
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_123")
player:GiveReward(rewardId ,eventId,1)
--添加奖励
if isConGet then
table.insert(player.gameData.SignPackMap[id].normalRewardIds,day)
end
elseif rewardType == 2 then--专属奖励
--判断是否已经领取
for _, value in ipairs(player.gameData.SignPackMap[id].specialRewardIds) do
if value == day then
s2cData.code = errorInfo.ErrorCode.NotGet
return
end
end
--判断是否包含可领取奖励
for _, specialRewardId in ipairs(specialRewardIds) do
if specialRewardId == day then
isConGet = true
break
end
end
--查找奖励
for _, payRewardItemStr in ipairs(cfgSignPack.payReward) do
--解析配置
local arr = skynet.server.common:Split(payRewardItemStr, "_")
if day == tonumber(arr[1]) then
rewardId = tonumber(arr[2])
break
end
end
--发奖
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_123")
player:GiveReward(rewardId ,eventId,1)
--添加奖励
if isConGet then
table.insert(player.gameData.SignPackMap[id].specialRewardIds,day)
end
else
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
return
end
-- 处理红点
local conNormalRewardIds,conSpecialRewardIds=self:GetConDrawReward(player)
if not next(conNormalRewardIds) and not next(conSpecialRewardIds) then
skynet.server.msgTips:ReduceAll(player, 109)
end
--返回信息
s2cData.data = assert(pb.encode("S2SignPackDrawReward", data))
end
skynet.server.activitySignPack = ActivitySignPack
return ActivitySignPack