local skynet = require "skynet" local oo = require "Class" local log = require "Log" local pb = require "pb" local dataType = require "DataType" local serverId = tonumber(skynet.getenv "serverId") local Activity = oo.class() Activity.UpdateTime = 0 Activity.ActivityInitHandler = {} --注册的活动初始化函数集合 Activity.ActivityCloseHandler = {} --注册的活动关闭函数集合 Activity.InProgressActivity = {} --进行中的活动 function Activity:Init() if not skynet.server.clusterServer:IsGameServer( serverId ) then return end end --每5秒调一次 function Activity:On5SecTimer() if not skynet.server.clusterServer:IsGameServer( serverId ) then return end local nowTime = skynet.GetTime() if math.abs(nowTime - self.UpdateTime) >= 60 then self:ServerActivityWatch() local playerList = skynet.server.playerCenter:GetPlayerList() for userId, value in pairs(playerList) do --每1分钟检查一次 if skynet.server.playerCenter.Status_Playing == value.status and skynet.server.activityManage:ChangeData(value.player, false) then --该玩家有新的活动开启是主动推送当前活动信息 local data = {} data.activityInfos = skynet.server.activity:GetAllActivityInfo(value.player) skynet.server.gameServer:SendMsgToUser(value.player.userId, "CMD_S2C_UpdateShowUI", data) end end self.UpdateTime = nowTime end end --注册需要服务器活动的初始化函数 function Activity:RegisterInitHandler(handler,describe,activityType) self.ActivityInitHandler[activityType] = handler log.info("活动初始化函数注册:" ..describe.."成功!") end --取消注册初始化事件 function Activity:UnregisterInitHandler(activityType) self.ActivityInitHandler[activityType] = nil end --注册需要服务器活动的关闭函数 function Activity:RegisterCloeseHandler(handler,describe,activityType) self.ActivityCloseHandler[activityType] = handler log.info("活动关闭函数注册:" ..describe.."成功!") end --取消注册关闭事件 function Activity:UnregisterCloeseHandler(activityType) self.ActivityCloseHandler[activityType] = nil end --服务器获取当前开启的活动,执行该活动的初始化函数 function Activity:ServerActivityWatch() local cfgActivity = skynet.server.gameConfig:GetAllCfg("Activity") local startTime = 0 local endTime = 0 local nowTime = skynet.GetTime() local cacheList = {} --遍历活动表,将开启的并且注册在集合中的活动执行初始化函数 for k, v in pairs(cfgActivity) do if v.startTime ~= nil and v.startTime ~= "" and v.endTime ~= nil and v.endTime ~= "" then startTime = skynet.server.common:GetTime(v.startTime) endTime = skynet.server.common:GetTime(v.endTime) end --判断是不是当前时间开启的活动,如果是判断该活动需不需需要执行服务器初始化逻辑 if nowTime >= startTime and nowTime <= endTime then if next(self.ActivityInitHandler) ~= nil and self.ActivityInitHandler[v.activityType] ~= nil then local handler = self.ActivityInitHandler[v.activityType] local isDo,callData = pcall( handler, v.activityId) if not isDo then --打印错误日志 local debugInfo = debug.getinfo(handler) if debugInfo then log.error("活动管理器初始化函数执行错误,相关信息", callData,debugInfo.source,debugInfo.linedefined) end else --table.insert(cacheList,v.activityType) --table.insert(self.InProgressActivity,v.activityType) cacheList[v.activityType] = v.activityId self.InProgressActivity[v.activityType] = v.activityId end end end end --检查正在进行的活动列表,将已经关闭的活动执行关闭函数并且移除(如果有的话) for i, v in pairs(self.InProgressActivity) do local inProgress = false for i2, v2 in pairs(cacheList) do if i == i2 then inProgress = true break end end if not inProgress then if self.ActivityCloseHandler[i] ~= nil then local handler = self.ActivityCloseHandler[i] local isDo,callData = pcall(handler) if not isDo then --打印错误日志 local debugInfo = debug.getinfo(handler) if debugInfo then log.error("活动管理器关闭活动执行错误,相关信息", callData,debugInfo.source,debugInfo.linedefined) end end end self.InProgressActivity[i] = nil end end end --获取当前开启活动的id,开始和结束时间 function Activity:GetActivityInfo(player, activityType, subType) subType = subType or 0 local cfgActivity = skynet.server.gameConfig:GetPlayerAllCfg(player, "Activity") local activityId = 0 local startTime = 0 local endTime = 0 local nowTime = skynet.GetTime() local id = 0 for k, v in pairs(cfgActivity) do if v.activityType == activityType then startTime = skynet.server.common:GetTime(v.startTime) endTime = skynet.server.common:GetTime(v.endTime) --判断是不是当前时间开启的活动 if nowTime >= startTime and nowTime <= endTime and subType == v.subType then activityId = v.activityId id = v.id break end end end --判断是否需要关闭玩家该活动 if self:CloseSomeActivity(player,id) then activityId = 0 startTime = 0 endTime = 0 end return activityId, startTime, endTime , id end --获取当前玩家可以进行显示的活动的相关信息 function Activity:GetAllActivityInfo(player) local activityInfo = {} --新人签到单独处理 if skynet.GetTime() < player.gameData.playerLand.endTime and player.gameData.playerLand.isShow then table.insert(activityInfo, { id = 3, startTime = 0, endTime = player.gameData.playerLand.endTime }) end --新手限时设计单独处理 local cfgNewPlayerRaffle = skynet.server.activityNewPlayerRaffle:CheckData(player) if player:IsUnlockSystem( dataType.UnlockSystem_ActivityNewPlayerRaffle ) and cfgNewPlayerRaffle ~= nil then table.insert(activityInfo, { id = 130, startTime = player.gameData.NewPlayerRaffleMap[cfgNewPlayerRaffle.id].activityOpenTime, endTime = skynet.server.activityNewPlayerRaffle:GetActivityEndTime(player.gameData.NewPlayerRaffleMap[cfgNewPlayerRaffle.id].activityOpenTime) }) end local cfgAllActivity = skynet.server.gameConfig:GetPlayerAllCfg(player, "Activity") for k, v in pairs(cfgAllActivity) do --处理分层礼包,已经购买不添加 if v.activityType == dataType.ActivityType_ActivityLevelPack and not skynet.server.activityLevelPack:isCanBuy(player) then goto continue end --进阶礼包 if v.activityType == dataType.ActivityType_ActivityStagePack and skynet.server.activityStagePack:isActivityEnd(player) then goto continue end --存钱罐 if v.activityType == dataType.ActivityType_SavingPot and skynet.server.activitySavingPot:isActivityEnd(player) then goto continue end if player.gameData.level >= v.level and v.activityType == dataType.ActivityType_Raffle and (v.subType == 3 or v.subType == 4 )then local startTime = skynet.server.common:GetTime(v.startTime) local endTime = skynet.server.common:GetTime(v.endTime) if skynet.GetTime() >= startTime and skynet.GetTime() < endTime and not self:CloseSomeActivity(player, v.id) then table.insert(activityInfo, { id = v.id, startTime = startTime, endTime = endTime }) end elseif player.gameData.level >= v.level and v.activityType ~= dataType.ActivityType_Raffle then if v.startTime ~= "" and v.endTime ~= "" then local startTime = skynet.server.common:GetTime(v.startTime) local endTime = skynet.server.common:GetTime(v.endTime) if skynet.GetTime() >= startTime and skynet.GetTime() < endTime and not self:CloseSomeActivity(player, v.id) then table.insert(activityInfo, { id = v.id, startTime = startTime, endTime = endTime }) end end end ::continue:: end return activityInfo end --活动即将过期 发送邮件 function Activity:ActivityExpiredSendMail(player) --从开启的活动中 查找是否有活动需要进行发送邮件 for k, v in pairs(player.gameData.activityManage) do if v.id > 0 then local cfgOneActivity = skynet.server.gameConfig:GetPlayerCurCfg(player, "Activity", v.id) --开启的活动中是否满足邮件的发送时间 if cfgOneActivity and "" ~= cfgOneActivity.mailTime and cfgOneActivity.mailId > 0 and skynet.GetTime() >= skynet.server.common:GetTime(cfgOneActivity.mailTime) then local mailId = "HDGQ-" .. cfgOneActivity.activityType .. "-" .. cfgOneActivity.activityId --判断是否已经发送过该邮件 local showSend = true for k1, v1 in pairs(player.gameData.mail.historyMail) do if v1 == mailId then showSend = false break end end if showSend then local cfgOneMail = skynet.server.gameConfig:GetPlayerCurCfg(player, "Mail", cfgOneActivity.mailId) --邮件对应奖励 local award = skynet.server.playerLand:GetRewardInfo(player, cfgOneMail.mailReward) local mailInfo = { mailType = "奖励", mailTitle = cfgOneMail.mailTitle, mailText = cfgOneMail.mailContent, mailEffectiveTime = 7 } skynet.server.mail:AddMail(player, mailId, mailInfo, award, false) end end end end end --是否关闭该玩家的对应活动 function Activity:CloseSomeActivity(player, id) local gameCgi = "chenzong_dwelstgz" --要关闭的玩家cgi local ids = { 58, 59, 60, 61, 62, 81 } --要关闭的活动 if player==nil or player.basicInfo.gameCgi ~= gameCgi then return false else for k, v in pairs(ids) do if v == id then return true end end end return false end skynet.server.activity = Activity return Activity