using System.Text.Json; namespace MSCO.Server; /// /// Prüft Steam-Anmeldetickets der Spieler über die Steam Web API /// (ISteamUserAuth/AuthenticateUserTicket), sofern in server.json ein Key eingetragen ist. /// Ohne Key wird nur geprüft, dass der Client eine Steam-ID und ein Ticket mitschickt. /// public sealed class SteamVerifier { const int MySummerCarAppId = 516750; readonly HttpClient http = new() { Timeout = TimeSpan.FromSeconds(10) }; readonly string apiKey; public bool Enabled => !string.IsNullOrWhiteSpace(apiKey); public SteamVerifier(string apiKey) { this.apiKey = apiKey; } /// Gibt null zurück, wenn alles passt, sonst den Ablehnungsgrund. public async Task VerifyAsync(ulong claimedSteamId, byte[] ticket, bool requireSteam) { bool hasSteam = claimedSteamId != 0 && ticket != null && ticket.Length > 0; if (!hasSteam) return requireSteam ? "Steam is required to join this server" : null; // Non-Steam-Server if (!Enabled) return null; string url = "https://api.steampowered.com/ISteamUserAuth/AuthenticateUserTicket/v1/?key=" + apiKey + "&appid=" + MySummerCarAppId + "&ticket=" + Convert.ToHexString(ticket); try { // Frisch erzeugte Tickets sind manchmal erst nach einem Moment gültig for (int attempt = 0; attempt < 3; attempt++) { using var doc = JsonDocument.Parse(await http.GetStringAsync(url)); var response = doc.RootElement.GetProperty("response"); if (response.TryGetProperty("params", out var p)) { string steamId = p.GetProperty("steamid").GetString(); if (steamId != claimedSteamId.ToString()) return "Steam ticket does not match your account"; if (p.TryGetProperty("vacbanned", out var vac) && vac.GetBoolean()) return "VAC banned"; return null; } await Task.Delay(1000); } return "Steam could not verify your ticket"; } catch (Exception e) { Console.WriteLine("[steam] verification failed: " + e.Message); return "Steam verification failed, try again"; } } }