miduo_client/Assets/ManagedResources/~Lua/Modules/Chat/ChatManager.lua

553 lines
19 KiB
Lua
Raw Normal View History

2020-08-25 15:46:38 +08:00
local _isDebug = false
2020-05-09 13:31:21 +08:00
local specialConfig=ConfigManager.GetConfig(ConfigName.SpecialConfig)
local function __DebugLog(str)
if _isDebug then
Log("<color=#aaaa00>" .. str .. "</color>")
end
end
ChatManager = {}
local this = ChatManager
-- 定时刷新时间
local _DeltaTime = 5
2020-05-09 13:31:21 +08:00
-- 定时刷新数据的通道枚举
local _CHANNEL = {
CHAT_CHANNEL.SYSTEM, -- 系统
CHAT_CHANNEL.GLOBAL, -- 世界
}
this.SYS_MSG_TYPE = {
2021-03-12 14:31:52 +08:00
[0] = {name = Language[10350]},
[1] = {name = Language[10351]},
[2] = {name = Language[10352]}
2020-05-09 13:31:21 +08:00
}
-- 聊天中要显示时间的时间间隔(毫秒)
this.ShowTimeDT = 300000
--初始化
function this.Initialize()
-- 记录玩家上线的时间,小于这个时间的聊天消息(出好友外)不显示(毫秒)
this.LoginTimeStamp = 0
-- 数据
this.ChatList = {}
this.FriendChatList = {}
-- msgId标志位用于记录当前最新消息的消息号刷新时按此消息号进行数据刷新
this.MsgIdFlag = {}
-- 我在世界发言中的时间冷却
this.MyChatTimeStamp = 0
-- 判断是否正在获取聊天信息(避免请求后台运行时请求积累)
this.IsGetMsg = 0
--跑马灯的速度(1秒移动的像素)
this.horseRunSpeed=tonumber(specialConfig[31].Value)
end
-- 每两秒刷新一次数据
function this.TimeUpdate()
if this.IsGetMsg > 0 then return end
-- 不包括好友数据
for _, channel in pairs(_CHANNEL) do
local msgId = this.GetMsgIdFlag(channel)
this.IsGetMsg = this.IsGetMsg + 1
NetManager.RequestChatMsg(channel, msgId, function(data)
this.IsGetMsg = this.IsGetMsg - 1
this.ChatDataAdapter(channel, data)
end)
end
-- 刷新主界面消息
this.RefreshMainPanelShowMsg()
end
-- 开始刷新聊天数据
function this.StartChatDataUpdate()
-- 开始定时刷新
if not this._CountDownTimer then
this._CountDownTimer = Timer.New(this.TimeUpdate, _DeltaTime, -1, true)
this._CountDownTimer:Start()
end
end
--关闭聊天数据刷新
function this.StopChatDataUpdate()
-- 关闭定时刷新
if this._CountDownTimer then
this._CountDownTimer:Stop()
this._CountDownTimer = nil
end
end
-- 公会聊天数据由服务器推送
function this.ReceiveFamilyChat(msg)
if msg.type ~= 2 then return end
this.ChatDataAdapter(CHAT_CHANNEL.FAMILY, {chatInfo = {msg.chatInfo}})
end
-- 初始化数据
function this.InitData(func)
-- 保存当前时间
this.LoginTimeStamp = GetTimeStamp() * 1000
-- 第一次获取数据
local index = 0
local maxIndex = 0
local function serverCB(channel, data)
-- 保存服务器数据
this.ChatDataAdapter(channel, data)
index = index + 1
if index >= maxIndex then
-- 刷新主界面消息
this.RefreshMainPanelShowMsg()
-- 执行回调
if func then func() end
end
end
-- 开始发送请求
for _, channel in pairs(_CHANNEL) do
maxIndex = maxIndex + 1
NetManager.RequestChatMsg(channel, 0, function(data)
serverCB(channel, data)
end)
end
end
-- 发送消息
function this.RequestSendChatMsg(channel, content, func)
-- 好友消息不能通过此接口发送
if CHAT_CHANNEL.FRIEND == channel then return end
-- 限制发言等级
if not ActTimeCtrlManager.SingleFuncState(FUNCTION_OPEN_TYPE.CHAT) then
2021-03-12 14:31:52 +08:00
PopupTipPanel.ShowTip(Language[10353])
2020-05-09 13:31:21 +08:00
return
end
-- 消息正确性检测
if string.len(content) <= 0 then
2021-03-12 14:31:52 +08:00
PopupTipPanel.ShowTip(Language[10354])
2020-05-09 13:31:21 +08:00
return
end
-- 世界发言冷却时间
if channel == CHAT_CHANNEL.GLOBAL then
local curTimeStamp = GetTimeStamp()
if curTimeStamp - this.MyChatTimeStamp < 3 then
2021-03-12 14:31:52 +08:00
PopupTipPanel.ShowTip(Language[10355])
2020-05-09 13:31:21 +08:00
return
end
this.MyChatTimeStamp = curTimeStamp
-- 世界发言消息特殊处理
content = string.format("%d|%s", GLOBAL_CHAT_TYPE.COMMON, content)
elseif channel == CHAT_CHANNEL.FAMILY then
-- 公会发言消息特殊处理
content = string.format("%d|%s", GLOBAL_CHAT_TYPE.COMMON, content)
end
-- 检测屏蔽字(改为后端检测)
-- 发送消息
NetManager.RequestSendChatMsg(channel, content, 0, function(msg)
local msgId = this.GetMsgIdFlag(channel) -- 获取当前最新消息的消息号
--- messageId ~= 0 表示发送的消息包含屏蔽字段,该消息不会被广播,但是发送者在世界聊天中可以看到自己的消息
--- 所以我们需要在前端保存这条消息,但是消息号设置为上一条的消息号,以保证在获取以后的数据时不会丢失数据。
if msg.chatInfo.messageId ~= 0 then
msg.chatInfo.messageId = -1
local data = {
chatInfo = {msg.chatInfo}
}
2021-03-12 14:31:52 +08:00
__DebugLog(Language[10356])
2020-05-09 13:31:21 +08:00
this.ChatDataAdapter(channel, data)
if func then func() end
else
2021-03-12 14:31:52 +08:00
__DebugLog(Language[10357])
2020-05-09 13:31:21 +08:00
if channel == CHAT_CHANNEL.FAMILY then
if func then func() end
else
NetManager.RequestChatMsg(channel, msgId, function(data)
this.ChatDataAdapter(channel, data)
if func then func() end
end)
end
end
end)
end
2020-06-30 18:59:44 +08:00
--
function this.RequestGMCommand(command)
-- 世界发言消息特殊处理
local content = string.format("%d|%s", GLOBAL_CHAT_TYPE.COMMON, command)
-- 请求发送
NetManager.RequestSendChatMsg(CHAT_CHANNEL.GLOBAL, content, 0, function(msg)
2021-03-12 14:31:52 +08:00
PopupTipPanel.ShowTip(Language[10358])
2020-06-30 18:59:44 +08:00
end)
end
2020-05-09 13:31:21 +08:00
-- 设置相应通道的消息的最新消息号
function this.SetMsgIdFlag(channel, msgId)
if not this.MsgIdFlag then
this.MsgIdFlag = {}
end
this.MsgIdFlag[channel] = msgId
end
-- 获取最新消息号
function this.GetMsgIdFlag(channel)
if not this.MsgIdFlag then
this.MsgIdFlag = {}
end
return this.MsgIdFlag[channel] or 0
end
-- 数据处理
function this.ChatDataAdapter(channel, data)
-- 好友数据特殊处理
if channel == CHAT_CHANNEL.FRIEND then return end
-- 先对数据排个序
table.sort(data.chatInfo, function(a, b)
return a.times < b.times
end)
-- 初始化
if not this.ChatList[channel] then
this.ChatList[channel] = {}
end
-- 数据没有变化,则不刷新
local len = #data.chatInfo
if len == 0 then return end
--- 公会数据无需判断消息号
if channel == CHAT_CHANNEL.FAMILY then
__DebugLog("++++++++++++++++++++++++++++++"..channel)
for i = 1, len do
table.insert(this.ChatList[channel], data.chatInfo[i])
2021-03-12 14:31:52 +08:00
__DebugLog(Language[10359]..data.chatInfo[i].msg)
2020-05-09 13:31:21 +08:00
-- 公会红包消息加入跑马灯显示
local anaMsg = string.split(data.chatInfo[i].msg, "#")
local msgType = tonumber(anaMsg[1])
if msgType == GLOBAL_CHAT_TYPE.GUILD_REDPACKET then
local content = this.AnalysisGlobalChat(data.chatInfo[i].msg).content
local race = {
messageId = 0,
msg = content,
speed = this.horseRunSpeed,
multiple = 1,
}
HorseRaceManager.AddRaceData(race)
Log("<color=yellow>ChatManager</color>")
-- if GuildRedPacketManager.isCheck then return end
GuildRedPacketManager.isCheck=true
CheckRedPointStatus(RedPointType.Guild_RedPacket)
end
end
__DebugLog("++++++++++++++++++++++++++++++"..channel)
-- 更新事件
Game.GlobalEvent:DispatchEvent(GameEvent.Chat.OnChatDataChanged, channel)
return
end
--- 非公会
--- 判断messageId是否符合要求新数据得第一条messageId必须比旧数据最后一条大
--- mssageId相等表示包含敏感字未发出的消息此消息需要在前端展示但是不会发送给其他人
__DebugLog("++++++++++++++++++++++++++++++"..channel)
for i = 1, len do
local newChat = data.chatInfo[i]
local newMsgId = tonumber(newChat.messageId) -- 新消息的消息号
local msgIdFlag = this.GetMsgIdFlag(channel) -- 获取当前最新消息号
__DebugLog("--")
2021-03-12 14:20:14 +08:00
LogGreen("消息内容:"..newChat.msg)
LogGreen("本地最新消息"..msgIdFlag..",新消息的消息号:"..newMsgId)
2021-01-26 17:08:39 +08:00
local msgStr = string.split(newChat.msg,"|")
if channel == CHAT_CHANNEL.SYSTEM then
for i = 2, #msgStr do
--1 需要翻译
local oneStr = string.sub(msgStr[i],1,1)
if tonumber(oneStr) == 1 then
msgStr[i] = tostring(string.sub(msgStr[i],2))
msgStr[i] = GetLanguageStrById(msgStr[i])
else
msgStr[i] = tostring(string.sub(msgStr[i],2))
end
end
newChat.msg = string.format(
GetLanguageStrById(msgStr[1]),
tostring(msgStr[2]),
tostring(msgStr[3]),
tostring(msgStr[4]),
tostring(msgStr[5]),
tostring(msgStr[6])
)
end
2021-03-12 14:20:14 +08:00
LogGreen("消息内容:"..newChat.msg)
2020-05-09 13:31:21 +08:00
if msgIdFlag < newMsgId or newMsgId == -1 then
2021-03-12 14:31:52 +08:00
__DebugLog(Language[10362]..tostring(newMsgId == -1))
2020-05-09 13:31:21 +08:00
if newMsgId ~= -1 then -- 消息号为-1表示屏蔽消息保存数据但不保存消息号
this.SetMsgIdFlag(channel, newMsgId) -- 保存当前消息的消息号,避免下次刷新时还会请求
end
2021-03-12 14:31:52 +08:00
__DebugLog(Language[10363]..tostring(tonumber(newChat.times) <= this.LoginTimeStamp))
2020-05-09 13:31:21 +08:00
if tonumber(newChat.times) > this.LoginTimeStamp then -- 登录时间之前的消息都不显示
if channel ~= CHAT_CHANNEL.SYSTEM or this.IsShowInChatPanel(newChat.messageType) then
if not GoodFriendManager.IsInBlackList(newChat.senderId) then -- 判断是否在黑名单中
table.insert(this.ChatList[channel], newChat)
if #this.ChatList[channel] >= PUBLIC_CHAT_MAX_NUM then -- 判断如果超出最大数量,删除最早得数据
table.remove(this.ChatList[channel], 1)
end
end
end
-- 跑马灯数据,保存到跑马灯管理器中
if this.IsShowInHorseRace(newChat.messageType) then
HorseRaceManager.AddRaceData(newChat)
end
end
end
__DebugLog("--")
end
__DebugLog("++++++++++++++++++++++++++++++"..channel)
-- 更新事件
Game.GlobalEvent:DispatchEvent(GameEvent.Chat.OnChatDataChanged, channel)
end
-- 获取好友聊天列表
function this.GetFriendChatChannelList()
local list = {}
local friendChatList = FriendChatManager.GetAllChatList()
for friendId, chatList in pairs(friendChatList) do
if GoodFriendManager.IsMyFriend(friendId) then
-- 获取最后一条数据
local chat = chatList[#chatList]
-- 我发的消息前面加一个我
local content = chat.msg
if chat.senderId == PlayerManager.uid then
2021-03-12 14:31:52 +08:00
content = Language[10364]..content
2020-05-09 13:31:21 +08:00
end
local data = {
friendId = friendId,
content = content,
times = chat.times
}
table.insert(list, data)
end
end
-- 先对数据排个序
table.sort(list, function(a, b)
return a.times > b.times
end)
return list
end
-- 获取数据
function this.GetChatList(channel)
-- 好友
if channel == CHAT_CHANNEL.FRIEND then
return this.GetFriendChatChannelList()
end
return this.ChatList[channel] or {}
end
-- 刷新主界面显示的消息
this._MainPanelChat = nil
local _MainChatList = {
CHAT_CHANNEL.GLOBAL,
CHAT_CHANNEL.SYSTEM,
CHAT_CHANNEL.FAMILY,
}
function this.RefreshMainPanelShowMsg()
-- 获取当前应该显示的数据
local channel = nil
local msg = nil
for _, cnl in pairs(_MainChatList) do
local chatList = this.GetChatList(cnl)
local chat = chatList[#chatList]
if chat then
if not msg or msg.times < chat.times then
channel = cnl
msg = chat
end
end
end
-- 没有要显示的数据
if not msg then return end
-- 保存数据
this._MainPanelChat = {
channel = channel,
chat = msg
}
-- 发送事件刷新
Game.GlobalEvent:DispatchEvent(GameEvent.Chat.OnMainChatChanged)
end
-- 获取主界面显示的消息
function this.GetMainPanelShowMsg()
return this._MainPanelChat
end
-- 请求发送公会邀请
function this.RequestSendGuildInvite(func)
if not PlayerManager.familyId then return end
-- 判断是否在冷却
local _CurTimeStamp = GetTimeStamp()
if this._GuildInviteTimeStamp and _CurTimeStamp - this._GuildInviteTimeStamp < GUILD_INVITE_CD then
local cd = math.floor(GUILD_INVITE_CD - (_CurTimeStamp - this._GuildInviteTimeStamp))
2021-03-12 14:31:52 +08:00
PopupTipPanel.ShowTip(cd..Language[10365])
2020-05-09 13:31:21 +08:00
return
end
-- 构建字符串
local channel = CHAT_CHANNEL.GLOBAL
local guildData = MyGuildManager.GetMyGuildInfo()
local content = string.format(
"%d#%d#%d#%s#%d#%d|",
GLOBAL_CHAT_TYPE.GUILD_INVITE,
PlayerManager.familyId,
guildData.levle,
guildData.name,
guildData.playerIntoLevel,
guildData.joinType
)
-- 发送消息
NetManager.RequestSendChatMsg(channel, content, 0, function()
local msgId = this.GetMsgIdFlag(channel)
NetManager.RequestChatMsg(channel, msgId, function(data)
this.ChatDataAdapter(channel, data)
if func then func() end
end)
this._GuildInviteTimeStamp = GetTimeStamp()
end)
end
2020-05-15 16:52:35 +08:00
-- 请求发送公会援助邀请
function this.RequestSendGuildAid(itemId1,itemId2,func)
if not PlayerManager.familyId then return end
-- 构建字符串
local channel = CHAT_CHANNEL.FAMILY
local guildData = MyGuildManager.GetMyGuildInfo()
local content = ""
if itemId2 then
2021-01-26 17:08:39 +08:00
content = string.format("%s#%s#%s#%s#%s#%s",
(ConfigManager.GetConfigData(ConfigName.ErrorCodeHint,121).Desc),
2020-05-15 16:52:35 +08:00
PlayerManager.nickName,
2021-01-26 17:08:39 +08:00
(ConfigManager.GetConfigData(ConfigName.ItemConfig,itemId1).Name),
2020-05-15 16:52:35 +08:00
tostring(ConfigManager.GetConfigData(ConfigName.GuildHelpConfig,1).RecourseTime[2]),
2021-01-26 17:08:39 +08:00
(ConfigManager.GetConfigData(ConfigName.ItemConfig,itemId2).Name),
2020-05-15 16:52:35 +08:00
tostring(ConfigManager.GetConfigData(ConfigName.GuildHelpConfig,1).RecourseTime[2])
)
else
2020-05-15 17:03:13 +08:00
2021-01-26 17:08:39 +08:00
content = string.format("%s#%s#%s#%s",
(ConfigManager.GetConfigData(ConfigName.ErrorCodeHint,120).Desc),
2020-05-15 16:52:35 +08:00
PlayerManager.nickName,
2021-01-26 17:08:39 +08:00
(ConfigManager.GetConfigData(ConfigName.ItemConfig,itemId1).Name),
2020-05-15 16:52:35 +08:00
tostring(ConfigManager.GetConfigData(ConfigName.GuildHelpConfig,1).RecourseTime[2])
)
end
2020-05-15 17:03:13 +08:00
content = string.format(
"%d#%s",
GLOBAL_CHAT_TYPE.GUILD_AID,
content
)
2020-05-15 16:52:35 +08:00
-- 发送消息
NetManager.RequestSendChatMsg(channel, content, 0, function()
local msgId = this.GetMsgIdFlag(channel)
NetManager.RequestChatMsg(channel, msgId, function(data)
if func then func() end
end)
end)
end
2020-08-20 20:05:38 +08:00
-- 请求发送公会副本
2020-08-21 18:22:53 +08:00
function this.RequestSendGuildTranscript(func)
2020-08-20 20:05:38 +08:00
if not PlayerManager.familyId then return end
-- 构建字符串
local channel = CHAT_CHANNEL.FAMILY
local guildData = MyGuildManager.GetMyGuildInfo()
2021-01-26 17:08:39 +08:00
local content = string.format(
GetLanguageStrById(ConfigManager.GetConfigData(ConfigName.ErrorCodeHint,135).Desc),
PlayerManager.nickName)
2020-08-21 18:22:53 +08:00
this.RequestSendChatMsg(channel, content, function()
2020-08-20 20:05:38 +08:00
end)
end
2020-05-09 13:31:21 +08:00
-- 请求发送公会红包信息
function this.RequestSendRedPacket(curIndex,func)
local redpack=ConfigManager.GetConfigData(ConfigName.GuildRedPackConfig,curIndex)
if not PlayerManager.familyId then return end
-- 构建字符串
local channel = CHAT_CHANNEL.FAMILY
local content = string.format(
"%d#%s#%s",--"%d#%d#%d#%s#%d#%d|",
GLOBAL_CHAT_TYPE.GUILD_REDPACKET,
PlayerManager.nickName,
2021-01-26 17:08:39 +08:00
GetLanguageStrById(redpack.Name)
2020-05-09 13:31:21 +08:00
)
-- 发送消息
NetManager.RequestSendChatMsg(channel, content, 0, function()
local msgId = this.GetMsgIdFlag(channel)
NetManager.RequestChatMsg(channel, msgId, function(data)
if func then func() end
end)
end)
end
-- 解析世界聊天数据
function this.AnalysisGlobalChat(msg)
local chat = {}
local msgList = string.split(msg, "|")
local headStr = table.remove(msgList, 1)
local headList = string.split(headStr, "#")
chat.type = tonumber(headList[1])
if chat.type == GLOBAL_CHAT_TYPE.COMMON then
chat.content = table.concat(msgList, "|")
elseif chat.type == GLOBAL_CHAT_TYPE.GUILD_INVITE then
chat.gId = tonumber(headList[2])
chat.gLv = tonumber(headList[3])
chat.gName = headList[4]
chat.gLimitLv = tonumber(headList[5])
chat.joinType = tonumber(headList[6])
chat.content = string.format(
2021-01-26 17:08:39 +08:00
GetLanguageStrById(ConfigManager.GetConfigData(ConfigName.ErrorCodeHint,136).Desc),
2020-05-09 13:31:21 +08:00
chat.gLv,
chat.gName,
chat.gLimitLv)
elseif chat.type==GLOBAL_CHAT_TYPE.GUILD_REDPACKET then
chat.nickName=headList[2]
2021-01-26 17:08:39 +08:00
chat.redpackName=GetLanguageStrById(headList[3])
chat.content = string.format(
GetLanguageStrById(ConfigManager.GetConfigData(ConfigName.ErrorCodeHint,137).Desc),
chat.nickName,
chat.redpackName)
2020-05-15 17:03:13 +08:00
elseif chat.type==GLOBAL_CHAT_TYPE.GUILD_AID then
2021-01-26 17:08:39 +08:00
--chat.content = headList[2]
chat.content = string.format(GetLanguageStrById(headList[2]),
GetLanguageStrById(tostring(headList[3])),
GetLanguageStrById(tostring(headList[4])),
GetLanguageStrById(tostring(headList[5])),
GetLanguageStrById(tostring(headList[6])),
GetLanguageStrById(tostring(headList[7])),
GetLanguageStrById(tostring(headList[8]))
)
2020-05-09 13:31:21 +08:00
end
return chat
end
-- 判断是否需要在聊天中显示
function this.IsShowInChatPanel(msgType)
local config = ConfigManager.TryGetConfigDataByKey(ConfigName.SystemMessageConfig, "Type", msgType)
if not config then return false end
return config.SystemShow == 1
end
-- 判断是否需要在跑马灯中显示
function this.IsShowInHorseRace(msgType)
local config = ConfigManager.TryGetConfigDataByKey(ConfigName.SystemMessageConfig, "Type", msgType)
if not config then return false end
return config.lanternShow == 1
end
2020-06-23 18:36:24 +08:00
return this