Volver al índice
src/main/java/ar/com/companeros/horror/HorrorConfig.java
package ar.com.companeros.horror;
import com.google.gson.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.Set;
/** Tiempos del operador; un día corresponde a 24 000 ticks guardados del mundo. */
public record HorrorConfig(boolean enabled, long meteorDelayTicks, long infectionDelayTicks,
long stageDurationTicks, int finalStage, int safeRadius) {
private static final Set<String> KEYS = Set.of("schemaVersion", "enabled", "meteorAfterDays",
"infectionAfterMeteorDays", "daysPerStage", "finalStage", "safeRadius");
public HorrorConfig {
if (meteorDelayTicks < 0 || infectionDelayTicks < 0 || stageDurationTicks < 20
|| finalStage != 4 || safeRadius < 32 || safeRadius > 256)
throw new IllegalArgumentException("Tiempos o límites del parásito inválidos");
}
public static HorrorConfig defaults() { return new HorrorConfig(true, 72_000, 48_000, 24_000, 4, 64); }
public static HorrorConfig load(Path root) throws IOException {
Files.createDirectories(root);
Path file = root.resolve("parasite.json");
if (!Files.exists(file)) {
JsonObject data = new JsonObject(); data.addProperty("schemaVersion", 1); data.addProperty("enabled", true);
data.addProperty("meteorAfterDays", 3); data.addProperty("infectionAfterMeteorDays", 2);
data.addProperty("daysPerStage", 1); data.addProperty("finalStage", 4); data.addProperty("safeRadius", 64);
Files.writeString(file, new GsonBuilder().setPrettyPrinting().create().toJson(data), StandardCharsets.UTF_8,
StandardOpenOption.CREATE_NEW);
}
if (Files.isSymbolicLink(file) || Files.size(file) > 8192) throw new IOException("parasite.json fuera de límite");
try {
JsonObject data = JsonParser.parseString(Files.readString(file, StandardCharsets.UTF_8)).getAsJsonObject();
if (!KEYS.containsAll(data.keySet()) || data.get("schemaVersion").getAsInt() != 1)
throw new IllegalArgumentException("Formato de parásito desconocido");
return new HorrorConfig(data.get("enabled").getAsBoolean(), days(data, "meteorAfterDays"),
days(data, "infectionAfterMeteorDays"), days(data, "daysPerStage"),
data.get("finalStage").getAsInt(), data.get("safeRadius").getAsInt());
} catch (RuntimeException failure) { throw new IOException("No se pudo leer parasite.json; se conserva el archivo", failure); }
}
private static long days(JsonObject data, String key) {
double value = data.get(key).getAsDouble();
if (!Double.isFinite(value) || value < 0 || value > 3650) throw new IllegalArgumentException("Días inválidos");
return Math.round(value * 24_000);
}
}