From 4dd67828549b50f4fa8b0a70a9455fe6ccf9b16f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 26 Mar 2026 02:21:00 +0000 Subject: [PATCH] webrtc handler for client logout --- .../WebRtcVoiceRegionModule.cs | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/OpenSim/Addons/os-webrtc-janus/WebRtcVoiceRegionModule/WebRtcVoiceRegionModule.cs b/OpenSim/Addons/os-webrtc-janus/WebRtcVoiceRegionModule/WebRtcVoiceRegionModule.cs index c1d21a6d3d..f1afd9c6d4 100644 --- a/OpenSim/Addons/os-webrtc-janus/WebRtcVoiceRegionModule/WebRtcVoiceRegionModule.cs +++ b/OpenSim/Addons/os-webrtc-janus/WebRtcVoiceRegionModule/WebRtcVoiceRegionModule.cs @@ -130,6 +130,8 @@ namespace osWebRtcVoice m_Enabled = false; } } + else + m_nonSpatialVoiceService = m_spatialVoiceService; if (m_Enabled) { @@ -171,6 +173,8 @@ namespace osWebRtcVoice OnRemovePresence(scene, agentID); }; + scene.EventManager.OnNewClient += OnNewClient; + ISimulatorFeaturesModule simFeatures = scene.RequestModuleInterface(); simFeatures?.AddFeature("VoiceServerType", OSD.FromString("webrtc")); } @@ -193,9 +197,54 @@ namespace osWebRtcVoice get { return null; } } + private void OnNewClient(IClientAPI client) + { + client.OnLogout += OnClientLogOut; + } + + private void OnClientLogOut(IClientAPI client) + { + client.OnLogout -= OnClientLogOut; + + if(client.SceneAgent is not ScenePresence sp) + return; + + List toremove = []; + if (VoiceViewerSession.TryGetViewerSessionsByAgentAndRegion(sp.UUID, sp.Scene.ID, out IEnumerable> vSessions)) + { + foreach(KeyValuePair v in vSessions) + { + if((v.Value.Flags & IVoiceViewerSession.VFlags.IsParcel) != 0) + toremove.Add(v.Value); + } + + foreach(IVoiceViewerSession v in toremove) + VoiceViewerSession.RemoveViewerSession(v.ViewerSessionID); + } + + Util.FireAndForget( x => + { + try + { + OSDMap vreq = new() + { + { "logout" , true}, + { "viewer_session" , UUID.Zero} + }; + + m_spatialVoiceService?.ProvisionVoiceAccountRequest(vreq , sp.UUID, sp.Scene.ID); + if(m_nonSpatialVoiceService != m_spatialVoiceService) + m_nonSpatialVoiceService?.ProvisionVoiceAccountRequest(vreq , sp.UUID, sp.Scene.ID); + } + catch (Exception ex) + { + m_log.Debug($"{LogHeader} OnClientLogOut exception: {ex.Message}"); + } + }); + } + private static void OnRemovePresence(Scene pScene, UUID pAgentID) { - // When a presence is removed, remove the parcel viewer sessions for that agent List toremove = []; if (VoiceViewerSession.TryGetViewerSessionsByAgentAndRegion(pAgentID, pScene.RegionInfo.RegionID, out IEnumerable> vSessions)) { @@ -226,7 +275,7 @@ namespace osWebRtcVoice catch (Exception ex) { m_log.Debug( - $"{LogHeader} OnRemovePresence: shutdown failed for viewer_session {v.ViewerSessionID}: {ex.Message}"); + $"{LogHeader} OnRemovePresence: failed for viewer_session {v.ViewerSessionID}: {ex.Message}"); } }); } @@ -248,6 +297,7 @@ namespace osWebRtcVoice $"{LogHeader} CleanupDuplicateSessions: removing stale viewer_session {candidate.Key} for agent {pAgentID}, scene {pSceneID}"); toremove.Add(candidate.Value); } + foreach(IVoiceViewerSession v in toremove) VoiceViewerSession.RemoveViewerSession(v.ViewerSessionID);