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

281 lines
12 KiB
Lua
Raw Permalink 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 json = require "json"
local common = require "Common"
local Announcement = oo.class()
Announcement.AnnouncementOpType_1 = 1 --获取公告列表
Announcement.AnnouncementOpStatus_Suc = 1 --操作状态成功
Announcement.AnnouncementOpStatus_NoAnnouncementID = 2 --不存在该公告ID
Announcement.EventAnnouncement = 1 --活动公告
Announcement.UpdateAnnouncement = 2 --更新公告
Announcement.PeripheralAnnouncement = 3 --周边公告
Announcement.NextAnnouncement = 4 --下次预告
Announcement.MaxSendCount = 100 --一次发送最大数量
function Announcement:Init()
self.announcementList = {}
end
--每5秒调一次
function Announcement:On5SecTimer()
self:BatchSend()
end
--从后台刷新公告列表
function Announcement:RefreshAnnouncementList()
--向后端请求
local param = {}
local web = skynet.server.gameConfig.WebConfig.host .. ":" .. skynet.server.gameConfig.WebConfig.port
local url = skynet.server.common.getAnnouncementUrl
local status, body = skynet.server.httpClient:PostJson(web, url, json:encode(param), "http")
if 200 == status then
-- newbody 即后台的 ResultModel
local newbody = json:decode(body)
if 200 == newbody.code then
--判断旧的公告是否还能继续使用
if next(Announcement.announcementList)~=nil then
for k ,v in pairs(Announcement.announcementList) do
local canGet = false
for k1, v1 in pairs(newbody.data) do
if v.announcementId==v1.id then
canGet = true
break
end
end
v.canGet = canGet
end
end
--添加新的公告
for k, v in pairs(newbody.data) do
local announcementId = v.id
if not Announcement.announcementList[announcementId] then
Announcement.announcementList[announcementId] = {}
local curAnnounce = Announcement.announcementList[announcementId]
curAnnounce.announcementId = announcementId
curAnnounce.status = dataType.AnnouncementStatus_NoGet
curAnnounce.announcementRemarks = v.remarks
curAnnounce.announcementWeight = v.weight
curAnnounce.title = v.announcementTitle
curAnnounce.content = v.announcementText
curAnnounce.receiveTime = skynet.GetTime()--skynet.server.common:GetStrTime(skynet.GetTime())
curAnnounce.announcementType = v.announcementType
curAnnounce.canGet = true
curAnnounce.isSendAllOnlineUser = false --是否发送所有在线玩家
--只显示一张图片
if v.img then
curAnnounce.image = v.img[1]
end
--Announcement:SendAnnouncementToOnlineUser(announcementId, v)
end
end
elseif 802 == newbody.code then
--s2cData.code = errorInfo.ErrorCode.AlreadyGet
--将所有公告的获取状态修改为不可获取
if next(Announcement.announcementList)~=nil then
for k ,v in pairs(Announcement.announcementList) do
v.canGet = false
end
end
end
else
log.info("公告刷新 获取数据失败 status ", status or 0)
end
end
--公告历史
function Announcement:History(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SAnnouncementHistory", c2sData.data))
local data = {}
data.announcementInfo = {}
for k, v in pairs(player.gameData.announcement.historyAnnouncement) do
for k1 , v1 in pairs(Announcement.announcementList) do
if v1.canGet then
for k2 ,v2 in pairs(player.gameData.announcement.announcementList) do
if v==k1 and v2.announcementId == v and not v2.look then
table.insert(data.announcementInfo ,v1)
if v1.announcementType == Announcement.EventAnnouncement then
skynet.server.msgTips:Reduce(player , 44)
v2.look = true
elseif v1.announcementType == Announcement.UpdateAnnouncement then
skynet.server.msgTips:Reduce(player , 45)
v2.look = true
elseif v1.announcementType == Announcement.PeripheralAnnouncement then
skynet.server.msgTips:Reduce(player , 46)
v2.look = true
elseif v1.announcementType == Announcement.NextAnnouncement then
skynet.server.msgTips:Reduce(player , 47)
v2.look = true
end
elseif v==k1 and v2.announcementId ==v and v2.look then
table.insert(data.announcementInfo ,v1)
end
end
end
end
end
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_AnnouncementHistory")
s2cData.data = assert(pb.encode("S2CAnnouncementHistory", data))
end
--发送新公告给在线玩家
function Announcement:SendAnnouncementToOnlineUser(announcementId, announcementInfo)
local playerList = skynet.server.playerCenter:GetPlayerList()
local t1 = skynet.GetTime()
local count = 0
--给在线玩家发送新公告
for userId, value in pairs(playerList) do
if skynet.server.playerCenter.Status_Playing == value.status then
Announcement:AddAnnouncement(value.player, announcementId, announcementInfo)
count = count + 1
end
end
log.info(string.format("公告板 全玩家发送公告 发送数量 %d 时间花费 %d ", count, skynet.GetTime() - t1))
end
--添加公告
function Announcement:AddAnnouncement(player, announcementId, announcementInfo)
--玩家已经存在该公告了,不再发送
if Announcement:IsExist(player, announcementId) then
return true
end
--[[
--玩家的APP版本是否符合
if self.basicInfo.appVersion < AnnouncementInfo.appVersion then
return
end
--玩家的渠道是否符合
if self.basicInfo.channel ~= AnnouncementInfo.channel and "all" ~= AnnouncementInfo.channel then
return
end
--玩家的系统不符也不发
if self.basicInfo.platform ~= AnnouncementInfo.operatingSystem and "all" ~= AnnouncementInfo.operatingSystem then
return
end
]]
local announcement = player.gameData.announcement
local curIndex = announcement.curIndex
announcement.announcementList[curIndex] = {}
announcement.announcementList[curIndex].announcementId = announcementId
announcement.announcementList[curIndex].look = false
--announcement.announcementList[curIndex].status = dataType.AnnouncementStatus_NoGet
--announcement.announcementList[curIndex].AnnouncementRemarks = AnnouncementInfo.remarks
--announcement.announcementList[curIndex].AnnouncementWeight = AnnouncementInfo.weight
--announcement.announcementList[curIndex].title = AnnouncementInfo.announcementTitle
--announcement.announcementList[curIndex].content = AnnouncementInfo.announcementText
--announcement.announcementList[curIndex].receiveTime = skynet.GetTime()--skynet.server.common:GetStrTime(skynet.GetTime())
--announcement.announcementList[curIndex].announcementType = AnnouncementInfo.announcementType
--插入玩家收到过的公告ID
table.insert(announcement.historyAnnouncement, announcementId)
--玩家最多30条最近的公告记录
announcement.curIndex = announcement.curIndex + 1
if announcement.curIndex >= 30 then
announcement.curIndex = 1
end
--打包数据给客户端
local data = {}
data.announcementInfo = {}
table.insert(data.announcementInfo , announcementInfo)
skynet.server.gameServer:SendMsgToUser(player.userId, "CMD_S2C_AnnouncementNew", data)
log.info(string.format("玩家 %d 公告版 新增公告 ID %s ", player.userId, announcementId))
end
--检查玩家是否有新公告
function Announcement:CheckNewAnnouncement(player)
--重置公告红点
skynet.server.msgTips:Reset(player , 44)
skynet.server.msgTips:Reset(player , 45)
skynet.server.msgTips:Reset(player , 46)
skynet.server.msgTips:Reset(player , 47)
for k, v in pairs(Announcement.announcementList) do
if not Announcement:IsExist(player, k) and v.canGet then
Announcement:AddAnnouncement(player, k, v)
end
end
--红点系统
if next(player.gameData.announcement.announcementList) ~= nil then
for k , v in pairs(player.gameData.announcement.announcementList) do
-- 如果玩家有未查看到的公告则添加对应的红点
if not v.look then
for k1 , v1 in pairs(Announcement.announcementList) do
--添加对应红点 判断一下公告类型
if v.announcementId==v1.announcementId and v1.announcementType == Announcement.EventAnnouncement and not v.look then
skynet.server.msgTips:Add(player , 44)
elseif v.announcementId==v1.announcementId and v1.announcementType == Announcement.UpdateAnnouncement and not v.look then
skynet.server.msgTips:Add(player , 45)
elseif v.announcementId==v1.announcementId and v1.announcementType == Announcement.PeripheralAnnouncement and not v.look then
skynet.server.msgTips:Add(player , 46)
elseif v.announcementId==v1.announcementId and v1.announcementType == Announcement.NextAnnouncement and not v.look then
skynet.server.msgTips:Add(player , 47)
end
end
end
end
end
end
--是否存在公告
function Announcement:IsExist(player, announcementId)
for k, v in pairs(player.gameData.announcement.historyAnnouncement) do
if announcementId == v then
return true
end
end
return false
end
--批量发送公告
function Announcement:BatchSend()
local t1 = skynet.GetTime()
local playerList = skynet.server.playerCenter:GetPlayerList()
local sendCount = 0 --此次发送邮件数量
local isSendMail = true --是否继续发送邮件
for announceId, v1 in pairs( self.announcementList ) do
local count = 0
if self.MailType_AllServer == v1.mailType and v1.canGet and not v1.isSendAllOnlineUser then --全服邮件 能发送 并且未发送完
for userId, value in pairs(playerList) do
if skynet.server.playerCenter.Status_Playing == value.status and not value.onlineAnnounceList[ announceId ] then --在线玩家并且未接收该邮件
self:AddAnnouncement(value.player, announceId, v1)
value.onlineAnnounceList[ announceId ] = 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.info(string.format("公告 全服公告 %s 在线已发送结束 ", announceId ))
else
log.info(string.format("公告 全服公告 %s 发送 发送数量 %d 时间花费 %d ", announceId , count, skynet.GetTime() - t1))
end
end
if not isSendMail then
break
end
end
end
--相当于单例
skynet.server.announcement = Announcement
return Announcement