Add WorldGuard auto-region creation and split ConfigLoader
- Add WorldGuardConfig with template-based naming ({mine_name}_{random_4}, etc.)
- Add WorldGuardRegionService for creating/updating/deleting WG regions
- Add WorldGuardConfigLoader for parsing WG config from YAML
- Add configurable flags, owners, members for WG regions
- Update MineConfig to include worldGuard section
- Update Mines.java to create/delete WG regions on mine create/delete
- Update MineFileManager to load WG defaults from defaults.yml
- Split ConfigLoader into specialized loaders:
- BlockConfigLoader, RegionConfigLoader, ResetConfigLoader
- RewardConfigLoader, TeleportConfigLoader, UIConfigLoader
- Reduce ConfigLoader from 427 lines to 151 lines
- Update defaults.yml with WorldGuard configuration section
This commit is contained in:
parent
75d785147d
commit
3ba6f303f8
15 changed files with 1126 additions and 318 deletions
|
|
@ -1,47 +1,38 @@
|
|||
package dev.loki.lomines.data.config;
|
||||
|
||||
import dev.loki.lomines.data.config.block.BlockConfig;
|
||||
import dev.loki.lomines.data.config.block.BlockKey;
|
||||
import dev.loki.lomines.data.config.block.FillMode;
|
||||
import dev.loki.lomines.data.config.region.RegionConfig;
|
||||
import dev.loki.lomines.data.config.reset.ResetConfig;
|
||||
import dev.loki.lomines.data.config.reward.RewardConfig;
|
||||
import dev.loki.lomines.data.config.reward.RewardConfig.RewardEntry;
|
||||
import dev.loki.lomines.data.config.reward.RewardConfig.RewardEntry.ItemReward;
|
||||
import dev.loki.lomines.data.config.teleport.TeleportConfig;
|
||||
import dev.loki.lomines.data.config.ui.UIConfig;
|
||||
import dev.loki.lomines.util.location.Cuboid;
|
||||
import dev.loki.lomines.util.location.LocationParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import dev.loki.lomines.data.config.loader.*;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Clean config loader for section-based configuration.
|
||||
* Supports YAML inheritance from defaults.
|
||||
* Delegates to specialized loaders for each section.
|
||||
*/
|
||||
public final class ConfigLoader {
|
||||
|
||||
private final Path dataFolder;
|
||||
private YamlConfiguration defaults;
|
||||
|
||||
// Section loaders
|
||||
private RegionConfigLoader regionLoader;
|
||||
private BlockConfigLoader blockLoader;
|
||||
private ResetConfigLoader resetLoader;
|
||||
private RewardConfigLoader rewardLoader;
|
||||
private TeleportConfigLoader teleportLoader;
|
||||
private UIConfigLoader uiLoader;
|
||||
private WorldGuardConfigLoader worldGuardLoader;
|
||||
|
||||
public ConfigLoader(Path dataFolder) {
|
||||
this.dataFolder = dataFolder;
|
||||
loadDefaults();
|
||||
initLoaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load or create defaults.yml.
|
||||
*/
|
||||
private void loadDefaults() {
|
||||
Path defaultsPath = dataFolder.resolve("mines").resolve("_defaults.yml");
|
||||
defaults = new YamlConfiguration();
|
||||
|
|
@ -49,7 +40,6 @@ public final class ConfigLoader {
|
|||
if (Files.exists(defaultsPath)) {
|
||||
defaults = YamlConfiguration.loadConfiguration(defaultsPath.toFile());
|
||||
} else {
|
||||
// Create defaults with sensible values
|
||||
setDefaults(defaults);
|
||||
try {
|
||||
Files.createDirectories(defaultsPath.getParent());
|
||||
|
|
@ -73,8 +63,19 @@ public final class ConfigLoader {
|
|||
yaml.set("ui.timer-format", "mm:ss");
|
||||
|
||||
yaml.set("teleport.enabled", false);
|
||||
|
||||
yaml.set("rewards", List.of());
|
||||
|
||||
worldGuardLoader.setDefaults(yaml);
|
||||
}
|
||||
|
||||
private void initLoaders() {
|
||||
regionLoader = new RegionConfigLoader();
|
||||
blockLoader = new BlockConfigLoader();
|
||||
resetLoader = new ResetConfigLoader(defaults);
|
||||
rewardLoader = new RewardConfigLoader();
|
||||
teleportLoader = new TeleportConfigLoader();
|
||||
uiLoader = new UIConfigLoader(defaults);
|
||||
worldGuardLoader = new WorldGuardConfigLoader(defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,18 +89,17 @@ public final class ConfigLoader {
|
|||
}
|
||||
|
||||
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(configPath.toFile());
|
||||
|
||||
// Merge with defaults (YAML inheritance)
|
||||
mergeDefaults(yaml);
|
||||
|
||||
try {
|
||||
return MineConfig.builder(mineName)
|
||||
.region(parseRegion(yaml))
|
||||
.blocks(parseBlocks(yaml))
|
||||
.reset(parseReset(yaml))
|
||||
.rewards(parseRewards(yaml))
|
||||
.teleport(parseTeleport(yaml))
|
||||
.ui(parseUI(yaml))
|
||||
.region(regionLoader.parse(yaml))
|
||||
.blocks(blockLoader.parse(yaml))
|
||||
.reset(resetLoader.parse(yaml))
|
||||
.rewards(rewardLoader.parse(yaml))
|
||||
.teleport(teleportLoader.parse(yaml))
|
||||
.ui(uiLoader.parse(yaml))
|
||||
.worldGuard(worldGuardLoader.parse(yaml))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
throw new ConfigLoadException("Failed to load mine '" + mineName + "': " + e.getMessage(), e);
|
||||
|
|
@ -111,26 +111,15 @@ public final class ConfigLoader {
|
|||
*/
|
||||
public void save(MineConfig config) throws ConfigLoadException {
|
||||
Path configPath = dataFolder.resolve("mines").resolve(config.name() + ".yml");
|
||||
|
||||
YamlConfiguration yaml = new YamlConfiguration();
|
||||
|
||||
// Save regions
|
||||
saveRegion(yaml, config.region());
|
||||
|
||||
// Save blocks
|
||||
saveBlocks(yaml, config.blocks());
|
||||
|
||||
// Save reset
|
||||
saveReset(yaml, config.reset());
|
||||
|
||||
// Save rewards
|
||||
saveRewards(yaml, config.rewards());
|
||||
|
||||
// Save teleport
|
||||
saveTeleport(yaml, config.teleport());
|
||||
|
||||
// Save UI
|
||||
saveUI(yaml, config.ui());
|
||||
regionLoader.save(yaml, config.region());
|
||||
blockLoader.save(yaml, config.blocks());
|
||||
resetLoader.save(yaml, config.reset());
|
||||
rewardLoader.save(yaml, config.rewards());
|
||||
teleportLoader.save(yaml, config.teleport());
|
||||
uiLoader.save(yaml, config.ui());
|
||||
worldGuardLoader.save(yaml, config.worldGuard());
|
||||
|
||||
try {
|
||||
Files.createDirectories(configPath.getParent());
|
||||
|
|
@ -140,272 +129,7 @@ public final class ConfigLoader {
|
|||
}
|
||||
}
|
||||
|
||||
// --- Parsers ---
|
||||
|
||||
private RegionConfig parseRegion(YamlConfiguration yaml) {
|
||||
List<Location> selections = new ArrayList<>();
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
String key = "region.selection." + i;
|
||||
if (yaml.contains(key)) {
|
||||
String locStr = yaml.getString(key);
|
||||
if (locStr != null && !locStr.isBlank()) {
|
||||
selections.add(parseLocation(locStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selections.isEmpty()) {
|
||||
// Legacy fallback
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
String key = "selection." + i;
|
||||
if (yaml.contains(key)) {
|
||||
String locStr = yaml.getString(key);
|
||||
if (locStr != null && !locStr.isBlank()) {
|
||||
selections.add(parseLocation(locStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selections.size() < 2) {
|
||||
throw new IllegalArgumentException("Mine must have at least 2 selection points (1 region)");
|
||||
}
|
||||
|
||||
return RegionConfig.fromSelections(selections);
|
||||
}
|
||||
|
||||
private BlockConfig parseBlocks(YamlConfiguration yaml) {
|
||||
ConfigurationSection contents = yaml.getConfigurationSection("blocks.contents");
|
||||
if (contents == null) {
|
||||
contents = yaml.getConfigurationSection("contents"); // Legacy fallback
|
||||
}
|
||||
|
||||
if (contents == null) {
|
||||
throw new IllegalArgumentException("Missing 'blocks.contents' section");
|
||||
}
|
||||
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
for (String key : contents.getKeys(false)) {
|
||||
double weight = contents.getDouble(key);
|
||||
if (weight <= 0) continue;
|
||||
weights.put(BlockKey.deserialize(key), weight);
|
||||
}
|
||||
|
||||
FillMode fillMode = FillMode.valueOf(
|
||||
yaml.getString("blocks.fill-mode", "CUBOID").toUpperCase()
|
||||
);
|
||||
|
||||
// Parse mask config if applicable
|
||||
BlockConfig.MaskConfig mask = null;
|
||||
if (fillMode == FillMode.MASK) {
|
||||
String markerStr = yaml.getString("blocks.mask.marker", "pink_concrete");
|
||||
BlockKey marker = BlockKey.deserialize(markerStr);
|
||||
|
||||
Map<String, Boolean> positions = new HashMap<>();
|
||||
List<String> posList = yaml.getStringList("blocks.mask.positions");
|
||||
for (String pos : posList) {
|
||||
positions.put(pos, true);
|
||||
}
|
||||
|
||||
mask = new BlockConfig.MaskConfig(marker, positions);
|
||||
}
|
||||
|
||||
return new BlockConfig(weights, fillMode, mask);
|
||||
}
|
||||
|
||||
private ResetConfig parseReset(YamlConfiguration yaml) {
|
||||
String intervalStr = yaml.getString("reset.interval", defaults.getString("reset.interval", "5m"));
|
||||
|
||||
return ResetConfig.builder()
|
||||
.interval(intervalStr)
|
||||
.percentTrigger(yaml.getDouble("reset.percent-trigger", defaults.getDouble("reset.percent-trigger", 10.0)))
|
||||
.percentEnabled(yaml.getBoolean("reset.percent-enabled", defaults.getBoolean("reset.percent-enabled", false)))
|
||||
.commands(yaml.getStringList("reset.commands"))
|
||||
.broadcastMessage(yaml.getString("reset.broadcast", ""))
|
||||
.build();
|
||||
}
|
||||
|
||||
private RewardConfig parseRewards(YamlConfiguration yaml) {
|
||||
List<RewardEntry> entries = new ArrayList<>();
|
||||
List<Map<?, ?>> rewardList = yaml.getMapList("rewards");
|
||||
|
||||
if (rewardList.isEmpty()) {
|
||||
rewardList = yaml.getMapList("random-rewards"); // Legacy fallback
|
||||
}
|
||||
|
||||
for (Map<?, ?> map : rewardList) {
|
||||
entries.add(parseRewardEntry(map));
|
||||
}
|
||||
|
||||
return new RewardConfig(entries);
|
||||
}
|
||||
|
||||
private RewardEntry parseRewardEntry(Map<?, ?> map) {
|
||||
double chance = ((Number) map.getOrDefault("chance", 0)).doubleValue();
|
||||
|
||||
List<BlockKey> blocks = new ArrayList<>();
|
||||
List<?> blockList = (List<?>) map.get("blocks");
|
||||
if (blockList != null) {
|
||||
for (Object b : blockList) {
|
||||
blocks.add(BlockKey.deserialize(b.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
List<ItemReward> items = new ArrayList<>();
|
||||
List<?> itemList = (List<?>) map.get("items");
|
||||
if (itemList != null) {
|
||||
for (Object i : itemList) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> itemMap = (Map<String, Object>) i;
|
||||
items.add(parseItemReward(itemMap));
|
||||
}
|
||||
}
|
||||
|
||||
List<String> commands = (List<String>) map.getOrDefault("commands", List.of());
|
||||
boolean preventDrops = (Boolean) map.getOrDefault("prevent-drops", false);
|
||||
|
||||
return new RewardEntry(blocks, chance, items, commands, preventDrops);
|
||||
}
|
||||
|
||||
private ItemReward parseItemReward(Map<String, Object> map) {
|
||||
String typeStr = (String) map.get("type");
|
||||
Material material = Material.matchMaterial(typeStr);
|
||||
if (material == null) {
|
||||
material = Material.STONE;
|
||||
}
|
||||
|
||||
int amount = ((Number) map.getOrDefault("amount", 1)).intValue();
|
||||
String name = (String) map.get("name");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> lore = (List<String>) map.getOrDefault("lore", List.of());
|
||||
|
||||
return new ItemReward(material, amount, name, lore);
|
||||
}
|
||||
|
||||
private TeleportConfig parseTeleport(YamlConfiguration yaml) {
|
||||
boolean enabled = yaml.getBoolean("teleport.enabled", false);
|
||||
if (!enabled) {
|
||||
return TeleportConfig.disabled();
|
||||
}
|
||||
|
||||
String locStr = yaml.getString("teleport.location");
|
||||
if (locStr == null) {
|
||||
return TeleportConfig.disabled();
|
||||
}
|
||||
|
||||
return TeleportConfig.at(parseLocation(locStr));
|
||||
}
|
||||
|
||||
private UIConfig parseUI(YamlConfiguration yaml) {
|
||||
boolean actionBarEnabled = yaml.getBoolean("ui.actionbar.enabled",
|
||||
defaults.getBoolean("ui.actionbar.enabled", true));
|
||||
|
||||
return new UIConfig(
|
||||
actionBarEnabled,
|
||||
yaml.getString("ui.actionbar.format", UIConfig.DEFAULT_ACTIONBAR_FORMAT),
|
||||
yaml.getDouble("ui.actionbar.range", 50.0),
|
||||
yaml.getString("ui.timer-format", UIConfig.DEFAULT_TIMER_FORMAT)
|
||||
);
|
||||
}
|
||||
|
||||
// --- Savers ---
|
||||
|
||||
private void saveRegion(YamlConfiguration yaml, RegionConfig region) {
|
||||
int i = 1;
|
||||
for (Cuboid cuboid : region.regions()) {
|
||||
yaml.set("region.selection." + i, LocationParser.format(cuboid.getMin()));
|
||||
i++;
|
||||
yaml.set("region.selection." + i, LocationParser.format(cuboid.getMax()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void saveBlocks(YamlConfiguration yaml, BlockConfig blocks) {
|
||||
for (var entry : blocks.weights().entrySet()) {
|
||||
yaml.set("blocks.contents." + entry.getKey().serialize(), entry.getValue());
|
||||
}
|
||||
yaml.set("blocks.fill-mode", blocks.fillMode().name().toLowerCase());
|
||||
|
||||
if (blocks.fillMode() == FillMode.MASK && blocks.mask() != null) {
|
||||
yaml.set("blocks.mask.marker", blocks.mask().marker().serialize());
|
||||
yaml.set("blocks.mask.positions", new ArrayList<>(blocks.mask().positions().keySet()));
|
||||
}
|
||||
}
|
||||
|
||||
private void saveReset(YamlConfiguration yaml, ResetConfig reset) {
|
||||
yaml.set("reset.interval", reset.intervalDisplay());
|
||||
yaml.set("reset.percent-trigger", reset.percentTrigger());
|
||||
yaml.set("reset.percent-enabled", reset.percentEnabled());
|
||||
yaml.set("reset.commands", reset.commands());
|
||||
yaml.set("reset.broadcast", reset.broadcastMessage());
|
||||
}
|
||||
|
||||
private void saveRewards(YamlConfiguration yaml, RewardConfig rewards) {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
for (RewardEntry entry : rewards.entries()) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("chance", entry.chance());
|
||||
map.put("blocks", entry.blocks().stream().map(BlockKey::serialize).toList());
|
||||
|
||||
List<Map<String, Object>> items = new ArrayList<>();
|
||||
for (ItemReward item : entry.items()) {
|
||||
Map<String, Object> itemMap = new LinkedHashMap<>();
|
||||
itemMap.put("type", item.material().name().toLowerCase());
|
||||
itemMap.put("amount", item.amount());
|
||||
if (item.displayName() != null) {
|
||||
itemMap.put("name", item.displayName());
|
||||
}
|
||||
if (!item.lore().isEmpty()) {
|
||||
itemMap.put("lore", item.lore());
|
||||
}
|
||||
items.add(itemMap);
|
||||
}
|
||||
map.put("items", items);
|
||||
map.put("commands", entry.commands());
|
||||
map.put("prevent-drops", entry.preventVanillaDrops());
|
||||
list.add(map);
|
||||
}
|
||||
yaml.set("rewards", list);
|
||||
}
|
||||
|
||||
private void saveTeleport(YamlConfiguration yaml, TeleportConfig teleport) {
|
||||
yaml.set("teleport.enabled", teleport.enabled());
|
||||
teleport.getLocation().ifPresent(loc ->
|
||||
yaml.set("teleport.location", LocationParser.format(loc)));
|
||||
}
|
||||
|
||||
private void saveUI(YamlConfiguration yaml, UIConfig ui) {
|
||||
yaml.set("ui.actionbar.enabled", ui.actionBarEnabled());
|
||||
yaml.set("ui.actionbar.format", ui.actionBarFormat());
|
||||
yaml.set("ui.actionbar.range", ui.actionBarRange());
|
||||
yaml.set("ui.timer-format", ui.timerFormat());
|
||||
}
|
||||
|
||||
// --- Helpers ---
|
||||
|
||||
private Location parseLocation(String str) {
|
||||
String[] parts = str.split(";");
|
||||
if (parts.length < 4) {
|
||||
throw new IllegalArgumentException("Invalid location format: " + str);
|
||||
}
|
||||
|
||||
World world = Bukkit.getWorld(parts[0]);
|
||||
if (world == null) {
|
||||
throw new IllegalArgumentException("Unknown world: " + parts[0]);
|
||||
}
|
||||
|
||||
double x = Double.parseDouble(parts[1]);
|
||||
double y = Double.parseDouble(parts[2]);
|
||||
double z = Double.parseDouble(parts[3]);
|
||||
float yaw = parts.length > 4 ? Float.parseFloat(parts[4]) : 0;
|
||||
float pitch = parts.length > 5 ? Float.parseFloat(parts[5]) : 0;
|
||||
|
||||
return new Location(world, x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
private void mergeDefaults(YamlConfiguration yaml) {
|
||||
// Simple shallow merge - could be enhanced for deep merging
|
||||
for (String key : defaults.getKeys(true)) {
|
||||
if (!yaml.contains(key)) {
|
||||
yaml.set(key, defaults.get(key));
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import dev.loki.lomines.data.config.reset.ResetConfig;
|
|||
import dev.loki.lomines.data.config.reward.RewardConfig;
|
||||
import dev.loki.lomines.data.config.teleport.TeleportConfig;
|
||||
import dev.loki.lomines.data.config.ui.UIConfig;
|
||||
import dev.loki.lomines.integration.worldguard.WorldGuardConfig;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
|
@ -20,7 +21,8 @@ public record MineConfig(
|
|||
ResetConfig reset,
|
||||
RewardConfig rewards,
|
||||
TeleportConfig teleport,
|
||||
UIConfig ui
|
||||
UIConfig ui,
|
||||
WorldGuardConfig worldGuard
|
||||
) {
|
||||
|
||||
public MineConfig {
|
||||
|
|
@ -36,6 +38,7 @@ public record MineConfig(
|
|||
Objects.requireNonNull(rewards, "Reward config cannot be null");
|
||||
Objects.requireNonNull(teleport, "Teleport config cannot be null");
|
||||
Objects.requireNonNull(ui, "UI config cannot be null");
|
||||
// worldGuard can be null (disabled by default)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,7 +73,8 @@ public record MineConfig(
|
|||
ResetConfig.defaults(),
|
||||
RewardConfig.empty(),
|
||||
TeleportConfig.disabled(),
|
||||
UIConfig.defaults()
|
||||
UIConfig.defaults(),
|
||||
WorldGuardConfig.disabled()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -84,6 +88,7 @@ public record MineConfig(
|
|||
private RewardConfig rewards = RewardConfig.empty();
|
||||
private TeleportConfig teleport = TeleportConfig.disabled();
|
||||
private UIConfig ui = UIConfig.defaults();
|
||||
private WorldGuardConfig worldGuard = WorldGuardConfig.disabled();
|
||||
|
||||
private Builder(String name) {
|
||||
this.name = name;
|
||||
|
|
@ -119,8 +124,13 @@ public record MineConfig(
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder worldGuard(WorldGuardConfig worldGuard) {
|
||||
this.worldGuard = worldGuard;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MineConfig build() {
|
||||
return new MineConfig(name, region, blocks, reset, rewards, teleport, ui);
|
||||
return new MineConfig(name, region, blocks, reset, rewards, teleport, ui, worldGuard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
package dev.loki.lomines.data.config.loader;
|
||||
|
||||
import dev.loki.lomines.data.config.block.BlockConfig;
|
||||
import dev.loki.lomines.data.config.block.BlockKey;
|
||||
import dev.loki.lomines.data.config.block.FillMode;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Loader for blocks configuration section.
|
||||
*/
|
||||
public final class BlockConfigLoader {
|
||||
|
||||
/**
|
||||
* Parses block configuration from YAML.
|
||||
*/
|
||||
public BlockConfig parse(YamlConfiguration yaml) {
|
||||
ConfigurationSection contents = yaml.getConfigurationSection("blocks.contents");
|
||||
if (contents == null) {
|
||||
contents = yaml.getConfigurationSection("contents"); // Legacy fallback
|
||||
}
|
||||
|
||||
if (contents == null) {
|
||||
throw new IllegalArgumentException("Missing 'blocks.contents' section");
|
||||
}
|
||||
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
for (String key : contents.getKeys(false)) {
|
||||
double weight = contents.getDouble(key);
|
||||
if (weight <= 0) continue;
|
||||
weights.put(BlockKey.deserialize(key), weight);
|
||||
}
|
||||
|
||||
FillMode fillMode = FillMode.valueOf(
|
||||
yaml.getString("blocks.fill-mode", "CUBOID").toUpperCase()
|
||||
);
|
||||
|
||||
// Parse mask config if applicable
|
||||
BlockConfig.MaskConfig mask = null;
|
||||
if (fillMode == FillMode.MASK) {
|
||||
String markerStr = yaml.getString("blocks.mask.marker", "pink_concrete");
|
||||
BlockKey marker = BlockKey.deserialize(markerStr);
|
||||
|
||||
Map<String, Boolean> positions = new HashMap<>();
|
||||
List<String> posList = yaml.getStringList("blocks.mask.positions");
|
||||
for (String pos : posList) {
|
||||
positions.put(pos, true);
|
||||
}
|
||||
|
||||
mask = new BlockConfig.MaskConfig(marker, positions);
|
||||
}
|
||||
|
||||
return new BlockConfig(weights, fillMode, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves block configuration to YAML.
|
||||
*/
|
||||
public void save(YamlConfiguration yaml, BlockConfig blocks) {
|
||||
for (var entry : blocks.weights().entrySet()) {
|
||||
yaml.set("blocks.contents." + entry.getKey().serialize(), entry.getValue());
|
||||
}
|
||||
yaml.set("blocks.fill-mode", blocks.fillMode().name().toLowerCase());
|
||||
|
||||
if (blocks.fillMode() == FillMode.MASK && blocks.mask() != null) {
|
||||
yaml.set("blocks.mask.marker", blocks.mask().marker().serialize());
|
||||
yaml.set("blocks.mask.positions", new ArrayList<>(blocks.mask().positions().keySet()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package dev.loki.lomines.data.config.loader;
|
||||
|
||||
import dev.loki.lomines.data.config.region.RegionConfig;
|
||||
import dev.loki.lomines.util.location.LocationParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Loader for region configuration section.
|
||||
*/
|
||||
public final class RegionConfigLoader {
|
||||
|
||||
/**
|
||||
* Parses region configuration from YAML.
|
||||
*/
|
||||
public RegionConfig parse(YamlConfiguration yaml) {
|
||||
List<Location> selections = new ArrayList<>();
|
||||
|
||||
// Try new format first
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
String key = "region.selection." + i;
|
||||
if (yaml.contains(key)) {
|
||||
String locStr = yaml.getString(key);
|
||||
if (locStr != null && !locStr.isBlank()) {
|
||||
selections.add(parseLocation(locStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy fallback
|
||||
if (selections.isEmpty()) {
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
String key = "selection." + i;
|
||||
if (yaml.contains(key)) {
|
||||
String locStr = yaml.getString(key);
|
||||
if (locStr != null && !locStr.isBlank()) {
|
||||
selections.add(parseLocation(locStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selections.size() < 2) {
|
||||
throw new IllegalArgumentException("Mine must have at least 2 selection points (1 region)");
|
||||
}
|
||||
|
||||
return RegionConfig.fromSelections(selections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves region configuration to YAML.
|
||||
*/
|
||||
public void save(YamlConfiguration yaml, RegionConfig region) {
|
||||
int i = 1;
|
||||
for (var cuboid : region.regions()) {
|
||||
yaml.set("region.selection." + i, LocationParser.format(cuboid.getMin()));
|
||||
i++;
|
||||
yaml.set("region.selection." + i, LocationParser.format(cuboid.getMax()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private Location parseLocation(String str) {
|
||||
String[] parts = str.split(";");
|
||||
if (parts.length < 4) {
|
||||
throw new IllegalArgumentException("Invalid location format: " + str);
|
||||
}
|
||||
|
||||
World world = Bukkit.getWorld(parts[0]);
|
||||
if (world == null) {
|
||||
throw new IllegalArgumentException("Unknown world: " + parts[0]);
|
||||
}
|
||||
|
||||
double x = Double.parseDouble(parts[1]);
|
||||
double y = Double.parseDouble(parts[2]);
|
||||
double z = Double.parseDouble(parts[3]);
|
||||
float yaw = parts.length > 4 ? Float.parseFloat(parts[4]) : 0;
|
||||
float pitch = parts.length > 5 ? Float.parseFloat(parts[5]) : 0;
|
||||
|
||||
return new Location(world, x, y, z, yaw, pitch);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package dev.loki.lomines.data.config.loader;
|
||||
|
||||
import dev.loki.lomines.data.config.reset.ResetConfig;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Loader for reset configuration section.
|
||||
*/
|
||||
public final class ResetConfigLoader {
|
||||
|
||||
private final YamlConfiguration defaults;
|
||||
|
||||
public ResetConfigLoader(YamlConfiguration defaults) {
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses reset configuration from YAML.
|
||||
*/
|
||||
public ResetConfig parse(YamlConfiguration yaml) {
|
||||
String intervalStr = yaml.getString("reset.interval",
|
||||
defaults.getString("reset.interval", "5m"));
|
||||
|
||||
return ResetConfig.builder()
|
||||
.interval(intervalStr)
|
||||
.percentTrigger(yaml.getDouble("reset.percent-trigger",
|
||||
defaults.getDouble("reset.percent-trigger", 10.0)))
|
||||
.percentEnabled(yaml.getBoolean("reset.percent-enabled",
|
||||
defaults.getBoolean("reset.percent-enabled", false)))
|
||||
.commands(yaml.getStringList("reset.commands"))
|
||||
.broadcastMessage(yaml.getString("reset.broadcast", ""))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves reset configuration to YAML.
|
||||
*/
|
||||
public void save(YamlConfiguration yaml, ResetConfig reset) {
|
||||
yaml.set("reset.interval", reset.intervalDisplay());
|
||||
yaml.set("reset.percent-trigger", reset.percentTrigger());
|
||||
yaml.set("reset.percent-enabled", reset.percentEnabled());
|
||||
yaml.set("reset.commands", reset.commands());
|
||||
yaml.set("reset.broadcast", reset.broadcastMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
package dev.loki.lomines.data.config.loader;
|
||||
|
||||
import dev.loki.lomines.data.config.block.BlockKey;
|
||||
import dev.loki.lomines.data.config.reward.RewardConfig;
|
||||
import dev.loki.lomines.data.config.reward.RewardConfig.RewardEntry;
|
||||
import dev.loki.lomines.data.config.reward.RewardConfig.RewardEntry.ItemReward;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Loader for rewards configuration section.
|
||||
*/
|
||||
public final class RewardConfigLoader {
|
||||
|
||||
/**
|
||||
* Parses rewards from YAML configuration.
|
||||
*/
|
||||
public RewardConfig parse(YamlConfiguration yaml) {
|
||||
List<RewardEntry> entries = new ArrayList<>();
|
||||
List<Map<?, ?>> rewardList = yaml.getMapList("rewards");
|
||||
|
||||
if (rewardList.isEmpty()) {
|
||||
rewardList = yaml.getMapList("random-rewards"); // Legacy fallback
|
||||
}
|
||||
|
||||
for (Map<?, ?> map : rewardList) {
|
||||
entries.add(parseRewardEntry(map));
|
||||
}
|
||||
|
||||
return new RewardConfig(entries);
|
||||
}
|
||||
|
||||
private RewardEntry parseRewardEntry(Map<?, ?> map) {
|
||||
double chance = ((Number) map.getOrDefault("chance", 0)).doubleValue();
|
||||
|
||||
List<BlockKey> blocks = new ArrayList<>();
|
||||
List<?> blockList = (List<?>) map.get("blocks");
|
||||
if (blockList != null) {
|
||||
for (Object b : blockList) {
|
||||
blocks.add(BlockKey.deserialize(b.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
List<ItemReward> items = new ArrayList<>();
|
||||
List<?> itemList = (List<?>) map.get("items");
|
||||
if (itemList != null) {
|
||||
for (Object i : itemList) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> itemMap = (Map<String, Object>) i;
|
||||
items.add(parseItemReward(itemMap));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> commands = (List<String>) map.getOrDefault("commands", List.of());
|
||||
boolean preventDrops = (Boolean) map.getOrDefault("prevent-drops", false);
|
||||
|
||||
return new RewardEntry(blocks, chance, items, commands, preventDrops);
|
||||
}
|
||||
|
||||
private ItemReward parseItemReward(Map<String, Object> map) {
|
||||
String typeStr = (String) map.get("type");
|
||||
Material material = Material.matchMaterial(typeStr);
|
||||
if (material == null) {
|
||||
material = Material.STONE;
|
||||
}
|
||||
|
||||
int amount = ((Number) map.getOrDefault("amount", 1)).intValue();
|
||||
String name = (String) map.get("name");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> lore = (List<String>) map.getOrDefault("lore", List.of());
|
||||
|
||||
return new ItemReward(material, amount, name, lore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves rewards to YAML configuration.
|
||||
*/
|
||||
public void save(YamlConfiguration yaml, RewardConfig rewards) {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
for (RewardEntry entry : rewards.entries()) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("chance", entry.chance());
|
||||
map.put("blocks", entry.blocks().stream().map(BlockKey::serialize).toList());
|
||||
|
||||
List<Map<String, Object>> items = new ArrayList<>();
|
||||
for (ItemReward item : entry.items()) {
|
||||
Map<String, Object> itemMap = new LinkedHashMap<>();
|
||||
itemMap.put("type", item.material().name().toLowerCase());
|
||||
itemMap.put("amount", item.amount());
|
||||
if (item.displayName() != null) {
|
||||
itemMap.put("name", item.displayName());
|
||||
}
|
||||
if (!item.lore().isEmpty()) {
|
||||
itemMap.put("lore", item.lore());
|
||||
}
|
||||
items.add(itemMap);
|
||||
}
|
||||
map.put("items", items);
|
||||
map.put("commands", entry.commands());
|
||||
map.put("prevent-drops", entry.preventVanillaDrops());
|
||||
list.add(map);
|
||||
}
|
||||
yaml.set("rewards", list);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package dev.loki.lomines.data.config.loader;
|
||||
|
||||
import dev.loki.lomines.data.config.teleport.TeleportConfig;
|
||||
import dev.loki.lomines.util.location.LocationParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
/**
|
||||
* Loader for teleport configuration section.
|
||||
*/
|
||||
public final class TeleportConfigLoader {
|
||||
|
||||
/**
|
||||
* Parses teleport configuration from YAML.
|
||||
*/
|
||||
public TeleportConfig parse(YamlConfiguration yaml) {
|
||||
boolean enabled = yaml.getBoolean("teleport.enabled", false);
|
||||
if (!enabled) {
|
||||
return TeleportConfig.disabled();
|
||||
}
|
||||
|
||||
String locStr = yaml.getString("teleport.location");
|
||||
if (locStr == null || locStr.isBlank()) {
|
||||
return TeleportConfig.disabled();
|
||||
}
|
||||
|
||||
return TeleportConfig.at(parseLocation(locStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves teleport configuration to YAML.
|
||||
*/
|
||||
public void save(YamlConfiguration yaml, TeleportConfig teleport) {
|
||||
yaml.set("teleport.enabled", teleport.enabled());
|
||||
teleport.getLocation().ifPresent(loc ->
|
||||
yaml.set("teleport.location", LocationParser.format(loc)));
|
||||
}
|
||||
|
||||
private Location parseLocation(String str) {
|
||||
String[] parts = str.split(";");
|
||||
if (parts.length < 4) {
|
||||
throw new IllegalArgumentException("Invalid location format: " + str);
|
||||
}
|
||||
|
||||
World world = Bukkit.getWorld(parts[0]);
|
||||
if (world == null) {
|
||||
throw new IllegalArgumentException("Unknown world: " + parts[0]);
|
||||
}
|
||||
|
||||
double x = Double.parseDouble(parts[1]);
|
||||
double y = Double.parseDouble(parts[2]);
|
||||
double z = Double.parseDouble(parts[3]);
|
||||
float yaw = parts.length > 4 ? Float.parseFloat(parts[4]) : 0;
|
||||
float pitch = parts.length > 5 ? Float.parseFloat(parts[5]) : 0;
|
||||
|
||||
return new Location(world, x, y, z, yaw, pitch);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package dev.loki.lomines.data.config.loader;
|
||||
|
||||
import dev.loki.lomines.data.config.ui.UIConfig;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
/**
|
||||
* Loader for UI configuration section.
|
||||
*/
|
||||
public final class UIConfigLoader {
|
||||
|
||||
private final YamlConfiguration defaults;
|
||||
|
||||
public UIConfigLoader(YamlConfiguration defaults) {
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses UI configuration from YAML.
|
||||
*/
|
||||
public UIConfig parse(YamlConfiguration yaml) {
|
||||
boolean actionBarEnabled = yaml.getBoolean("ui.actionbar.enabled",
|
||||
defaults.getBoolean("ui.actionbar.enabled", true));
|
||||
|
||||
return new UIConfig(
|
||||
actionBarEnabled,
|
||||
yaml.getString("ui.actionbar.format", UIConfig.DEFAULT_ACTIONBAR_FORMAT),
|
||||
yaml.getDouble("ui.actionbar.range", 50.0),
|
||||
yaml.getString("ui.timer-format", UIConfig.DEFAULT_TIMER_FORMAT)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves UI configuration to YAML.
|
||||
*/
|
||||
public void save(YamlConfiguration yaml, UIConfig ui) {
|
||||
yaml.set("ui.actionbar.enabled", ui.actionBarEnabled());
|
||||
yaml.set("ui.actionbar.format", ui.actionBarFormat());
|
||||
yaml.set("ui.actionbar.range", ui.actionBarRange());
|
||||
yaml.set("ui.timer-format", ui.timerFormat());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package dev.loki.lomines.data.config.loader;
|
||||
|
||||
import dev.loki.lomines.data.config.ConfigLoader;
|
||||
import dev.loki.lomines.integration.worldguard.WorldGuardConfig;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Loader for WorldGuard configuration section.
|
||||
*/
|
||||
public final class WorldGuardConfigLoader {
|
||||
|
||||
private final YamlConfiguration defaults;
|
||||
|
||||
public WorldGuardConfigLoader(YamlConfiguration defaults) {
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses WorldGuard configuration from YAML.
|
||||
*/
|
||||
public WorldGuardConfig parse(YamlConfiguration yaml) {
|
||||
ConfigurationSection wgSection = yaml.getConfigurationSection("worldguard");
|
||||
if (wgSection == null) {
|
||||
// Check defaults
|
||||
boolean defaultEnabled = defaults.getBoolean("worldguard.enabled", false);
|
||||
if (!defaultEnabled) {
|
||||
return WorldGuardConfig.disabled();
|
||||
}
|
||||
}
|
||||
|
||||
boolean enabled = yaml.getBoolean("worldguard.enabled",
|
||||
defaults.getBoolean("worldguard.enabled", false));
|
||||
|
||||
if (!enabled) {
|
||||
return WorldGuardConfig.disabled();
|
||||
}
|
||||
|
||||
String template = yaml.getString("worldguard.region-template",
|
||||
defaults.getString("worldguard.region-template", "{mine_name}_{random_4}"));
|
||||
|
||||
List<String> owners = yaml.getStringList("worldguard.owners");
|
||||
if (owners.isEmpty()) {
|
||||
owners = defaults.getStringList("worldguard.owners");
|
||||
}
|
||||
|
||||
List<String> members = yaml.getStringList("worldguard.members");
|
||||
if (members.isEmpty()) {
|
||||
members = defaults.getStringList("worldguard.members");
|
||||
}
|
||||
|
||||
List<String> flags = yaml.getStringList("worldguard.flags");
|
||||
if (flags.isEmpty()) {
|
||||
flags = defaults.getStringList("worldguard.flags");
|
||||
}
|
||||
if (flags.isEmpty()) {
|
||||
flags = List.of("passthrough=deny", "build=allow");
|
||||
}
|
||||
|
||||
boolean protect = yaml.getBoolean("worldguard.protect-on-create",
|
||||
defaults.getBoolean("worldguard.protect-on-create", true));
|
||||
|
||||
return WorldGuardConfig.builder()
|
||||
.enabled(true)
|
||||
.template(template)
|
||||
.owners(owners)
|
||||
.members(members)
|
||||
.flags(flags)
|
||||
.protectOnCreate(protect)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves WorldGuard configuration to YAML.
|
||||
*/
|
||||
public void save(YamlConfiguration yaml, WorldGuardConfig config) {
|
||||
yaml.set("worldguard.enabled", config.enabled());
|
||||
|
||||
if (config.enabled()) {
|
||||
yaml.set("worldguard.region-template", config.regionNameTemplate());
|
||||
yaml.set("worldguard.owners", config.owners());
|
||||
yaml.set("worldguard.members", config.members());
|
||||
yaml.set("worldguard.flags", config.flags());
|
||||
yaml.set("worldguard.protect-on-create", config.protectOnCreate());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default values for WorldGuard configuration.
|
||||
*/
|
||||
public void setDefaults(YamlConfiguration yaml) {
|
||||
yaml.set("worldguard.enabled", false);
|
||||
yaml.set("worldguard.region-template", "{mine_name}_{random_4}");
|
||||
yaml.set("worldguard.owners", List.of());
|
||||
yaml.set("worldguard.members", List.of());
|
||||
yaml.set("worldguard.flags", List.of("passthrough=deny", "build=allow"));
|
||||
yaml.set("worldguard.protect-on-create", true);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue