--[[ 语音房间相关逻辑 将进入语音房间,开启听筒和麦克风分装起来 ]] local VoiceRoom_Controller = {} local private = {} local JSON = require("cjson") local EventSystem = require("Event/EventSystem") local LuaFuncEntry = require("Main/LuaFuncEntry") function VoiceRoom_Controller.OnStartup() private.SetupEntryFunc(true) --因为需要进房间后才能设置麦克风和听筒状态,所以需要先缓存 private.cacheRoomState = {} private.curRoomState = {} private.ResetParams() end function private.SetupEntryFunc(isRegist) LuaFuncEntry.SetupMainEntryFunc(isRegist, LuaFuncEntry.FuncType.MicrophonePermissionCallBack, private.OnGetMicrophonePermission, --麦克风权限回调 LuaFuncEntry.FuncType.ChatVoiceRoomActionCallback, private.OnEnterVoiceRoomCallback, LuaFuncEntry.FuncType.OnEnableMicrophoneSuccess, private.OnEnableMicrophoneSuccess, --打开麦克风成功 LuaFuncEntry.FuncType.OnEnableMicrophoneFailed, private.OnEnableMicrophoneFailed --打开麦克风失败 ) end function VoiceRoom_Controller.OnShutdown() private.SetupEntryFunc(false) end function private.OnEnableMicrophoneSuccess() private.OnEnableMicrophoneResult(true) end function private.OnEnableMicrophoneFailed(...) private.OnEnableMicrophoneResult(false, ...) end function private.ResetParams() private.cacheRoomState.enableListener = false private.cacheRoomState.enableMicrophone = false private.curRoomState.voiceRoomType = MDL.VoiceRoom.VoiceRoomType.None private.curRoomState.voiceRoomId = nil private.curRoomState.isEnteredRoom = false private.curRoomState.enableListener = false private.curRoomState.enableMicrophone = false end function VoiceRoom_Controller.EnterVoiceRoom(voiceRoomType, voiceRoomId, enableListener, enableMicrophone) if GameAppInfo.IsMacPackage() then CTL.Tips.AddTipsMsg("当前版本不支持语音功能") return end if not VoiceRoom_Controller.IsInVoiceRoom(voiceRoomType) then logging.crit(LTAG.CRIT, "开始进入语音房间", voiceRoomType, voiceRoomId, enableListener, enableMicrophone) VoiceRoom_Controller.ExitVoiceRoom(private.curRoomState.voiceRoomType) --进入房间是异步过程,缓存一下进入房间后的操作 private.cacheRoomState.enableListener = enableListener private.cacheRoomState.enableMicrophone = enableMicrophone private.curRoomState.voiceRoomType = voiceRoomType private.curRoomState.voiceRoomId = voiceRoomId private.curRoomState.isEnteredRoom = false SDKUtil.EnterVoiceRoom(voiceRoomId) else logging.crit(LTAG.CRIT, "已经在语音房间了,只处理麦克风和听筒", voiceRoomType, voiceRoomId) VoiceRoom_Controller.EnableListener(voiceRoomType, enableListener) VoiceRoom_Controller.EnableMicrophone(voiceRoomType, enableMicrophone) end end --进入语音房间成功 function private.OnEnterVoiceRoomCallback(resultStr) local params = string.split(resultStr, "|") local resultCode = tonumber(params[1]) if resultCode == 2005 then logging.crit(LTAG.CRIT, "收到房间回调", params) if private.curRoomState.isEnteredRoom then return end if UNITY_ANDROID then --安卓的这个接口广播任何一个玩家的进入或者离开消息,iOS只关注自己 if string.isNilOrEmpty(params[2]) then return end local roomMemberData = JSON.decode(params[2]) if tonumber(roomMemberData.roleId) ~= MDL.Player.GetRoleId() then return end end --进入房间成功,看是否需要开启麦克风听筒之类的 private.curRoomState.isEnteredRoom = true EventSystem.Dispatch(EventID.SDK_OnVoiceRoomStateChange, MDL.VoiceRoom.VoiceRoomStateChange.Room, private.curRoomState.voiceRoomType, true) if private.cacheRoomState.enableListener then VoiceRoom_Controller.EnableListener(private.curRoomState.voiceRoomType, private.cacheRoomState.enableListener) end if private.cacheRoomState.enableMicrophone then VoiceRoom_Controller.EnableMicrophone(private.curRoomState.voiceRoomType, private.cacheRoomState.enableMicrophone) end elseif resultCode == -1 or resultCode == 2006 then EventSystem.Dispatch(EventID.SDK_OnVoiceRoomStateChange, MDL.VoiceRoom.VoiceRoomStateChange.Room, private.curRoomState.voiceRoomType, false) end end function VoiceRoom_Controller.ExitVoiceRoom(voiceRoomType) if not VoiceRoom_Controller.IsInVoiceRoom(voiceRoomType) then return end --退出房间,需要先关麦和听筒,再退出房间 VoiceRoom_Controller.EnableListener(voiceRoomType, false) VoiceRoom_Controller.EnableMicrophone(voiceRoomType, false) SDKUtil.ExitVoiceRoom(private.curRoomState.voiceRoomId) private.ResetParams() end function VoiceRoom_Controller.IsInVoiceRoom(voiceRoomType) if voiceRoomType == MDL.VoiceRoom.VoiceRoomType.None then return false end return VoiceRoom_Controller.GetCurRoomType() == voiceRoomType end function VoiceRoom_Controller.GetCurRoomType() return private.curRoomState.voiceRoomType end function VoiceRoom_Controller.GetCurRoomId() return private.curRoomState.voiceRoomId end function VoiceRoom_Controller.IsEnabledListener() return private.curRoomState.enableListener end function VoiceRoom_Controller.EnableListener(voiceRoomType, enableListener) if not VoiceRoom_Controller.IsInVoiceRoom(voiceRoomType) then logging.warn(LTAG.WARN, "开始操作听筒失败,还没有进入房间") return end if private.curRoomState.enableListener == enableListener then logging.warn(LTAG.WARN, "开始操作听筒失败,已经是该状态了") return end if not private.curRoomState.isEnteredRoom then --在房间但是还没进入,证明是在等进房间回调 logging.warn(LTAG.WARN, "开启听筒时还没有真正进入房间,等待进入房间的回调") private.cacheRoomState.enableListener = enableListener else logging.crit(LTAG.CRIT, "操作听筒结果", enableListener) private.cacheRoomState.enableListener = false private.curRoomState.enableListener = enableListener SDKUtil.EnableSpeaker(enableListener) EventSystem.Dispatch(EventID.SDK_OnVoiceRoomStateChange, MDL.VoiceRoom.VoiceRoomStateChange.Listener, private.curRoomState.voiceRoomType, private.curRoomState.enableListener) end end function VoiceRoom_Controller.IsEnabledMicrophone() return private.curRoomState.enableMicrophone end function VoiceRoom_Controller.EnableMicrophone(voiceRoomType, enableMicrophone) if not VoiceRoom_Controller.IsInVoiceRoom(voiceRoomType) then return end if private.curRoomState.enableMicrophone == enableMicrophone then return end private.cacheRoomState.enableMicrophone = enableMicrophone if not private.curRoomState.isEnteredRoom then --在房间但是还没进入,证明是在等进房间回调 logging.warn(LTAG.WARN, "开启麦克风时还没有真正进入房间,等待进入房间的回调") else logging.crit(LTAG.CRIT, "开始尝试获取麦克风权限") SDKUtil.TryEnableMicrophone(enableMicrophone) end end function private.OnGetMicrophonePermission(permissionStr) logging.crit(LTAG.CRIT, "获取麦克风权限回调", permissionStr) if permissionStr and permissionStr == "true" then SDKUtil.EnableMicrophone(private.cacheRoomState.enableMicrophone) else local params = string.split(permissionStr, "|") if params and params[2] and params[2] == "4020" then logging.crit(LTAG.CRIT, "玩家拒绝了麦克风权限") MDL.VoiceRoom.OnRefuseEnableMicrophone(VoiceRoom_Controller.GetCurRoomType()) end --没有权限提示权限不足 CTL.Tips.AddTipsMsg(Const_IDS.IDS_Chat_Jurisdiction) end end function private.OnEnableMicrophoneResult(isSuccess, errorCode) if not isSuccess then if errorCode == "4010" then logging.crit(LTAG.CRIT, "正在申请麦克风权限...") else logging.crit(LTAG.CRIT, "打开麦克风失败", errorCode) end return end logging.crit(LTAG.CRIT, "操作麦克风结果", isSuccess, private.cacheRoomState.enableMicrophone) private.curRoomState.enableMicrophone = isSuccess and private.cacheRoomState.enableMicrophone or false private.cacheRoomState.enableMicrophone = false EventSystem.Dispatch(EventID.SDK_OnVoiceRoomStateChange, MDL.VoiceRoom.VoiceRoomStateChange.Microphone, private.curRoomState.voiceRoomType, private.curRoomState.enableMicrophone) end function VoiceRoom_Controller.CheckNeedLeaveVoiceRoom() if BattleDataGetter.IsSyncTeamPVP() or UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UISyncTeamPVPSelectHeroPanel) then if BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.SyncTeamFairChampionship) then CTL.VoiceRoom.ExitVoiceRoom(MDL.VoiceRoom.VoiceRoomType.TeamFairChampionship) else CTL.VoiceRoom.ExitVoiceRoom(MDL.VoiceRoom.VoiceRoomType.Room_3V3) end elseif BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.SyncUnfairTeamPVP) then CTL.VoiceRoom.ExitVoiceRoom(MDL.VoiceRoom.VoiceRoomType.Room_HeroMatch3V3) elseif BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.TeamFairChampionshipTown) then CTL.VoiceRoom.ExitVoiceRoom(MDL.VoiceRoom.VoiceRoomType.TeamFairChampionship) elseif BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.SyncFourCountryChaos) then CTL.VoiceRoom.ExitVoiceRoom(MDL.VoiceRoom.VoiceRoomType.Room_SyncFourCountry) elseif BattleDataGetter.IsGuildWarLevel() or BattleDataGetter.IsGuildWarWaitingArea() then CTL.VoiceRoom.ExitVoiceRoom(MDL.VoiceRoom.VoiceRoomType.GuildWar) elseif BattleDataGetter.IsCityWarLevel() or BattleDataGetter.IsCityWarWaitingLevel() then CTL.VoiceRoom.ExitVoiceRoom(MDL.VoiceRoom.VoiceRoomType.ChangAnSiege) end end --获取要进入的语音房间id function VoiceRoom_Controller.GetPreEnterVoiceRoomID(roomType) if roomType == MDL.VoiceRoom.VoiceRoomType.Guild then local guildInfo = MDL.Guild.GetMyGuildInfo() if guildInfo then return guildInfo.guildId .. "Guild" end elseif roomType == MDL.VoiceRoom.VoiceRoomType.DragonArtery then return MDL.DragonArtery.GetDragonArteryChannelPrefix(false) .. "DragonArtery" end return nil end --显示通用的语聊界面,只有听筒和麦克风的按钮 function VoiceRoom_Controller.OpenCommonVoiceChat(viewCanvas, voiceRoomType, isNeedServer) local viewContext = {voiceRoomType=voiceRoomType, isNeedServer=isNeedServer} return viewCanvas:OpenView(GetViewClass(Const_UI_Lua.UIEnum.UICommonVoiceChat), viewContext) end return VoiceRoom_Controller