271 lines
8.6 KiB
C#
271 lines
8.6 KiB
C#
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<List<int>> GetAllIds()
|
|
{
|
|
SendMessage("/getAllIds");
|
|
var response = await udpClientReceive.ReceiveMessageAsync();
|
|
if (response.Address.Value == "/getAllIds")
|
|
{
|
|
List<int> playerIds = new List<int>();
|
|
foreach (var argument in response.Arguments)
|
|
{
|
|
playerIds.Add((int)argument);
|
|
}
|
|
return playerIds;
|
|
}
|
|
return new List<int>();
|
|
}
|
|
|
|
// < 0 = no confirmation; 0 = confirm; > 0 = player id
|
|
|
|
//public async Task<int> GetPlayerId(List<Player> targets, List<Player> 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<object>().ToArray().Concat(pois.Select(p => p.id).Cast<object>()).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<int> GetPlayerId(List<Player> targets, List<Player> 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<object>();
|
|
|
|
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<bool> GetConfirmation(List<Player> players)
|
|
{
|
|
int maxRetries = 50;
|
|
int timeoutSeconds = 20;
|
|
|
|
var args = new List<object>();
|
|
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<bool> GetConfirmationEveryoneAsleep()
|
|
{
|
|
return true;
|
|
SendMessage("/everyoneAsleep");
|
|
|
|
var response = await udpClientReceive.ReceiveMessageAsync();
|
|
if (response.Address.Value == "/everyoneAsleep")
|
|
{
|
|
return (bool)response.Arguments.ElementAt(0);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|