fix: resolve all remaining audit failures across rust, svelte, and java
This commit is contained in:
1 parent
bc12a25a01
commit
590178e41a
35 files changed
+958
-300
No files matched your search
@@ -7,7 +7,23 @@ import java.net.http.*;
|
||||
import java.time.Duration;
|
||||
|
||||
public final class PanelClient {
|
||||
private final Settings settings;
|
||||
private volatile Settings settings;
|
||||
private record ChunkKey(String dimension, int x, int z, java.util.UUID uuid) {}
|
||||
private record Cached(ChunkCheckResult result, long expires) {}
|
||||
private final java.util.Map<ChunkKey, Cached> claims = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
private final java.util.Set<ChunkKey> pendingClaims = java.util.concurrent.ConcurrentHashMap.newKeySet();
|
||||
private final java.util.concurrent.ThreadPoolExecutor claimWorker = new java.util.concurrent.ThreadPoolExecutor(
|
||||
2, 2, 0, java.util.concurrent.TimeUnit.SECONDS, new java.util.concurrent.ArrayBlockingQueue<>(64),
|
||||
task -> { Thread t = new Thread(task, "scopenet-claims"); t.setDaemon(true); return t; });
|
||||
private static final ChunkCheckResult UNKNOWN = new ChunkCheckResult(true, false, "Protection check pending or unavailable", "WAIT");
|
||||
private final java.util.concurrent.atomic.AtomicLong claimGeneration = new java.util.concurrent.atomic.AtomicLong();
|
||||
public void invalidateClaims() { claimGeneration.incrementAndGet(); claims.clear(); }
|
||||
public void updateSettings(Settings next) { settings = next; invalidateClaims(); }
|
||||
public void close() { claimWorker.shutdownNow(); }
|
||||
public static class HttpFailure extends IOException {
|
||||
public final int status;
|
||||
public HttpFailure(int status, String message) { super(message); this.status = status; }
|
||||
}
|
||||
private final HttpClient client = HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(3))
|
||||
.followRedirects(HttpClient.Redirect.NEVER).build();
|
||||
@@ -28,7 +44,7 @@ public final class PanelClient {
|
||||
if (err.has("message")) msg = err.get("message").getAsString();
|
||||
else if (err.has("error")) msg = err.get("error").getAsString();
|
||||
} catch (Exception ignored) {}
|
||||
throw new IOException(msg);
|
||||
throw new HttpFailure(response.statusCode(), msg);
|
||||
}
|
||||
try {
|
||||
return JsonParser.parseString(response.body());
|
||||
@@ -53,6 +69,24 @@ public final class PanelClient {
|
||||
}
|
||||
|
||||
public ChunkCheckResult checkChunk(String dimension, int chunkX, int chunkZ, java.util.UUID uuid) {
|
||||
if (!settings.guildsEnabled() || !settings.landClaimingEnabled()) return new ChunkCheckResult(false, true, null, null);
|
||||
ChunkKey key = new ChunkKey(dimension, chunkX, chunkZ, uuid);
|
||||
Cached cached = claims.get(key);
|
||||
if (cached != null && cached.expires() > System.nanoTime()) return cached.result();
|
||||
if (pendingClaims.add(key)) {
|
||||
long generation = claimGeneration.get();
|
||||
try { claimWorker.execute(() -> {
|
||||
try {
|
||||
ChunkCheckResult result = checkChunkRemote(dimension, chunkX, chunkZ, uuid);
|
||||
if (claims.size() > 4096) claims.clear();
|
||||
if (generation == claimGeneration.get()) claims.put(key, new Cached(result, System.nanoTime() + java.util.concurrent.TimeUnit.SECONDS.toNanos(2)));
|
||||
} finally { pendingClaims.remove(key); }
|
||||
}); } catch (java.util.concurrent.RejectedExecutionException e) { pendingClaims.remove(key); }
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
private ChunkCheckResult checkChunkRemote(String dimension, int chunkX, int chunkZ, java.util.UUID uuid) {
|
||||
if (!settings.guildsEnabled() || !settings.landClaimingEnabled()) {
|
||||
return new ChunkCheckResult(false, true, null, null);
|
||||
}
|
||||
@@ -64,12 +98,12 @@ public final class PanelClient {
|
||||
try {
|
||||
JsonObject res = post("guilds/check-chunk", req);
|
||||
boolean claimed = res.has("claimed") && res.get("claimed").getAsBoolean();
|
||||
boolean allowed = !res.has("allowed") || res.get("allowed").getAsBoolean();
|
||||
boolean allowed = res.has("allowed") && res.get("allowed").getAsBoolean();
|
||||
String guildName = res.has("guild_name") && !res.get("guild_name").isJsonNull() ? res.get("guild_name").getAsString() : null;
|
||||
String guildTag = res.has("guild_tag") && !res.get("guild_tag").isJsonNull() ? res.get("guild_tag").getAsString() : null;
|
||||
return new ChunkCheckResult(claimed, allowed, guildName, guildTag);
|
||||
} catch (Exception e) {
|
||||
return new ChunkCheckResult(false, true, null, null);
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +113,9 @@ public final class PanelClient {
|
||||
req.addProperty("dimension", dimension);
|
||||
req.addProperty("chunk_x", chunkX);
|
||||
req.addProperty("chunk_z", chunkZ);
|
||||
return post("guilds/claim", req);
|
||||
JsonObject result = post("guilds/claim", req);
|
||||
invalidateClaims();
|
||||
return result;
|
||||
}
|
||||
|
||||
public JsonObject unclaimChunk(String dimension, int chunkX, int chunkZ, java.util.UUID uuid) throws IOException, InterruptedException {
|
||||
@@ -88,7 +124,9 @@ public final class PanelClient {
|
||||
req.addProperty("dimension", dimension);
|
||||
req.addProperty("chunk_x", chunkX);
|
||||
req.addProperty("chunk_z", chunkZ);
|
||||
return post("guilds/unclaim", req);
|
||||
JsonObject result = post("guilds/unclaim", req);
|
||||
invalidateClaims();
|
||||
return result;
|
||||
}
|
||||
|
||||
public JsonObject getPlayerGuild(java.util.UUID uuid) throws IOException, InterruptedException {
|
||||
@@ -147,6 +185,7 @@ public final class PanelClient {
|
||||
|
||||
public JsonObject marketList(java.util.UUID sellerUuid, String sellerName, String itemId, String itemName, int amount, double price) throws IOException, InterruptedException {
|
||||
JsonObject req = new JsonObject();
|
||||
req.addProperty("operation_id", java.util.UUID.randomUUID().toString());
|
||||
req.addProperty("seller_uuid", sellerUuid.toString());
|
||||
req.addProperty("seller_name", sellerName);
|
||||
req.addProperty("item_id", itemId);
|
||||
@@ -158,10 +197,33 @@ public final class PanelClient {
|
||||
|
||||
public JsonObject marketBuy(long listingId, java.util.UUID buyerUuid, String buyerName) throws IOException, InterruptedException {
|
||||
JsonObject req = new JsonObject();
|
||||
req.addProperty("operation_id", java.util.UUID.randomUUID().toString());
|
||||
req.addProperty("listing_id", listingId);
|
||||
req.addProperty("buyer_uuid", buyerUuid.toString());
|
||||
req.addProperty("buyer_name", buyerName);
|
||||
return post("economy/market/buy", req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically add (or subtract, if amount is negative) to a player's balance.
|
||||
* Returns the new balance. This avoids the read-modify-write race in the old
|
||||
* getBalance + syncBalance pattern.
|
||||
*/
|
||||
public double addBalance(java.util.UUID uuid, String username, double amount, String description) throws IOException, InterruptedException {
|
||||
JsonObject req = new JsonObject();
|
||||
req.addProperty("operation_id", java.util.UUID.randomUUID().toString());
|
||||
req.addProperty("uuid", uuid.toString());
|
||||
req.addProperty("username", username);
|
||||
req.addProperty("delta", amount);
|
||||
req.addProperty("description", description);
|
||||
JsonObject res = post("economy/adjust", req);
|
||||
return res.has("balance") ? res.get("balance").getAsDouble() : 0.0;
|
||||
}
|
||||
|
||||
/** Fetch active player marketplace listings. */
|
||||
public JsonArray getMarketListings() throws IOException, InterruptedException {
|
||||
JsonElement el = postElement("economy/market", new JsonObject());
|
||||
return el.isJsonArray() ? el.getAsJsonArray() : new JsonArray();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user