Complete private authentication, server integrations and activity reporting

Add Fabric/Forge version builds and Paper integration, preserve permanent player identities across renames, harden session authorization, and surface privacy-conscious launcher/server activity in the panel.
This commit is contained in:
SCOPEDD committed 2026-09-28 13:31:17 -04:00
commit a1f19e86c6
74 files changed
+2108 -95

No files matched your search

@@ -0,0 +1,45 @@
package net.scopenet.integration;
import com.google.gson.*;
import java.io.IOException;
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
public final class PanelClient {
private final Settings settings;
private final HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(3))
.followRedirects(HttpClient.Redirect.NEVER).build();
public PanelClient(Settings settings) { this.settings = settings; }
public JsonObject post(String endpoint, JsonObject payload) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder(URI.create(settings.panel() + "/api/server/v1/" + endpoint))
.timeout(Duration.ofSeconds(5))
.header("Authorization", "Bearer " + settings.token())
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload.toString())).build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
// Never log the token, request body, or an untrusted HTML error page.
throw new IOException("Panel " + endpoint + " returned HTTP " + response.statusCode());
}
try {
return JsonParser.parseString(response.body()).getAsJsonObject();
} catch (RuntimeException e) {
throw new IOException("Invalid panel response", e);
}
}
public static String verdict(JsonObject response) throws IOException {
JsonElement allowed = response.get("allowed");
if (allowed == null || !allowed.isJsonPrimitive() || !allowed.getAsJsonPrimitive().isBoolean()) {
throw new IOException("Missing login verdict");
}
if (allowed.getAsBoolean()) return null;
JsonElement message = response.get("message");
return message != null && message.isJsonPrimitive() && message.getAsJsonPrimitive().isString()
? message.getAsString() : "You do not have access to this server.";
}
}