using System; using System.Net.Http; using System.Net.Http.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; namespace ModpackLauncher.Services; /// /// Friend-side wrapper for the brass-sigil-server's public whitelist endpoints. /// Exists so the launcher can: /// - Send a "please add me" request without the friend needing to share their /// MC username with the admin out-of-band. /// - Poll status afterwards so the launcher UI reflects pending/approved/denied. /// public sealed class WhitelistRequestService { private static readonly HttpClient _http = new() { Timeout = TimeSpan.FromSeconds(10) }; public sealed class StatusResponse { [JsonPropertyName("ok")] public bool Ok { get; set; } [JsonPropertyName("status")] public string? Status { get; set; } } public sealed class RequestResponse { [JsonPropertyName("ok")] public bool Ok { get; set; } [JsonPropertyName("status")] public string? Status { get; set; } [JsonPropertyName("error")] public string? Error { get; set; } } /// /// Returns "pending" / "approved" / "denied" / "unknown" / "" (network error). /// public async Task GetStatusAsync(string panelUrl, string username) { try { var url = $"{panelUrl.TrimEnd('/')}/api/whitelist/status?username={Uri.EscapeDataString(username)}"; var resp = await _http.GetFromJsonAsync(url); return resp?.Status ?? ""; } catch { return ""; } } public async Task SubmitAsync(string panelUrl, string username, string? message = null) { try { var url = $"{panelUrl.TrimEnd('/')}/api/whitelist/request"; var resp = await _http.PostAsJsonAsync(url, new { username, message }); var body = await resp.Content.ReadFromJsonAsync(); if (body is null) return new RequestResponse { Ok = false, Error = "Empty response." }; if (!resp.IsSuccessStatusCode && string.IsNullOrEmpty(body.Error)) body.Error = $"HTTP {(int)resp.StatusCode}"; return body; } catch (Exception ex) { return new RequestResponse { Ok = false, Error = ex.Message }; } } }