786 lines
32 KiB
Lua
786 lines
32 KiB
Lua
|
|
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 errorInfo = require "ErrorInfo"
|
|||
|
|
local json = require "json"
|
|||
|
|
local serverId = tonumber(skynet.getenv "serverId")
|
|||
|
|
local Mail = oo.class()
|
|||
|
|
|
|||
|
|
Mail.MailOpType_1 = 1 --获取邮件列表
|
|||
|
|
Mail.MailOpType_2 = 2 --查阅/领取奖品
|
|||
|
|
|
|||
|
|
Mail.MailOpStatus_Suc = 1 --操作状态成功
|
|||
|
|
Mail.MailOpStatus_NoMailID = 2 --不存在该邮件ID
|
|||
|
|
Mail.MailOpStatus_AlreadyGet = 3 --已经领取了
|
|||
|
|
|
|||
|
|
Mail.MailProperty_AllServer = 1 --全服邮件
|
|||
|
|
Mail.MailProperty_User = 2 --用户邮件
|
|||
|
|
|
|||
|
|
Mail.MailType_Msg = 1 --消息邮件
|
|||
|
|
Mail.MailType_Award = 2 --奖励邮件
|
|||
|
|
Mail.MailType_Compensate = 3 --补偿邮件
|
|||
|
|
|
|||
|
|
Mail.MaxSendCount = 100 --一次发送最大数量
|
|||
|
|
|
|||
|
|
Mail.WXMailList = {} --微信通知邮件列表
|
|||
|
|
|
|||
|
|
|
|||
|
|
function Mail:Init()
|
|||
|
|
self.mailList = {}
|
|||
|
|
if not skynet.server.clusterServer:IsGameServer( serverId ) then
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--登陆初始化数据
|
|||
|
|
function Mail:LoginInitData( player )
|
|||
|
|
self:CheckNewMail( player )
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--每5秒调一次
|
|||
|
|
function Mail:On5SecTimer()
|
|||
|
|
if not skynet.server.clusterServer:IsGameServer( serverId ) then
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
self:BatchAddMail()
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--redis订阅消息(废弃,后面再清理)
|
|||
|
|
function Mail:RedisMsgRecv(msg)
|
|||
|
|
local mailData = json:decode(msg)
|
|||
|
|
|
|||
|
|
local player = skynet.server.playerCenter:GetPlayer(mailData.userId)
|
|||
|
|
if not player then
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--玩家在该服务器,才会给玩家发送数据
|
|||
|
|
self:AddNewMail(player, mailData.mailType, mailData.mailTitle, mailData.mailText, mailData.award)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--从后台刷新邮件列表
|
|||
|
|
function Mail:RefreshMailList()
|
|||
|
|
--向后端请求
|
|||
|
|
local param = { backstageId = 1 }
|
|||
|
|
param.mailIds = {}
|
|||
|
|
for k ,v in pairs(self.mailList) do
|
|||
|
|
table.insert(param.mailIds,k)
|
|||
|
|
end
|
|||
|
|
local web = skynet.server.gameConfig.WebConfig.host .. ":" .. skynet.server.gameConfig.WebConfig.port
|
|||
|
|
local url = skynet.server.common.getMailUrl
|
|||
|
|
local status, body = skynet.server.httpClient:PostJson(web, url, json:encode(param), "http")
|
|||
|
|
|
|||
|
|
if 200 == status then
|
|||
|
|
local newbody = json:decode(body)
|
|||
|
|
if 200 == newbody.code then
|
|||
|
|
--移除过期的邮件
|
|||
|
|
for k, v in pairs(newbody.data.delMailIds) do
|
|||
|
|
for k1 , v1 in pairs(self.mailList) do
|
|||
|
|
if k1 == v then
|
|||
|
|
self.mailList[k1] = nil
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--添加新的邮件
|
|||
|
|
for k, v in pairs(newbody.data.mailVos) do
|
|||
|
|
local mailId = v.mailModel.mailId
|
|||
|
|
if not self.mailList[mailId] then
|
|||
|
|
self.mailList[mailId] = {}
|
|||
|
|
local curMail = self.mailList[mailId]
|
|||
|
|
curMail.mailInfo = v.mailModel
|
|||
|
|
curMail.award = v.giftArticlesModels
|
|||
|
|
curMail.isSendAllOnlineUser = false --是否发送所有在线玩家
|
|||
|
|
|
|||
|
|
if "全服" == curMail.mailInfo.mailCondition then
|
|||
|
|
curMail.mailType = self.MailProperty_AllServer
|
|||
|
|
elseif "ID" == curMail.mailInfo.mailCondition then
|
|||
|
|
curMail.mailType = self.MailType_User
|
|||
|
|
local t1 = skynet.GetTime()
|
|||
|
|
local count = 0
|
|||
|
|
local playerList = skynet.server.playerCenter:GetPlayerList()
|
|||
|
|
--给指定在线玩家发送新邮件
|
|||
|
|
local uidList = skynet.server.common:Split(curMail.mailInfo.uidlist, ",")
|
|||
|
|
for k1, v1 in pairs(uidList) do
|
|||
|
|
for userId, value in pairs(playerList) do
|
|||
|
|
if value.player.account == v1 and skynet.server.playerCenter.Status_Playing == value.status then
|
|||
|
|
self:AddMail(value.player, mailId, curMail.mailInfo, curMail.award, true)
|
|||
|
|
count = count + 1
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
log.info(string.format("邮箱 部分玩家发送邮件 发送数量 %d 时间花费 %d ", count, skynet.GetTime() - t1))
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
elseif 702 == newbody.code then
|
|||
|
|
log.info("当前没有需要发送的邮件")
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
log.warning("邮箱刷新 获取数据失败 status ", status)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--邮件历史
|
|||
|
|
function Mail:History(player, c2sData, s2cData)
|
|||
|
|
c2sData.data = assert(pb.decode("C2SMailHistory", c2sData.data))
|
|||
|
|
local data = {}
|
|||
|
|
data.mailInfo = {}
|
|||
|
|
local t1 = skynet.GetTime()
|
|||
|
|
for k, v in pairs(player.gameData.mail.mailList) do
|
|||
|
|
for k1, v1 in pairs(player.gameData.mail.historyMail) do
|
|||
|
|
if v1 == v.mailId then
|
|||
|
|
--判断邮件是否到期
|
|||
|
|
local nowTime = skynet.GetTime()
|
|||
|
|
if nowTime >= v.failureTime then
|
|||
|
|
player.gameData.mail.mailList[k] = nil
|
|||
|
|
skynet.server.msgTips:Reduce(player, 23)
|
|||
|
|
else
|
|||
|
|
local info = skynet.server.common:DeepCopy(v)
|
|||
|
|
table.insert(data.mailInfo, info)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
--log.info("邮件历史花费时间 %d", skynet.GetTime() - t1)
|
|||
|
|
--处理单引号的问题
|
|||
|
|
for k, v in pairs(data.mailInfo) do
|
|||
|
|
v.content = string.gsub(v.content, "'", "'")
|
|||
|
|
v.content = string.gsub(v.content, " ", " ")
|
|||
|
|
end
|
|||
|
|
--处理红点问题
|
|||
|
|
if skynet.server.msgTips:GetOneTips(player, 23).count > 0 then
|
|||
|
|
local redDotError = true
|
|||
|
|
for k, v in pairs(player.gameData.mail.mailList) do
|
|||
|
|
if v.status ~= dataType.MailStatus_AlreadyGet then
|
|||
|
|
redDotError = false
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
--如果所有的邮件都已经领取或者看过 将红点消除
|
|||
|
|
if redDotError then
|
|||
|
|
skynet.server.msgTips:ReduceAll(player, 23)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_MailHistory")
|
|||
|
|
s2cData.data = assert(pb.encode("S2CMailHistory", data))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--邮件领取奖励
|
|||
|
|
function Mail:Award(player, c2sData, s2cData)
|
|||
|
|
c2sData.data = assert(pb.decode("C2SMailAward", c2sData.data))
|
|||
|
|
local mailId = c2sData.data.mailId
|
|||
|
|
|
|||
|
|
local data = {}
|
|||
|
|
data.mailInfo = {}
|
|||
|
|
local param = { backstageId = 1 }
|
|||
|
|
param.mails = {}
|
|||
|
|
if not mailId then
|
|||
|
|
s2cData.code = errorInfo.ErrorCode.ErrRequestParams
|
|||
|
|
else
|
|||
|
|
local isExist = false
|
|||
|
|
local nowTime = skynet.GetTime()
|
|||
|
|
for k, v in pairs(player.gameData.mail.mailList) do
|
|||
|
|
if mailId == v.mailId and dataType.MailStatus_NoGet == v.status and nowTime < v.failureTime then
|
|||
|
|
--未获取,可以正常领取
|
|||
|
|
isExist = true
|
|||
|
|
self:Bonus(player, mailId, v.award)
|
|||
|
|
v.status = dataType.MailStatus_AlreadyGet
|
|||
|
|
--告诉后台该玩家领取了邮件
|
|||
|
|
table.insert(param.mails,{ mailId = mailId, playerId = player.account })
|
|||
|
|
local web = skynet.server.gameConfig.WebConfig.host .. ":" .. skynet.server.gameConfig.WebConfig.port
|
|||
|
|
local url = skynet.server.common.useMailUrl
|
|||
|
|
local status, body = skynet.server.httpClient:PostJson(web, url, json:encode(param), "http")
|
|||
|
|
skynet.server.msgTips:Reduce(player, 23)
|
|||
|
|
data.mailInfo = v
|
|||
|
|
break
|
|||
|
|
elseif mailId == v.mailId and dataType.MailStatus_AlreadyGet == v.Status then
|
|||
|
|
--已经领取了,无法再次领取
|
|||
|
|
isExist = true
|
|||
|
|
s2cData.code = errorInfo.ErrorCode.AlreadyGet
|
|||
|
|
data.mailInfo = v
|
|||
|
|
break
|
|||
|
|
elseif mailId == v.mailId and nowTime >= v.failureTime then
|
|||
|
|
--已经领取了,无法再次领取
|
|||
|
|
isExist = true
|
|||
|
|
s2cData.code = errorInfo.ErrorCode.AlreadyGet
|
|||
|
|
data.mailInfo = v
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if not isExist then
|
|||
|
|
s2cData.code = errorInfo.ErrorCode.NoExistMailID
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_MailAward")
|
|||
|
|
s2cData.data = assert(pb.encode("S2CMailAward", data))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--邮件读取
|
|||
|
|
function Mail:Read(player, c2sData, s2cData)
|
|||
|
|
c2sData.data = assert(pb.decode("C2SReadMail", c2sData.data))
|
|||
|
|
local mailId = c2sData.data.mailId
|
|||
|
|
local data = {}
|
|||
|
|
data.mailInfo = {}
|
|||
|
|
if not mailId then
|
|||
|
|
s2cData.code = errorInfo.ErrorCode.ErrRequestParams
|
|||
|
|
else
|
|||
|
|
local t1 = skynet.GetTime()
|
|||
|
|
for k, v in pairs(player.gameData.mail.mailList) do
|
|||
|
|
if mailId == v.mailId then
|
|||
|
|
-- 修改邮件的读取状态
|
|||
|
|
v.status = dataType.MailStatus_AlreadyGet
|
|||
|
|
skynet.server.msgTips:Reduce(player, 23)
|
|||
|
|
local info = skynet.server.common:DeepCopy(v)
|
|||
|
|
data.mailInfo = info
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
log.info("邮件读取花费时间 %d", skynet.GetTime() - t1)
|
|||
|
|
end
|
|||
|
|
--处理单引号的问题
|
|||
|
|
if data.mailInfo.content then
|
|||
|
|
data.mailInfo.content = string.gsub(data.mailInfo.content, "'", "'")
|
|||
|
|
data.mailInfo.content = string.gsub(data.mailInfo.content, " ", " ")
|
|||
|
|
end
|
|||
|
|
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ReadMail")
|
|||
|
|
s2cData.data = assert(pb.encode("S2CReadMail", data))
|
|||
|
|
log.debug(string.format("玩家 %d 读取邮件 ID", player.userId, mailId))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--删除已读邮件
|
|||
|
|
function Mail:DeleteRead(player, c2sData, s2cData)
|
|||
|
|
c2sData.data = assert(pb.decode("C2SReadMail", c2sData.data))
|
|||
|
|
local data = {}
|
|||
|
|
data.mailInfo = {}
|
|||
|
|
if player.gameData.mail.mailList then
|
|||
|
|
-- 当玩家有邮件才进行以下逻辑
|
|||
|
|
for k, v in pairs(player.gameData.mail.mailList) do
|
|||
|
|
-- 领取或者读取过的邮件就删除 否则返回给客户端1
|
|||
|
|
if dataType.MailStatus_AlreadyGet == v.status then
|
|||
|
|
player.gameData.mail.mailList[k] = nil
|
|||
|
|
else
|
|||
|
|
table.insert(data.mailInfo, v)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_DeleteReadMail")
|
|||
|
|
s2cData.data = assert(pb.encode("S2CDeleteReadMail", data))
|
|||
|
|
log.debug(string.format("删除 玩家 %d 读取过的邮件", player.userId))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--一键领取邮件奖励
|
|||
|
|
function Mail:AllAward(player, c2sData, s2cData)
|
|||
|
|
c2sData.data = assert(pb.decode("C2SMailAllAward", c2sData.data))
|
|||
|
|
local data = {}
|
|||
|
|
data.mailInfo = {}
|
|||
|
|
local nowTime = skynet.GetTime()
|
|||
|
|
local param = { backstageId = 1 }
|
|||
|
|
param.mails = {}
|
|||
|
|
for k, v in pairs(player.gameData.mail.mailList) do
|
|||
|
|
if dataType.MailStatus_NoGet == v.status and pb.enum("PBMailInfo.MailType", "Award") == v.mailType and nowTime < v.failureTime then
|
|||
|
|
--未获取,可以正常领取
|
|||
|
|
self:Bonus(player, v.mailId, v.award)
|
|||
|
|
v.status = dataType.MailStatus_AlreadyGet
|
|||
|
|
table.insert(param.mails,{ mailId = v.mailId, playerId = player.account })
|
|||
|
|
-- 将邮件信息返回
|
|||
|
|
table.insert(data.mailInfo, v)
|
|||
|
|
--消除红点
|
|||
|
|
skynet.server.msgTips:Reduce(player, 23)
|
|||
|
|
elseif dataType.MailStatus_AlreadyGet == v.Status then
|
|||
|
|
--已经领取了,无法再次领取
|
|||
|
|
s2cData.code = errorInfo.ErrorCode.AlreadyGet
|
|||
|
|
elseif nowTime >= v.failureTime then
|
|||
|
|
--邮件已经过期,无法进行领取 删除对应邮件
|
|||
|
|
player.gameData.mail.mailList[k] = nil
|
|||
|
|
s2cData.code = errorInfo.ErrorCode.AlreadyGet
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--告诉后台该玩家领取了邮件
|
|||
|
|
local web = skynet.server.gameConfig.WebConfig.host .. ":" .. skynet.server.gameConfig.WebConfig.port
|
|||
|
|
local url = skynet.server.common.useMailUrl
|
|||
|
|
local status, body = skynet.server.httpClient:PostJson(web, url, json:encode(param), "http")
|
|||
|
|
|
|||
|
|
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_MailAllAward")
|
|||
|
|
s2cData.data = assert(pb.encode("S2CMailAllAward", data))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--发放邮件奖励
|
|||
|
|
function Mail:Bonus(player, mailId, award)
|
|||
|
|
for k, v in pairs(award) do
|
|||
|
|
--货币或者奖励id直接发放就行
|
|||
|
|
if v.type < 10 or v.type == dataType.GoodsType_RewardId or v.type == dataType.GoodsType_Points then
|
|||
|
|
if dataType.GoodsType_Coin == v.type then
|
|||
|
|
local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_34")
|
|||
|
|
player:MoneyChange(pb.enum("EnumGoodsType", "Coin"), v.count, eventId)
|
|||
|
|
elseif dataType.GoodsType_Clovers == v.type then
|
|||
|
|
local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_34")
|
|||
|
|
player:MoneyChange(pb.enum("EnumGoodsType", "Clovers"), v.count, eventId)
|
|||
|
|
elseif dataType.GoodsType_Volute == v.type then
|
|||
|
|
local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_34")
|
|||
|
|
player:MoneyChange(pb.enum("EnumGoodsType", "VoluteCoin"), v.count, eventId)
|
|||
|
|
elseif dataType.GoodsType_Fragment == v.type then
|
|||
|
|
local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_34")
|
|||
|
|
player:MoneyChange(pb.enum("EnumGoodsType", "Fragment"), v.count, eventId)
|
|||
|
|
elseif dataType.GoodsType_RewardId == v.type then
|
|||
|
|
local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_34")
|
|||
|
|
player:GiveReward( v.id , eventId )
|
|||
|
|
elseif dataType.GoodsType_Points == v.type then
|
|||
|
|
local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_34")
|
|||
|
|
if v.id == dataType.PointsType_Store then
|
|||
|
|
player.gameData.storePack.rechargeAmount = player.gameData.storePack.rechargeAmount + v.count
|
|||
|
|
local myPlayerId = player.gameData.partner.id
|
|||
|
|
if myPlayerId then
|
|||
|
|
--充值时更新下最新的充值记录
|
|||
|
|
skynet.server.personal:SetDetail( myPlayerId , "rechargeAmount" , player.gameData.storePack.rechargeAmount )
|
|||
|
|
end
|
|||
|
|
elseif v.id == dataType.PointsType_Time then
|
|||
|
|
-- --限时累充积分修改
|
|||
|
|
-- local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue" )
|
|||
|
|
-- if next(player.gameData.design.timeCardPoolInfo) ~= nil then
|
|||
|
|
-- for k1 , v1 in pairs(player.gameData.design.timeCardPoints) do
|
|||
|
|
-- if v1.raffleId == player.gameData.design.timeCardPoolInfo.id then
|
|||
|
|
-- v1.points = v1.points + v.count * cfgSValue.valueAccumulatePoint
|
|||
|
|
-- break
|
|||
|
|
-- end
|
|||
|
|
-- end
|
|||
|
|
-- end
|
|||
|
|
|
|||
|
|
--添加累计积分
|
|||
|
|
skynet.server.activityLimitedAccum:AddPoints(player,v.count)
|
|||
|
|
|
|||
|
|
end
|
|||
|
|
skynet.server.store:ChangePoint( player )
|
|||
|
|
end
|
|||
|
|
elseif v.type >= dataType.GoodsType_Furniture and v.type <= dataType.GoodsType_End then
|
|||
|
|
--套装单独处理
|
|||
|
|
if v.type == dataType.GoodsType_Suit then
|
|||
|
|
local cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Suit")
|
|||
|
|
for k1 , v1 in pairs(cfgAll) do
|
|||
|
|
if v1.id == v.id then
|
|||
|
|
--家具套装
|
|||
|
|
local cfgAllFur = skynet.server.gameConfig:GetPlayerAllCfg(player, "Furniture")
|
|||
|
|
for k2 , v2 in pairs(cfgAllFur) do
|
|||
|
|
if v2.suitType == v1.id then
|
|||
|
|
skynet.server.bag:AddGoodsNoExp(player, dataType.GoodsType_Furniture, v2.id, v.count,true)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
--装修套装
|
|||
|
|
local cfgAllDec = skynet.server.gameConfig:GetPlayerAllCfg(player, "Decoration")
|
|||
|
|
for k2 , v2 in pairs(cfgAllDec) do
|
|||
|
|
if v2.suitType == v1.id then
|
|||
|
|
skynet.server.bag:AddGoodsNoExp(player, dataType.GoodsType_Decorate, v2.id, v.count,true)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
elseif v.type == dataType.GoodsType_ClothesSuit then
|
|||
|
|
local cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "ClothesSuit")
|
|||
|
|
for k1 , v1 in pairs(cfgAll) do
|
|||
|
|
if v1.id == v.id and v1.type == 1 then
|
|||
|
|
--人物套装
|
|||
|
|
local cfgAllClothes = skynet.server.gameConfig:GetPlayerAllCfg(player, "Clothes")
|
|||
|
|
for k2 , v2 in pairs(cfgAllClothes) do
|
|||
|
|
if v2.suitId == v1.id then
|
|||
|
|
skynet.server.bag:AddGoodsNoExp(player, dataType.GoodsType_Clothes, v2.id, v.count,true)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
break
|
|||
|
|
elseif v1.id == v.id and v1.type == 2 then
|
|||
|
|
--宠物套装
|
|||
|
|
local cfgAllClothes = skynet.server.gameConfig:GetPlayerAllCfg(player, "PetClothes")
|
|||
|
|
for k2 , v2 in pairs(cfgAllClothes) do
|
|||
|
|
if v2.suitId == v1.id then
|
|||
|
|
skynet.server.bag:AddGoodsNoExp(player, dataType.GoodsType_PetClothes, v2.id, v.count,true)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
skynet.server.bag:AddGoodsNoExp(player, v.type, v.id, v.count , true)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
if not v.id then
|
|||
|
|
log.debug(string.format("玩家 %d 邮件 ID %s 领取奖励 类型 %d 数量 %d", player.userId, mailId, v.type, v.count))
|
|||
|
|
else
|
|||
|
|
log.debug(string.format("玩家 %d 邮件 ID %s 领取奖励 类型 %d ID %d 数量 %d", player.userId, mailId, v.type, v.id, v.count))
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--批量发送邮件
|
|||
|
|
function Mail:BatchAddMail()
|
|||
|
|
local t1 = skynet.GetTime()
|
|||
|
|
local playerList = skynet.server.playerCenter:GetPlayerList()
|
|||
|
|
local sendCount = 0 --此次发送邮件数量
|
|||
|
|
local isSendMail = true --是否继续发送邮件
|
|||
|
|
for mailId, v1 in pairs(self.mailList) do
|
|||
|
|
local count = 0
|
|||
|
|
if self.MailProperty_AllServer == v1.mailType and not v1.isSendAllOnlineUser then
|
|||
|
|
--全服邮件 能发送 并且未发送完
|
|||
|
|
for userId, value in pairs(playerList) do
|
|||
|
|
if skynet.server.playerCenter.Status_Playing == value.status and not value.onlineMailList[mailId] then
|
|||
|
|
--在线玩家并且未接收该邮件
|
|||
|
|
self:AddMail(value.player, mailId, v1.mailInfo, v1.award, true)
|
|||
|
|
value.onlineMailList[mailId] = true
|
|||
|
|
count = count + 1
|
|||
|
|
sendCount = sendCount + 1
|
|||
|
|
|
|||
|
|
if sendCount >= self.MaxSendCount then
|
|||
|
|
isSendMail = false
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if 0 == count then
|
|||
|
|
v1.isSendAllOnlineUser = true
|
|||
|
|
log.debug(string.format("邮箱 全服邮件 %s 在线已发送结束 ", mailId))
|
|||
|
|
else
|
|||
|
|
log.debug(string.format("邮箱 全服邮件 %s 发送 发送数量 %d 时间花费 %d ", mailId, count, skynet.GetTime() - t1))
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if not isSendMail then
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--添加邮件
|
|||
|
|
function Mail:AddMail(player, mailId, mailInfo, award, isWebSend, isLogin)
|
|||
|
|
--玩家已经存在该邮件了,不再发送
|
|||
|
|
if self:IsExist(player, mailId) then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local nowTime = skynet.GetTime()
|
|||
|
|
--过了或者未到有效时间,不再发送
|
|||
|
|
if isWebSend then
|
|||
|
|
--玩家游戏的包的cig是否符合该公告的cgi
|
|||
|
|
local cgi = player.basicInfo.gameCgi
|
|||
|
|
if mailInfo.gameId ~= cgi then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
--玩家的渠道是否符合
|
|||
|
|
if player.basicInfo.channel ~= mailInfo.useChannel and "all" ~= mailInfo.useChannel then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
--玩家的系统是否符合
|
|||
|
|
if player.basicInfo.system ~= mailInfo.operatingSystem and "all" ~= mailInfo.operatingSystem and "双端" ~= mailInfo.operatingSystem then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
--玩家的APP版本是否符合
|
|||
|
|
if player.basicInfo.appVersion < tonumber(mailInfo.minVersion) then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
--判断玩家的创建时间是否符合
|
|||
|
|
if mailInfo.playerCreateStart and player.basicInfo.regTime < skynet.server.common:GetTime(mailInfo.playerCreateStart) then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
if mailInfo.playerCreateEnd and player.basicInfo.regTime > skynet.server.common:GetTime(mailInfo.playerCreateEnd) then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
--判断该邮件还需继续发送吗
|
|||
|
|
if nowTime > skynet.server.common:GetTime(mailInfo.playerFailureTime) or nowTime < skynet.server.common:GetTime(mailInfo.playerEffectiveTime) then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local mail = player.gameData.mail
|
|||
|
|
local mailType = nil
|
|||
|
|
if "信息" == mailInfo.mailType then
|
|||
|
|
mailType = pb.enum("PBMailInfo.MailType", "Message")
|
|||
|
|
elseif "奖励" == mailInfo.mailType then
|
|||
|
|
mailType = pb.enum("PBMailInfo.MailType", "Award")
|
|||
|
|
elseif "补偿" == mailInfo.mailType then
|
|||
|
|
mailType = pb.enum("PBMailInfo.MailType", "Award")
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local curIndex = mail.curIndex
|
|||
|
|
mail.mailList[curIndex] = {}
|
|||
|
|
mail.mailList[curIndex].mailId = mailId
|
|||
|
|
mail.mailList[curIndex].status = dataType.MailStatus_NoGet
|
|||
|
|
mail.mailList[curIndex].mailType = mailType
|
|||
|
|
mail.mailList[curIndex].mailSubType = 1
|
|||
|
|
mail.mailList[curIndex].title = mailInfo.mailTitle
|
|||
|
|
mail.mailList[curIndex].content = mailInfo.mailText
|
|||
|
|
mail.mailList[curIndex].award = {} --奖励
|
|||
|
|
|
|||
|
|
if award then
|
|||
|
|
if not isWebSend then
|
|||
|
|
--不是来自后台的邮件
|
|||
|
|
for k, v in pairs(award) do
|
|||
|
|
if v.type == 0 then
|
|||
|
|
table.insert(mail.mailList[curIndex].award, { type = v.id, count = v.count })
|
|||
|
|
else
|
|||
|
|
table.insert(mail.mailList[curIndex].award, { type = v.type, id = v.id, count = v.count })
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
--来自后台的邮件
|
|||
|
|
for k, v in pairs(award) do
|
|||
|
|
local goodsType = skynet.server.common:AwardTypeStrToInt(v.articlesType)
|
|||
|
|
if goodsType == dataType.GoodsType_Init then
|
|||
|
|
table.insert(mail.mailList[curIndex].award, { type = v.articlesId, count = v.articlesNumber })
|
|||
|
|
else
|
|||
|
|
table.insert(mail.mailList[curIndex].award, { type = goodsType, id = v.articlesId, count = v.articlesNumber })
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
mail.mailList[curIndex].receiveTime = skynet.GetTime()
|
|||
|
|
mail.mailList[curIndex].failureTime = skynet.server.common:GetAfterSomeHour(mailInfo.mailEffectiveTime * 24) --邮件的失效时间就是玩家获取到邮件之后的多少天
|
|||
|
|
|
|||
|
|
--插入玩家领取过的邮件ID
|
|||
|
|
table.insert(mail.historyMail, mailId)
|
|||
|
|
|
|||
|
|
--增加邮件红点
|
|||
|
|
if isLogin then
|
|||
|
|
skynet.server.msgTips:AddNoNotice(player, 23)
|
|||
|
|
else
|
|||
|
|
skynet.server.msgTips:Add(player, 23)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--玩家最多30条最近的邮件记录
|
|||
|
|
mail.curIndex = mail.curIndex + 1
|
|||
|
|
if mail.curIndex >= 30 then
|
|||
|
|
mail.curIndex = 1
|
|||
|
|
end
|
|||
|
|
--skynet.server.gameServer:SendMsgToUser(self.userId, "CMD_S2C_Mail", data)
|
|||
|
|
log.debug(string.format("玩家 %d 邮箱 新增邮件 ID %s ", player.userId, mailId))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--添加新邮件
|
|||
|
|
function Mail:AddNewMail(player, mailType, mailTitle, mailText, award, isLogin)
|
|||
|
|
--转义
|
|||
|
|
mailText = string.gsub(mailText,"\n","\\n")
|
|||
|
|
mailText = string.gsub(mailText,"\r","\\r")
|
|||
|
|
mailText = string.gsub(mailText,"\t","\\t")
|
|||
|
|
mailText = string.gsub(mailText,"\"","")
|
|||
|
|
mailText = string.gsub(mailText,'"',"")
|
|||
|
|
|
|||
|
|
local curMailType = nil
|
|||
|
|
if self.MailType_Msg == mailType then
|
|||
|
|
curMailType = "信息"
|
|||
|
|
elseif self.MailType_Award == mailType then
|
|||
|
|
curMailType = "奖励"
|
|||
|
|
elseif self.MailType_Compensate == mailType then
|
|||
|
|
curMailType = "补偿"
|
|||
|
|
end
|
|||
|
|
if isLogin == nil then
|
|||
|
|
isLogin = false
|
|||
|
|
end
|
|||
|
|
local mailInfo = { mailType = curMailType, mailTitle = mailTitle, mailText = mailText, mailEffectiveTime = 7 }
|
|||
|
|
local mailId = player.gameData.partner.id .. math.random(1000, 9999) .. math.random(1000000, 9999999)
|
|||
|
|
self:AddMail(player, mailId, mailInfo, award, false, isLogin)
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--通过好友ID发送异步邮件
|
|||
|
|
function Mail:SendAsyncMailForPartnerId( partnerId, mailType, mailTitle, mailText, award )
|
|||
|
|
local playerInfo = skynet.server.personal:GetDetail( partnerId )
|
|||
|
|
if not playerInfo then
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--获取邮件消息数据
|
|||
|
|
local function GetMailMsgData()
|
|||
|
|
local msgData = {}
|
|||
|
|
local mailData = {}
|
|||
|
|
|
|||
|
|
mailData.mailType = mailType
|
|||
|
|
mailData.mailTitle = mailTitle
|
|||
|
|
mailData.mailText = mailText
|
|||
|
|
mailData.award = award
|
|||
|
|
|
|||
|
|
msgData.userId = playerInfo.userId
|
|||
|
|
msgData.mailData = mailData
|
|||
|
|
return msgData
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if playerInfo.isOnline and 0 ~= playerInfo.gameServerId then
|
|||
|
|
if serverId == playerInfo.gameServerId then
|
|||
|
|
--玩家在线,直接发到同一服
|
|||
|
|
local player = skynet.server.playerCenter:GetPlayer( playerInfo.userId )
|
|||
|
|
if not player then
|
|||
|
|
log.info(string.format("玩家 %s 发送异步邮件失败,不存在玩家" , playerInfo.account ))
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
self:AddNewMail( player , mailType, mailTitle, mailText, award )
|
|||
|
|
return true
|
|||
|
|
else
|
|||
|
|
--玩家在线,通过架构内消息,将新增邮件推到玩家所在的游戏服
|
|||
|
|
local msgData = GetMailMsgData()
|
|||
|
|
skynet.server.clusterServer:SendMsgToServer( playerInfo.gameServerId , skynet.server.clusterServer.GameToGame_AddMail, msgData )
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
--玩家离线,将邮件数据放到玩家的在redis中的列表去,上线就能获取
|
|||
|
|
local msgData = GetMailMsgData()
|
|||
|
|
skynet.server.personal:AddOfflineMsg( partnerId , dataType.OfflineMsgType_AddMail , msgData , 45 , 0)
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--通过账号发送异步邮件
|
|||
|
|
function Mail:SendAsyncMailForAccount( account , mailType, mailTitle, mailText, award )
|
|||
|
|
local userDBInfo = skynet.server.redisCenter:GetRedisDBInfo( account )
|
|||
|
|
if userDBInfo and userDBInfo.PartnerId then
|
|||
|
|
self:SendAsyncMailForPartnerId( userDBInfo.PartnerId, mailType, mailTitle, mailText, award )
|
|||
|
|
else
|
|||
|
|
log.info(string.format("玩家 %s 发送异步邮件失败,不存在玩家" , account))
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--检查玩家是否有新邮件
|
|||
|
|
function Mail:CheckNewMail(player)
|
|||
|
|
for mailId, value in pairs(self.mailList) do
|
|||
|
|
if not self:IsExist(player, mailId) then
|
|||
|
|
if "全服" == value.mailInfo.mailCondition then
|
|||
|
|
self:AddMail(player, mailId, value.mailInfo, value.award, true, true)
|
|||
|
|
elseif "ID" == value.mailInfo.mailCondition then
|
|||
|
|
local uidList = skynet.server.common:Split(value.mailInfo.uidlist, ",")
|
|||
|
|
for k, v in pairs(uidList) do
|
|||
|
|
--如果存在本人邮件就发送
|
|||
|
|
if player.account == v then
|
|||
|
|
self:AddMail(player, mailId, value.mailInfo, value.award, true, true)
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--向redis请求我是否有离线邮件根据好友码,后面与下面的功能需要合并
|
|||
|
|
--[[
|
|||
|
|
local partnerId = player.gameData.partner.id
|
|||
|
|
local redisKey = string.format(redisKeyUrl.GameServerMailMyNewZSet, partnerId)
|
|||
|
|
local redisMailList = skynet.server.redis:zrange(redisKey, 0, -1)
|
|||
|
|
for k, v in pairs(redisMailList) do
|
|||
|
|
local tmp = json:decode(v)
|
|||
|
|
self:AddNewMail(player, tmp.mailType, tmp.mailTitle, tmp.mailText, tmp.award, true)
|
|||
|
|
end
|
|||
|
|
skynet.server.redis:zremrangebyscore(redisKey, "-inf", "+inf")
|
|||
|
|
|
|||
|
|
--向redis请求我是否有离线邮件根据帐号
|
|||
|
|
|
|||
|
|
local account = player.basicInfo.accountName
|
|||
|
|
redisKey = string.format(redisKeyUrl.GameServerMailMyNewForAccountZSet, account)
|
|||
|
|
redisMailList = skynet.server.redis:zrange(redisKey, 0, -1)
|
|||
|
|
for k, v in pairs(redisMailList) do
|
|||
|
|
local tmp = json:decode(v)
|
|||
|
|
self:AddNewMail(player, tmp.mailType, tmp.mailTitle, tmp.mailText, tmp.award, true )
|
|||
|
|
end
|
|||
|
|
skynet.server.redis:zremrangebyscore(redisKey, "-inf", "+inf")
|
|||
|
|
]]
|
|||
|
|
|
|||
|
|
--判断邮件是否到期
|
|||
|
|
for k, v in pairs(player.gameData.mail.mailList) do
|
|||
|
|
if v and next(v) ~= nil then
|
|||
|
|
local nowTime = skynet.GetTime()
|
|||
|
|
if nowTime >= v.failureTime then
|
|||
|
|
player.gameData.mail.mailList[k] = nil
|
|||
|
|
skynet.server.msgTips:Reduce(player, 23)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--是否存在邮件
|
|||
|
|
function Mail:IsExist(player, mailId)
|
|||
|
|
for k, v in pairs(player.gameData.mail.historyMail) do
|
|||
|
|
if mailId == v then
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--[[ 返回的newbody.data内容
|
|||
|
|
data ={
|
|||
|
|
mailModel,
|
|||
|
|
giftArticlesModels
|
|||
|
|
}
|
|||
|
|
mailModel{
|
|||
|
|
id = number,
|
|||
|
|
gameId = string, 游戏id
|
|||
|
|
mailId = string, 邮件id
|
|||
|
|
remarks = string, 邮件备注
|
|||
|
|
mailTitle = string, 邮件标题
|
|||
|
|
mailText = string, 邮件正文
|
|||
|
|
giftId = string, 礼包id
|
|||
|
|
giftName = string, 礼包名称
|
|||
|
|
mailCondition = string, 邮件发送条件(全服/id)
|
|||
|
|
quantity = number, 邮件发送数量
|
|||
|
|
uidlist = string, 游戏用户id集合(配合mailCondition为id时使用)
|
|||
|
|
mailType = string, 邮件类型(信息/奖励/补偿)
|
|||
|
|
operatingSystem = string, 邮件发送对应的操作系统
|
|||
|
|
useChannel = string, 使用渠道
|
|||
|
|
packageName = string, 邮件发送对应的包名
|
|||
|
|
minVersion = string, 邮件发送的最小使用版本(默认全版本)
|
|||
|
|
generationTime = string, 生成时间 yyyy-MM-dd HH:mm:ss
|
|||
|
|
mailSendTime = string, 邮件发送时间(邮件点击发送后,若该字段为空,则立即发送;否则,等待该时间后再进行发送邮件) yyyy-MM-dd HH:mm:ss
|
|||
|
|
mailEffectiveTime = number, 邮件发送后可以存在的时间
|
|||
|
|
playerEffectiveTime = string, 玩家登录生效时间 yyyy-MM-dd HH:mm:ss
|
|||
|
|
playerFailureTime = string, 玩家登录失效时间,在此时间之内登录的玩家可以接收到邮件 yyyy-MM-dd HH:mm:ss
|
|||
|
|
enable = string, 邮件状态(未发送/已发送/已失效)
|
|||
|
|
playerCreateStart = string, 玩家创建开始时间 yyyy-MM-dd HH:mm:ss
|
|||
|
|
playerCreateEnd = string, 玩家创建结束时间(在此之间可以领取) yyyy-MM-dd HH:mm:ss
|
|||
|
|
backstageId = number 游戏后台id
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
giftArticlesModels ={
|
|||
|
|
{GiftArticlesModel},{GiftArticlesModel},{GiftArticlesModel}...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
GiftArticlesModel={
|
|||
|
|
id = number,
|
|||
|
|
giftId = string, 礼包id
|
|||
|
|
articlesId = number, 物品id
|
|||
|
|
articlesName = string, 物品名称
|
|||
|
|
articlesType = string, 物品类型
|
|||
|
|
articlesNumber = number,物品数量
|
|||
|
|
articlesPicture = string 物品图片
|
|||
|
|
}
|
|||
|
|
]]
|
|||
|
|
function Mail:FindMailByMailId(mailId)
|
|||
|
|
local mailId = mailId
|
|||
|
|
|
|||
|
|
--缓存存在
|
|||
|
|
if self.WXMailList[mailId] ~= nil and self.WXMailList[mailId].expirationTime > skynet.GetTime() then
|
|||
|
|
return self.WXMailList[mailId].Mail
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local web = skynet.server.gameConfig.WebConfig.host .. ":" .. skynet.server.gameConfig.WebConfig.port
|
|||
|
|
local url = skynet.server.common.findMailUrl
|
|||
|
|
local status, body = skynet.server.httpClient:PostJson(web, url, json:encode(mailId), "http")
|
|||
|
|
if 200 == status then
|
|||
|
|
local newbody = json:decode(body)
|
|||
|
|
if 200 == newbody.code then
|
|||
|
|
self.WXMailList[mailId]={}
|
|||
|
|
self.WXMailList[mailId].Mail= newbody.data
|
|||
|
|
self.WXMailList[mailId].expirationTime = skynet.GetTime() + 60*60*5--一个小时后过期
|
|||
|
|
|
|||
|
|
return self.WXMailList[mailId].Mail
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--默认返回空
|
|||
|
|
return nil
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
skynet.server.mail = Mail
|
|||
|
|
return Mail
|