This commit is contained in:
		
							parent
							
								
									e409c0d907
								
							
						
					
					
						commit
						a49affb44e
					
				| 
						 | 
				
			
			@ -1,9 +1,6 @@
 | 
			
		|||
package org.itqop.whitelist;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.gson.JsonParser;
 | 
			
		||||
import com.google.gson.*;
 | 
			
		||||
import com.mojang.logging.LogUtils;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +10,7 @@ import java.net.http.HttpRequest;
 | 
			
		|||
import java.net.http.HttpResponse;
 | 
			
		||||
import java.time.Duration;
 | 
			
		||||
import java.time.Instant;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +20,7 @@ public class WhitelistApiClient {
 | 
			
		|||
    public static void refreshConfigFromSpec() { INSTANCE.refreshFromConfig(); }
 | 
			
		||||
 | 
			
		||||
    private static final Logger LOGGER = LogUtils.getLogger();
 | 
			
		||||
    private static final Gson GSON = new Gson();
 | 
			
		||||
    private static final Gson GSON = new GsonBuilder().create();
 | 
			
		||||
 | 
			
		||||
    private volatile HttpClient http;
 | 
			
		||||
    private volatile String baseUrl;
 | 
			
		||||
| 
						 | 
				
			
			@ -58,45 +56,69 @@ public class WhitelistApiClient {
 | 
			
		|||
        return addPlayer(playerName, null, null, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CompletableFuture<Boolean> addPlayer(String playerName, String playerUuid, String addedBy, String addedAt) {
 | 
			
		||||
    public CompletableFuture<Boolean> addPlayer(String playerName, String playerUuid, String addedBy, String addedAtIso) {
 | 
			
		||||
        Objects.requireNonNull(playerName, "playerName");
 | 
			
		||||
        if (Config.enableLogging) LOGGER.info("[ADD] player={}", playerName);
 | 
			
		||||
        JsonObject body = new JsonObject();
 | 
			
		||||
        body.addProperty("player_name", playerName);
 | 
			
		||||
        if (playerUuid != null && !playerUuid.isBlank()) body.addProperty("player_uuid", playerUuid);
 | 
			
		||||
        if (addedBy != null && !addedBy.isBlank()) body.addProperty("added_by", addedBy);
 | 
			
		||||
        if (addedAt != null && !addedAt.isBlank()) body.addProperty("added_at", addedAt);
 | 
			
		||||
        if (addedAtIso != null && !addedAtIso.isBlank()) body.addProperty("added_at", addedAtIso);
 | 
			
		||||
        return makeRequest("POST", "/add", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
 | 
			
		||||
                .thenApply(resp -> resp != null && resp.statusCode() / 100 == 2);
 | 
			
		||||
                .thenApply(resp -> resp != null && resp.statusCode() == 201);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CompletableFuture<WhitelistEntry> addPlayer(String playerName,
 | 
			
		||||
                                                       String playerUuid,
 | 
			
		||||
                                                       String addedBy,
 | 
			
		||||
                                                       Instant addedAt,
 | 
			
		||||
                                                       Instant expiresAt,
 | 
			
		||||
                                                       Boolean isActive,
 | 
			
		||||
                                                       String reason) {
 | 
			
		||||
        Objects.requireNonNull(playerName, "playerName");
 | 
			
		||||
        JsonObject body = new JsonObject();
 | 
			
		||||
        body.addProperty("player_name", playerName);
 | 
			
		||||
        if (playerUuid != null && !playerUuid.isBlank()) body.addProperty("player_uuid", playerUuid);
 | 
			
		||||
        if (addedBy != null && !addedBy.isBlank()) body.addProperty("added_by", addedBy);
 | 
			
		||||
        if (addedAt != null) body.addProperty("added_at", addedAt.toString());
 | 
			
		||||
        if (expiresAt != null) body.addProperty("expires_at", expiresAt.toString());
 | 
			
		||||
        if (isActive != null) body.addProperty("is_active", isActive);
 | 
			
		||||
        if (reason != null && !reason.isBlank()) body.addProperty("reason", reason);
 | 
			
		||||
        return makeRequest("POST", "/add", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
 | 
			
		||||
                .thenApply(resp -> {
 | 
			
		||||
                    if (resp == null || resp.statusCode() != 201) return null;
 | 
			
		||||
                    try {
 | 
			
		||||
                        JsonObject json = JsonParser.parseString(resp.body()).getAsJsonObject();
 | 
			
		||||
                        return WhitelistEntry.fromJson(json);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CompletableFuture<Boolean> removePlayer(String playerName) {
 | 
			
		||||
        Objects.requireNonNull(playerName, "playerName");
 | 
			
		||||
        if (Config.enableLogging) LOGGER.info("[REMOVE] player={}", playerName);
 | 
			
		||||
        JsonObject body = new JsonObject();
 | 
			
		||||
        body.addProperty("player_name", playerName);
 | 
			
		||||
        return makeRequest("POST", "/remove", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
 | 
			
		||||
                .thenApply(resp -> resp != null && resp.statusCode() / 100 == 2);
 | 
			
		||||
                .thenApply(resp -> resp != null && resp.statusCode() == 204);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CompletableFuture<CheckResponse> checkPlayer(String playerName) {
 | 
			
		||||
        Objects.requireNonNull(playerName, "playerName");
 | 
			
		||||
        if (Config.enableLogging) LOGGER.info("[CHECK] player={}", playerName);
 | 
			
		||||
        JsonObject body = new JsonObject();
 | 
			
		||||
        body.addProperty("player_name", playerName);
 | 
			
		||||
        return makeRequest("POST", "/check", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
 | 
			
		||||
                .thenApply(response -> {
 | 
			
		||||
                    if (response == null) return new CheckResponse(false, false, null);
 | 
			
		||||
                    try {
 | 
			
		||||
                        String bodyStr = response.body();
 | 
			
		||||
                        JsonElement el = JsonParser.parseString(bodyStr);
 | 
			
		||||
                        JsonObject json = el.getAsJsonObject();
 | 
			
		||||
                        boolean ok = json.has("ok") && json.get("ok").getAsBoolean();
 | 
			
		||||
                        int code = response.statusCode();
 | 
			
		||||
                        if (code < 200 || code >= 300) return new CheckResponse(false, false, null);
 | 
			
		||||
                        JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject();
 | 
			
		||||
                        boolean isWhitelisted = json.has("is_whitelisted") && json.get("is_whitelisted").getAsBoolean();
 | 
			
		||||
                        String uuid = json.has("player_uuid") && !json.get("player_uuid").isJsonNull()
 | 
			
		||||
                                ? json.get("player_uuid").getAsString()
 | 
			
		||||
                                : null;
 | 
			
		||||
                        return new CheckResponse(ok, isWhitelisted, uuid);
 | 
			
		||||
                        return new CheckResponse(true, isWhitelisted, uuid);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        return new CheckResponse(false, false, null);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +126,38 @@ public class WhitelistApiClient {
 | 
			
		|||
                .exceptionally(ex -> new CheckResponse(false, false, null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CompletableFuture<WhitelistListResponse> listAll() {
 | 
			
		||||
        return makeRequest("GET", "/", HttpRequest.BodyPublishers.noBody())
 | 
			
		||||
                .thenApply(resp -> {
 | 
			
		||||
                    if (resp == null) return null;
 | 
			
		||||
                    try {
 | 
			
		||||
                        JsonObject json = JsonParser.parseString(resp.body()).getAsJsonObject();
 | 
			
		||||
                        JsonArray arr = json.getAsJsonArray("entries");
 | 
			
		||||
                        int total = json.has("total") ? json.get("total").getAsInt() : 0;
 | 
			
		||||
                        WhitelistEntry[] entries = new WhitelistEntry[arr.size()];
 | 
			
		||||
                        for (int i = 0; i < arr.size(); i++) {
 | 
			
		||||
                            entries[i] = WhitelistEntry.fromJson(arr.get(i).getAsJsonObject());
 | 
			
		||||
                        }
 | 
			
		||||
                        return new WhitelistListResponse(List.of(entries), total);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CompletableFuture<Integer> count() {
 | 
			
		||||
        return makeRequest("GET", "/count", HttpRequest.BodyPublishers.noBody())
 | 
			
		||||
                .thenApply(resp -> {
 | 
			
		||||
                    if (resp == null) return null;
 | 
			
		||||
                    try {
 | 
			
		||||
                        JsonObject json = JsonParser.parseString(resp.body()).getAsJsonObject();
 | 
			
		||||
                        return json.has("total") ? json.get("total").getAsInt() : 0;
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private CompletableFuture<HttpResponse<String>> makeRequest(String method, String path, HttpRequest.BodyPublisher body) {
 | 
			
		||||
        HttpRequest.Builder b = baseBuilder(path);
 | 
			
		||||
        if ("POST".equalsIgnoreCase(method)) b.POST(body);
 | 
			
		||||
| 
						 | 
				
			
			@ -126,4 +180,47 @@ public class WhitelistApiClient {
 | 
			
		|||
        public boolean isWhitelisted() { return isWhitelisted; }
 | 
			
		||||
        public String getPlayerUuid() { return playerUuid; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class WhitelistEntry {
 | 
			
		||||
        public final String id;
 | 
			
		||||
        public final String playerName;
 | 
			
		||||
        public final String playerUuid;
 | 
			
		||||
        public final String addedBy;
 | 
			
		||||
        public final String addedAt;
 | 
			
		||||
        public final String expiresAt;
 | 
			
		||||
        public final boolean isActive;
 | 
			
		||||
        public final String reason;
 | 
			
		||||
 | 
			
		||||
        public WhitelistEntry(String id, String playerName, String playerUuid, String addedBy, String addedAt, String expiresAt, boolean isActive, String reason) {
 | 
			
		||||
            this.id = id;
 | 
			
		||||
            this.playerName = playerName;
 | 
			
		||||
            this.playerUuid = playerUuid;
 | 
			
		||||
            this.addedBy = addedBy;
 | 
			
		||||
            this.addedAt = addedAt;
 | 
			
		||||
            this.expiresAt = expiresAt;
 | 
			
		||||
            this.isActive = isActive;
 | 
			
		||||
            this.reason = reason;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static WhitelistEntry fromJson(JsonObject json) {
 | 
			
		||||
            String id = json.has("id") && !json.get("id").isJsonNull() ? json.get("id").getAsString() : null;
 | 
			
		||||
            String pn = json.has("player_name") && !json.get("player_name").isJsonNull() ? json.get("player_name").getAsString() : null;
 | 
			
		||||
            String pu = json.has("player_uuid") && !json.get("player_uuid").isJsonNull() ? json.get("player_uuid").getAsString() : null;
 | 
			
		||||
            String by = json.has("added_by") && !json.get("added_by").isJsonNull() ? json.get("added_by").getAsString() : null;
 | 
			
		||||
            String at = json.has("added_at") && !json.get("added_at").isJsonNull() ? json.get("added_at").getAsString() : null;
 | 
			
		||||
            String exp = json.has("expires_at") && !json.get("expires_at").isJsonNull() ? json.get("expires_at").getAsString() : null;
 | 
			
		||||
            boolean active = json.has("is_active") && !json.get("is_active").isJsonNull() && json.get("is_active").getAsBoolean();
 | 
			
		||||
            String rsn = json.has("reason") && !json.get("reason").isJsonNull() ? json.get("reason").getAsString() : null;
 | 
			
		||||
            return new WhitelistEntry(id, pn, pu, by, at, exp, active, rsn);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class WhitelistListResponse {
 | 
			
		||||
        public final List<WhitelistEntry> entries;
 | 
			
		||||
        public final int total;
 | 
			
		||||
        public WhitelistListResponse(List<WhitelistEntry> entries, int total) {
 | 
			
		||||
            this.entries = entries;
 | 
			
		||||
            this.total = total;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ import java.util.concurrent.CompletableFuture;
 | 
			
		|||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
public class WhitelistCommands {
 | 
			
		||||
    private static final WhitelistApiClient API = new WhitelistApiClient();
 | 
			
		||||
    private static final WhitelistApiClient API = WhitelistApiClient.get();
 | 
			
		||||
 | 
			
		||||
    private static final SuggestionProvider<CommandSourceStack> ONLINE_PLAYER_SUGGESTIONS = (ctx, builder) -> {
 | 
			
		||||
        List<String> names = ctx.getSource().getServer().getPlayerList().getPlayers()
 | 
			
		||||
| 
						 | 
				
			
			@ -79,21 +79,24 @@ public class WhitelistCommands {
 | 
			
		|||
 | 
			
		||||
    private static int addPlayer(CommandContext<CommandSourceStack> ctx) {
 | 
			
		||||
        String player = StringArgumentType.getString(ctx, "player");
 | 
			
		||||
        String input = ctx.getInput();
 | 
			
		||||
        String reason = null;
 | 
			
		||||
        int idx = input.indexOf(" add ");
 | 
			
		||||
        if (idx >= 0) {
 | 
			
		||||
            String tail = input.substring(idx + 5);
 | 
			
		||||
            int sp = tail.indexOf(' ');
 | 
			
		||||
            if (sp >= 0) reason = tail.substring(sp + 1).trim();
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            reason = StringArgumentType.getString(ctx, "reason");
 | 
			
		||||
            if (reason != null && reason.isBlank()) reason = null;
 | 
			
		||||
        } catch (IllegalArgumentException ignored) {}
 | 
			
		||||
 | 
			
		||||
        String addedBy = getSourceName(ctx);
 | 
			
		||||
        String addedAt = Instant.now().toString();
 | 
			
		||||
        String uuid = resolveUuid(ctx.getSource().getServer(), player);
 | 
			
		||||
 | 
			
		||||
        sendOnServer(ctx, Component.literal("Adding player to whitelist: " + player), false);
 | 
			
		||||
        API.addPlayer(player, uuid, addedBy, addedAt).thenAccept(success ->
 | 
			
		||||
 | 
			
		||||
        CompletableFuture<WhitelistApiClient.WhitelistEntry> fut =
 | 
			
		||||
                API.addPlayer(player, uuid, addedBy, Instant.parse(addedAt), null, true, reason);
 | 
			
		||||
 | 
			
		||||
        fut.thenAccept(entry ->
 | 
			
		||||
                dispatchBack(ctx, () -> {
 | 
			
		||||
                    if (success) {
 | 
			
		||||
                    if (entry != null) {
 | 
			
		||||
                        ctx.getSource().sendSuccess(() -> Component.literal("Player " + player + " added"), false);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ctx.getSource().sendFailure(Component.literal("Failed to add " + player));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue