package me.viper.teamplugin.manager; import me.viper.teamplugin.Main; import me.viper.teamplugin.util.Utils; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.*; import java.util.stream.Collectors; public class DataManager { private static final String FORCE_OFFLINE_PATH = "Status.force-offline"; private static File file; private static FileConfiguration data; public static void setup() { try { file = new File(Main.getInstance().getDataFolder(), "data.yml"); if (!file.exists()) { Main.getInstance().getDataFolder().mkdirs(); file.createNewFile(); data = YamlConfiguration.loadConfiguration(file); data.createSection("Team"); save(); } else { data = YamlConfiguration.loadConfiguration(file); if (data.getConfigurationSection("Team") == null) { data.createSection("Team"); save(); } } // Ensure backup folder exists if enabled if (Main.getInstance().getConfig().getBoolean("backup.enabled", true)) { File backups = new File(Main.getInstance().getDataFolder(), Main.getInstance().getConfig().getString("backup.folder", "backups")); if (!backups.exists()) backups.mkdirs(); } } catch (IOException e) { e.printStackTrace(); } } /** Reload data.yml from disk (used after restore). */ public static void reloadData() { if (file == null) file = new File(Main.getInstance().getDataFolder(), "data.yml"); data = YamlConfiguration.loadConfiguration(file); if (data.getConfigurationSection("Team") == null) { data.createSection("Team"); save(); } } public static FileConfiguration getData() { if (data == null) setup(); return data; } public static void save() { try { if (data != null && file != null) data.save(file); } catch (IOException e) { e.printStackTrace(); } } public static void addMember(String rank, String name) { List list = data.getStringList("Team." + rank); if (!list.contains(name)) { list.add(name); data.set("Team." + rank, list); // store join date if enabled if (Main.getInstance().getConfig().getBoolean("storeJoinDate", true)) { data.set("JoinDates." + name, Utils.formatIsoNow()); } save(); } } public static boolean removeMember(String name) { boolean removed = false; if (data.getConfigurationSection("Team") != null) { for (String rank : data.getConfigurationSection("Team").getKeys(false)) { List members = data.getStringList("Team." + rank); if (members.removeIf(s -> s.equalsIgnoreCase(name))) { data.set("Team." + rank, members); removed = true; } } if (removed) { data.set("JoinDates." + name, null); data.set(FORCE_OFFLINE_PATH + "." + normalizeName(name), null); save(); } } return removed; } // Backups public static String createBackup() { String folderName = Main.getInstance().getConfig().getString("backup.folder", "backups"); File backupsFolder = new File(Main.getInstance().getDataFolder(), folderName); if (!backupsFolder.exists()) backupsFolder.mkdirs(); String timestamp = Utils.formatIsoNow().replace(":", "-"); String fileName = "data-backup-" + timestamp + ".yml"; File dest = new File(backupsFolder, fileName); try { // ensure current file exists if (file == null) file = new File(Main.getInstance().getDataFolder(), "data.yml"); if (!file.exists()) { // nothing to backup return null; } Files.copy(file.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING); // prune backups pruneBackups(backupsFolder); return fileName; } catch (IOException e) { e.printStackTrace(); return null; } } /** * Restore a backup by filename (relative to backup folder). * Returns true on success. */ public static boolean restoreBackup(String fileName) { String folderName = Main.getInstance().getConfig().getString("backup.folder", "backups"); File backupsFolder = new File(Main.getInstance().getDataFolder(), folderName); File src = new File(backupsFolder, fileName); if (!src.exists()) return false; try { if (file == null) file = new File(Main.getInstance().getDataFolder(), "data.yml"); Files.copy(src.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); // reload data from the restored file reloadData(); return true; } catch (IOException e) { e.printStackTrace(); return false; } } public static List listBackups() { String folderName = Main.getInstance().getConfig().getString("backup.folder", "backups"); File backupsFolder = new File(Main.getInstance().getDataFolder(), folderName); if (!backupsFolder.exists()) return Collections.emptyList(); return Arrays.stream(Objects.requireNonNull(backupsFolder.listFiles())) .filter(File::isFile) .map(File::getName) .sorted(Comparator.reverseOrder()) .collect(Collectors.toList()); } private static void pruneBackups(File backupsFolder) { int keep = Main.getInstance().getConfig().getInt("backup.keep", 10); List files = Arrays.stream(Objects.requireNonNull(backupsFolder.listFiles())) .filter(File::isFile) .sorted(Comparator.comparingLong(File::lastModified).reversed()) .collect(Collectors.toList()); for (int i = keep; i < files.size(); i++) { files.get(i).delete(); } } // helper public static String getJoinDate(String name) { return data.getString("JoinDates." + name, ""); } public static boolean isForcedOffline(String name) { return data.getBoolean(FORCE_OFFLINE_PATH + "." + normalizeName(name), false); } public static void setForcedOffline(String name, boolean forcedOffline) { data.set(FORCE_OFFLINE_PATH + "." + normalizeName(name), forcedOffline ? true : null); save(); } private static String normalizeName(String name) { return name == null ? "" : name.toLowerCase(Locale.ROOT); } }