0.5.0: Lobby ueber das BSO-Relay (ohne Portfreigabe)

- Server relay:<Lobby> verbindet per WebSocket ueber eine lokale Bruecke (RelayClient)
- Ticket mit Lobby, Anzeige 'Lobby von ...'
- Nach Szenenwechsel Mitspieler-Modelle erst nach 3 s neu anlegen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 19:30:20 +01:00
co-authored by Claude Opus 5.5
parent 1dca505e3c
commit 8a1329f5fa
9 changed files with 170 additions and 21 deletions
+23 -5
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using BSO.Net;
@@ -66,7 +67,7 @@ namespace BSO
}
}
const int ConnectTimeoutMs = 5000;
const int ConnectTimeoutMs = 5000, RelayTimeoutMs = 20000; // Relay: Website + Antwort des Lobby-Servers
const int SendIntervalMs = 100, PingIntervalMs = 2000;
public static NetStatus Status { get; private set; }
@@ -125,6 +126,8 @@ namespace BSO
}
public static string ServerAddress => Config.Current.Server;
/// <summary>Fuer die Anzeige: "Lobby von ..." statt relay:&lt;id&gt;.</summary>
public static string ServerDisplay => Config.Current.ServerLabel ?? (ServerAddress.StartsWith("relay:") ? "Lobby" : ServerAddress);
/// <summary>
/// Gueltiges Spiel-Ticket vom Launcher? Ohne gibt es keinen Multiplayer - der Server prueft es zusaetzlich (die Mod
@@ -152,11 +155,26 @@ namespace BSO
Bootstrap.Log("Nicht verbunden: " + problem);
return;
}
(string host, int port) = ParseAddress(ServerAddress);
Bootstrap.Log($"Verbinde mit {host}:{port} ...");
LastError = "";
tcp = new TcpClient();
connectTask = tcp.ConnectAsync(host, port);
if (ServerAddress.StartsWith("relay:"))
{
// Server der Lobby: laeuft im BSO-Relay, verbunden ueber eine lokale Bruecke - keine Portfreigabe noetig
string lobby = ServerAddress.Substring(6), relay = Config.Current.Relay, ticket = Config.Current.Ticket;
Bootstrap.Log($"Verbinde ueber {relay} mit Lobby {lobby} ...");
TcpClient client = tcp;
connectTask = Task.Run(async () =>
{
int port = await RelayClient.JoinAsync(relay, lobby, ticket, CancellationToken.None);
await client.ConnectAsync("127.0.0.1", port);
});
}
else
{
(string host, int port) = ParseAddress(ServerAddress);
Bootstrap.Log($"Verbinde mit {host}:{port} ...");
connectTask = tcp.ConnectAsync(host, port);
}
connectClock.Restart();
Status = NetStatus.Connecting;
}
@@ -165,7 +183,7 @@ namespace BSO
{
if (!connectTask.IsCompleted)
{
if (connectClock.ElapsedMilliseconds > ConnectTimeoutMs) Fail("Server antwortet nicht");
if (connectClock.ElapsedMilliseconds > (ServerAddress.StartsWith("relay:") ? RelayTimeoutMs : ConnectTimeoutMs)) Fail("Server antwortet nicht");
return;
}
if (connectTask.IsFaulted || !tcp.Connected)