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);
    }
}