package dev.viper.eventengine.config; import dev.viper.eventengine.EventEngine; import dev.viper.eventengine.model.EventDefinition; import dev.viper.eventengine.model.ScheduleEntry; import dev.viper.eventengine.util.ColorUtil; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; import java.io.IOException; import java.time.DayOfWeek; import java.time.LocalTime; import java.time.format.DateTimeParseException; import java.util.*; import java.util.logging.Logger; public class ConfigManager { private static final List DEFAULT_ITEM_RAIN_ITEMS = List.of( Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT, Material.EMERALD, Material.COAL, Material.BREAD, Material.ARROW, Material.GOLDEN_APPLE, Material.EXPERIENCE_BOTTLE ); private final EventEngine plugin; private final Logger log; private FileConfiguration mainConfig; private File customEventsFile; private FileConfiguration customEventsConfig; private final List schedule = new ArrayList<>(); private int intervalMinutes; private boolean useInterval; private boolean randomOnInterval; private String defaultEventId; private int announceBefore; private boolean logEvents; private String prefix; private boolean enforceRegionBoundary; private boolean noExplosionBlockDamage; private boolean restrictBlockInteraction; private List itemRainItems; /** Sekunden für den 3-2-1-Go Countdown vor jedem Event-Start (0 = deaktiviert) */ private int countdownSeconds; public ConfigManager(EventEngine plugin) { this.plugin = plugin; this.log = plugin.getLogger(); } // ─── Laden ───────────────────────────────────────────────────────────── public void load() { plugin.saveDefaultConfig(); plugin.reloadConfig(); mainConfig = plugin.getConfig(); loadSchedule(); loadGeneral(); loadCustomEventsFile(); } private void loadGeneral() { intervalMinutes = mainConfig.getInt("settings.interval-minutes", 60); useInterval = mainConfig.getBoolean("settings.use-interval", false); randomOnInterval = mainConfig.getBoolean("settings.random-on-interval", true); defaultEventId = mainConfig.getString("settings.default-event", "RANDOM"); announceBefore = mainConfig.getInt("settings.announce-before-seconds", 30); logEvents = mainConfig.getBoolean("settings.log-events", true); countdownSeconds = mainConfig.getInt("settings.countdown-seconds", 3); enforceRegionBoundary = mainConfig.getBoolean("protection.enforce-region-boundary", true); noExplosionBlockDamage = mainConfig.getBoolean("protection.no-explosion-block-damage", true); restrictBlockInteraction = mainConfig.getBoolean("protection.restrict-block-interaction", true); prefix = ColorUtil.color(mainConfig.getString("settings.prefix", "&8[&6EventEngine&8]&r ")); List rawItems = mainConfig.getStringList("item-rain.items"); itemRainItems = new ArrayList<>(); for (String name : rawItems) { try { Material mat = Material.valueOf(name.toUpperCase()); if (mat.isItem()) itemRainItems.add(mat); } catch (Exception ignored) {} } if (itemRainItems.isEmpty()) itemRainItems.addAll(DEFAULT_ITEM_RAIN_ITEMS); } private void loadSchedule() { schedule.clear(); List> entries = mainConfig.getMapList("schedule"); for (Map entry : entries) { try { String timeStr = (String) entry.get("time"); String eventId = (String) entry.get("event"); if (timeStr == null || eventId == null) continue; LocalTime time = LocalTime.parse(timeStr); List days = new ArrayList<>(); Object daysRaw = entry.get("days"); if (daysRaw instanceof List dayList) { for (Object d : dayList) { String ds = d.toString().toUpperCase(); if (ds.equals("DAILY")) { days.clear(); break; } try { days.add(DayOfWeek.valueOf(ds)); } catch (Exception ignored) {} } } schedule.add(new ScheduleEntry(days, time, eventId)); } catch (DateTimeParseException e) { log.warning("Ungültiger Zeitplan-Eintrag: " + entry); } } log.info("Zeitplan geladen: " + schedule.size() + " Einträge."); } private void loadCustomEventsFile() { customEventsFile = new File(plugin.getDataFolder(), "custom_events.yml"); if (!customEventsFile.exists()) { try { customEventsFile.createNewFile(); } catch (IOException e) { log.severe("Konnte custom_events.yml nicht erstellen!"); } } customEventsConfig = YamlConfiguration.loadConfiguration(customEventsFile); } // ─── Custom Events lesen/schreiben ───────────────────────────────────── public Map loadCustomEvents() { Map result = new LinkedHashMap<>(); ConfigurationSection root = customEventsConfig.getConfigurationSection("events"); if (root == null) return result; for (String id : root.getKeys(false)) { ConfigurationSection sec = root.getConfigurationSection(id); if (sec != null) { EventDefinition def = EventDefinition.fromConfig(id, sec); result.put(id, def); } } log.info("Custom Events geladen: " + result.size()); return result; } public void saveCustomEvent(EventDefinition def) { ConfigurationSection root = customEventsConfig.getConfigurationSection("events"); if (root == null) root = customEventsConfig.createSection("events"); ConfigurationSection sec = root.createSection(def.getId()); def.saveToConfig(sec); try { customEventsConfig.save(customEventsFile); } catch (IOException e) { log.severe("Konnte custom_events.yml nicht speichern: " + e.getMessage()); } } public void deleteCustomEvent(String id) { if (customEventsConfig.contains("events." + id)) { customEventsConfig.set("events." + id, null); try { customEventsConfig.save(customEventsFile); } catch (IOException e) { log.severe("Speicherfehler: " + e.getMessage()); } } } // ─── Getter ──────────────────────────────────────────────────────────── public List getSchedule() { return Collections.unmodifiableList(schedule); } public int getIntervalMinutes() { return intervalMinutes; } public boolean isUseInterval() { return useInterval; } public boolean isRandomOnInterval() { return randomOnInterval; } public String getDefaultEventId() { return defaultEventId; } public int getAnnounceBefore() { return announceBefore; } public boolean isLogEvents() { return logEvents; } public String getPrefix() { return prefix; } public boolean isEnforceRegionBoundary() { return enforceRegionBoundary; } public boolean isNoExplosionBlockDamage() { return noExplosionBlockDamage; } public boolean isRestrictBlockInteraction() { return restrictBlockInteraction; } public FileConfiguration getMainConfig() { return mainConfig; } public List getItemRainItems() { return Collections.unmodifiableList(itemRainItems); } /** Countdown-Sekunden vor dem eigentlichen Event-Start (0 = kein Countdown) */ public int getCountdownSeconds() { return countdownSeconds; } public void setItemRainItems(List items) { itemRainItems = new ArrayList<>(items); if (itemRainItems.isEmpty()) itemRainItems.addAll(DEFAULT_ITEM_RAIN_ITEMS); List raw = itemRainItems.stream().map(Material::name).toList(); mainConfig.set("item-rain.items", raw); plugin.saveConfig(); } public void resetItemRainItems() { setItemRainItems(DEFAULT_ITEM_RAIN_ITEMS); } }