using CoreOSC; using CoreOSC.IO; using CoreOSC.Types; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Net; using System.Net.Sockets; using System.Security.Cryptography; using System.Text; namespace Wolf { internal class OSCClient { UdpClient udpClientSend; UdpClient udpClientReceive; public OSCClient(string hostname, int port) { // 1. Lokalen Port binden (für Empfang) udpClientSend = new UdpClient(hostname, port); udpClientReceive = new UdpClient(new IPEndPoint(IPAddress.Any, port)); } public async Task SendMessage(string endpoint) { var message = new OscMessage(new Address(endpoint)); await udpClientSend.SendMessageAsync(message); } public async Task SpeakId(int textId) { var message = new OscMessage( address: new Address("/speak"), arguments: new object[] { textId }); await udpClientSend.SendMessageAsync(message); } public async Task Read(string text, bool readStory = true) { string endpoint = readStory ? "/read_story" : "/read"; var message = new OscMessage( address: new Address(endpoint), arguments: new object[] { text, 2 }); await udpClientSend.SendMessageAsync(message); } public async Task SendMessageWithArguments(string endpoint, params object[] param) { var message = new OscMessage( address: new Address(endpoint), arguments: param ); await udpClientSend.SendMessageAsync(message); } public async Task ReceiveMessageWithoutArguments() { var response = await udpClientReceive.ReceiveMessageAsync(); Console.WriteLine(response.Address.Value); // Do something with the arguments, (depending on the address) foreach (var argument in response.Arguments) { Console.WriteLine(argument.GetType()); } } public async Task ReceiveMessageWithArguments() { var response = await udpClientReceive.ReceiveMessageAsync(); if (response.Address.Value == "/example4") { Console.WriteLine("/example4"); var stringArgument = (string)response.Arguments.ElementAt(0); var intArgument = (int)response.Arguments.ElementAt(1); var falseArgument = (OscFalse)response.Arguments.ElementAt(2); Console.WriteLine($"First string argument: {stringArgument}"); Console.WriteLine($"Second int argument: {intArgument}"); Console.WriteLine($"Third OscFalse argument:{falseArgument}"); } } public async Task> GetAllIds() { SendMessage("/getAllIds"); var response = await udpClientReceive.ReceiveMessageAsync(); if (response.Address.Value == "/getAllIds") { List playerIds = new List(); foreach (var argument in response.Arguments) { playerIds.Add((int)argument); } return playerIds; } return new List(); } // < 0 = no confirmation; 0 = confirm; > 0 = player id //public async Task GetPlayerId(List targets, List pois) //{ // //SendMessageWithArguments("/getPlayerID", targets.Select(p => p.id).ToArray(), pois.Select(p => p.id).ToArray()); // var message = new OscMessage( // address: new Address("/getPlayerID"), // //arguments: new object[] { targets.Select(p => p.id).ToArray(), pois.Select(p => p.id).ToArray() } // arguments: Concat(targets.Select(p => p.id).Cast().ToArray().Concat(pois.Select(p => p.id).Cast()).ToArray() // ); // await udpClientSend.SendMessageAsync(message); // var response = await udpClientReceive.ReceiveMessageAsync(); // if (response.Address.Value == "/getPlayerID") // { // return (int)response.Arguments.ElementAt(0); // } // return -1; //} public async Task GetPlayerId(List targets, List pois) { //return (int) targets.FirstOrDefault().id; // Arrays extrahieren var arr2 = targets.Select(p => p.id).ToArray(); var arr1 = pois.Select(p => p.id).ToArray(); // OSC-kompatibles int-Argument-Array bauen: // Länge1 | Werte1 | Länge2 | Werte2 var args = new List(); args.Add(arr1.Length); foreach (var id in arr1) args.Add(id); args.Add(arr2.Length); foreach (var id in arr2) args.Add(id); // Nachricht senden var message = new OscMessage( new Address("/getPlayerID"), args.ToArray() ); int maxRetries = 50; int timeoutSeconds = 20; // Anfrage senden await udpClientSend.SendMessageAsync(message); for (int attempt = 1; attempt <= maxRetries; attempt++) { // Timeout für Receive var receiveTask = udpClientReceive.ReceiveMessageAsync(); var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeoutSeconds)); var completed = await Task.WhenAny(receiveTask, timeoutTask); if (completed == receiveTask) { var response = await receiveTask; // Prüfen, ob es die erwartete Antwort ist if (response.Address.Value == "/getPlayerID") { return (int)response.Arguments.ElementAt(0); } // Falsche Antwort → ignorieren und weiter versuchen continue; } await udpClientSend.SendMessageAsync(message); } return -1; } public async Task GetConfirmation(List players) { int maxRetries = 50; int timeoutSeconds = 20; var args = new List(); foreach (var p in players) { args.Add(p.id); } // Anfrage senden var message = new OscMessage( new Address("/confirmation"), args.ToArray() ); await udpClientSend.SendMessageAsync(message); //await udpClientReceive.ReceiveMessageAsync(); for (int attempt = 1; attempt <= maxRetries; attempt++) { // Timeout für Receive var receiveTask = udpClientReceive.ReceiveMessageAsync(); var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeoutSeconds)); var completed = await Task.WhenAny(receiveTask, timeoutTask); if (completed == receiveTask) { var response = await receiveTask; // Prüfen, ob es die erwartete Antwort ist if (response.Address.Value == "/confirmation") { if (response.Arguments.ElementAt(0) is OscFalse) { return false; } if (response.Arguments.ElementAt(0) is OscTrue) { return true; } } // Falsche Antwort → ignorieren und weiter versuchen continue; } await udpClientSend.SendMessageAsync(message); } return false; } public async Task GetConfirmationEveryoneAsleep() { return true; SendMessage("/everyoneAsleep"); var response = await udpClientReceive.ReceiveMessageAsync(); if (response.Address.Value == "/everyoneAsleep") { return (bool)response.Arguments.ElementAt(0); } return false; } } }