local skynet = require "skynet" local oo = require "Class" local log = require "Log" local redisKeyUrl = require "RedisKeyUrl" local sqlUrl = require "SqlUrl" local json =require "json" local errorInfo = require "ErrorInfo" local MailManage = oo.class() MailManage.Type_Test = 1 --春节邮件 MailManage.Status_NoBonus = 1 --未发货 MailManage.Status_StartBonus = 2 --开始发货 MailManage.Status_AlreadyBonus = 3 --已发货 MailManage.Status_OutDate = 4 --邮件过期 MailManage.OpType_Add = 1 --新建 MailManage.OpType_Modify = 2 --修改 MailManage.OpType_Delete = 3 --删除 function MailManage:Init() self.mailTemplate = {} --邮件模板 self.mailList = {} --邮件列表 self:LoadDB() end function MailManage:OnNewDay() --跨天 end --每5秒调一次 function MailManage:On5SecTimer() self:Refresh() end --从DB中载入数据 function MailManage:LoadDB() --加载邮件模板 local sql = sqlUrl.selectInfoFromMailTemplate local queryData = skynet.server.db:Query( "game" , sql ) for k, v in pairs(queryData) do self:NewMailTemplateRecord( v.Name , json:decode(v.Data) ) log.info(string.format("加载邮件模版信息 模版Name %d " , v.Name )) end --加载邮件列表 sql = string.format(sqlUrl.selectInfoFromMailList , self.Status_StartBonus ) queryData = skynet.server.db:Query( "game" , sql ) for k, v in pairs(queryData) do self:NewMailListRecord( v.ID , v.Status , v.BonusPlayerCount , json:decode(v.Data)) log.info(string.format("加载邮件信息 邮件ID %d " , v.ID )) end end --保存数据到DB function MailManage:SaveDB() local sql = nil local queryData = nil --保存邮件模板 for k, v in pairs(self.mailTemplate) do sql = string.format(sqlUrl.updateDataToMailTemplate, json:encode(v.data) , v.name ) queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("修改邮件模板数据失败,不存在该名称" , v.name ) else log.info("成功保存邮件模板" , v.name ) end end --保存邮件列表 for k, v in pairs(self.mailList) do sql = string.format(sqlUrl.updateDataToMailList , json:encode(v.data) , v.mailId ) queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("修改邮件数据失败,不存在该ID" , v.mailId ) else log.info("成功保存邮件列表" , v.mailId ) end end end --获取所有邮件信息 function MailManage:GetMailList() return self.mailList end --新增模板 function MailManage:AddTemplate( c2sData , s2cData ) --获取模板ID local redisKey = string.format(redisKeyUrl.GameServerMailTemplateID ) local templateId = skynet.server.redis:incr(redisKey) local name = c2sData.Name local sql = string.format(sqlUrl.insertInfoToMailTemplate , templateId , name , json:encode(c2sData.data)) local queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("新增邮件模板列表失败" , templateId ) skynet.server.redis:decr(redisKey) s2cData.code = errorInfo.ErrorCode.NewMailFailed return false end self:NewMailTemplateRecord( name , c2sData.data ) s2cData.name = name log.info(string.format("新增邮件模板 模板ID %d " , templateId )) end --修改模板 function MailManage:ModifyTemplate( c2sData , s2cData ) local name = c2sData.name local data = json:encode(c2sData.data) local sql = string.format(sqlUrl.updateDataToMailTemplate , data , name ) local queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("修改邮件模板数据失败,不存在该名称" , name ) s2cData.code = errorInfo.ErrorCode.NoExistMailID return false end self.mailTemplate[ name ].data = json:decode(data) s2cData.name = name log.info(string.format("成功修改邮件模板信息 名称 %s" , name )) end --删除模板 function MailManage:DeleteTemplate( c2sData , s2cData ) local name = c2sData.name local sql = string.format(sqlUrl.deleteInfoFromMailTemplate , name ) local queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("删除邮件模板数据失败,不存在该名称" , name ) s2cData.code = errorInfo.ErrorCode.NoExistMailID return false end if self.mailTemplate[ name ] then self.mailList[ name ].data = nil self.mailList[ name ] = nil end s2cData.name = name log.info(string.format("成功删除邮件模板信息 名称 %s" , name )) end --新增邮件 function MailManage:AddMail( c2sData , s2cData ) --获取邮件ID local redisKey = string.format(redisKeyUrl.GameServerMailListID ) local mailId = skynet.server.redis:incr(redisKey) local sql = string.format(sqlUrl.insertInfoToMailList , mailId , self.Status_NoBonus , json:encode(c2sData.data)) local queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("新增邮件列表失败" , mailId ) skynet.server.redis:decr(redisKey) s2cData.code = errorInfo.ErrorCode.NewMailFailed return false end self:NewMailListRecord( mailId , self.Status_NoBonus , 0 , c2sData.data ) s2cData.mailId = mailId log.info(string.format("新增邮件信息 邮件ID %d " , mailId )) return true end --修改邮件 function MailManage:ModifyMail( c2sData , s2cData ) local mailId = c2sData.mailID local data = json:encode(c2sData.data) local sql = string.format(sqlUrl.updateDataToMailList , data , mailId ) local queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("修改邮件数据失败,不存在该ID" , mailId ) s2cData.code = errorInfo.ErrorCode.NoExistMailID return false end self.mailList[ mailId ].data = json:decode(data) s2cData.mailId = mailId log.info(string.format("成功修改邮件信息 ID %d" , mailId )) end --删除邮件 function MailManage:DeleteMail( c2sData , s2cData ) local mailId = c2sData.mailID local sql = string.format(sqlUrl.deleteInfoFromMailList , mailId ) local queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info("删除邮件数据失败,不存在该ID" , mailId ) s2cData.code = errorInfo.ErrorCode.NoExistMailID return false end if self.mailList[ mailId ] then self.mailList[ mailId ].data = nil self.mailList[ mailId ] = nil end --通知所有游戏删除该邮件 table.insert( c2sData , { mailId =mailId , opType = self.OpType_Delete }) self:SendMsgUpdateMailList( c2sData ) s2cData.mailId = mailId log.info(string.format("成功删除邮件信息 ID %d" , mailId )) end --刷新 function MailManage:Refresh() local sql = nil local c2sData = {} local startTime,endTime = nil ,nil for k, v in pairs(self.mailList) do --将2023-01-01 00:00:00 转化为时间戳 startTime = skynet.server.common:GetTime( v.data.startTime ) endTime = skynet.server.common:GetTime( v.data.endTime ) if self.Status_NoBonus == v.status and skynet.GetTime() >= startTime and skynet.GetTime() <= endTime then --邮件列表中有邮件可以生效,并将列表中的数据推向各游戏服 local isSuc = self:UpdateStatus( v.mailId , self.Status_StartBonus , 0 ) if isSuc then table.insert( c2sData , { mailId = v.mailId , opType = self.OpType_Add , data = v.data }) end elseif self.Status_AlreadyBonus == v.status then --邮件列表中有邮件已经过期,并通知所有游戏服删除该邮件 table.insert( c2sData , { mailId = v.mailId , opType = self.OpType_Delete }) elseif skynet.GetTime() >= endTime then --邮件列表中有邮件已经发放完,并通知所有游戏服删除该邮件 local isSuc = self:UpdateStatus( v.mailId , self.Status_OutDate , v.bonusPlayerCount ) if isSuc then table.insert( c2sData , { mailId = v.mailId , opType = self.OpType_Delete }) end end end --对于已经发放结束和过期的邮件删除 for k, v in pairs(self.mailList) do if self.Status_AlreadyBonus == v.status or self.Status_OutDate == v.status then self.mailList[ k ].data= nil self.mailList[ k ]= nil end end --有数据才推 if #c2sData >= 1 then self:SendMsgUpdateMailList( c2sData ) end end --更新状态 function MailManage:UpdateStatus( mailId , status , bonusPlayerCount ) --更新状态到DB local sql = string.format(sqlUrl.updateStatusToMailList , status , bonusPlayerCount , mailId ) local queryData = skynet.server.db:Query( "game" , sql ) if 1 ~= queryData.affected_rows then log.info(string.format("邮件 ID %d 更新状态 %d 失败" , mailId , status )) return false else self.mailList[ mailId ].status = status log.info(string.format("邮件 ID %d 更新状态 %d 成功" , mailId , status )) return true end end --更新玩家统计人数 function MailManage:UpdateMailPlayerCount( mailId , userId ) if not self.mailList[ mailId ] then --邮件已经过期或都已经领取结束了,就不再统计了 return end self.mailList[ mailId ].bonusPlayerCount = self.mailList[ mailId ].bonusPlayerCount + 1 local isAllUser = self.mailList[ mailId ].data.isAllUser if not isAllUser then --非所有人发送邮件,人数领取完了就可以保存该邮件了 local getCount = self.mailList[ mailId ].bonusPlayerCount local needCount = #self.mailList[ mailId ].data.userList if getCount == needCount then self:UpdateStatus( mailId , self.Status_AlreadyBonus , self.mailList[ mailId ].bonusPlayerCount) log.info(string.format("邮件人数已经领取玩 MailID %d 需要人数 %d 获取人数 %d" , mailId , needCount , getCount)) end end end --新增邮件模板记录 function MailManage:NewMailTemplateRecord( name , record ) if not self.mailTemplate[ name ] then self.mailTemplate[ name ] = {} end self.mailTemplate[ name ].name = name self.mailTemplate[ name ].data = record end --新增邮件记录 function MailManage:NewMailListRecord( mailId , status , bonusPlayerCount, record ) if not self.mailList[ mailId ] then self.mailList[ mailId ] = {} end self.mailList[ mailId ].mailId = mailId self.mailList[ mailId ].status = status self.mailList[ mailId ].bonusPlayerCount = bonusPlayerCount self.mailList[ mailId ].data = record end --更新邮件列表到各个游戏服务器 function MailManage:SendMsgUpdateMailList( c2sData ) for k, v in pairs( skynet.server.multiServer.clusterInfo ) do if v.serverId >= skynet.server.multiServer.gameServerMinID and v.serverId <= skynet.server.multiServer.gameServerMaxID then skynet.server.multiServer:SendMsgToServer( k , skynet.server.multiServer.Multi2Game_UpdateMailList , c2sData) end end end skynet.server.mailManage = MailManage return MailManage