From 868180e3ec2b83b91a641012be914f720646fc8d Mon Sep 17 00:00:00 2001 From: "tom.hempel" Date: Sat, 25 Oct 2025 15:58:28 +0200 Subject: [PATCH] refactored VRExperimentController to utilize SharedUDPListener for packet handling --- .../Scripts/Multiplayer/SharedUDPListener.cs | 1 + .../Assets/Scripts/VRExperimentController.cs | 122 ++++-------------- .../ProjectSettings/EditorBuildSettings.asset | 2 +- .../ProjectSettings/ProjectSettings.asset | 2 +- 4 files changed, 25 insertions(+), 102 deletions(-) diff --git a/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs b/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs index 492d1ab..b3774b8 100644 --- a/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs +++ b/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs @@ -93,6 +93,7 @@ namespace Convai.Scripts.Runtime.Multiplayer ConvaiLogger.Info($" - Voice Audio: 0xC0A1", ConvaiLogger.LogCategory.Character); ConvaiLogger.Info($" - NPC Speech: 0xC0A3", ConvaiLogger.LogCategory.Character); ConvaiLogger.Info($" - Avatar Sync: 0xC0A0", ConvaiLogger.LogCategory.Character); + ConvaiLogger.Info($" - Experiment Control: JSON (text-based)", ConvaiLogger.LogCategory.Character); // Start listening for all packets _ = ListenForPackets(_cancellationTokenSource.Token); diff --git a/Unity-Master/Assets/Scripts/VRExperimentController.cs b/Unity-Master/Assets/Scripts/VRExperimentController.cs index bbc6020..05810af 100644 --- a/Unity-Master/Assets/Scripts/VRExperimentController.cs +++ b/Unity-Master/Assets/Scripts/VRExperimentController.cs @@ -2,9 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Net; -using System.Net.Sockets; using System.Text; -using System.Threading; using UnityEngine; using Newtonsoft.Json; @@ -34,8 +32,6 @@ public class VRExperimentController : MonoBehaviour [SerializeField] private bool enableDebugLogging = true; // Network components - private UdpClient udpClient; - private Thread udpListenerThread; private bool isListening = false; private int udpPort; @@ -197,70 +193,40 @@ public class VRExperimentController : MonoBehaviour { try { - if (allowPortSharing) + // Wait for shared listener to be ready + if (Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance == null) { - // Create UDP client with port reuse for local testing - udpClient = new UdpClient(); - udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, udpPort)); - } - else - { - // Standard UDP client binding - udpClient = new UdpClient(udpPort); + LogError("SharedUDPListener not found! Make sure it's in the scene."); + return; } - udpListenerThread = new Thread(new ThreadStart(UDPListenerLoop)); - udpListenerThread.IsBackground = true; + // Subscribe to shared listener + Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance.OnPacketReceived += HandlePacketReceived; isListening = true; - udpListenerThread.Start(); - LogMessage($"UDP Experiment Control Listener started on port {udpPort} (filtering JSON messages only, Port sharing: {allowPortSharing})"); + LogMessage($"UDP Experiment Control Listener subscribed to shared listener on port {udpPort} (filtering JSON messages only)"); } catch (Exception e) { - if (allowPortSharing) - { - LogError($"Failed to start UDP listener with port sharing: {e.Message}"); - LogMessage("Trying with different port..."); - TryAlternativePort(); - } - else - { - LogError($"Failed to start UDP listener: {e.Message}"); - } + LogError($"Failed to subscribe to shared UDP listener: {e.Message}"); } } /// - /// Try alternative ports for local testing + /// Handle packet received from shared listener /// - private void TryAlternativePort() + private void HandlePacketReceived(byte[] data, IPEndPoint senderEndPoint) { - // Try a few alternative ports for local testing - int[] alternativePorts = { 1222, 1223, 1224, 1225, 1226 }; + // Check if this is an experiment control message (JSON) + if (!IsExperimentControlMessage(data)) return; - foreach (int port in alternativePorts) + string message = Encoding.UTF8.GetString(data); + + // Add message to queue for main thread processing + lock (queueLock) { - try - { - udpClient = new UdpClient(port); - udpListenerThread = new Thread(new ThreadStart(UDPListenerLoop)); - udpListenerThread.IsBackground = true; - isListening = true; - udpListenerThread.Start(); - - LogMessage($"UDP Experiment Control Listener started on alternative port {port}"); - return; - } - catch (Exception) - { - // Try next port - continue; - } + messageQueue.Enqueue(message); } - - LogError("Failed to start UDP listener on any available port"); } /// @@ -270,59 +236,15 @@ public class VRExperimentController : MonoBehaviour { isListening = false; - if (udpClient != null) + // Unsubscribe from shared listener + if (Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance != null) { - udpClient.Close(); - udpClient = null; - } - - if (udpListenerThread != null && udpListenerThread.IsAlive) - { - udpListenerThread.Join(1000); // Wait up to 1 second - if (udpListenerThread.IsAlive) - { - udpListenerThread.Abort(); - } - udpListenerThread = null; + Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance.OnPacketReceived -= HandlePacketReceived; } LogMessage("UDP Listener stopped"); } - /// - /// UDP listener loop (runs in separate thread) - /// - private void UDPListenerLoop() - { - while (isListening) - { - try - { - IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, udpPort); - byte[] data = udpClient.Receive(ref remoteEndPoint); - - // Check if this looks like a JSON experiment control message - if (IsExperimentControlMessage(data)) - { - string message = Encoding.UTF8.GetString(data); - - // Add message to queue for main thread processing - lock (queueLock) - { - messageQueue.Enqueue(message); - } - } - // If it's not an experiment control message (likely avatar data), ignore it - } - catch (Exception e) - { - if (isListening) // Only log if we're still supposed to be listening - { - LogError($"UDP Listener error: {e.Message}"); - } - } - } - } /// /// Check if the received data is an experiment control message (JSON) vs avatar data (binary) @@ -684,9 +606,9 @@ public class VRExperimentController : MonoBehaviour /// private int GetActualListenPort() { - if (udpClient?.Client?.LocalEndPoint != null) + if (Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance != null) { - return ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + return Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance.ListenPort; } return udpPort; } diff --git a/Unity-Master/ProjectSettings/EditorBuildSettings.asset b/Unity-Master/ProjectSettings/EditorBuildSettings.asset index 290a860..fb169eb 100644 --- a/Unity-Master/ProjectSettings/EditorBuildSettings.asset +++ b/Unity-Master/ProjectSettings/EditorBuildSettings.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57814a7518569d818e2d6fd8ddb8c5543ec9a81bdd1b5c6266f4d9f5ea9eaf31 +oid sha256:1ae56a0aa5e5fcd905f8d677138aa623b5c695c0f95a066ae70847afb086ef01 size 1111 diff --git a/Unity-Master/ProjectSettings/ProjectSettings.asset b/Unity-Master/ProjectSettings/ProjectSettings.asset index a8004b2..5687f99 100644 --- a/Unity-Master/ProjectSettings/ProjectSettings.asset +++ b/Unity-Master/ProjectSettings/ProjectSettings.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9fbb1f7b761b58869e3f1adcbabe77be01115d75cefd557c504b4fb3aa50b129 +oid sha256:e3021b170955d24126c440f68eacf051f182187e316381b898403f6bba7b1271 size 24723