local ChannelChat_Model = {} local private = {} local EventSystem = require("Event/EventSystem") local use_trumt_pb = require "Proto/use_trumt_pb" local chat_pb = require("Proto/chat_pb") local chat_operate_pb = require("Proto/chat_operate_pb") local chat_error_pb = require("Proto/chat_error_pb") local chat_gamex_pb = require("Proto/chat_gamex_pb") local JSON = require("cjson") local LuaUpdater = require("Main.LuaUpdater") local LuaFuncEntry = require("Main/LuaFuncEntry") local SERVER_SHOW_FORMAT = "[%s]" local EMPTY_CHANNEL_NAME = "Empty_Channel" local AUDIO_RED_KEY = "AUDIO_CHAT_NOT_RED" local AUDIO_AUTO_PLAY_KEY = "AUDIO_CHAT_AUTO_PLAY" -- 语音自动播放开关 local AUDIO_AUTO_BULLET_KEY = "AUDIO_AUTO_BULLET_KEY" -- 弹幕频道开关 local INTERVAL_PLAY_AUDIO = 1 --**********公有数据********** --保存频道ID,对应值是配置表Chat.csv中的ID ChannelChat_Model.ChannelCfgId = { World = 1, -- 世界 Legion = 2, -- 势力 Team = 3, -- 队伍 ZhaoMu = 4, -- 招募 Current = 5, -- 当前 System = 6, -- 系统 GuildWar = 7, -- 势力战 Mixture = 8, -- 综合 不是一个单独频道是将其他频道都显示出来 GuildPartyExam = 11, -- 答题 MyCamp = 12, -- 我方 Cross = 13, -- 跨服 WarZone = 14, -- 战区 SpecifiedActivity = 15, -- 特定活动 Bullet = 16, -- 弹幕 Country = 17, -- 国家 SceneQuiz = 18, --场景答题 PKRoom = 20, -- 切磋房间 GVGFight = 21, -- 攻城略地(GVG) GroupChat = 23, -- 群聊用,不显示在聊天UI内 PetBreedChat = 24, -- 宠物繁殖房间用 } -- 动态添加设置的频道 private.DynamicSettingChannel = { [ChannelChat_Model.ChannelCfgId.WarZone] = true, [ChannelChat_Model.ChannelCfgId.GuildWar] = true, [ChannelChat_Model.ChannelCfgId.SpecifiedActivity] = true, [ChannelChat_Model.ChannelCfgId.Bullet] = true, [ChannelChat_Model.ChannelCfgId.Country] = true, [ChannelChat_Model.ChannelCfgId.GVGFight] = true } --动态连接聊天服的频道 private.DynamicJoinChatChannelId = { [ChannelChat_Model.ChannelCfgId.Team] = 1, [ChannelChat_Model.ChannelCfgId.Current] = 1, [ChannelChat_Model.ChannelCfgId.Legion] = 1, [ChannelChat_Model.ChannelCfgId.GuildPartyExam] = 1, [ChannelChat_Model.ChannelCfgId.GuildWar] = 1, [ChannelChat_Model.ChannelCfgId.WarZone] = 1, [ChannelChat_Model.ChannelCfgId.SpecifiedActivity] = 1, [ChannelChat_Model.ChannelCfgId.MyCamp] = 1, [ChannelChat_Model.ChannelCfgId.Bullet] = 1, [ChannelChat_Model.ChannelCfgId.PKRoom] = 1, [ChannelChat_Model.ChannelCfgId.Country] = 1, [ChannelChat_Model.ChannelCfgId.SceneQuiz] = 1, [ChannelChat_Model.ChannelCfgId.GVGFight] = 1, [ChannelChat_Model.ChannelCfgId.GroupChat] = 1, [ChannelChat_Model.ChannelCfgId.PetBreedChat] = 1, } ChannelChat_Model.TrumtType = { SelfServer = use_trumt_pb.SelfSever, -- 本服喇叭 WarZone = use_trumt_pb.WarZone, -- 战区喇叭 Cross = use_trumt_pb.Cross, -- 跨服喇叭 } ChannelChat_Model.TrumtType2ChannelCfgId = { [ChannelChat_Model.TrumtType.Cross] = ChannelChat_Model.ChannelCfgId.Cross, [ChannelChat_Model.TrumtType.WarZone] = ChannelChat_Model.ChannelCfgId.WarZone, [ChannelChat_Model.TrumtType.SelfServer] = ChannelChat_Model.ChannelCfgId.World, } --**********End公有数据********** --**********私有数据********** local HandleMsgCountLimit = 5 local recvMsgIdList = {} local recvMsgDataList = {} local GlobalMsgNum = 20 local CurChannelID = "" local CurPrivateChatID = 0 --4个需要显示红点的频道是否有新消息 local WorldChannelNewMsg = false local TeamChannelNewMsg = false local ZoneChannelNewMsg = false local ChannelChatIsOpen = false local GlobalChatDlgIsOpen = false local NeedRefreshRedPointChannelID = "" local AnnouncementMsg = "" local LoginTime = 0 --保存聊天小窗的100条消息 local ChatDlgMsgList = {} local NotSendMsg = "" --封禁理由 local forbiddenChatReason = "" --封禁结束时间 -1 永久封禁 local forbiddenChatEndTime = 0 local allChannelMsgList = {} local switchingCrossChannel = nil local curCrossSubChannelSuffix = nil --当前的跨服子频道 local curWarZoneId = nil --禁言频道 local silenceChannels --该类型主要用于区分是私聊还是频道聊天 local CurChatType = 0 local CurChannelType = 0 local isDragToEnd = true local notReadMsgCount = 0 local isFirstPassLevelForNew = true local tmpGuideStep = -1 local ChannelCfgIdNameDict = {} --CfgID->ChannelID --策划需求当前频道聊天框切换之后不情况内容 --该变量用于记录缓存,切换场景之后再添加到当前频道 local CurrentChannelCacheMsgList = {} ChannelChat_Model.TemplateParamType = { --角色名 RoleName = chat_pb.TemplateParam.RoleName, --道具名 ItemName = chat_pb.TemplateParam.ItemName, --地图名 MapName = chat_pb.TemplateParam.MapName, --世界Boss BossName = chat_pb.TemplateParam.BossName, --/时间 Time = chat_pb.TemplateParam.Time, --地图坐标 MapPoint = chat_pb.TemplateParam.MapPoint, --队伍招募信息 TeamRecruit = chat_pb.TemplateParam.TeamRecruit, GuildName = chat_pb.TemplateParam.GuildName, GuildLevel = chat_pb.TemplateParam.GuildLevel, --军团招募 GuildRecruit = chat_pb.TemplateParam.GuildRecruit, --军团引荐 GuildRecommend = chat_pb.TemplateParam.GuildRecommend, IdsOrStr = chat_pb.TemplateParam.IdsOrStr, -- GuildBuilding = chat_pb.TemplateParam.GuildBuilding, -- 军团势力名 GuildAlliesPowerName = chat_pb.TemplateParam.PowerName, GuildWarBattle = chat_pb.TemplateParam.GuildWarBattle, -- 军团活动答题结果 GuildPartyAnswer = chat_pb.TemplateParam.GuildPartyAnswer, Achievement = chat_pb.TemplateParam.Achievement, -- 成就 Nobility = chat_pb.TemplateParam.Nobility, -- 爵位 GoldenHeroBossActivity = chat_pb.TemplateParam.ActivityId, --金将体验协同讨伐boss的活动ID GoldenHeroBossId = chat_pb.TemplateParam.GoldHeroBossId, --金将体验协同讨伐boss的唯一ID TreasureId = chat_pb.TemplateParam.TreasureId, --宝物id HorseId = chat_pb.TemplateParam.HorseId, --战骑id MonthCard = chat_pb.TemplateParam.MonthCard, --月卡id RedEnvelopeID = chat_pb.TemplateParam.RedEnvelopeID, -- 红包的唯一ID。 RedEnvelopeCfgID = chat_pb.TemplateParam.RedEnvelopeCfgID, -- 红包策划配置ID。 TimeRefreshId = chat_pb.TemplateParam.TimeRefreshId, --时间刷新ID VoiceChat = chat_pb.TemplateParam.VoiceChat, --语音聊天 GoldHeroReprint = chat_pb.TemplateParam.GoldHeroReprint, --语音聊天 CountryName = chat_pb.TemplateParam.CountryName, --国家名 CountryJobIds = chat_pb.TemplateParam.CountryJobIds, --国家职位ids CountryNightBossRecruit = chat_pb.TemplateParam.CountryBossRecruit, -- 国战晚间Boss召集 Arabic = chat_pb.TemplateParam.Arabic, --阿拉伯语 GveLand = chat_pb.TemplateParam.GveLand, --SlgGvE城池Boss召集 } local sortedEmojiDataList = nil --**********End私有数据********** --**********私有数据访问********** function ChannelChat_Model.GetNotReadMsgCount() return notReadMsgCount end function ChannelChat_Model.ResetNotReadMsgCount() notReadMsgCount = 0 end function ChannelChat_Model.GetIsDragToEnd() return isDragToEnd end function ChannelChat_Model.SetIsDragToEnd(isEnd) isDragToEnd = isEnd end function ChannelChat_Model.GetCurPrivateChatID() return CurPrivateChatID end function ChannelChat_Model.SetCurPrivateChatID(friendId) CurPrivateChatID = friendId end function ChannelChat_Model.GetCurChannelID() return CurChannelID end function ChannelChat_Model.SetFirstPassLevelForNew(guideStep) if tmpGuideStep <= guideStep then tmpGuideStep = guideStep end isFirstPassLevelForNew = tmpGuideStep >= 1 --这里先这么做 代表通过第几个新手引导步骤 解锁聊天 end function ChannelChat_Model.GetFirstPassLevelForNew() return isFirstPassLevelForNew end function ChannelChat_Model.SetCurChannelID(channelID) CurChannelID = channelID end --获取当前聊天房间(频道)的所有缓存数据 function ChannelChat_Model.GetCurChannelMsgList() return allChannelMsgList[ChannelChat_Model.GetCurChannelID()] end local historyCount = 20 --聊天翻页一次刷新请求20条信息 --获取当前频道拉取历史信息的indexBegin和indexEnd范围 function ChannelChat_Model.GetCurChannelHistoryMsgBeginAndEndIndex() local curMsgCount = 0 local curChannelMsgList = ChannelChat_Model.GetCurChannelMsgList() if curChannelMsgList ~= nil then curMsgCount = #curChannelMsgList end if curMsgCount == 0 then --初始0到5 return 0, historyCount end local channelId = ChannelChat_Model.GetCurChannelID() local maxMsgNum = ChannelChat_Model.GetChatCfgDataByChannelId(channelId).Num local offset = maxMsgNum - curMsgCount --缓存消息数量已到达上限,不再请求历史 if offset <= 0 then return 0, 0 end --请求的数量不超过上限 if offset > historyCount then return curMsgCount, curMsgCount + historyCount - 1 else return curMsgCount, curMsgCount + offset - 1 end end function ChannelChat_Model.GetWorldChannelNewMsg() return WorldChannelNewMsg end function ChannelChat_Model.SetWorldChannelNewMsg(newMsg) WorldChannelNewMsg = newMsg end function ChannelChat_Model.GetTeamChannelNewMsg() return TeamChannelNewMsg end function ChannelChat_Model.SetTeamChannelNewMsg(newMsg) TeamChannelNewMsg = newMsg end function ChannelChat_Model.GetZoneChannelNewMsg() return ZoneChannelNewMsg end function ChannelChat_Model.SetZoneChannelNewMsg(newMsg) ZoneChannelNewMsg = newMsg end function ChannelChat_Model.GetChannelChatIsOpen() return ChannelChatIsOpen end function ChannelChat_Model.SetChannelChatIsOpen(isOpen) ChannelChatIsOpen = isOpen end function ChannelChat_Model.SetGlobalChatDlgIsOpen(isOpen) GlobalChatDlgIsOpen = isOpen end function ChannelChat_Model.GetNeedRefreshRedPointChannelID() return NeedRefreshRedPointChannelID end function ChannelChat_Model.GetAnnouncementMsg() return AnnouncementMsg end function ChannelChat_Model.SetLoginTime(loginTime) --logging.log(LTAG.LOG, "---Lua--Chat--SetLoginTime---------" , loginTime) LoginTime = loginTime end function ChannelChat_Model.GetChatDlgMsgListCount() return #ChatDlgMsgList end function ChannelChat_Model.GetDlgMsgList() return ChatDlgMsgList end function ChannelChat_Model.SetMsgIteratorData() private.enumNextIndex = 1 end function ChannelChat_Model.EnumMsgIterator() local data = ChatDlgMsgList[private.enumNextIndex] if data then private.enumNextIndex = private.enumNextIndex + 1 if not ChannelChat_Model.IsMsgFromBlack(data) then return data else return ChannelChat_Model.EnumMsgIterator() end else return nil end end function ChannelChat_Model.RemoveDlgMsgChannel(chatCfgId) for i = #ChatDlgMsgList, 1, -1 do if ChatDlgMsgList[i].ChatCfgId == chatCfgId then table.remove(ChatDlgMsgList, i) end end end function ChannelChat_Model.SaveRecordVoiceRedState(uuid) local redStateDict = PersistentData.PlayerData:Get(AUDIO_RED_KEY) if redStateDict == nil then redStateDict = {} end redStateDict[uuid] = 1 PersistentData.PlayerData:Set(AUDIO_RED_KEY, redStateDict, true) end function ChannelChat_Model.SetCurAudioChannelCfgId(channelCfgID) private.curAudioChannelCfgId = channelCfgID end function ChannelChat_Model.GetCurAudioChannelCfgId() return private.curAudioChannelCfgId end --语音条是否显示红点 function ChannelChat_Model.HasAudioShowRed(chatData) if chatData.isSelf then return false end if CTL.ChannelChat.CanPlayVoice(chatData, false) == false then --无法播放的,不显示红点 return false end local redStateDict = PersistentData.PlayerData:Get(AUDIO_RED_KEY) if redStateDict then return redStateDict[chatData.uuid] == nil end return true end function private.InitAutoPlayVoiceSettings() local dic = PersistentData.DeviceData:Get(AUDIO_AUTO_PLAY_KEY, nil) if dic == nil then --默认只开启军团 dic = { [ChannelChat_Model.ChannelCfgId.Legion] = true, } PersistentData.DeviceData:Set(AUDIO_AUTO_PLAY_KEY, dic, true) end private.autoPlaySettingDict = dic end function ChannelChat_Model.GetAutoPlayVoiceChannelState(channelCfgIdId) return private.autoPlaySettingDict[channelCfgIdId] end function ChannelChat_Model.GetSortedAutoPlayVoiceSettings() local result = {} for i,v in DataSheetManager.Chat:GetEnumerator() do if v.SetAudioChatShow == 1 and ChannelCfgIdNameDict[v.ID] ~= nil then table.insert(result, v) end end table.sort(result, private.SortChatRule) return result end function ChannelChat_Model.SetAutoPlayVoiceChannel(channelCfgIdId, state) private.autoPlaySettingDict[channelCfgIdId] = state PersistentData.DeviceData:Set(AUDIO_AUTO_PLAY_KEY, private.autoPlaySettingDict, true) end function ChannelChat_Model.RemovePlayVoiceQueue() table.clearArray(private.autoPlayVoiceQueue) end --当预播放队列里的语音中小于时间戳的,从自动播放队列中移除 function ChannelChat_Model.TryBreakPlayVoiceQueue(timestamp) if #private.autoPlayVoiceQueue > 0 then for i = #private.autoPlayVoiceQueue, 1, -1 do local chatData = private.autoPlayVoiceQueue[i] if chatData.msgTime <= timestamp then table.remove(private.autoPlayVoiceQueue, i) end end end end function private.TryAutoPlayVoice(channelCfgIdId, chatData) if CTL.ChannelChat.CanPlayVoice(chatData, false) == false then return end if private.autoPlaySettingDict[channelCfgIdId] then if chatData.voiceRecordPath and chatData.voiceDuration > 0 then if CTL.ChannelChat.IsRecordingVoice() or CTL.ChannelChat.IsPlayingVoice() then table.insert(private.autoPlayVoiceQueue, chatData) else CTL.ChannelChat.PlayRecordVoice(chatData) end end end end function ChannelChat_Model.TryPlayNextVoice() if private.playNextVoiceTimer then return end if CTL.ChannelChat.IsRecordingVoice() then return end if #private.autoPlayVoiceQueue > 0 then local chatData = table.remove(private.autoPlayVoiceQueue, 1) local isPlayNext = false local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(chatData.targetId) if chatCfgData then if private.autoPlaySettingDict[chatCfgData.ID] then isPlayNext = true private.playNextVoiceTimer = TimerUtil.Interval(function() CTL.ChannelChat.PlayRecordVoice(chatData) private.playNextVoiceTimer = nil end, INTERVAL_PLAY_AUDIO, 1) end end if isPlayNext == false then ChannelChat_Model.TryPlayNextVoice() end end end --**********End私有数据访问********** local ChatQuickMsgKey = "ChatQuickMsgKey" function ChannelChat_Model.OnStartup() private.SetupEntryFunc(true) private.HasConnectChatServer = false NetManager.RegisterMsgCB(MessageEnums.MessageUseTrumt, private.UseTrumtResponse) NetManager.RegisterMsgCB(MessageEnums.MessageGameChatMsg, private.MessageGameChatMsgResp) NetManager.RegisterMsgCB(MessageEnums.MessageG2CVoiceChatInfo,private.SetVoiceRoomNum) NetManager.RegisterMsgCB(MessageEnums.MessageGameVoiceChatMsg,private.OnGameVoiceChatMsgResp) EventSystem.Regist(EventID.WarZone_State_Change, private.UpdateSettingFlag) ChannelChat_Model.InitChatCfgData() silenceChannels = DataSheetManager.ConstData:GetDataByID("OfficialForbiddenChannel").IntListValue sortedEmojiDataList = {} for i, v in DataSheetManager.ChatEmoji:GetEnumerator() do sortedEmojiDataList[i] = v end table.sort(sortedEmojiDataList, private.EmojiSortRule) private.autoPlayVoiceQueue = {} private.InitAutoPlayVoiceSettings() end function private.SetupEntryFunc(isRegist) LuaFuncEntry.SetupMainEntryFunc(isRegist, LuaFuncEntry.FuncType.OnLoginChatServer, private.Login, LuaFuncEntry.FuncType.OnRecvChatMsgByCS, private.RecvChatMsgByCS ) end function private.EmojiSortRule(emoji1, emoji2) return emoji1.SortID < emoji2.SortID end function ChannelChat_Model.GetSortedEmojiList() return sortedEmojiDataList end function ChannelChat_Model.OnShutdown() for k, v in pairs(ChannelCfgIdNameDict) do allChannelMsgList[v] = nil end --如果回到登录界面,model被注销,当前频道数据将不会保存 ChatDlgMsgList = nil private.SetupEntryFunc(false) end function private.SortChatRule(chatCfgData1, chatCfgData2) return chatCfgData1.Sort < chatCfgData2.Sort end -- --region---初始化聊天数据------------------------ local chatCfgData = {} function ChannelChat_Model.InitChatCfgData() for _, data in DataSheetManager.Chat:GetEnumerator() do local tmp = data if tmp.Show == 1 then if GameAppInfo.IsOverseaHMT() and tmp.ID == ChannelChat_Model.ChannelCfgId.Cross then -- 61亚服大区不显示跨服频道 else table.insert(chatCfgData, tmp) end end end table.sort(chatCfgData, private.SortChatRule) end function ChannelChat_Model.GetChatCfgData() return chatCfgData end function ChannelChat_Model.DefaultOpenChannel() return 0 end function ChannelChat_Model.IsJoinChannel(channelCfgId) if ChannelCfgIdNameDict[channelCfgId] == nil then if channelCfgId == ChannelChat_Model.ChannelCfgId.WarZone then CTL.Tips.AddTipsMsg(Const_IDS.IDS_CrossServerChat_UnderMaintenance) elseif channelCfgId == ChannelChat_Model.ChannelCfgId.Cross then CTL.Tips.AddTipsMsg(Const_IDS.IDS_CrossServerChat_Wait) end return false end return true end -- --region----------频道相关-------------- function ChannelChat_Model.InitChannel(serverName) for i = 1, #chatCfgData do if private.DynamicJoinChatChannelId[chatCfgData[i].ID] then ChannelCfgIdNameDict[chatCfgData[i].ID] = nil else local channelName if chatCfgData[i].ID == ChannelChat_Model.ChannelCfgId.Cross then --跨服聊天有多个子频道,每个子频道需要加上对应的Suffix --默认连接第一个子频道 local crossChannelCfg = private.GetCrossChannelCfg() channelName = private.GetCrossChannel(chatCfgData[i].ChannelPrefix, crossChannelCfg.Suffix) else channelName = chatCfgData[i].ChannelPrefix .. serverName end ChannelCfgIdNameDict[chatCfgData[i].ID] = channelName ChannelChat_Model.JoinChannel(chatCfgData[i].ID, channelName) end end end --聊天服务器重连后,直接加入本地存储的所有频道 function ChannelChat_Model.JoinAllChannel() for chatCfgId, channelId in pairs(ChannelCfgIdNameDict) do ChannelChat_Model.JoinChannel(chatCfgId, channelId) end CTL.SpecialTeam.JoinAllGroupChat() end --是否已经加入到了聊天房间中 function ChannelChat_Model.IsInChatRoomByRoomId(chatRoomId) for __, channelId in pairs(ChannelCfgIdNameDict) do if channelId == chatRoomId then return true end end if CTL.SpecialTeam.IsInGroupChatChannel(chatRoomId) then return true end return false end --根据常量配置,判断是否要根据地区、大区 特殊处理 function private.GetCrossChannelCfg() local channelCfgID = 1 local crossServerHornCost = DataSheetManager.ConstData:GetDataByID("CrossChatRoom1").StringListValue if crossServerHornCost then -- 根据配置,某地的某大区特殊处理 if GameAppInfo.Global_PackageType == crossServerHornCost[1] and GameAppInfo.Global_ProductId == crossServerHornCost[2] then local myServer = MDL.Login.GetServerShowId() if myServer <= tonumber(crossServerHornCost[3]) then channelCfgID = 1 else channelCfgID = 7 --新手频道2的配置 end end end -- 国服使用随机的频道 if GameAppInfo.IsChinesePackage() then local allCount = 0 for i, v in MDL.OperationActivity.CrossServerChatRoom:GetEnumerator() do allCount = allCount + 1 end local index = math.random(allCount) for i, v in MDL.OperationActivity.CrossServerChatRoom:GetEnumerator() do if i == index then channelCfgID = v.ID end end end local crossChannelCfg = MDL.OperationActivity.CrossServerChatRoom:GetDataByID(channelCfgID) return crossChannelCfg end --更换跨服频道,注意需要退出原来的跨服频道 function ChannelChat_Model.SwitchCrossChannel(suffix) if suffix == curCrossSubChannelSuffix then return end local crossChatCfgData = DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Cross) switchingCrossChannel = private.GetCrossChannel(crossChatCfgData.ChannelPrefix, suffix) private.LeaveRoom(ChannelChat_Model.GetChannelIdByCfgID(ChannelChat_Model.ChannelCfgId.Cross)) end function private.GetCrossChannel(channelPrefix, suffix) local virtualDistrictId = MDL.Login.GetVirtualDistrictId() if virtualDistrictId and virtualDistrictId > 0 then return channelPrefix .. virtualDistrictId .. "_" .. suffix else return channelPrefix .. suffix -- channelPrefix 要保证已下划线做结尾 end end --enterWorld调用,此时还未连接聊天服,这里只是缓存战区id function ChannelChat_Model.SetWarZoneId(warZoneId) curWarZoneId = warZoneId end function ChannelChat_Model.GetWarZoneId() return curWarZoneId end --0是无变化 -1是无战区 function ChannelChat_Model.SyncWarZoneId(warZoneId) if warZoneId == 0 or curWarZoneId == warZoneId then return end curWarZoneId = warZoneId local channelId = ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.WarZone] if channelId then --需要断开 private.LeaveRoom(channelId) else ChannelChat_Model.TryJoinWarZoneChannel() end end function ChannelChat_Model.TryJoinWarZoneChannel() if curWarZoneId == nil or curWarZoneId == -1 then return end local warZoneChatCfgData = DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.WarZone) local channel = warZoneChatCfgData.ChannelPrefix .. curWarZoneId ChannelChat_Model.JoinChannel(ChannelChat_Model.ChannelCfgId.WarZone, channel) end function ChannelChat_Model.JoinCountryChannel(countryId) if countryId > 0 and countryId <= 4 and ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Country] == nil then local chatCfgData = DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Country) local channel = chatCfgData.ChannelPrefix .. countryId .. "_" .. curWarZoneId ChannelChat_Model.JoinChannel(ChannelChat_Model.ChannelCfgId.Country, channel) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Country] = channel end end function ChannelChat_Model.TryJoinGVGFightChannel() local isUnlock = CTL.Activities.IsOpen(LuaConst.ActivityType.GVGFight) if isUnlock then local chatCfgData = DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.GVGFight) local channel = chatCfgData.ChannelPrefix .. "_" .. MDL.GVGFight.GetChatGVGFightGroupId() if ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.GVGFight] ~= channel then ChannelChat_Model.JoinChannel(ChannelChat_Model.ChannelCfgId.GVGFight, channel) end end end function ChannelChat_Model.JoinPetBreedChannel(acid) local chatCfgData = DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.PetBreedChat) local channel = chatCfgData.ChannelPrefix .. "_" .. acid ChannelChat_Model.JoinChannel(ChannelChat_Model.ChannelCfgId.PetBreedChat, channel) end function ChannelChat_Model.ExitPetBreedChannel() if MDL.ChannelChat.ExitChannelByChannelType(ChannelChat_Model.ChannelCfgId.PetBreedChat) then MDL.ChannelChat.RemoveDlgMsgChannel(ChannelChat_Model.ChannelCfgId.PetBreedChat) end ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.PetBreedChat] = nil end function ChannelChat_Model.ClearGVGFightNameDict() ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.GVGFight] = nil end --军团战聊天频道特殊处理,进了战场才创建 function ChannelChat_Model.JoinGuildWarChannel() local channelName = ChannelChat_Model.GetGuildWarChannelName() ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.GuildWar] = channelName ChannelChat_Model.JoinChannel(ChannelChat_Model.ChannelCfgId.GuildWar, channelName) end function ChannelChat_Model.GetGuildWarChannelName() local channelName for i = 1, #chatCfgData do if chatCfgData[i].ID == ChannelChat_Model.ChannelCfgId.GuildWar then channelName=chatCfgData[i].ChannelPrefix end end local myGuildId=MDL.Guild.GetMyGuildId() local enemyGuildId=MDL.GuildWar.GetEnemyGuildId() if myGuildId ==0 or enemyGuildId ==0 then return "" end --保证 两个公会加入的频道ID相同 if myGuildId < enemyGuildId then channelName= channelName.."_"..myGuildId.."_"..enemyGuildId else channelName= channelName.."_"..enemyGuildId.."_"..myGuildId end --时间 +战场场次 local curTimeStamp = UTL.Time.GetServerTimestamp() local dayName = os.date(UTL.Time.FormatDateEnum.YMD, curTimeStamp) local info = MDL.GuildWar.GetWarInfo() local battleName="" if info.fightStage==MDL.GuildWar.FightStages.FirstPrepare or info.fightStage==MDL.GuildWar.FightStages.FirstFighting then battleName=1 elseif info.fightStage==MDL.GuildWar.FightStages.SecondPrepare or info.fightStage==MDL.GuildWar.FightStages.SecondFighting then battleName=2 end channelName=channelName.."_"..dayName.."_"..battleName return channelName end function ChannelChat_Model.GetChannelIdByCfgID(id) if ChannelCfgIdNameDict[id] then return ChannelCfgIdNameDict[id] end if id == ChannelChat_Model.ChannelCfgId.Team then if CTL.Team.IsInTeam() then logging.error(LTAG.ERROR, "没有加入相关的队伍聊天频道") end elseif id == ChannelChat_Model.ChannelCfgId.Legion then if MDL.Guild.IsHasGuild() then logging.error(LTAG.ERROR, "没有加入相关的势力聊天频道", id) end end return EMPTY_CHANNEL_NAME end function ChannelChat_Model.SetWarZoneChannelInfo(channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.WarZone] = channelName if channelName == nil then --断开之后,连新的战区id ChannelChat_Model.TryJoinWarZoneChannel() else EventSystem.Dispatch(EventID.UI_ChannelChat_OnJoinChannel, ChannelChat_Model.ChannelCfgId.WarZone, channelName) end end function ChannelChat_Model.SetSpecifiedActivityChannelInfo(channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.SpecifiedActivity] = channelName private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.SpecifiedActivity, 1) EventSystem.Dispatch(EventID.UI_ChannelChat_OnJoinChannel, ChannelChat_Model.ChannelCfgId.SpecifiedActivity, channelName) end function ChannelChat_Model.SetCrossChannelInfo(channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Cross] = channelName if channelName == nil then if switchingCrossChannel then ChannelChat_Model.JoinChannel(ChannelChat_Model.ChannelCfgId.Cross, switchingCrossChannel) switchingCrossChannel = nil end else -- 用 "_" 做分割,最后一位是子频道id local list = string.split(channelName, "_") curCrossSubChannelSuffix = tonumber(list[#list]) EventSystem.Dispatch(EventID.UI_ChannelChat_OnJoinChannel, ChannelChat_Model.ChannelCfgId.Cross, channelName) end end function ChannelChat_Model.GetCurCrossSubChannelSuffix() return curCrossSubChannelSuffix end function ChannelChat_Model.SetTeamChannelInfo(channelName) logging.log(LTAG.LOG, "--SetTeamChannelInfo--channelName ", channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Team] = channelName EventSystem.Dispatch(EventID.UI_ChannelChat_OnJoinChannel,ChannelChat_Model.ChannelCfgId.Team,channelName) end function ChannelChat_Model.SetCurrentChannelInfo(channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Current] = channelName EventSystem.Dispatch(EventID.UI_ChannelChat_OnJoinChannel,ChannelChat_Model.ChannelCfgId.Current,channelName) end function ChannelChat_Model.SetGuildChannelInfo(channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Legion] = channelName EventSystem.Dispatch(EventID.UI_ChannelChat_OnJoinChannel,ChannelChat_Model.ChannelCfgId.Legion,channelName) end function ChannelChat_Model.SetGuildPartyExamChannelInfo(channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.GuildPartyExam] = channelName end function ChannelChat_Model.SetCountryChannelInfo(channelName) ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Country] = channelName end function ChannelChat_Model.GetChatCfgDataByChannelId(channelId) for k, v in pairs(ChannelCfgIdNameDict) do if v == channelId then local chatCfgId = k return DataSheetManager.Chat:GetDataByID(chatCfgId) end end if private.IsTeamChannelByPrefix(channelId) then if CTL.Team.IsInTeam() then logging.error(LTAG.ERROR, "GetChatCfgDataByChannelId获取队伍频道的信息有误", channelId) end return DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Team) elseif private.IsGuildChannelByPrefix(channelId) then if MDL.Guild.IsHasGuild() then logging.error(LTAG.ERROR, "GetChatCfgDataByChannelId获取势力频道的信息有误", channelId) end return DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Legion) elseif ChannelChat_Model.IsCurrentChannelByPrefix(channelId) then logging.error(LTAG.ERROR, "GetChatCfgDataByChannelId获取当前频道的信息有误", channelId, BattleDataGetter.GetLevelID()) return DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Current) elseif private.IsGuildPartyExamByPrefix(channelId) then logging.error(LTAG.ERROR, "GetChatCfgDataByChannelId获取势力答题频道的信息有误", channelId) return DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.GuildPartyExam) elseif private.IsPrivateChatByPrefix(channelId) then return nil elseif private.IsChannelEquals(channelId, ChannelChat_Model.ChannelCfgId.GroupChat) then return DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.GroupChat) end logging.error(LTAG.ERROR, "本地没有加入的channelid", channelId) return nil end function ChannelChat_Model.GetChatChanelTabIndexByCfgID(cfgID) for i, v in ipairs(CTL.ChannelChat.GetShowChannelCfgData()) do if v.ID == cfgID then return i - 1 end end return -1 end --这里的判断可以根据每个频道做处理判断,这种处理也是很无奈 function ChannelChat_Model.IsDisplayCurrentChatChannel() local levelType = BattleDataGetter.GetCurLevelType() if not levelType then return false end local ChatCurrentShow = DataSheetManager.ConstData:GetDataByID("ChatCurrentShow").IntListValue if ChatCurrentShow ~= nil then for i = 1, #ChatCurrentShow do if ChatCurrentShow[i] == levelType then return false end end end return true end function ChannelChat_Model.GetCurrentChannelCacheMsgList() return CurrentChannelCacheMsgList end --每次切换当前频道后,根据缓存数据重新初始化下当前频道数据 function ChannelChat_Model.GetCurrentChannelMsgList() local currentChannel = ChannelChat_Model.GetChannelIdByCfgID(ChannelChat_Model.ChannelCfgId.Current) allChannelMsgList[currentChannel] = {} for i = 1, #CurrentChannelCacheMsgList do table.insert(allChannelMsgList[currentChannel], CurrentChannelCacheMsgList[i]) end return allChannelMsgList[currentChannel] end function ChannelChat_Model.IsInSilenceChannelByCfgId(cfgID) for i, v in ipairs(silenceChannels) do if v == cfgID then return true end end return false end function ChannelChat_Model.IsWorldChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData.ID == ChannelChat_Model.ChannelCfgId.World end function ChannelChat_Model.IsWorldChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.World end function ChannelChat_Model.IsLegionChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Legion end function ChannelChat_Model.IsWarZoneChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData.ID == ChannelChat_Model.ChannelCfgId.WarZone end function ChannelChat_Model.IsWarZoneChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.WarZone end function ChannelChat_Model.IsLegionChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.Legion end function ChannelChat_Model.IsTeamChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Team end function ChannelChat_Model.IsCrossChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Cross end function ChannelChat_Model.IsTeamChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.Team end function ChannelChat_Model.IsZhaoMuChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData.ID == ChannelChat_Model.ChannelCfgId.ZhaoMu end function ChannelChat_Model.IsZhaoMuChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.ZhaoMu end function ChannelChat_Model.IsCurrentChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Current end function ChannelChat_Model.IsCurrentChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.Current end function ChannelChat_Model.IsSystemChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData.ID == ChannelChat_Model.ChannelCfgId.System end function ChannelChat_Model.IsSystemChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.System end function ChannelChat_Model.IsGuildPartyExamChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and chatCfgData.ID == ChannelChat_Model.ChannelCfgId.GuildPartyExam end function ChannelChat_Model.IsSceneQuizChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and chatCfgData.ID == ChannelChat_Model.ChannelCfgId.SceneQuiz end function ChannelChat_Model.IsBulletChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Bullet end function ChannelChat_Model.IsBulletChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.Bullet end function ChannelChat_Model.IsPKRoomChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and chatCfgData.ID == ChannelChat_Model.ChannelCfgId.PKRoom end function ChannelChat_Model.IsPKRoomChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.PKRoom end function ChannelChat_Model.IsGVGFightChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and chatCfgData.ID == ChannelChat_Model.ChannelCfgId.GVGFight end function ChannelChat_Model.IsGVGFightChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.GVGFight end -- 不能发言的频道 function ChannelChat_Model.IsCanChatByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.ZhaoMu or cfgId == ChannelChat_Model.ChannelCfgId.System or cfgId == ChannelChat_Model.ChannelCfgId.Mixture end function ChannelChat_Model.IsMixtureChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Mixture end function ChannelChat_Model.IsMixtureChannelByCfgId(cfgId) return cfgId == ChannelChat_Model.ChannelCfgId.Mixture end -- --end region----------频道相关-------------- -- --end region---初始化聊天数据------------------------ --将消息加入小窗消息队列 function ChannelChat_Model.AddMsgToChatDlgMsgList(uuid, channelID, content, isSelf, senderName, isVoice, fromId, trumpetType, ChatMsgData) local extraParam = ChatMsgData.extraParam if ChannelChat_Model.CanAddToDlgMsgList(channelID) then if true then --军团战过滤一些消息,只能看到本势力或是对方势力全体的消息 local isGuildWar=private.IsGuildWarChannelByPrefix(channelID) if isGuildWar then local isCanAdd = ChannelChat_Model.IsCanAddMsgList(channelID, fromId, content, extraParam) if not isCanAdd then return false end end local msgNum = #ChatDlgMsgList if msgNum >= GlobalMsgNum then table.remove(ChatDlgMsgList, 1) end -- table.insert(ChatDlgMsgList, contentTemp) local data = {} local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelID) if chatCfgData ~= nil then data.FlagName = chatCfgData.Name data.ChatCfgId = chatCfgData.ID end data.uuid = uuid data.isSelf = isSelf data.senderName = senderName data.content = content data.ChannelId = channelID data.fromId = fromId data.trumpetType = trumpetType data.bubble = ChatMsgData.bubble data.heroId = extraParam.PlayerShowInfo.mainHeroId data.level = extraParam.PlayerShowInfo.level data.sex = extraParam.PlayerShowInfo.sex data.emblemFrame = extraParam.PlayerShowInfo.EmblemFrame data.emblemContent = extraParam.PlayerShowInfo.EmblemContent data.jobTitle = extraParam.PlayerShowInfo.JobTitle data.officialId = extraParam.PlayerShowInfo.OfficialId data.serId = extraParam.PlayerShowInfo.ShowServerId data.portraitId = extraParam.PlayerShowInfo.PortraitId data.frameId = extraParam.PlayerShowInfo.FrameId data.color = extraParam.color data.isVoice = isVoice data.countryId = extraParam.PlayerShowInfo.CountryId data.countryOfficial = extraParam.PlayerShowInfo.CountryOfficial data.wearSignetId = extraParam.PlayerShowInfo.WearSignetId data.signetTimestamp = extraParam.PlayerShowInfo.SignetTimestamp table.insert(ChatDlgMsgList, data) return true else return false end else return false end end --将消息加入当前频道缓存列表中 --todo by gjh,这块老代码写得是不是有问题啊,有空看看 function ChannelChat_Model.AddMsgToCurrentChannelCacheMsgList(channelID, isNewMsg, itemData) if channelID == nil then return end if not ChannelChat_Model.IsCurrentChannelByPrefix(channelID) then return end -- if ChannelChat_Model.IsSystemChannelByChannelId(channelID) then -- return -- end local itemData = { uuid = uuid, isSelf = isSelf, senderName = senderName, content = content, fromId = fromId, heroId = extraParam.PlayerShowInfo.mainHeroId, level = extraParam.PlayerShowInfo.level, sex = extraParam.PlayerShowInfo.sex, emblemFrame = extraParam.PlayerShowInfo.EmblemFrame, emblemContent = extraParam.PlayerShowInfo.EmblemContent, jobTitle = extraParam.PlayerShowInfo.JobTitle, officialId = extraParam.PlayerShowInfo.OfficialId, portraitId = extraParam.PlayerShowInfo.PortraitId, frameId = extraParam.PlayerShowInfo.FrameId, color = extraParam.color, -- 消息的颜色(默认为空) wearSignetId = extraParam.PlayerShowInfo.WearSignetId, signetTimestamp = extraParam.PlayerShowInfo.SignetTimestamp, } local currentChannelCfgData = DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Current) local msgNum = #CurrentChannelCacheMsgList if msgNum >= currentChannelCfgData.Num then table.remove(CurrentChannelCacheMsgList, 1) end if isNewMsg == false then local msgCount = msgNum if msgCount > 0 then table.insert(CurrentChannelCacheMsgList, 1, itemData) else table.insert(CurrentChannelCacheMsgList, itemData) end else table.insert(CurrentChannelCacheMsgList, itemData) end end --这个channelName是对“_”split之后的结果 function private.IsChannelByPrefix(channelName, channelCfgId) if channelName == nil or #channelName <= 0 then return false end local chatCfgData = DataSheetManager.Chat:GetDataByID(channelCfgId) local match = string.match(chatCfgData.ChannelPrefix, channelName) if match ~= nil then return true end return false end function private.IsChannelEquals(channelFullName, channelCfgId) if channelFullName == nil or #channelFullName <= 0 then return false end local chatCfgData = DataSheetManager.Chat:GetDataByID(channelCfgId) local match = string.match(channelFullName, chatCfgData.ChannelPrefix) if match ~= nil then return true end return false end function private.IsWarZoneChannelByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.WarZone) end function private.IsCrossChannelByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.Cross) end function ChannelChat_Model.IsCurrentChannelByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.Current) end function private.IsTeamChannelByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.Team) end function private.IsGuildWarChannelByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.GuildWar) end function private.IsGuildChannelByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.Legion) end function private.IsGuildPartyExamByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.GuildPartyExam) end function private.IsPrivateChatByPrefix(channelName) local PRIVATE_CHAT_CHANNELID_FLAG = ":" return string.find(channelName, PRIVATE_CHAT_CHANNELID_FLAG, 1, true) end function private.IsCountryChannelByPrefix(channelName) return private.IsChannelByPrefix(channelName, ChannelChat_Model.ChannelCfgId.Country) end --是否过滤消息显示 function ChannelChat_Model.IsCanAddMsgList(channelID, fromId, content, ChatMsgData) local extraParam = ChatMsgData.extraParam local templateInfo = ChatMsgData.templateInfo -- 势力设置控制是否显示 官员上线聊天内容 if templateInfo.idsTemplate == "IDS_GuildMemberLogin_ChatMsg1" then return PersistentData.DeviceData:Get("OfficerLoginTipsKey", true) end -- 势力设置控制是否显示 合纵连横 被离间消息 if templateInfo.idsTemplate == "IDS_GuildAllies_LobbyResult_Decrease" or templateInfo.idsTemplate == "IDS_GuildAllies_BanquetResult_Decrease" or templateInfo.idsTemplate == "IDS_GuildAllies_LobbyPlusResult_Decrease" or templateInfo.idsTemplate == "IDS_GuildAllies_LobbyUltraPlusResult_Decrease" then return PersistentData.DeviceData:Get("BeAlienatedTipsKey", true) end local isMatchAll = false local channelName = ChannelChat_Model.GetGuildWarChannelName() local isShowGuildWar = channelID == channelName --军团战消息显示规则需要特殊处理,只显示本方的 和全部的,敌方的信息不显示 if isShowGuildWar then local isMyGuild = MDL.Guild.IsMember(fromId) if isMyGuild then return true else isMatchAll = true end elseif private.IsChannelEquals(channelID, ChannelChat_Model.ChannelCfgId.SpecifiedActivity) and BattleDataGetter.IsDragonArteryType() then --龙脉战,“本方”同国家可见 if MDL.Country.IsSameCountry(extraParam.PlayerShowInfo.CountryId) then return true else isMatchAll = true end end if isMatchAll then --敌方必须是发给全体的才能显示 local allTitle = UIUtils.GetLocalizedTxt(Const_IDS.IDS_WarChannel_All_InChannel) allTitle = ChannelChat_Model.ReplaceSpecialChar(allTitle) local contentTemp = ChannelChat_Model.ReplaceSpecialChar(content) if string.find(contentTemp, allTitle) then return true end return false end return true end --去掉特殊字符 function ChannelChat_Model.ReplaceSpecialChar(str) local temp = string.gsub(str,"%[","",1); temp = string.gsub(temp,"%]","",1); return temp end --重连以后关闭聊天UI防止出问题 function ChannelChat_Model.CloseChatMainUIAfterReconnect() if UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIChannelChatMain) then EventSystem.Dispatch(EventID.UI_ChannelChat_ClickBack) end end function ChannelChat_Model.GetChannelChatList(channelID) return allChannelMsgList[channelID] or {} end function ChannelChat_Model.IsMsgFromBlack(msg) return MDL.Friend.IsPlayerBlack(msg.fromId) or MDL.Friend.IsPlayerBlack(msg.targetId) end --创建聊天信息 function ChannelChat_Model.CreatChatMsg(uuid, channelID, content, isSelf, senderName, trumpetType, fromId, msgTime, extraParam, voiceRecordPath, voiceDuration, voiceChatUrl, hide, bubble) local msg = { uuid = uuid, isSelf = isSelf, senderName = senderName, content = content, trumpetType = trumpetType, fromId = fromId, targetId = channelID, msgTime = msgTime, heroId = extraParam.PlayerShowInfo.mainHeroId, level = extraParam.PlayerShowInfo.level, sex = extraParam.PlayerShowInfo.sex, emblemFrame = extraParam.PlayerShowInfo.EmblemFrame, emblemContent = extraParam.PlayerShowInfo.EmblemContent, jobTitle = extraParam.PlayerShowInfo.JobTitle, officialId = extraParam.PlayerShowInfo.OfficialId, serId = extraParam.PlayerShowInfo.ShowServerId, portraitId = extraParam.PlayerShowInfo.PortraitId, frameId = extraParam.PlayerShowInfo.FrameId, color = extraParam.color, -- 消息的颜色 countryId = extraParam.PlayerShowInfo.CountryId, countryOfficial = extraParam.PlayerShowInfo.CountryOfficial, pureText = MDL.Translate.GetPureText(uuid), voiceRecordPath = voiceRecordPath, voiceDuration = voiceDuration, voiceChatUrl = voiceChatUrl, hide = hide, --服务器保存了这条消息,但某些客户端不显示,所以需要把这条消息存在消息列表里但是不显示出来,与服务器消息的下标对齐 bubble = bubble, --聊天气泡装饰Id } --由于私聊会将这块数据json序列化,直接将proto中的数组或者数据结构赋值过来,会导致json序列化失败 if extraParam.PlayerShowInfo.WearSignetId and #extraParam.PlayerShowInfo.WearSignetId > 0 then msg.wearSignetId = {} for i, v in ipairs(extraParam.PlayerShowInfo.WearSignetId) do msg.wearSignetId[i] = v end end if extraParam.PlayerShowInfo.SignetTimestamp and #extraParam.PlayerShowInfo.SignetTimestamp > 0 then msg.signetTimestamp = {} for i, v in ipairs(extraParam.PlayerShowInfo.SignetTimestamp) do msg.signetTimestamp[i] = v end end return msg end --将消息加入消息列表缓存 function ChannelChat_Model.AddMsgToList(uuid, content, isSelf, senderName, isNewMsg, msgData, extraParam, hide, bubble) local channelID = msgData.targetId local voiceRecordPath, voiceDuration, voiceChatUrl = private.GetChatVoiceParam(msgData) local chatData = ChannelChat_Model.CreatChatMsg(uuid, channelID, content, isSelf, senderName, msgData.isTrumpet and msgData.trumtType or -1, msgData.fromId, msgData.sendStamp, extraParam, voiceRecordPath, voiceDuration, voiceChatUrl, hide, bubble) ChannelChat_Model.OperationAllChannelMsgListByID(channelID, chatData, isNewMsg) EventSystem.Dispatch(EventID.ChannelChat_ReceiveNewMsg, chatData, isNewMsg) EventSystem.Dispatch(EventID.UI_ChannelChat_BulletScreen, chatData, msgData, isNewMsg) return chatData end function private.GetChatVoiceParam(msgData) local param = msgData.templateInfo.params[1] if param and param.paramType == ChannelChat_Model.TemplateParamType.VoiceChat then return param.param.chatVoicePath, param.param.time, msgData.voiceChatUrl end return nil end function ChannelChat_Model.OperationAllChannelMsgListByID(channelID, itemData, isNewMsg) allChannelMsgList[channelID] = allChannelMsgList[channelID] or {} if isNewMsg == false then table.insert(allChannelMsgList[channelID], 1, itemData) else table.insert(allChannelMsgList[channelID], itemData) end local msgNum = #allChannelMsgList[channelID] local maxMsgNum = ChannelChat_Model.GetChatCfgDataByChannelId(channelID).Num if msgNum > maxMsgNum then table.remove(allChannelMsgList[channelID], 1) end end --**********协议处理********** --使用喇叭请求 function ChannelChat_Model.UseTrumtReq(msgContent, trumtTyp) local msg = use_trumt_pb.UseTrumtReq() private.SetExtraParam(msg.extraParam) msgContent = CTL.ChannelChat.PreProcessChatContentForEmoji(msgContent) local hyperlinkIndex = nil if CTL.ChannelChat.HasHyperlinkTag(msgContent) then msgContent, hyperlinkIndex = CTL.ChannelChat.ReplaceHyperlinkContent(msgContent) end local hyperlinkCount = hyperlinkIndex and table.getn(hyperlinkIndex) or 0; for i=1, hyperlinkCount do local template = private.CreateTemplate(hyperlinkIndex[i]); msg.templateInfo.templateId = -1 ----这里的-1代表客户端给服务器发的模板数据 需要解析出来 table.insert(msg.templateInfo.params, template) end msg.content = msgContent msg.trumtTyp = trumtTyp NetManager.SendMessage(MessageEnums.MessageUseTrumt, msg) end --使用喇叭请求Rsp function private.UseTrumtResponse(msgResp) logging.log(LTAG.LOG, "UseItemResponse", msgResp) end function private.MessageGameChatMsgResp(msgResp) end --*********************C2S***Chat通信流程,不出意外都是按照连接顺序写的***************** --登录请求 function private.Login(token) local msg = chat_pb.ChatLogin() msg.playerId = BattleDataGetter.GetAcID() msg.token = token AuxUtil.ChatMsg(chat_operate_pb.C2SLogin, msg:SerializeToString()) end --加入频道请求 function ChannelChat_Model.JoinChannel(channelType, channerlId) --亚服61大区,屏蔽跨服频道 if GameAppInfo.IsOverseaHMT() and channelType == ChannelChat_Model.ChannelCfgId.Cross then return end --请求Chat Server 加入频道,默认是世界频道 local msg = chat_pb.JoinRoom() logging.log(LTAG.LOG, "--JoinChannel---channerlId= ", channerlId, " channelType= ", channelType) msg.roomId:append(channerlId) AuxUtil.ChatMsg(chat_operate_pb.C2SJoinRoom, msg:SerializeToString()) --设置当前频道 if channelType ~= ChannelChat_Model.ChannelCfgId.GroupChat then allChannelMsgList[channerlId] = {} CurChannelType = channelType end end --退出频道请求 function private.LeaveRoom(channelId) local msg = chat_pb.LeaveRoom() msg.roomId:append(channelId) AuxUtil.ChatMsg(chat_operate_pb.C2SLeaveRoom, msg:SerializeToString()) end function ChannelChat_Model.ExitChannelByChannelType(channelType) local channelId = MDL.ChannelChat.GetChannelIdByCfgID(channelType) if channelId ~= nil then ChannelChat_Model.ExitChannel(channelType, channelId) return true end return false end function ChannelChat_Model.ExitChannel(channelType, channelId) private.LeaveRoom(channelId) if CurChannelID == channelId then UIManager.CloseView(Const_UI_Lua.UIEnum.UIChannelChatMain) end end --发送聊天消息 function ChannelChat_Model.SendChatMsg(channelID, content, chatType, hyperlinkIndex, colorHex) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = channelID local chatType = chatType or chat_pb.Room msg.type = chatType local isArabic, resultStr = UTL.String.ArabicFix(content) if isArabic then msg.content = resultStr local templateParam = chat_pb.TemplateParam() templateParam.paramType = ChannelChat_Model.TemplateParamType.Arabic templateParam.param.idsOrStr = content table.insert(msg.templateInfo.params, templateParam) else msg.content = content end private.SetExtraParam(msg.extraParam, colorHex) local hyperlinkCount = hyperlinkIndex and table.getn(hyperlinkIndex) or 0; for i=1, hyperlinkCount do local template = private.CreateTemplate(hyperlinkIndex[i]); table.insert(msg.templateInfo.params, template) end msg.templateInfo.templateId = -1 ----这里的-1代表客户端给服务器发的模板数据 需要解析出来 NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) logging.log(LTAG.LOG," SendChatMsg ",msg) end --发送语音聊天消息 function ChannelChat_Model.SendAudioChatMsg(channelID, content, chatType, recordPath, duration) if LuaExt.FileExists(recordPath) == false then logging.error(LTAG.ERROR, "voice not exists", recordPath) return end local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = channelID local chatType = chatType or chat_pb.Room msg.type = chatType msg.content = content private.SetExtraParam(msg.extraParam) local templateParam = chat_pb.TemplateParam() table.insert(msg.templateInfo.params, templateParam) templateParam.paramType = ChannelChat_Model.TemplateParamType.VoiceChat templateParam.param.chatVoicePath = recordPath templateParam.param.time = duration msg.templateInfo.templateId = -1 --语音二进制数据 msg.voiceChat = LuaExt.FileReadBytes(recordPath) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function ChannelChat_Model.SendGuildRecommendChatMsg(acid, name, targetAcid) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = targetAcid msg.type = chat_pb.Personal msg.content = "1" private.SetExtraParam(msg.extraParam) local templateParam = chat_pb.TemplateParam() table.insert(msg.templateInfo.params, templateParam) templateParam.paramType = ChannelChat_Model.TemplateParamType.GuildRecommend templateParam.param.acid = acid templateParam.param.name = name msg.templateInfo.templateId = -1 NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function ChannelChat_Model.SendPetBreedMsg(channelCfgId, content, pedigree, petId) if UTL.String.CheckIsIds(content) == false and CTL.ChannelChat.IsOutOfLength(content, MDL.ChannelChat.GetChannelIdByCfgID(channelCfgId)) then return false end local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = ChannelChat_Model.GetChannelIdByCfgID(channelCfgId) local chatType = chat_pb.Room msg.type = chatType private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() table.insert(template.param.strCommonParam, tostring(CTL.ChannelChat.HyperlinkTag.PetBreedApply)) table.insert(template.param.strCommonParam, BattleDataGetter.GetAcID()) --如果content是IDS,塞进template中做本地化;如果是自定义文本,则放到content里,需要走屏蔽字规则 if UTL.String.CheckIsIds(content) == false then msg.content = content table.insert(template.param.strCommonParam, "") else msg.content = "" table.insert(template.param.strCommonParam, content) end table.insert(template.param.strCommonParam, tostring(pedigree)) table.insert(template.param.strCommonParam, tostring(petId)) table.insert(template.param.strCommonParam, BattleDataGetter.GetPlayerName()) msg.templateInfo.templateId = -1 table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) return true end function ChannelChat_Model.SendChatTeamRecruitMsg(channelID, content, teamInfo) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = channelID local chatType = chat_pb.Room msg.type = chatType msg.content = "" private.SetExtraParam(msg.extraParam) if teamInfo then local template = chat_pb.TemplateParam() template.paramType = ChannelChat_Model.TemplateParamType.TeamRecruit template.param.teamRecruitInfo.teamId = teamInfo.teamId template.param.teamRecruitInfo.name = teamInfo.name template.param.teamRecruitInfo.curCount = teamInfo.curCount template.param.teamRecruitInfo.target.mainTarget = teamInfo.teamTarget.mainTarget template.param.teamRecruitInfo.target.subTarget = teamInfo.teamTarget.subTarget template.param.teamRecruitInfo.limit.level = teamInfo.teamLimit.level template.param.teamRecruitInfo.limit.rank = teamInfo.teamLimit.level template.param.teamRecruitInfo.limit.power = teamInfo.teamLimit.power template.param.teamRecruitInfo.cartRarity = teamInfo.cartRarity msg.templateInfo.templateId = -1 table.insert(msg.templateInfo.params, template) end NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function ChannelChat_Model.SendChatSpecialTeamRecruitMsg(teamId, curCount, leaderName, teamName, functionId, channelType) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = ChannelChat_Model.GetChannelIdByCfgID(channelType) local chatType = chat_pb.Room msg.type = chatType msg.content = "" private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() table.insert(template.param.strCommonParam, tostring(CTL.ChannelChat.HyperlinkTag.SpecialTeamApply)) table.insert(template.param.strCommonParam, leaderName) table.insert(template.param.strCommonParam, teamName) table.insert(template.param.strCommonParam, tostring(curCount)) table.insert(template.param.strCommonParam, teamId) table.insert(template.param.strCommonParam, tostring(functionId)) msg.templateInfo.templateId = -1 table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function ChannelChat_Model.ShareDragonArteryResult(channelCfgID, shareId) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = ChannelChat_Model.GetChannelIdByCfgID(channelCfgID) msg.type = chat_pb.Room msg.content = "" private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() table.insert(template.param.strCommonParam, tostring(CTL.ChannelChat.HyperlinkTag.DragonArteryResultShare)) table.insert(template.param.strCommonParam, BattleDataGetter.GetAcID()) table.insert(template.param.strCommonParam, shareId) msg.templateInfo.templateId = -1 table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function ChannelChat_Model.SendChatGuildRecruitMsg(defaultStr, content, guild) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = MDL.ChannelChat.GetChannelIdByCfgID(MDL.ChannelChat.ChannelCfgId.World) local chatType = chat_pb.Room msg.type = chatType msg.content = content private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() template.paramType = ChannelChat_Model.TemplateParamType.GuildRecruit template.param.guildId = guild template.param.idsOrStr = defaultStr msg.templateInfo.templateId = -1 table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function ChannelChat_Model.SendGuildWarBattleMsg(battleData,content,id) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = id msg.type = chat_pb.Room msg.content = content private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() msg.templateInfo.templateId = -1 template.paramType = ChannelChat_Model.TemplateParamType.GuildWarBattle local guildWarBattleInfo = template.param.guildWarBattleInfo guildWarBattleInfo.score = battleData.score guildWarBattleInfo.killNum = battleData.killNum guildWarBattleInfo.continuousKilling = battleData.continuousKilling guildWarBattleInfo.assiantNum = battleData.assiantNum guildWarBattleInfo.seriousInjury = battleData.seriousInjury guildWarBattleInfo.occupycamp = battleData.occupycamp guildWarBattleInfo.killBoss = battleData.killBoss guildWarBattleInfo.wallDemage = battleData.wallDemage guildWarBattleInfo.handInResource = battleData.handInResource guildWarBattleInfo.gsSum = battleData.gsSum for i = 1, 3 do local kda = chat_pb.KDA() kda.k = battleData.kda[i].k kda.d = battleData.kda[i].d kda.a = battleData.kda[i].a kda.heroId1 = battleData.kda[i].heroId1 kda.heroId2 = battleData.kda[i].heroId2 table.insert(guildWarBattleInfo.kda,kda) end table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end --势力驻地答题聊天 function ChannelChat_Model.SendGuildPartyExamMsg(content, isCorrect, rankIndex) local examChannelId = MDL.ChannelChat.GetChannelIdByCfgID(MDL.ChannelChat.ChannelCfgId.GuildPartyExam) if not examChannelId then logging.error(LTAG.ERROR, "没有加入到公会答题频道") return end local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = examChannelId msg.type = chat_pb.Room msg.content = content private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() msg.templateInfo.templateId = -1 template.paramType = ChannelChat_Model.TemplateParamType.GuildPartyAnswer --1,正确2,错误,3,无效 table.insert(template.param.intCommonParam, isCorrect); template.param.index = rankIndex or 0 table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end --场景答题-初赛聊天 function ChannelChat_Model.SendSceneQuizPreliminaryMsg(content, isCorrect, rankIndex) local examChannelId = MDL.ChannelChat.GetChannelIdByCfgID(MDL.ChannelChat.ChannelCfgId.SceneQuiz) if not examChannelId then logging.error(LTAG.ERROR, "没有加入到场景答题频道") return end local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = examChannelId msg.type = chat_pb.Room msg.content = content private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() msg.templateInfo.templateId = -1 --1,正确2,错误,3,无效 table.insert(template.param.intCommonParam, isCorrect) template.param.index = rankIndex or 0 table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end --发送频道内的系统消息 function ChannelChat_Model.SendChannelSystemMsg(channelID, idsTemplate, ...) local msg = chat_gamex_pb.GameChatMsgReq() msg.content = "" msg.targetId = channelID msg.type = chat_pb.Room msg.templateInfo.idsTemplate = idsTemplate local count = select('#', ...) for i = 1, count do local template = select(i, ...) table.insert(msg.templateInfo.params, template) end NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end --【我方】频道下喊话 function ChannelChat_Model.SendMyCampShortcutMsg(idsTemplate) local targetId = ChannelChat_Model.GetChannelIdByCfgID(ChannelChat_Model.ChannelCfgId.MyCamp) local errorCode, leftTime = CTL.ChannelChat.CheckCanSendTextMsg(idsTemplate, targetId, chat_pb.Room) if errorCode == CTL.ChannelChat.ErrorCode.Success then local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = targetId msg.type = chat_pb.Room msg.content = "" msg.templateInfo.idsTemplate = idsTemplate private.SetExtraParam(msg.extraParam) --这里武将id传当前战斗内的武将 if BattleDataGetter.GetHeroIsAwaken(BattleDataGetter.GetCurPlayerID()) then msg.extraParam.PlayerShowInfo.mainHeroId = CTL.HeroAwaken.EncodeHeroId(BattleDataGetter.GetMainPlayerCharacterID()) else msg.extraParam.PlayerShowInfo.mainHeroId = BattleDataGetter.GetMainPlayerCharacterID() end NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) else CTL.ChannelChat.ProcessError(errorCode, leftTime) end end function ChannelChat_Model.CreatChatTemplateParam(paramType) local template = chat_pb.TemplateParam() template.paramType = paramType return template end -- 成就 function ChannelChat_Model.SendAchievementMsg(channelID, chatType, content, playerName, achievementId, ids) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = channelID msg.type = chatType msg.content = content msg.templateInfo.templateId = -1 private.SetExtraParam(msg.extraParam) local template = chat_pb.TemplateParam() template.paramType = ChannelChat_Model.TemplateParamType.Achievement template.param.name = playerName template.param.idsOrStr = ids template.param.achievementId = achievementId template.param.idsOrStr = ids table.insert(msg.templateInfo.params, template) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function ChannelChat_Model.SendGuildPrivateNotificationMsg(content) local msg = chat_gamex_pb.GameChatMsgReq() msg.targetId = "" msg.type = chat_pb.GuildBroadCast msg.content = content private.SetExtraParam(msg.extraParam) NetManager.SendMessage(MessageEnums.MessageGameChatMsg, msg) end function private.CreateTemplate(hyperlinkIndex) local pairSplits = string.split(hyperlinkIndex[3],"|") local templateParam = chat_pb.TemplateParam() local hyperlinkType = tonumber(pairSplits[1]) templateParam.insertBeginIndex = hyperlinkIndex[1] templateParam.insertEndIndex = hyperlinkIndex[2] if hyperlinkType == CTL.ChannelChat.HyperlinkTag.Location or hyperlinkType == CTL.ChannelChat.HyperlinkTag.Scrimmage then -- 显示内容:[徐州(207,349)1 Line] -- 发送给服务器内容地图坐标结构 templateParam.paramType = ChannelChat_Model.TemplateParamType.MapPoint local params = string.split(pairSplits[2],",") templateParam.param.mapPointInfo.mapId = tonumber(params[1]) templateParam.param.mapPointInfo.pos.X = tonumber(params[2]) templateParam.param.mapPointInfo.pos.Y = tonumber(params[3]) templateParam.param.mapPointInfo.pos.Z = 0 templateParam.param.mapPointInfo.lineId = tonumber(params[4]) if hyperlinkType == CTL.ChannelChat.HyperlinkTag.Scrimmage then templateParam.param.mapPointInfo.posIndex = tonumber(params[5]) end elseif hyperlinkType == CTL.ChannelChat.HyperlinkTag.PetShare then table.insert(templateParam.param.strCommonParam, pairSplits[1]) table.insert(templateParam.param.strCommonParam, pairSplits[2]) --petUniqId table.insert(templateParam.param.strCommonParam, pairSplits[3]) --petConfigId table.insert(templateParam.param.strCommonParam, pairSplits[4]) --petConfigStage table.insert(templateParam.param.strCommonParam, pairSplits[5]) --acid elseif hyperlinkType == CTL.ChannelChat.HyperlinkTag.Item then templateParam.paramType = ChannelChat_Model.TemplateParamType.ItemName local params = string.split(pairSplits[2],",") templateParam.param.itemId = tonumber(params[1]) end return templateParam end --是不是一个超链里有多个处理函数 function private.IsHyperText(params, index) for i,v in ipairs(params) do if index>= params[i].insertBeginIndex and index" local hpstr = utf8.sub(content,templateParam.insertBeginIndex,templateParam.insertEndIndex) returnStr = frontTag..hpstr.."" elseif templateParam.paramType == ChannelChat_Model.TemplateParamType.ItemName then local itemData = DataSheetManager.ItemData:GetDataByID(templateParam.param.itemId) local frontTag = "" local chatItemName = string.FormatByIdsKey("IDS_Chat_item", UTL.Item.GetItemDataSpliceByType(templateParam.param.itemId).Name) returnStr = frontTag..UTL.Color.FormatQualityText(chatItemName, itemData.Color)..""; end return returnStr end function private.GetHyperlinkContent(content, chatMsgData) if chatMsgData.templateInfo.templateId == -1 then if table.getn(chatMsgData.templateInfo.params)>1 then local tempStr = ""; local contenLength = UTL.String.GetStrLen(content) local i=1 while i<=contenLength do local isInHyper, hyperParam = private.IsHyperText(chatMsgData.templateInfo.params, i); if not isInHyper then tempStr = tempStr .. utf8.sub(content, i, i+1); i = i+1 else tempStr = tempStr .. private.GetHyperContentByParam(content, hyperParam); i = i+hyperParam.insertEndIndex-hyperParam.insertBeginIndex; end end content = tempStr; else for i,v in ipairs(chatMsgData.templateInfo.params) do if v.paramType == ChannelChat_Model.TemplateParamType.MapPoint then local mapInfo = v.param.mapPointInfo local posIndex = mapInfo.posIndex if posIndex ~= nil and posIndex > 0 then local mapId = mapInfo.mapId local lineId = mapInfo.lineId content = CTL.ChannelChat.FormatScrimmage(content, posIndex, mapId, lineId) else content = CTL.ChannelChat.FormatMapPointMsg(content, v) end elseif v.paramType == ChannelChat_Model.TemplateParamType.TeamRecruit then content = CTL.ChannelChat.FormatTeamRecruitMsg(v.param.teamRecruitInfo) elseif v.paramType == ChannelChat_Model.TemplateParamType.GuildRecruit then content = CTL.ChannelChat.FormatGuildRecruitMsg(content,v.param) elseif v.paramType == ChannelChat_Model.TemplateParamType.GuildRecommend then content = CTL.ChannelChat.FormatGuildRecommend(content,v.param) elseif v.paramType == ChannelChat_Model.TemplateParamType.ItemName then content = CTL.ChannelChat.FormatReceiveItemMsg(content,v) elseif v.paramType == ChannelChat_Model.TemplateParamType.GuildWarBattle then content = CTL.ChannelChat.FormatGuildWarMsg(content,v.param.guildWarBattleInfo,chatMsgData.extraParam) elseif v.paramType == ChannelChat_Model.TemplateParamType.Achievement then content = CTL.ChannelChat.FormatAchievementMsg(content, v.param) elseif v.paramType == ChannelChat_Model.TemplateParamType.GveLand then content = CTL.ChannelChat.FormatSlgGvEAttackCityOrBossMsg(v.param) elseif v.param.strCommonParam and #v.param.strCommonParam > 0 then if tonumber(v.param.strCommonParam[1]) == CTL.ChannelChat.HyperlinkTag.DragonArteryResultShare then content = CTL.ChannelChat.FormatDragonArteryResultShare(v.param.strCommonParam) elseif tonumber(v.param.strCommonParam[1]) == CTL.ChannelChat.HyperlinkTag.SpecialTeamApply then content = CTL.ChannelChat.FormatSpecialTeamApplyMsg(v.param.strCommonParam) elseif tonumber(v.param.strCommonParam[1]) == CTL.ChannelChat.HyperlinkTag.PetBreedApply then content = CTL.ChannelChat.FormatPetBreedApplyMsg(v.param.strCommonParam, content) elseif tonumber(v.param.strCommonParam[1]) == CTL.ChannelChat.HyperlinkTag.PetShare then content = CTL.ChannelChat.FormatPetShareMsg(v.param.strCommonParam, v, content) end elseif v.paramType == ChannelChat_Model.TemplateParamType.CountryNightBossRecruit then content = CTL.ChannelChat.FormatCountryNightBossRecruitHyperlinkContent( v.param.bossId, v.param.index, v.param.name, v.param.countryJobIds ) end end end elseif not string.isNilOrEmpty(chatMsgData.templateInfo.idsTemplate) then local strParams = {} for i,v in ipairs(chatMsgData.templateInfo.params) do if v.paramType == ChannelChat_Model.TemplateParamType.RoleName then table.insert(strParams,v.param.name) elseif v.paramType == ChannelChat_Model.TemplateParamType.IdsOrStr then if string.match(v.param.idsOrStr,"^IDS") then ---这里可能多个ids 以 ids/ids/ids结构发送 local idss = string.split(v.param.idsOrStr,"/") local str = nil for _,ids in ipairs(idss) do if str == nil then str = UIUtils.GetLocalizedTxt(Const_IDS[ids]) else str = str.."/"..UIUtils.GetLocalizedTxt(Const_IDS[ids]) end end table.insert(strParams,str) else table.insert(strParams,v.param.idsOrStr) end elseif v.paramType == ChannelChat_Model.TemplateParamType.ItemName then table.insert(strParams,CTL.ChannelChat.FormatItemMsg(v.param.itemId)) elseif v.paramType == ChannelChat_Model.TemplateParamType.GuildName then table.insert(strParams,v.param.name) elseif v.paramType == ChannelChat_Model.TemplateParamType.GuildBuilding then table.insert(strParams,v.param.level) if GameAppInfo.IsJapanesePackage() then table.insert(strParams,CTL.ChannelChat.FormatGuildBuildingName(v.param)) table.insert(strParams,CTL.ChannelChat.FormatGuildBuildingGoBoost(v.param)) else table.insert(strParams,CTL.ChannelChat.FormatGuildBuilding(content,v.param)) end elseif v.paramType == ChannelChat_Model.TemplateParamType.Time then table.insert(strParams,UTL.Time.GetShowTimeBySeconds(tonumber(v.param.time))) elseif v.paramType == ChannelChat_Model.TemplateParamType.GuildLevel then table.insert(strParams,CTL.Guild.GetGuildLevelStr(tonumber(v.param.level))) elseif v.paramType == ChannelChat_Model.TemplateParamType.RedEnvelopeID then table.insert(strParams, CTL.ChannelChat.FormatRedPacket(v.param.redEnvelopeID)) elseif v.paramType == ChannelChat_Model.TemplateParamType.RedEnvelopeCfgID then table.insert(strParams, CTL.RedPacket.GetRedPacketDescForChat(tonumber(v.param.redEnvelopeCfgID))) elseif v.paramType == ChannelChat_Model.TemplateParamType.TimeRefreshId then table.insert(strParams, UTL.Time.GetDiffLocalStrById(v.param.timeRefreshId)) elseif v.paramType == ChannelChat_Model.TemplateParamType.CountryName then table.insert(strParams, CTL.Country.GetCountryName(v.param.countryId)) elseif v.paramType == ChannelChat_Model.TemplateParamType.MapName then local mapInfo = DataSheetManager.LevelInfoData:GetDataByLevelID(v.param.mapId) local mapName = UIUtils.GetLocalizedTxt(Const_IDS[mapInfo.LevelNameIDS]) table.insert(strParams, mapName) end end content = string.FormatByIdsKey(chatMsgData.templateInfo.idsTemplate, unpack(strParams)) return content elseif IsServerDataNotNil(chatMsgData.templateInfo.params) then content = CTL.Broadcast.FormatBroadcastMsgContent(chatMsgData.templateInfo, true) return content end return content end function private.SetExtraParam(extraParam, colorHex) extraParam.PlayerShowInfo.acid = BattleDataGetter.GetAcID() extraParam.PlayerShowInfo.mainHeroId = MDL.Player.GetCurShowId() extraParam.PlayerShowInfo.name = BattleDataGetter.GetPlayerName() extraParam.PlayerShowInfo.level = MDL.HeroSelect.GetTeamLevel() extraParam.PlayerShowInfo.sex = MDL.Player.GetSelfGender() extraParam.PlayerShowInfo.WarZoneId = curWarZoneId or 0 extraParam.PlayerShowInfo.ShowServerId = MDL.Login.GetServerShowId() extraParam.PlayerShowInfo.PortraitId = MDL.Character.GetCurWearPortrait() extraParam.PlayerShowInfo.FrameId = MDL.Character.GetCurWearFrame() extraParam.PlayerShowInfo.OfficialId = MDL.OfficialPosition.GetCurTitle() local myGuildData = MDL.Guild.GetMyGuildInfo() extraParam.PlayerShowInfo.EmblemFrame = myGuildData.emblemFrame extraParam.PlayerShowInfo.EmblemContent = myGuildData.emblemContent extraParam.PlayerShowInfo.JobTitle = myGuildData.jobTitle if colorHex then extraParam.color = colorHex end extraParam.PlayerShowInfo.CountryId = MDL.Country.GetMyCountryId() or 0 extraParam.PlayerShowInfo.CountryOfficial = MDL.Country.GetMyJobId() for i, v in ipairs(MDL.HonorSignet.GetEquipList()) do table.insert(extraParam.PlayerShowInfo.WearSignetId, v) table.insert(extraParam.PlayerShowInfo.SignetTimestamp, MDL.HonorSignet.GetActiveInfo(v)) end end --获取相关频道的历史消息 function ChannelChat_Model.GetHistoryInfos() local indexBegin, indexEnd = ChannelChat_Model.GetCurChannelHistoryMsgBeginAndEndIndex() if indexEnd > 0 then ChannelChat_Model.GetHistoryInfosByChannelId(ChannelChat_Model.GetCurChannelID(), indexBegin, indexEnd) else EventSystem.Dispatch(EventID.UI_ChannelChat_OnMainReceiveHistoryMsg, true) end end function ChannelChat_Model.GetHistoryInfosByChannelId(channelID, indexBegin, indexEnd) local msg = chat_pb.HistoryMsg() msg.targetId = channelID msg.type = chat_pb.Room msg.indexBegin = indexBegin msg.indexEnd = indexEnd AuxUtil.ChatMsg(chat_operate_pb.C2SHistroyMsg, msg:SerializeToString()) end --*********************S2C*********服务器返回聊天相关数据****************** function private.HandleChatMsg(id, data) --登录返回消息处理 if id == chat_operate_pb.S2CLogin then --加入房间返回消息处理 local msgResp = chat_pb.ChatLoginResp() msgResp:ParseFromString(data) local errorCode = msgResp.code if errorCode == chat_error_pb.Success then private.HasConnectChatServer = true AuxUtil.ChatLoginSuccess(true) --设置登录ChatServer时间,之前的逻辑是用这个时间作为删除过期聊天的判断,后面如有需求再看吧 ChannelChat_Model.SetLoginTime(UTL.Time.GetServerTimestamp()) forbiddenChatReason = msgResp.reason forbiddenChatEndTime = msgResp.endTime --forbiddenChatReason = "发送垃圾信息" --forbiddenChatEndTime = -1 --登录成功之后请求服务器加入频道 CTL.ChannelChat.JoinChannel() --请求私聊离线记录 CTL.Friend.LoadOfflineChatMsg() end elseif id == chat_operate_pb.S2CJoinRoom then --聊天消息返回处理 local msgResp = chat_pb.JoinRoomResp() msgResp:ParseFromString(data) --判断加入的是房间频道还是私聊 CurChatType = chat_pb.Room if msgResp.code == chat_error_pb.Success then for i = 1, #msgResp.roomId do local roomId = msgResp.roomId[i] ChannelChat_Model.SetCurChannelID(roomId) local splits = string.split(roomId, "_") if #splits >= 2 then if private.IsTeamChannelByPrefix(splits[1]) then ChannelChat_Model.SetTeamChannelInfo(roomId) elseif ChannelChat_Model.IsCurrentChannelByPrefix(splits[1]) then ChannelChat_Model.SetCurrentChannelInfo(roomId) elseif private.IsGuildPartyExamByPrefix(splits[1]) then ChannelChat_Model.SetGuildPartyExamChannelInfo(roomId) CTL.GuildParty.ResetHistoryChatMsg() elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.SceneQuiz) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.SceneQuiz] = roomId CTL.SceneQuiz.ResetHistoryChatMsg() elseif private.IsGuildChannelByPrefix(splits[1]) then ChannelChat_Model.SetGuildChannelInfo(roomId) elseif private.IsCrossChannelByPrefix(splits[1]) then ChannelChat_Model.SetCrossChannelInfo(roomId) elseif private.IsWarZoneChannelByPrefix(splits[1]) then ChannelChat_Model.SetWarZoneChannelInfo(roomId) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.MyCamp) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.MyCamp] = roomId private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.MyCamp, 1) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.SpecifiedActivity) then ChannelChat_Model.SetSpecifiedActivityChannelInfo(roomId) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.GroupChat) then CTL.SpecialTeam.OnJoinGroupChat(roomId) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.Bullet) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Bullet] = roomId private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.Bullet, 1) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.PKRoom) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.PKRoom] = roomId private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.PKRoom, 0) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.GVGFight) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.GVGFight] = roomId private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.GVGFight, 1) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.PetBreedChat) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.PetBreedChat] = roomId private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.PetBreedChat, 1) end end ChannelChat_Model.GetHistoryInfos() -- 加入房间后 聊天页签切换到对应房间页签 if roomId then local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(roomId) if chatCfgData then EventSystem.Dispatch(EventID.UI_ChannelChat_JumpToSpecifiedChannel, chatCfgData.ID) end end end end elseif id == chat_operate_pb.S2CChatMsg then local msgResp = chat_pb.ChatMsgResp() msgResp:ParseFromString(data) if msgResp.code == chat_error_pb.Success then local ChatMsgData = msgResp.msg local uuid = ChatMsgData.uuid local fromId = ChatMsgData.fromId local targetId = ChatMsgData.targetId local type = ChatMsgData.type local content = ChatMsgData.content --local sdkParam = ChatMsgData.sdkParam local sendStamp = ChatMsgData.sendStamp local isTrumpet = ChatMsgData.isTrumpet local isSelf = false local senderName = "" --问了一下服务器,加入房间成功的消息和收到某房间的聊天信息是异步的,可能出现客户端发送了加入房间,但是加入成功还没收到的时候收到了该房间的其他消息 --目前可以舍弃,因为在收到房间加入成功的时候,会请求该房间的历史消息 if type == chat_pb.Room and not ChannelChat_Model.IsInChatRoomByRoomId(targetId) then return end if fromId == BattleDataGetter.GetAcID() and ChatMsgData.extraParam.PlayerShowInfo.mainHeroId > 0 then isSelf = true senderName = BattleDataGetter.GetPlayerName() end local sendInfo = ChatMsgData.extraParam.PlayerShowInfo if not isSelf then senderName = sendInfo.name end local isGroupChat = private.IsChannelEquals(targetId, ChannelChat_Model.ChannelCfgId.GroupChat) --是否群聊 --好友私聊分开处理 if type == chat_pb.Personal or isGroupChat then MDL.Translate.GeneratePureText(ChatMsgData) if isSelf then CTL.Pet.ProcessSharePetMsg(ChatMsgData) end local ids = ChatMsgData.templateInfo.idsTemplate local content if string.isNilOrEmpty(ids) then content = private.GetHyperlinkContent(ChatMsgData.content,ChatMsgData) else local findCount = string.find(UIUtils.GetLocalizedTxt(Const_IDS[ids]), "%%s") if findCount and findCount > 0 then content = private.GetHyperlinkContent(UIUtils.GetLocalizedTxt(Const_IDS[ids]), ChatMsgData) else content = UIUtils.GetLocalizedTxt(Const_IDS[ids]) end end local voiceRecordPath, voiceDuration, voiceChatUrl = private.GetChatVoiceParam(ChatMsgData) local msgData = ChannelChat_Model.CreatChatMsg(uuid, targetId, content, isSelf, senderName, -1, fromId, sendStamp, ChatMsgData.extraParam, voiceRecordPath, voiceDuration, voiceChatUrl) msgData.unRead = fromId ~= BattleDataGetter.GetAcID() --添加到本地的聊天记录中 if isGroupChat then CTL.SpecialTeam.AddGroupChatMsg(targetId, msgData, false) else CTL.Friend.AddChatHistory(msgData) EventSystem.Dispatch(EventID.UI_FriendChat_ReceiveNewMsg, msgData) end EventSystem.Dispatch(EventID.UI_UpdateChatRed) elseif MDL.ChannelChat.IsGuildPartyExamChannelByChannelId(targetId) then local param = ChatMsgData.templateInfo.params[1].param CTL.GuildParty.AddNewChatMsg(isSelf, content, senderName, param.intCommonParam[1], param.index, ChatMsgData.extraParam) elseif ChannelChat_Model.IsSceneQuizChannelByChannelId(targetId) then local param = ChatMsgData.templateInfo.params[1].param CTL.SceneQuiz.AddNewChatMsg(isSelf, content, senderName, param.intCommonParam[1], param.index, ChatMsgData.extraParam) else --这里处理 MDL.Translate.GeneratePureText(ChatMsgData) if isSelf then CTL.Pet.ProcessSharePetMsg(ChatMsgData) end ChannelChat_Model.RecvChannelMsg(isSelf, senderName, ChatMsgData) if isTrumpet then ChannelChat_Model.RecvChannelTrumpetMsg(targetId, ChatMsgData, isSelf, senderName, sendStamp) end end end elseif id == chat_operate_pb.S2CHistroyMsg then --elseif id == chat_operate_pb.S2CHeartbeat then --聊天的心跳在C#端处理 --离开房间返回消息处理 local msgResp = chat_pb.HistoryMsgResp() local ret = msgResp:ParseFromString(data) if msgResp == nil then --logging.log(LTAG.ERROR, "---Lua----ChannelChat-----聊天历史信息为空-----") return end local errorCode = msgResp.code local historyDatas = msgResp.msg if errorCode == chat_error_pb.Success then if #historyDatas <= 0 then logging.log(LTAG.LOG, "---暂无历史消息-----") EventSystem.Dispatch(EventID.UI_ChannelChat_OnMainReceiveHistoryMsg, true) return end local groupChatCount = 0 local isFriendChat = false local isGuildPartyExamChat = false local isSceneQuizChat = false for i = 1, #historyDatas do --处理历史消息显示 local ChatMsgData = historyDatas[i] local uuid = ChatMsgData.uuid local fromId = ChatMsgData.fromId local targetId = ChatMsgData.targetId local type = ChatMsgData.type local content = ChatMsgData.content local sdkParam = ChatMsgData.sdkParam local sendStamp = ChatMsgData.sendStamp local isTrumpet = ChatMsgData.isTrumpet local bubble = ChatMsgData.bubble local isSelf = false local senderName = "" if fromId == BattleDataGetter.GetAcID()and ChatMsgData.extraParam.PlayerShowInfo.mainHeroId > 0 then isSelf = true senderName = BattleDataGetter.GetPlayerName() end if content ~= nil then local _senderName = ChatMsgData.extraParam.PlayerShowInfo.name if isSelf == false then senderName = _senderName end local isGroupChat = private.IsChannelEquals(targetId, ChannelChat_Model.ChannelCfgId.GroupChat) --是否群聊 if isGroupChat then groupChatCount = groupChatCount + 1 end --私聊消息,另外处理 if type == chat_pb.Personal or isGroupChat then MDL.Translate.GeneratePureText(ChatMsgData) isFriendChat = true local ids = ChatMsgData.templateInfo.idsTemplate local content if string.isNilOrEmpty(ids) then content = private.GetHyperlinkContent(ChatMsgData.content,ChatMsgData) else local findCount = string.find(UIUtils.GetLocalizedTxt(Const_IDS[ids]), "%%s") if findCount and findCount > 0 then content = private.GetHyperlinkContent(UIUtils.GetLocalizedTxt(Const_IDS[ids]), ChatMsgData) else content = UIUtils.GetLocalizedTxt(Const_IDS[ids]) end end local voiceRecordPath, voiceDuration, voiceChatUrl = private.GetChatVoiceParam(ChatMsgData) local msgData = ChannelChat_Model.CreatChatMsg(uuid, targetId, content, fromId == BattleDataGetter.GetAcID(), senderName, -1, fromId, sendStamp, ChatMsgData.extraParam, voiceRecordPath, voiceDuration, voiceChatUrl) if isGroupChat then msgData.unRead = CTL.SpecialTeam.IsMsgUnRead(msgData) CTL.SpecialTeam.AddGroupChatMsg(targetId, msgData, true) else msgData.unRead = fromId ~= BattleDataGetter.GetAcID() CTL.Friend.AddChatHistory(msgData) end else --这里处理 MDL.Translate.GeneratePureText(ChatMsgData) -- TODO 这里使用pcall处理一下。Story-JWS2-35483 优化了合纵连横的历史消息ids,导致历史消息中使用原来ids时参数数量对不上 local showContent, correctResult correctResult, showContent = pcall(private.GetHyperlinkContent, ChatMsgData.content, ChatMsgData) if correctResult then --根据消息的参数判断是否需要广播,然后处理字符串 if ChatMsgData.isGameMarquee then showContent = CTL.Broadcast.FormatBroadcastMsgContent(ChatMsgData.templateInfo, true) end if ChatMsgData.isGmMarquee then showContent = CTL.Broadcast.FormatBroadcastGMContent(ChatMsgData.gmMarquee) end local isCanAdd = ChannelChat_Model.IsCanAddMsgList(targetId, fromId, content, ChatMsgData) if showContent and isCanAdd then if MDL.ChannelChat.IsGuildPartyExamChannelByChannelId(targetId) then isGuildPartyExamChat = true local param = ChatMsgData.templateInfo.params[1].param CTL.GuildParty.InitHistoryChatMsg(isSelf, showContent, senderName, param.intCommonParam[1], param.index, ChatMsgData.extraParam) elseif ChannelChat_Model.IsSceneQuizChannelByChannelId(targetId) then isSceneQuizChat = true local param = ChatMsgData.templateInfo.params[1].param CTL.SceneQuiz.InitHistoryChatMsg(isSelf, showContent, senderName, param.intCommonParam[1], param.index, ChatMsgData.extraParam) else local hide = ChannelChat_Model.CheckIsHideMsg(ChatMsgData,targetId) local chatData = ChannelChat_Model.AddMsgToList(uuid, showContent, isSelf, senderName, false, ChatMsgData, ChatMsgData.extraParam, hide, bubble) ChannelChat_Model.AddMsgToCurrentChannelCacheMsgList(targetId, false, chatData) end end end end end end if groupChatCount > 0 then EventSystem.Dispatch(EventID.UI_AddGroupChatHistoryCount, groupChatCount) end if isFriendChat then EventSystem.Dispatch(EventID.UI_UpdateChatRed) else if ChannelChatIsOpen then EventSystem.Dispatch(EventID.UI_ChannelChat_OnMainReceiveHistoryMsg) end if isGuildPartyExamChat then EventSystem.Dispatch(EventID.UI_GuildParty_ExamChatHistory) end if isSceneQuizChat then EventSystem.Dispatch(EventID.UI_SceneQuiz_PreliminaryHistoryChat) end end else -- logging.log(LTAG.LOG, "--ChannelChat---historyDatas errorCode----", errorCode) end elseif id == chat_operate_pb.S2CLeaveRoom then local msgResp = chat_pb.LeaveRoomResp() msgResp:ParseFromString(data) local leaveRoomId = msgResp.roomId local errorCode = msgResp.code if errorCode == chat_error_pb.Success then for i = 1, #leaveRoomId do local splits = string.split(leaveRoomId[i], "_") if #splits >= 2 then if private.IsTeamChannelByPrefix(splits[1]) then ChannelChat_Model.SetTeamChannelInfo(nil) elseif ChannelChat_Model.IsCurrentChannelByPrefix(splits[1]) then ChannelChat_Model.SetCurrentChannelInfo(nil) elseif private.IsGuildPartyExamByPrefix(splits[1]) then ChannelChat_Model.SetGuildPartyExamChannelInfo(nil) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.SceneQuiz) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.SceneQuiz] = nil CTL.SceneQuiz.ResetHistoryChatMsg() elseif private.IsGuildChannelByPrefix(splits[1]) then ChannelChat_Model.SetGuildChannelInfo(nil) elseif private.IsCrossChannelByPrefix(splits[1]) then ChannelChat_Model.SetCrossChannelInfo(nil) elseif private.IsWarZoneChannelByPrefix(splits[1]) then ChannelChat_Model.SetWarZoneChannelInfo(nil) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.MyCamp) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.MyCamp] = nil private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.MyCamp, nil) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.SpecifiedActivity) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.SpecifiedActivity] = nil private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.SpecifiedActivity, nil) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.GroupChat) then CTL.SpecialTeam.OnExitGroupChat(leaveRoomId[i]) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.Bullet) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.Bullet] = nil private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.Bullet, nil) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.PKRoom) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.PKRoom] = nil private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.PKRoom, nil) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.GVGFight) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.GVGFight] = nil private.SetDynamicSettingFlag(ChannelChat_Model.ChannelCfgId.GVGFight, nil) elseif private.IsChannelByPrefix(splits[1], ChannelChat_Model.ChannelCfgId.PetBreedChat) then ChannelCfgIdNameDict[ChannelChat_Model.ChannelCfgId.PetBreedChat] = nil elseif private.IsCountryChannelByPrefix(splits[1]) then ChannelChat_Model.SetCountryChannelInfo(nil) end end allChannelMsgList[leaveRoomId[i]] = nil end end elseif id == chat_operate_pb.S2CForbidden then --logging.log(LTAG.LOG, "---Lua----ChannelChat-----Forbidden Reason------", reason) --logging.log(LTAG.LOG, "---Lua----ChannelChat-----Forbidden endTime------", endTime) local msgResp = chat_pb.ForbiddenResp() msgResp:ParseFromString(data) forbiddenChatReason = msgResp.reason forbiddenChatEndTime = msgResp.endTime elseif id == chat_operate_pb.S2CUnForbidden then logging.log(LTAG.LOG, "---Lua----ChannelChat-----解除禁言------") forbiddenChatReason = "" elseif id == chat_operate_pb.S2CTranslate then local msgResp = chat_pb.TranslateResp() msgResp:ParseFromString(data) MDL.Translate.TranslateResp(msgResp) end end function private.RecvChatMsgByCS(id, data) table.insert(recvMsgIdList, id) table.insert(recvMsgDataList, data) if not private.handleMsgEnabled then LuaUpdater.StartUpdate(private.HandleRecvMsgList) private.handleMsgEnabled = true end end function private.HandleRecvMsgList(dt, ts) for i= 1, HandleMsgCountLimit do local msgId = table.remove(recvMsgIdList, 1) if msgId ~= nil then local msgData = table.remove(recvMsgDataList, 1) private.HandleChatMsg(msgId, msgData) else LuaUpdater.StopUpdate(private.HandleRecvMsgList) private.handleMsgEnabled = nil break end end end function ChannelChat_Model.RecvChannelMsg(isSelf, senderName, msgData) local channelID = msgData.targetId local content = msgData.content local msgTime = msgData.sendStamp local fromId = msgData.fromId local uuid = msgData.uuid local bubble = msgData.bubble if isSelf == false then senderName = msgData.extraParam.PlayerShowInfo.name end local showContent = private.GetHyperlinkContent(msgData.content,msgData) --根据消息的参数判断是否需要广播,然后处理字符串 if msgData.isGameMarquee then showContent = CTL.Broadcast.InsertBroadcastMsg(msgData.templateInfo, true) end if msgData.isGmMarquee then showContent = CTL.Broadcast.InsertBroadcastGM(msgData.gmMarquee) end local hide = ChannelChat_Model.CheckIsHideMsg(msgData,channelID) local isCanAdd = ChannelChat_Model.IsCanAddMsgList(channelID, fromId, content, msgData) if showContent and isCanAdd then local chatData = ChannelChat_Model.AddMsgToList(uuid, showContent, isSelf, senderName, true, msgData, msgData.extraParam, hide, bubble) ChannelChat_Model.AddMsgToCurrentChannelCacheMsgList(channelID, false, chatData) if not hide then --以下这些即时生效的逻辑hide时不处理 local isVoice = chatData.voiceRecordPath ~= nil --自动播放语音 if isVoice and chatData.isSelf == false then local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelID) private.TryAutoPlayVoice(chatCfgData.ID, chatData) end -- 处理综合聊天框信息,TODO 此处保存了两份数据后续优化时统一数据 local addSucc = ChannelChat_Model.AddMsgToChatDlgMsgList( uuid, channelID, showContent, isSelf, senderName, isVoice, fromId, msgData.trumtType, msgData ) if GlobalChatDlgIsOpen and addSucc then EventSystem.Dispatch(EventID.UI_ChannelChat_OnReceiveNewMsg, ChatDlgMsgList[#ChatDlgMsgList]) end end end --根据聊天设置筛选频道数据 --CurrentChannelCacheMsgList if ChannelChatIsOpen and showContent and isCanAdd then --黑名单和被hide的不需要提示 if not ChannelChat_Model.IsMsgFromBlack(msgData) and not hide then if channelID == CurChannelID or ChannelChat_Model.IsMixtureChannelByChannelId(CurChannelID) then -- 刷新当前聊天内容,如果是滑动不是在最下面则处理显示有多少条消息 if ChannelChat_Model.GetIsDragToEnd() then EventSystem.Dispatch(EventID.UI_ChannelChat_OnMainReceiveNewMsg) else notReadMsgCount = notReadMsgCount + 1 if notReadMsgCount >= 99 then notReadMsgCount = 99 end EventSystem.Dispatch(EventID.UI_ChannelChat_OnMainNotReadMsg) end else notReadMsgCount = 0 CTL.ChannelChat.SetRefreshRedPoint(true) NeedRefreshRedPointChannelID = channelID end end end end --有些消息需要进队列但是记为隐藏。比如服务器保存了这条消息,但某些客户端不显示,所以需要把这条消息存在消息列表里但是不显示出来,与服务器消息的下标对齐 function ChannelChat_Model.CheckIsHideMsg(ChatMsgData,channelID) local hide = false --跨服频道,新增开关把限制负面言论在同战区里(没有战区就限制在同服里) if ChatMsgData.needCross2Zone and ChannelChat_Model.IsCrossChannelByChannelId(channelID) then if ChatMsgData.extraParam.PlayerShowInfo.ShowServerId == MDL.Login.GetServerShowId() then hide = false --优先判断是否同服,同服则可以显示 elseif curWarZoneId and curWarZoneId > 0 then hide = curWarZoneId ~= ChatMsgData.extraParam.PlayerShowInfo.WarZoneId --隐藏不同战区的 end end return hide end local TrumpetDatas = {} function ChannelChat_Model.RecvChannelTrumpetMsg(channelID, msgData, isSelf, senderName, msgTime) --跨服的喇叭消息会被转发到世界频道去,防止多弹一遍,这里加个判断,只有喇叭类型和当前频道一致才弹表现 local channelCfg = ChannelChat_Model.GetChatCfgDataByChannelId(channelID) local trumtTypeChanel = ChannelChat_Model.TrumtType2ChannelCfgId[msgData.trumtType] if channelCfg == nil or trumtTypeChanel ~= channelCfg.ID then return end local showContent = private.GetHyperlinkContent(msgData.content,msgData) local chanelType = channelCfg.ID local serShow = CTL.ChannelChat.GetServerShow(chanelType, msgData.extraParam.PlayerShowInfo.ShowServerId) if serShow then senderName = senderName .. string.format(SERVER_SHOW_FORMAT, serShow) end local content = senderName .. ":" ..showContent .. ":" .. chanelType if #TrumpetDatas > 0 then table.insert(TrumpetDatas, 1, content) else table.insert(TrumpetDatas, content) end if not UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIChannelChatMarquee) then UIManager.OpenView(Const_UI_Lua.UIEnum.UIChannelChatMarquee) end end function ChannelChat_Model.GetTrumpetDatas() return TrumpetDatas end function ChannelChat_Model.CanSendMsg() --return true if forbiddenChatEndTime == -1 then return false end if (MDL.ChannelChat.forbiddenChatReason ~= nil) and (MDL.ChannelChat.forbiddenChatReason ~= "") and (forbiddenChatEndTime ~= 0 and forbiddenChatEndTime > UTL.Time.GetServerTimestamp()) then return false end return true end function ChannelChat_Model.CanSendPrivateMsg() --私聊需要优先判断是否连接聊天服 if private.HasConnectChatServer == false then CTL.Tips.AddTipsMsg(Const_IDS.IDS_Friend_SentError) return false end if ChannelChat_Model.CanSendMsg() == false then CTL.Tips.AddTipsMsg(MDL.ChannelChat.GetForbiddenMsg()) return false end return true end --**********End协议处理********** function ChannelChat_Model.JudgeUnlockByParameterTable(unlockTable) local isUnlock = true local content = "" for k, v in pairs(unlockTable) do local type = v.TriggerType local param = v.Parm local des = v.UnlockDes local tmpIsUnlock, tmpContent = MDL.Unlock.IsComplete(type, param, des) isUnlock = isUnlock and tmpIsUnlock content = tmpContent if not isUnlock then return isUnlock, content end end return isUnlock, content end -- function ChannelChat_Model.SetInputHistoryData(content) -- if inputHistoryData ~= nil and #inputHistoryData > 0 then -- local isInsert = true -- for i = 1, #inputHistoryData do -- if inputHistoryData[i] == content then -- isInsert = false -- break -- end -- end -- if isInsert then -- if #inputHistoryData >= 6 then -- table.remove(inputHistoryData) -- table.insert(inputHistoryData, 1, content) -- else -- table.insert(inputHistoryData, 1, content) -- end -- end -- else -- table.insert(inputHistoryData, content) -- end -- end local inputHistoryDictData = {} local inputHistoryData = {} function ChannelChat_Model.SetInputHistoryData(simpleContent, origionContent) if inputHistoryData ~= nil and #inputHistoryData > 0 then local isInsert = true for i = 1, #inputHistoryData do if inputHistoryData[i] == simpleContent then isInsert = false break end end if isInsert then if #inputHistoryData >= 6 then local key = inputHistoryData[#inputHistoryData] inputHistoryDictData[key] = nil table.remove(inputHistoryData) table.insert(inputHistoryData, 1, simpleContent) inputHistoryDictData[simpleContent] = origionContent else table.insert(inputHistoryData, 1, simpleContent) inputHistoryDictData[simpleContent] = origionContent end end else table.insert(inputHistoryData, simpleContent) inputHistoryDictData[simpleContent] = origionContent end end function ChannelChat_Model.GetInputHistoryData() return inputHistoryData end function ChannelChat_Model.GetInputHistoryDataByKey(key) return inputHistoryDictData[key] end function ChannelChat_Model.GetForbiddenMsg() return forbiddenChatReason end function ChannelChat_Model.IsChannelOpen(cfgId) local chatCfgData = DataSheetManager.Chat:GetDataByID(cfgId) local isOpen, unlockText = ChannelChat_Model.JudgeUnlockByParameterTable(chatCfgData.Unlock_Table) return isOpen, unlockText end -- ---------Chat Setting------------------------------ local UIChatSettingDisplayChatContentNewKey = "UIChatSettingKey" --这里数组对应的下标是和Chat.csv中的ID相同的 local TmpChatSettingMsgFlag = {} function ChannelChat_Model.InitChannelSettingMsgFlag() local content = PersistentData.PlayerData:Get(UIChatSettingDisplayChatContentNewKey) if content == nil or #content <= 0 then for i,v in DataSheetManager.Chat:GetEnumerator() do if v.SetShow == 1 then --默认都打开 TmpChatSettingMsgFlag[v.ID] = 1 end end else local array = string.split(content, '|') for i, v in ipairs(array) do local key,value = string.match(v, "(%d*),(%d*)") TmpChatSettingMsgFlag[tonumber(key)] = tonumber(value) end end private.UpdateSettingFlag() end function private.UpdateSettingFlag() --动态添加不默认开启的频道 for ID, val in pairs(private.DynamicSettingChannel) do private.InitDynamicSettingFlag(ID) end end function private.SetDynamicSettingFlag(ID, value) TmpChatSettingMsgFlag[ID] = value end function private.InitDynamicSettingFlag(ID) local canShowToggle = false if TmpChatSettingMsgFlag[ID] then elseif ID == ChannelChat_Model.ChannelCfgId.WarZone then canShowToggle = MDL.ChannelChat.IsWarZoneChannelByCfgId(ID) and CTL.ChannelChat.IsCanShowWarZoneChannel() TmpChatSettingMsgFlag[ID] = canShowToggle and 1 or nil elseif ID == ChannelChat_Model.ChannelCfgId.GuildWar then TmpChatSettingMsgFlag[ID] = 1 --战场频道默认一直显示,不做开关 elseif ID == ChannelChat_Model.ChannelCfgId.Country then TmpChatSettingMsgFlag[ID] = 1 end end function ChannelChat_Model.GetSortedChatSettingList() local sortedList = {} for i, v in pairs(TmpChatSettingMsgFlag) do local chatCfgData = DataSheetManager.Chat:GetDataByID(i) if chatCfgData then if chatCfgData.SetShow == 1 then table.insert(sortedList,chatCfgData) elseif chatCfgData.SetShow == 0 then if MDL.ChannelChat.IsWarZoneChannelByCfgId(chatCfgData.ID) and CTL.ChannelChat.IsCanShowWarZoneChannel() then table.insert(sortedList,chatCfgData) end end end end table.sort(sortedList, private.SortChatRule) return sortedList end function ChannelChat_Model.GetSettingValue(id) return TmpChatSettingMsgFlag[id] == 1 end --1勾选 0不勾选 function ChannelChat_Model.SetSettingValue(id, value) TmpChatSettingMsgFlag[id] = value and 1 or 0 private.SaveSettingToLocal() end function private.SaveSettingToLocal() local result for k, v in pairs(TmpChatSettingMsgFlag) do if result == nil then result = string.format("%d,%d", k, v) else result = result .. string.format("|%d,%d", k, v) end end PersistentData.PlayerData:Set(UIChatSettingDisplayChatContentNewKey, result, true) end function ChannelChat_Model.CanAddToDlgMsgList(channelID) for k, v in pairs(ChannelCfgIdNameDict) do if channelID == v then local flag = TmpChatSettingMsgFlag[k] if flag and flag == 1 then return true end end end return false end -- ---------便捷聊天数据-------------- local localSaveContentArr = {} local QuickMsgDatas = {} function private.JsonDecodeLocalMsg() local localSaveContentStr = PersistentData.PlayerData:Get(ChatQuickMsgKey) if not string.isNilOrEmpty(localSaveContentStr) then local savedata = JSON.decode(localSaveContentStr) if type(savedata) == 'table' then for Id, data in pairs(savedata) do if type(data) == 'string' then localSaveContentArr[Id] = data QuickMsgDatas[Id] = data end end end end end function private.JsonDecodeLocalErrorMsg(msg) end --获取便捷聊天数据 function ChannelChat_Model.GetQuickMsgData() if #QuickMsgDatas > 0 then return QuickMsgDatas end local cfgData = UIUtils.GetLocalizedTxt(Const_IDS.IDS_Chat_Convenient) local cfgDataArray = string.split(cfgData, ';') --初始化配置内容添加至table中 for i = 1, #cfgDataArray do table.insert(QuickMsgDatas, cfgDataArray[i]) end --获取本地数据,这里使用xpall,是为了兼容之前存储的数据,后续大家都有了,会干掉 xpcall(private.JsonDecodeLocalMsg, private.JsonDecodeLocalErrorMsg, nil) return QuickMsgDatas end --保存便捷聊天数据 function ChannelChat_Model.SaveQuickMsg(index, content) localSaveContentArr[index] = content QuickMsgDatas[index] = content PersistentData.PlayerData:Set(ChatQuickMsgKey, JSON.encode(localSaveContentArr), true) end --获取便捷文字 function ChannelChat_Model.GetQuickMsgByIndex(index) return QuickMsgDatas[index] end --超过长度,显示... function ChannelChat_Model.ProcessQuickMsg(msg, comp, width) comp.text = msg if comp.preferredWidth >= width then local length = string.len(msg) while (length > 0) do length = length - 1 local subValue = utf8.sub(msg, 1, length) comp.text = subValue if comp.preferredWidth <= width - 10 then comp.text = subValue .. "..." break end end end end --获取语音文件带权限的地址 function ChannelChat_Model.GameVoiceChatMsgReq(url) local msg = chat_gamex_pb.GameVoiceChatMsgReq() msg.voiceChatUrl = url NetManager.SendMessage(MessageEnums.MessageGameVoiceChatMsg, msg) end function private.OnGameVoiceChatMsgResp(msgResp) if msgResp.Resp.Code == 0 then CTL.ChannelChat.DownloadVoice(msgResp.voiceChatUrl) end end ---------------------------------未发送聊天------------------ function ChannelChat_Model.GetNotSendMsg() return NotSendMsg; end function ChannelChat_Model.SetNotSendMsg(notSendMsg) NotSendMsg = notSendMsg; end ----------------------------语音聊天室状态相关---------------- function private.SetVoiceRoomNum(msg) CTL.ChannelChat.SetVoiceListenCount(msg.type,msg.num) EventSystem.Dispatch(EventID.UI_ChannelChat_RefreshVoiceChatInfo) end function ChannelChat_Model.SendEnterVoiceRoom(type, roomId) local msg = chat_gamex_pb.C2GVoiceChatOperation() msg.oper = chat_gamex_pb.Join msg.type = type msg.roomId = roomId NetManager.SendMessage(MessageEnums.MessageC2GVoiceChatOperation,msg) end function ChannelChat_Model.SendQuitVoiceRoom(type, roomId) local msg = chat_gamex_pb.C2GVoiceChatOperation() msg.oper = chat_gamex_pb.Exit msg.type = type msg.roomId = roomId NetManager.SendMessage(MessageEnums.MessageC2GVoiceChatOperation,msg) end function ChannelChat_Model.AcquireVoiceRoomNum(type, roomId) -- logging.log(LTAG.LOG,"AcquireNum, Type: ",type) local msg = chat_gamex_pb.C2GGetVoiceChatInfo() msg.type = type msg.roomId = roomId NetManager.SendMessage(MessageEnums.MessageC2GGetVoiceChatInfo,msg) end ----------------------------语音聊天室状态结束---------------- --region ------------------ 弹幕 ------------------ -- 组队频道和势力频道弹幕 function ChannelChat_Model.IsCommonBulletChannelByChannelId(channelId) local chatCfgData = ChannelChat_Model.GetChatCfgDataByChannelId(channelId) return chatCfgData and (chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Team or chatCfgData.ID == ChannelChat_Model.ChannelCfgId.Legion or chatCfgData.ID == ChannelChat_Model.ChannelCfgId.GVGFight) end -- 弹幕频道 function ChannelChat_Model.GetSortedAutoPlayBulletScreenSettings() local guildIsUnlock = MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.Guild) local teamIsUnlock = MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.Team) if guildIsUnlock and teamIsUnlock then return {DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Legion), DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Team)} elseif guildIsUnlock and not teamIsUnlock then return {DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Legion)} elseif not guildIsUnlock and teamIsUnlock then return {DataSheetManager.Chat:GetDataByID(ChannelChat_Model.ChannelCfgId.Team)} end end function private.InitAutoPlayBulletScreenSettings() local bulletScreenSettingDict = PersistentData.DeviceData:Get(AUDIO_AUTO_BULLET_KEY, nil) if not bulletScreenSettingDict then bulletScreenSettingDict = { [ChannelChat_Model.ChannelCfgId.Legion] = true, [ChannelChat_Model.ChannelCfgId.Team] = true, } PersistentData.DeviceData:Set(AUDIO_AUTO_BULLET_KEY, private.autoPlayBulletScreenSettingDict, true) end private.autoPlayBulletScreenSettingDict = bulletScreenSettingDict end function ChannelChat_Model.GetAutoPlayBulletScreenChannelState(channelCfgIdId) -- 处于攻城略地玩法中屏蔽其他弹幕 local isUnlock = CTL.Activities.IsOpen(LuaConst.ActivityType.GVGFight) if isUnlock and CTL.GVGFight.IsExistInGVGFightMain() then return CTL.GVGFight.GetGVGFightBulletScreenOpen() and channelCfgIdId == ChannelChat_Model.ChannelCfgId.GVGFight else if not private.autoPlayBulletScreenSettingDict then private.InitAutoPlayBulletScreenSettings() end return private.autoPlayBulletScreenSettingDict[channelCfgIdId] end end function ChannelChat_Model.SetAutoPlayBulletScreenChannel(channelCfgIdId, state) if not private.autoPlayBulletScreenSettingDict then private.InitAutoPlayBulletScreenSettings() end private.autoPlayBulletScreenSettingDict[channelCfgIdId] = state PersistentData.DeviceData:Set(AUDIO_AUTO_BULLET_KEY, private.autoPlayBulletScreenSettingDict, true) if not state then -- 立即清除关闭弹幕开关的频道弹幕 CTL.BulletScreen.ClearChannelScreen(channelCfgIdId) end end --endregion ------------------ 弹幕 ------------------ return ChannelChat_Model