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
+7 -2
View File
@@ -6,7 +6,7 @@ using System.Text.Json;
namespace BSO.Net
{
/// <summary>
/// Spiel-Ticket der BSO-Website: base64url(JSON {u, id, iat, exp}) + "." + base64url(RSA-SHA256-Signatur). Der Launcher
/// Spiel-Ticket der BSO-Website: base64url(JSON {u, id, iat, exp, lb?, ln?}) + "." + base64url(RSA-SHA256-Signatur). Der Launcher
/// holt es beim Spielen und schreibt es in BSO.json, die Mod schickt es im Hello mit. Die Mod liest es nur (Name, Ablauf),
/// pruefen kann es nur der Server mit dem oeffentlichen Schluessel der Website (Verify) - wer die Mod veraendert, kommt so
/// trotzdem nicht ohne gueltiges Konto auf einen Server.
@@ -16,6 +16,9 @@ namespace BSO.Net
public string Username { get; private set; }
public string AccountId { get; private set; }
public DateTime Expires { get; private set; }
/// <summary>Lobby, fuer die das Ticket gilt (null = keine) und ihr Name ("Lobby von ...").</summary>
public string Lobby { get; private set; }
public string LobbyName { get; private set; }
public bool Expired => DateTime.UtcNow >= Expires;
/// <summary>Inhalt lesen, ohne die Signatur zu pruefen. null = kein Ticket / kaputt.</summary>
@@ -32,7 +35,9 @@ namespace BSO.Net
{
Username = r.GetProperty("u").GetString(),
AccountId = r.GetProperty("id").GetString(),
Expires = DateTimeOffset.FromUnixTimeSeconds(r.GetProperty("exp").GetInt64()).UtcDateTime
Expires = DateTimeOffset.FromUnixTimeSeconds(r.GetProperty("exp").GetInt64()).UtcDateTime,
Lobby = r.TryGetProperty("lb", out var lb) ? lb.GetString() : null,
LobbyName = r.TryGetProperty("ln", out var ln) ? ln.GetString() : null
};
}
catch { return null; }