Files
2026-09-26 19:45:02 +02:00

58 lines
2.3 KiB
C#

using System.Text.Json;
namespace MSCO.Server;
/// <summary>
/// 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.
/// </summary>
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;
}
/// <summary>Gibt null zurück, wenn alles passt, sonst den Ablehnungsgrund.</summary>
public async Task<string> 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";
}
}
}