Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
package us.tss3.blockparty.config;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.tss3.blockparty.logic.ArenaConfigValidator;
|
||||
import us.tss3.blockparty.util.LocationUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/** Loads/saves individual arena yml files. Each arena is loaded independently; a bad file is logged and skipped. */
|
||||
public class ArenaConfigLoader {
|
||||
|
||||
private final Plugin plugin;
|
||||
private final File arenasFolder;
|
||||
|
||||
public ArenaConfigLoader(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.arenasFolder = new File(plugin.getDataFolder(), "arenas");
|
||||
if (!arenasFolder.exists()) {
|
||||
arenasFolder.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public File getArenasFolder() {
|
||||
return arenasFolder;
|
||||
}
|
||||
|
||||
public List<ArenaConfig> loadAll() {
|
||||
List<ArenaConfig> arenas = new ArrayList<>();
|
||||
File[] files = arenasFolder.listFiles((dir, name) -> name.endsWith(".yml"));
|
||||
if (files == null) {
|
||||
return arenas;
|
||||
}
|
||||
for (File file : files) {
|
||||
try {
|
||||
ArenaConfig cfg = load(file);
|
||||
if (cfg != null) {
|
||||
arenas.add(cfg);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to load arena file " + file.getName() + ": " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return arenas;
|
||||
}
|
||||
|
||||
public ArenaConfig load(File file) {
|
||||
String name = file.getName().replace(".yml", "");
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
|
||||
ArenaConfig cfg = new ArenaConfig(name);
|
||||
cfg.setWorldName(yml.getString("world"));
|
||||
cfg.setLobby(LocationUtil.fromSection(yml.getConfigurationSection("lobby")));
|
||||
cfg.setSpawn(LocationUtil.fromSection(yml.getConfigurationSection("spawn")));
|
||||
cfg.setSpectator(LocationUtil.fromSection(yml.getConfigurationSection("spectator")));
|
||||
if (yml.contains("pos1")) {
|
||||
cfg.setPos1(new int[]{yml.getInt("pos1.x"), yml.getInt("pos1.y"), yml.getInt("pos1.z")});
|
||||
}
|
||||
if (yml.contains("pos2")) {
|
||||
cfg.setPos2(new int[]{yml.getInt("pos2.x"), yml.getInt("pos2.y"), yml.getInt("pos2.z")});
|
||||
}
|
||||
cfg.setMinPlayers(yml.getInt("min-players", 2));
|
||||
cfg.setMaxPlayers(yml.getInt("max-players", 16));
|
||||
cfg.setCountdownDuration(yml.getInt("countdown-duration", 15));
|
||||
cfg.setRoundPrepDuration(yml.getInt("round-prep-duration", 5));
|
||||
cfg.setFloorRemoveDelaySeconds(yml.getInt("floor-remove-delay", 1));
|
||||
cfg.setFloorRestoreDelaySeconds(yml.getInt("floor-restore-delay", 3));
|
||||
cfg.setStartingRoundTime(yml.getInt("starting-round-time", 20));
|
||||
cfg.setMinimumRoundTime(yml.getInt("minimum-round-time", 4));
|
||||
cfg.setRoundTimeReduction(yml.getInt("round-time-reduction", 1));
|
||||
cfg.setWinEndingDelaySeconds(yml.getInt("win-ending-delay", 6));
|
||||
cfg.setAllowJoinWhileStarting(yml.getBoolean("allow-join-while-waiting", true));
|
||||
cfg.setSpectatorsAllowed(yml.getBoolean("spectators-allowed", true));
|
||||
cfg.setEnabled(yml.getBoolean("enabled", false));
|
||||
|
||||
List<Material> materials = new ArrayList<>();
|
||||
for (String matName : yml.getStringList("floor-materials")) {
|
||||
Material mat = Material.matchMaterial(matName);
|
||||
if (mat == null) {
|
||||
plugin.getLogger().warning("Arena '" + name + "': invalid floor material '" + matName + "' skipped.");
|
||||
continue;
|
||||
}
|
||||
materials.add(mat);
|
||||
}
|
||||
cfg.setFloorMaterials(materials);
|
||||
cfg.setGeneratedLayout(yml.getStringList("generated-layout"));
|
||||
return cfg;
|
||||
}
|
||||
|
||||
public void save(ArenaConfig cfg) {
|
||||
File file = new File(arenasFolder, cfg.getName() + ".yml");
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
if (cfg.getWorldName() != null) {
|
||||
yml.set("world", cfg.getWorldName());
|
||||
}
|
||||
if (cfg.getLobby() != null) {
|
||||
LocationUtil.toSection(yml.createSection("lobby"), cfg.getLobby());
|
||||
}
|
||||
if (cfg.getSpawn() != null) {
|
||||
LocationUtil.toSection(yml.createSection("spawn"), cfg.getSpawn());
|
||||
}
|
||||
if (cfg.getSpectator() != null) {
|
||||
LocationUtil.toSection(yml.createSection("spectator"), cfg.getSpectator());
|
||||
}
|
||||
if (cfg.getPos1() != null) {
|
||||
yml.set("pos1.x", cfg.getPos1()[0]);
|
||||
yml.set("pos1.y", cfg.getPos1()[1]);
|
||||
yml.set("pos1.z", cfg.getPos1()[2]);
|
||||
}
|
||||
if (cfg.getPos2() != null) {
|
||||
yml.set("pos2.x", cfg.getPos2()[0]);
|
||||
yml.set("pos2.y", cfg.getPos2()[1]);
|
||||
yml.set("pos2.z", cfg.getPos2()[2]);
|
||||
}
|
||||
yml.set("min-players", cfg.getMinPlayers());
|
||||
yml.set("max-players", cfg.getMaxPlayers());
|
||||
yml.set("countdown-duration", cfg.getCountdownDuration());
|
||||
yml.set("round-prep-duration", cfg.getRoundPrepDuration());
|
||||
yml.set("floor-remove-delay", cfg.getFloorRemoveDelaySeconds());
|
||||
yml.set("floor-restore-delay", cfg.getFloorRestoreDelaySeconds());
|
||||
yml.set("starting-round-time", cfg.getStartingRoundTime());
|
||||
yml.set("minimum-round-time", cfg.getMinimumRoundTime());
|
||||
yml.set("round-time-reduction", cfg.getRoundTimeReduction());
|
||||
yml.set("win-ending-delay", cfg.getWinEndingDelaySeconds());
|
||||
yml.set("allow-join-while-waiting", cfg.isAllowJoinWhileStarting());
|
||||
yml.set("spectators-allowed", cfg.isSpectatorsAllowed());
|
||||
yml.set("enabled", cfg.isEnabled());
|
||||
List<String> matNames = new ArrayList<>();
|
||||
for (Material m : cfg.getFloorMaterials()) {
|
||||
matNames.add(m.name());
|
||||
}
|
||||
yml.set("floor-materials", matNames);
|
||||
yml.set("generated-layout", cfg.getGeneratedLayout());
|
||||
try {
|
||||
yml.save(file);
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to save arena " + cfg.getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean delete(String name) {
|
||||
File file = new File(arenasFolder, name + ".yml");
|
||||
return file.exists() && file.delete();
|
||||
}
|
||||
|
||||
public List<String> validate(ArenaConfig cfg) {
|
||||
boolean worldOk = cfg.getWorldName() != null && Bukkit.getWorld(cfg.getWorldName()) != null;
|
||||
ArenaConfigValidator.Fields fields = new ArenaConfigValidator.Fields(
|
||||
cfg.getName(),
|
||||
worldOk ? cfg.getWorldName() : null,
|
||||
cfg.getLobby() != null,
|
||||
cfg.getSpawn() != null,
|
||||
cfg.getSpectator() != null,
|
||||
cfg.hasFloorRegion(),
|
||||
cfg.getMinPlayers(),
|
||||
cfg.getMaxPlayers(),
|
||||
cfg.getCountdownDuration(),
|
||||
cfg.getRoundPrepDuration(),
|
||||
cfg.getFloorRemoveDelaySeconds(),
|
||||
cfg.getFloorRestoreDelaySeconds(),
|
||||
cfg.getStartingRoundTime(),
|
||||
cfg.getMinimumRoundTime(),
|
||||
cfg.getRoundTimeReduction(),
|
||||
cfg.getWinEndingDelaySeconds(),
|
||||
cfg.getFloorMaterials().stream().map(Material::name).toList()
|
||||
);
|
||||
List<String> errors = new ArrayList<>(ArenaConfigValidator.validate(fields));
|
||||
if (!worldOk && cfg.getWorldName() != null) {
|
||||
errors.add("world '" + cfg.getWorldName() + "' is not currently loaded");
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user