HomeServer/lualib-src/Server-main/AllServer/GameServer/PassCheck.lua

632 lines
25 KiB
Lua
Raw Normal View History

2024-11-20 15:41:09 +08:00
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 PassCheck = oo.class()
PassCheck.RewardType_Normal = 1 --普通奖励
PassCheck.RewardType_Pay = 2 --付费奖励
PassCheck.TaskType_Normal = 1 --常规任务
PassCheck.TaskType_LimitTime = 2 --限时任务
PassCheck.TaskType_Daily = 3 --每日任务
PassCheck.surplusTime = 100 --剩余时间
PassCheck.MaxShowItem = 4 --任务最大显示多少个
function PassCheck:Init()
end
--初始化数据
function PassCheck:CheckNew( player )
if not player:IsUnlockSystem( dataType.UnlockSystem_PassCheck ) then
return
end
--根据开始和结束时间找到当期的任务
local curCfgPassCheck = self:GetCurPeriodCfg( player )
local passCheck = player.gameData.passCheck
if curCfgPassCheck and curCfgPassCheck.id ~= passCheck.curId then
--新的一期初始化数据
passCheck.curId = curCfgPassCheck.id --获取最新的通行证ID
passCheck.rewards = {}
passCheck.tasks = {}
passCheck.score = 0
passCheck.isVip = false
passCheck.infiniteRewardCount = 0
local cfgPassCheckClass = skynet.server.gameConfig.PassCheckClass --奖励配置
for k, v in pairs( cfgPassCheckClass ) do
if curCfgPassCheck.id == v.passCheckId then
table.insert( passCheck.rewards , { id = v.id , normalStatus = dataType.RewardStatus_NoGet , payStatus = dataType.RewardStatus_NoGet })
end
end
local tmpCfgPassCheckTask = self:GetRandTask( player , curCfgPassCheck )
for k, v in pairs( tmpCfgPassCheckTask ) do
--任务类型(注意配置中用的是taskTime),任务种类,当前进度,是否完成
if self.TaskType_Normal == v.taskTime then
--if v.id >=1 and v.id <= 18 then
-- table.insert( passCheck.tasks , { id = v.id , type = v.taskTime , kind = v.taskType , progress = 0 , status = skynet.server.task.TaskStatus_AlreadyGet})
--else
table.insert( passCheck.tasks , { id = v.id , type = v.taskTime , kind = v.taskType , progress = 0 , status = skynet.server.task.TaskStatus_NoComplete})
--end
elseif self.TaskType_LimitTime == v.taskTime then
--if v.id >=21 and v.id <= 39 then
-- table.insert( passCheck.tasks , { id = v.id , type = v.taskTime , kind = v.taskType , progress = 0 , status = skynet.server.task.TaskStatus_OutOfTime , endTime = 0})
--else
table.insert( passCheck.tasks , { id = v.id , type = v.taskTime , kind = v.taskType , progress = 0 , status = skynet.server.task.TaskStatus_NoComplete , endTime = 0})
--end
elseif self.TaskType_Daily == v.taskTime then
table.insert( passCheck.tasks , { id = v.id , type = v.taskTime , kind = v.taskType , progress = 0 , status = skynet.server.task.TaskStatus_NoComplete })
end
end
end
end
--通行证奖励显示
function PassCheck:RewardShow( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPassCheckRewardShow", c2sData.data ))
local passCheck = player.gameData.passCheck
local data = {}
data.basicInfo = { score = passCheck.score , surplusTime = self.surplusTime , passCheckId = passCheck.curId }
data.rewards = passCheck.rewards
data.isVip = passCheck.isVip
data.infiniteRewardCount = passCheck.infiniteRewardCount
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PassCheckRewardShow")
s2cData.data = assert(pb.encode("S2CPassCheckRewardShow", data))
end
--获得当前期配置
function PassCheck:GetCurPeriodCfg( player )
local curCfgPassCheck = nil
local cfgPassCheck = skynet.server.gameConfig.PassCheck
for k, v in pairs(cfgPassCheck) do
local startTime = skynet.server.common:GetTime( v.startTime )
local endTime = skynet.server.common:GetTime( v.endTime )
if skynet.GetTime() >= startTime and skynet.GetTime() <= endTime then
curCfgPassCheck = v --获取当前通行证ID
break
end
end
return curCfgPassCheck
end
--随机任务
function PassCheck:GetRandTask( player , curCfgPassCheck )
--打乱现有配置顺序
local cfgPassCheckTask = skynet.server.gameConfig.PassCheckTask --任务配置
local tmpCfgPassCheckTask = {}
for k, v in pairs(cfgPassCheckTask) do
--每日任务直接加入
if self.TaskType_Daily == v.taskTime then
v.randValue = 0
table.insert(tmpCfgPassCheckTask , v)
else
--常规和限时任务部分任务才能加入
if self:IsJoinTask( curCfgPassCheck , v.taskTime , v.id ) then
v.randValue = math.random(1,1000)
table.insert(tmpCfgPassCheckTask , v)
end
end
end
--根据随机值进行排序
table.sort(tmpCfgPassCheckTask , function (a,b)
if a.randValue >b.randValue then --降序
return
end
end)
return tmpCfgPassCheckTask
end
--获取普通奖励信息
function PassCheck:GetNormalReward( player , rewardId )
local isGainReward = false
local getRewardIds = {} --奖励的信息
local passCheck = player.gameData.passCheck
local curCfgPassCheckClass = skynet.server.gameConfig:GetCurCfg("PassCheckClass" , rewardId )
local curCfgPassCheck = skynet.server.gameConfig:GetCurCfg("PassCheck" , passCheck.curId )
--获取当前奖励信息
local curReward = {}
for k, v in pairs( passCheck.rewards ) do
if rewardId == v.id then
curReward = v
break
end
end
--非无限奖励领奖
if dataType.RewardStatus_CanGet == curReward.normalStatus then --普通奖励
for k, v in pairs( curCfgPassCheckClass.normalReward ) do
table.insert( getRewardIds , v )
end
curReward.normalStatus = dataType.RewardStatus_AlreadyGet
isGainReward =true
log.info(string.format("玩家 %d 通行证 普通奖励获取 奖励ID %d" , player.userId, rewardId))
end
if passCheck.isVip and dataType.RewardStatus_CanGet == curReward.payStatus then --付费奖励
for k, v in pairs( curCfgPassCheckClass.payReward ) do
table.insert( getRewardIds , v )
end
curReward.payStatus = dataType.RewardStatus_AlreadyGet
isGainReward =true
log.info(string.format("玩家 %d 通行证 付费奖励获取 奖励ID %d", player.userId , rewardId))
end
--发奖
for k, v in pairs( getRewardIds ) do
player:GiveReward( v )
end
return getRewardIds,isGainReward
end
--获取无限奖励信息
function PassCheck:GetInfiniteReward( player , rewardId , s2cData)
local isGainReward = false
local getRewardIds = {} --奖励的信息
local passCheck = player.gameData.passCheck
local curCfgPassCheckClass = skynet.server.gameConfig:GetCurCfg("PassCheckClass" , rewardId )
local curCfgPassCheck = skynet.server.gameConfig:GetCurCfg("PassCheck" , passCheck.curId )
local data = {}
if passCheck.infiniteRewardCount >= curCfgPassCheck.ultimateLimit then
s2cData.code = errorInfo.ErrorCode.MaxLimit
elseif not passCheck.isVip then
return data,isGainReward
else
--获取当前奖励信息
local curReward = {}
for k, v in pairs( passCheck.rewards ) do
if rewardId == v.id then
curReward = v
break
end
end
if dataType.RewardStatus_CanGet == curReward.normalStatus then --普通奖励
--发奖
local weight = curCfgPassCheckClass.ultimateRewardWeight
local allWeight = 0
--计算权重总数
for k, v in pairs( weight ) do
allWeight = allWeight + v
end
--在1和总权重进行随机
local rand = math.random(1 , allWeight)
log.info(string.format("玩家 %d 通行证 随机值 %d 随机区间[ %d , %d ]" , player.userId , rand , 1, allWeight))
local curCount = 0
local weightIndex = 0
for k, v in pairs( weight ) do
curCount = curCount + v
if rand <= curCount then
weightIndex = k
break
end
end
for k, v in pairs( curCfgPassCheckClass.ultimateReward ) do
data = player:SelectOneReward( v , weightIndex)
end
passCheck.infiniteRewardCount = passCheck.infiniteRewardCount + 1
--无线领奖状态修改为已获取
if passCheck.infiniteRewardCount >= curCfgPassCheck.ultimateLimit then
curReward.payStatus = dataType.RewardStatus_AlreadyGet
end
isGainReward = true
log.info(string.format("玩家 %d 通行证 无限奖励获取 奖励索引 %d" , player.userId , weightIndex))
end
return data,isGainReward
end
end
--通行证奖励获取
function PassCheck:RewardGet( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPassCheckRewardGet", c2sData.data ))
local rewardId = c2sData.data.rewardId
local data = {}
data.gainRewards = {}
data.infiniteMoneys = {}
if not rewardId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local getRewardIds = {} --获取奖励的ID
local passCheck = player.gameData.passCheck
local getRewardIds = {}
if 0 == rewardId % 31 then
local rewardInfo,isGainReward = self:GetInfiniteReward( player , rewardId , s2cData )
if isGainReward then
table.insert( data.infiniteMoneys ,rewardInfo )
end
else
data.gainRewards = self:GetNormalReward( player , rewardId ) --当前奖励信息
end
for k, v in pairs( passCheck.rewards ) do
if rewardId == v.id then
data.reward = v
break
end
end
data.infiniteRewardCount = passCheck.infiniteRewardCount
end
self:CheckMsgTips( player )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PassCheckRewardGet")
s2cData.data = assert(pb.encode("S2CPassCheckRewardGet", data))
end
--通行证奖励一键获取
function PassCheck:RewardAllGet( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPassCheckRewardAllGet", c2sData.data ))
local data = {}
data.rewards = {}
data.gainRewards = {}
data.infiniteMoneys = {}
local getRewardIds = {} --获取奖励的ID
local passCheck = player.gameData.passCheck
for k1, v1 in pairs( passCheck.rewards ) do
if 0 == v1.id % 31 then
local curCfgPassCheck = skynet.server.gameConfig:GetCurCfg("PassCheck" , passCheck.curId )
local gainCount = curCfgPassCheck.ultimateLimit - passCheck.infiniteRewardCount
if gainCount > 0 then
for i = 1, gainCount, 1 do
local rewardInfo,isGainReward = self:GetInfiniteReward( player , v1.id , s2cData )
if isGainReward then
table.insert( data.infiniteMoneys ,rewardInfo )
table.insert( data.rewards , v1 )
end
end
end
else
local gainRewards,isGainReward = self:GetNormalReward( player , v1.id ) --当前奖励信息
for k, v in pairs(gainRewards) do
table.insert(data.gainRewards ,v)
end
if isGainReward then
table.insert( data.rewards , v1 )
end
end
end
self:CheckMsgTips( player )
data.infiniteRewardCount = passCheck.infiniteRewardCount
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PassCheckRewardAllGet")
s2cData.data = assert(pb.encode("S2CPassCheckRewardAllGet", data))
end
--通行证任务显示
function PassCheck:TaskShow( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPassCheckTaskShow", c2sData.data ))
local taskType = c2sData.data.taskType
local data = {}
if not taskType then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local passCheck = player.gameData.passCheck
data.taskType = taskType
data.basicInfo = { score = passCheck.score , surplusTime = self.surplusTime }
--获取任务信息
data.taskInfos = self:GetShowTaskData( player , taskType )
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PassCheckTaskShow")
s2cData.data = assert(pb.encode("S2CPassCheckTaskShow", data))
end
--通行证任务获取
function PassCheck:TaskGet( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPassCheckTaskGet", c2sData.data ))
local taskType = c2sData.data.taskType
local taskId = c2sData.data.taskId
local data = {}
if not taskType or not taskId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local passCheck = player.gameData.passCheck
local curTask = self:GetTaskInfo( player , taskType , taskId )
if curTask.status == skynet.server.task.TaskStatus_AlreadyComplete then --已经完成才能领取
local curCfgPassCheckTask = skynet.server.gameConfig:GetCurCfg("PassCheckTask" , taskId )
local passCheck = player.gameData.passCheck
passCheck.score = passCheck.score + curCfgPassCheckTask.taskPoint
--领取了积分修改已经领取状态
curTask.status = skynet.server.task.TaskStatus_AlreadyGet
--检查下普通和付费奖励是否能领取
self:CheckNormalReward( player )
self:CheckPayReward( player )
log.info(string.format("玩家 %d 通行证 任务完成领取积分 任务ID %d" , player.userId ,taskId))
else
s2cData.code = errorInfo.ErrorCode.GetAwardFailed
end
data.taskType = taskType
data.basicInfo = { score = passCheck.score , surplusTime = self.surplusTime }
data.taskInfo = self:GetShowTaskData( player , taskType )
end
self:CheckMsgTips( player )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PassCheckTaskGet")
s2cData.data = assert(pb.encode("S2CPassCheckTaskGet", data))
end
--通行证充值
function PassCheck:Pay( player , storeId )
local passCheck = player.gameData.passCheck
passCheck.isVip = true --开起VIP
--充值了,检查下玩家的是否能领取付费礼包
self:CheckPayReward( player )
end
--通行证修改任务
function PassCheck:Modify( player , kind , count )
if not player:IsUnlockSystem( dataType.UnlockSystem_PassCheck ) then
return
end
log.info(string.format("玩家 %d 通行证 任务修改 种类 %d 数量 %d" , player.userId , kind , count ))
local maxProgress = 0
local passCheck = player.gameData.passCheck
for k, v in pairs( passCheck.tasks ) do
if (self.TaskType_Normal == v.type or self.TaskType_LimitTime == v.type) and kind == v.kind and skynet.server.task.TaskStatus_NoComplete == v.status and self:IsShowTask( player , v.type , v.id ) then
--获取最大进度
maxProgress = skynet.server.gameConfig:GetCurCfg("PassCheckTask" , v.id ).taskNum
v.progress = v.progress + count
--检查是否完成任务
if v.progress >= maxProgress then
v.status =skynet.server.task.TaskStatus_AlreadyComplete
self:CheckMsgTips( player )
v.progress = maxProgress
log.info(string.format("玩家 %d 通行证 任务种类 %d 任务ID %d 完成 " , player.userId , kind ,v.id))
end
end
end
--每日任务统计
for k, v in pairs( passCheck.tasks ) do
if self.TaskType_Daily == v.type and kind == v.kind then
local curCfgPassCheckTask = skynet.server.gameConfig:GetCurCfg("PassCheckTask" , v.id )
if v.progress < curCfgPassCheckTask.limit then
--每日任务直接更新积分
v.progress = v.progress + 1
passCheck.score = passCheck.score + curCfgPassCheckTask.taskPoint
--检查下普通和付费奖励是否能领取
self:CheckNormalReward( player )
self:CheckPayReward( player )
log.info(string.format("玩家 %d 通行证 任务种类 %d 任务ID %d 完成 " , player.userId , kind ,v.id))
end
end
end
end
--检查能领取的普通奖励
function PassCheck:CheckNormalReward( player )
local passCheck = player.gameData.passCheck
local rewardLevel = self:GetRewardLevel( player )
for k, v in pairs( passCheck.rewards ) do
local curCfg = skynet.server.gameConfig:GetCurCfg("PassCheckClass" , v.id )
--检查可以领取的普通奖励
if curCfg.level <= rewardLevel and dataType.RewardStatus_NoGet == v.normalStatus then
v.normalStatus = dataType.RewardStatus_CanGet
elseif curCfg.level > rewardLevel then
break
end
end
end
--检查能领取的付费奖励
function PassCheck:CheckPayReward( player )
local passCheck = player.gameData.passCheck
if passCheck.isVip then
local rewardLevel = self:GetRewardLevel( player )
--开通了VIP才给付费奖励
for k, v in pairs( passCheck.rewards ) do
local curCfg = skynet.server.gameConfig:GetCurCfg("PassCheckClass" , v.id )
--无法领取的付费奖励状态都设为可领取
if curCfg.level <= rewardLevel and dataType.RewardStatus_NoGet == v.payStatus then
v.payStatus = dataType.RewardStatus_CanGet
elseif curCfg.level > rewardLevel then
break
end
end
end
end
--获取奖励等级
function PassCheck:GetRewardLevel( player )
local score = player.gameData.passCheck.score
local level = 0
local cfgPassCheckClass = skynet.server.gameConfig.PassCheckClass --奖励配置
for k, v in pairs( cfgPassCheckClass ) do
score = score - v.Integral
if score < 0 then
break
end
level = level + 1
end
return level
end
--获取任务信息
function PassCheck:GetTaskInfo( player , taskType , taskId )
local passCheck = player.gameData.passCheck
for k, v in pairs( passCheck.tasks ) do
if taskType == v.type and taskId == v.id then
return v
end
end
return nil
end
--检查有不有消息提示
function PassCheck:CheckMsgTips( player )
local passCheck = player.gameData.passCheck
skynet.server.msgTips:Reset( player , 24 )
for k, v in pairs( passCheck.rewards ) do
if dataType.RewardStatus_CanGet == v.normalStatus or dataType.RewardStatus_CanGet == v.payStatus then
skynet.server.msgTips:Add( player , 24 )
break
end
end
skynet.server.msgTips:Reset( player , 25 )
for k, v in pairs( passCheck.tasks ) do
if self.TaskType_Normal == v.type and skynet.server.task.TaskStatus_AlreadyComplete == v.status then
skynet.server.msgTips:Add( player , 25 )
break
end
end
skynet.server.msgTips:Reset( player , 26 )
for k, v in pairs( passCheck.tasks ) do
if self.TaskType_LimitTime == v.type and skynet.server.task.TaskStatus_AlreadyComplete == v.status then
skynet.server.msgTips:Add( player , 26 )
break
end
end
skynet.server.msgTips:SendLastTips( player , 24)
skynet.server.msgTips:SendLastTips( player , 25)
skynet.server.msgTips:SendLastTips( player , 26)
end
--获取数量
function PassCheck:GetTaskData( player , taskType )
local data = {}
local passCheck = player.gameData.passCheck
local count = 0
for k, v in pairs( passCheck.tasks ) do
if count >= self.MaxShowItem then
break
end
--限时任务超过时间就改为过期状态
if self.TaskType_LimitTime == v.type and skynet.server.task.TaskStatus_OutOfTime ~= v.status and skynet.GetTime() >= v.endTime and 0 ~=v.endTime then
v.status = skynet.server.task.TaskStatus_OutOfTime
end
--未完成和已完成才会显示
if skynet.server.task.TaskStatus_NoComplete == v.status or skynet.server.task.TaskStatus_AlreadyComplete == v.status then
if (self.TaskType_Normal == taskType or self.TaskType_Daily == taskType) and taskType == v.type then
--常规任务和每日任务
table.insert( data , { id = v.id , progress = v.progress , status = v.status , endTime = 0} )
count = count + 1
elseif self.TaskType_LimitTime == taskType and taskType == v.type then
--限时任务有个截止时间
if 0 == v.endTime then
local cfgCurPassCheckTask = skynet.server.gameConfig:GetCurCfg("PassCheckTask", v.id)
local runTime = cfgCurPassCheckTask.timeNum * 86400
local endTime = skynet.GetTime() + runTime
v.endTime = endTime
end
table.insert( data , { id = v.id , progress = v.progress , status = v.status , endTime = v.endTime })
count = count + 1
end
end
end
return data,count
end
--获取显示的任务信息
function PassCheck:GetShowTaskData( player , taskType )
local data = {}
local count = 0
--获取下任务数据
data,count = self:GetTaskData( player , taskType )
--如果找出来的数量小于指定数量
if count < self.MaxShowItem then
local passCheck = player.gameData.passCheck
local tmpCount = self.MaxShowItem - count --需要补足多少个任务
--找出能够恢复的任务
local allRandTask = {}
for k, v in pairs( passCheck.tasks ) do
if skynet.server.task.TaskStatus_AlreadyGet== v.status or skynet.server.task.TaskStatus_OutOfTime == v.status then
local isAdd = true
if 12 == v.kind then
local cfgCount = #skynet.server.gameConfig.StyleList --设计奖励配置数量
local rewardsCount = #player.gameData.shop[ dataType.ShopType_Style ].gainRewards --已经获取的奖励数量
local count = cfgCount - rewardsCount
local curCfgPassCheckTask = skynet.server.gameConfig:GetCurCfg( "PassCheckTask" , v.id )
if count < curCfgPassCheckTask.taskNum then --小于数量就不再添加
isAdd = false
end
end
if isAdd then
table.insert( allRandTask , { id = v.id })
end
end
end
--随机指定数量
local randTask = skynet.server.shop:GetNoRepeatGoods( tmpCount , allRandTask )
for k1, v1 in pairs( randTask ) do
for k2, v2 in pairs( passCheck.tasks ) do
if v1 == v2.id then
--任务重置
v2.status = skynet.server.task.TaskStatus_NoComplete
v2.progress = 0
--限时任务需要多重置个截止时间
if self.TaskType_LimitTime == taskType and taskType == v2.type then
v2.endTime = 0
end
end
end
end
--再获取下任务数据
data,count = self:GetTaskData( player , taskType )
end
return data
end
--是否显示中的任务
function PassCheck:IsShowTask( player , taskType , taskId )
local allTask = self:GetShowTaskData( player , taskType )
for k, v in pairs(allTask) do
if taskId == v.id then
return true
end
end
return false
end
--是否加入任务
function PassCheck:IsJoinTask( curCfgPassCheck , taskType , taskId )
if self.TaskType_Normal == taskType then
for k, v in pairs( curCfgPassCheck.normalTask ) do
if taskId == v then
return true
end
end
elseif self.TaskType_LimitTime == taskType then
for k, v in pairs( curCfgPassCheck.limitTask ) do
if taskId == v then
return true
end
end
end
return false
end
skynet.server.passCheck = PassCheck
return PassCheck