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:
loki5512344 2026-05-31 22:39:01 +02:00
parent 75d785147d
commit 3ba6f303f8
15 changed files with 1126 additions and 318 deletions

View file

@ -6,6 +6,7 @@ import dev.loki.lomines.core.service.MineFileManager;
import dev.loki.lomines.core.service.MineRepository;
import dev.loki.lomines.data.config.ConfigLoader;
import dev.loki.lomines.data.config.MineConfig;
import dev.loki.lomines.integration.worldguard.WorldGuardRegionService;
import org.bukkit.Location;
import java.io.IOException;
@ -26,6 +27,7 @@ public final class Mines {
private final MineFileManager fileManager;
private final MineRepository repository;
private final MaskScanService maskScanService;
private final WorldGuardRegionService worldGuardService;
public Mines(LoMinesPlugin plugin) {
this.plugin = plugin;
@ -33,6 +35,7 @@ public final class Mines {
this.fileManager = new MineFileManager(minesFolder);
this.repository = new MineRepository(plugin, fileManager);
this.maskScanService = new MaskScanService(repository, fileManager);
this.worldGuardService = new WorldGuardRegionService(plugin);
}
/**
@ -77,6 +80,7 @@ public final class Mines {
/**
* Creates a new mine; optional corners define {@code selection.1} and {@code selection.2} (same world required).
* If WorldGuard integration is enabled, creates a region for the mine.
*/
public void create(String name, Location corner1, Location corner2) throws IOException {
if (repository.exists(name)) {
@ -96,12 +100,19 @@ public final class Mines {
throw new IOException("Failed to parse created mine configuration: " + e.getMessage(), e);
}
// Create WorldGuard region if enabled
String regionName = worldGuardService.createRegion(name, config);
if (regionName != null) {
plugin.loLogger().info("Created WorldGuard region '" + regionName + "' for mine: " + name);
}
repository.createAndStart(name, config);
plugin.loLogger().info("Created mine: " + name);
}
/**
* Deletes a mine by name.
* Also deletes the associated WorldGuard region if it exists.
*/
public void delete(String name) throws IOException {
Mine mine = repository.remove(name);
@ -111,6 +122,14 @@ public final class Mines {
}
mine.stop();
// Delete WorldGuard region if exists
MineConfig config = mine.getConfig();
boolean wgDeleted = worldGuardService.deleteRegion(name, config);
if (wgDeleted) {
plugin.loLogger().info("Deleted WorldGuard region for mine: " + name);
}
fileManager.deleteConfig(name);
}
@ -156,8 +175,27 @@ public final class Mines {
/**
* Reloads one mine from disk (stop, replace instance, start tasks).
* Updates WorldGuard region if mine regions changed.
*/
public void reloadMine(String name) throws IOException, ConfigLoader.ConfigLoadException {
// Get old config before reload
Mine oldMine = repository.find(name).orElse(null);
repository.reload(name);
// Update WorldGuard region if mine exists
if (oldMine != null) {
Mine newMine = repository.find(name).orElse(null);
if (newMine != null) {
worldGuardService.updateRegion(name, newMine.getConfig());
}
}
}
/**
* Returns the WorldGuard region service for direct access.
*/
public WorldGuardRegionService getWorldGuardService() {
return worldGuardService;
}
}

View file

@ -10,6 +10,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 dev.loki.lomines.util.location.Cuboid;
import dev.loki.lomines.util.location.LocationParser;
import org.bukkit.Location;
@ -44,6 +45,7 @@ public record MineFileManager(Path minesFolder, ConfigLoader configLoader) {
/**
* Creates a default mine configuration with new format.
* WorldGuard region settings are loaded from defaults.yml.
*/
public void createDefaultConfig(String name, Location corner1, Location corner2) throws IOException {
ensureFolderExists();
@ -62,6 +64,9 @@ public record MineFileManager(Path minesFolder, ConfigLoader configLoader) {
weights.put(new BlockKey.Vanilla(Material.STONE), 1.0);
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
// Load WorldGuard defaults from _defaults.yml
WorldGuardConfig wgConfig = loadWorldGuardDefaults();
// Build mine config with defaults
MineConfig config = MineConfig.builder(name)
.region(region)
@ -70,12 +75,51 @@ public record MineFileManager(Path minesFolder, ConfigLoader configLoader) {
.rewards(RewardConfig.empty())
.teleport(TeleportConfig.disabled())
.ui(UIConfig.defaults())
.worldGuard(wgConfig)
.build();
// Save using new loader
configLoader.save(config);
}
/**
* Loads WorldGuard configuration from defaults.yml.
*/
private WorldGuardConfig loadWorldGuardDefaults() {
Path defaultsPath = minesFolder.resolve("_defaults.yml");
if (!Files.exists(defaultsPath)) {
return WorldGuardConfig.disabled();
}
try {
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(defaultsPath.toFile());
ConfigurationSection wgSection = yaml.getConfigurationSection("worldguard");
if (wgSection == null) {
return WorldGuardConfig.disabled();
}
boolean enabled = wgSection.getBoolean("enabled", false);
if (!enabled) {
return WorldGuardConfig.disabled();
}
String template = wgSection.getString("region-template", "{mine_name}_{random_4}");
return WorldGuardConfig.builder()
.enabled(true)
.template(template)
.owners(wgSection.getStringList("owners"))
.members(wgSection.getStringList("members"))
.flags(wgSection.getStringList("flags"))
.protectOnCreate(wgSection.getBoolean("protect-on-create", true))
.build();
} catch (Exception e) {
return WorldGuardConfig.disabled();
}
}
public MineConfig loadConfig(String name) throws IOException, ConfigLoader.ConfigLoadException {
return configLoader.load(name);
}
@ -115,6 +159,7 @@ public record MineFileManager(Path minesFolder, ConfigLoader configLoader) {
.rewards(config.rewards())
.teleport(config.teleport())
.ui(config.ui())
.worldGuard(config.worldGuard())
.build();
configLoader.save(updated);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,155 @@
package dev.loki.lomines.integration.worldguard;
import java.util.List;
import java.util.Objects;
import java.util.Random;
/**
* Configuration for WorldGuard auto-region creation.
*/
public record WorldGuardConfig(
boolean enabled,
String regionNameTemplate,
List<String> owners,
List<String> members,
List<String> flags,
boolean protectOnCreate
) {
private static final Random RANDOM = new Random();
private static final String DEFAULT_TEMPLATE = "{mine_name}_{random_4}";
public WorldGuardConfig {
enabled = enabled;
regionNameTemplate = regionNameTemplate != null && !regionNameTemplate.isBlank()
? regionNameTemplate
: DEFAULT_TEMPLATE;
owners = owners != null ? List.copyOf(owners) : List.of();
members = members != null ? List.copyOf(members) : List.of();
flags = flags != null ? List.copyOf(flags) : List.of(
"passthrough=deny",
"build=allow"
);
protectOnCreate = protectOnCreate;
}
/**
* Generates a region name from the template.
*
* @param mineName the name of the mine
* @return the generated region name
*/
public String generateRegionName(String mineName) {
String result = regionNameTemplate;
// Replace {mine_name}
result = result.replace("{mine_name}", mineName);
// Replace {random_4} with 4 random digits
if (result.contains("{random_4}")) {
int randomNum = RANDOM.nextInt(10000);
result = result.replace("{random_4}", String.format("%04d", randomNum));
}
// Replace {random_3} with 3 random digits
if (result.contains("{random_3}")) {
int randomNum = RANDOM.nextInt(1000);
result = result.replace("{random_3}", String.format("%03d", randomNum));
}
// Replace {random_6} with 6 random alphanumeric
if (result.contains("{random_6}")) {
result = result.replace("{random_6}", generateRandomString(6));
}
// Sanitize for WorldGuard (only alphanumeric, underscore, hyphen)
return result.replaceAll("[^a-zA-Z0-9_-]", "_").toLowerCase();
}
private String generateRandomString(int length) {
String chars = "abcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(chars.charAt(RANDOM.nextInt(chars.length())));
}
return sb.toString();
}
/**
* Default configuration with auto-region enabled.
*/
public static WorldGuardConfig defaults() {
return new WorldGuardConfig(
true,
DEFAULT_TEMPLATE,
List.of(),
List.of(),
List.of("passthrough=deny", "build=allow"),
true
);
}
/**
* Disabled configuration.
*/
public static WorldGuardConfig disabled() {
return new WorldGuardConfig(
false,
DEFAULT_TEMPLATE,
List.of(),
List.of(),
List.of(),
false
);
}
/**
* Builder for fluent construction.
*/
public static Builder builder() {
return new Builder();
}
public static class Builder {
private boolean enabled = true;
private String template = DEFAULT_TEMPLATE;
private List<String> owners = List.of();
private List<String> members = List.of();
private List<String> flags = List.of("passthrough=deny", "build=allow");
private boolean protectOnCreate = true;
public Builder enabled(boolean enabled) {
this.enabled = enabled;
return this;
}
public Builder template(String template) {
this.template = template;
return this;
}
public Builder owners(List<String> owners) {
this.owners = owners;
return this;
}
public Builder members(List<String> members) {
this.members = members;
return this;
}
public Builder flags(List<String> flags) {
this.flags = flags;
return this;
}
public Builder protectOnCreate(boolean protect) {
this.protectOnCreate = protect;
return this;
}
public WorldGuardConfig build() {
return new WorldGuardConfig(enabled, template, owners, members, flags, protectOnCreate);
}
}
}

View file

@ -0,0 +1,55 @@
package dev.loki.lomines.integration.worldguard;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import dev.loki.lomines.LoMinesPlugin;
/**
* Parses and applies WorldGuard flags from string entries.
*/
public final class WorldGuardFlagParser {
private final LoMinesPlugin plugin;
public WorldGuardFlagParser(LoMinesPlugin plugin) {
this.plugin = plugin;
}
/**
* Parses and sets a flag from a "key=value" string entry.
*
* @param region the region to set the flag on
* @param flagEntry the flag entry in format "flag=value"
*/
public void parseAndSetFlag(ProtectedRegion region, String flagEntry) {
String[] parts = flagEntry.split("=", 2);
if (parts.length != 2) {
return;
}
String flagName = parts[0].trim().toLowerCase();
String value = parts[1].trim();
try {
switch (flagName) {
case "passthrough" -> setStateFlag(region, Flags.PASSTHROUGH, value);
case "build" -> setStateFlag(region, Flags.BUILD, value);
case "pvp" -> setStateFlag(region, Flags.PVP, value);
case "tnt" -> setStateFlag(region, Flags.TNT, value);
case "creeper-explosion" -> setStateFlag(region, Flags.CREEPER_EXPLOSION, value);
case "greeting" -> region.setFlag(Flags.GREET_MESSAGE, value);
case "farewell" -> region.setFlag(Flags.FAREWELL_MESSAGE, value);
default -> plugin.loLogger().warn("Unknown WorldGuard flag: " + flagName);
}
} catch (Exception e) {
plugin.loLogger().warn("Failed to set flag " + flagName + ": " + e.getMessage());
}
}
private void setStateFlag(ProtectedRegion region, StateFlag flag, String value) {
region.setFlag(flag, "allow".equalsIgnoreCase(value)
? StateFlag.State.ALLOW
: StateFlag.State.DENY);
}
}

View file

@ -0,0 +1,225 @@
package dev.loki.lomines.integration.worldguard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import dev.loki.lomines.LoMinesPlugin;
import dev.loki.lomines.data.config.MineConfig;
import dev.loki.lomines.util.location.Cuboid;
import org.bukkit.Bukkit;
import org.bukkit.World;
import java.util.List;
import java.util.UUID;
/**
* Service for managing WorldGuard regions for mines.
* Creates, updates, and deletes WorldGuard regions when mines are managed.
*/
public final class WorldGuardRegionService {
private final LoMinesPlugin plugin;
private final WorldGuardFlagParser flagParser;
private boolean worldGuardEnabled;
public WorldGuardRegionService(LoMinesPlugin plugin) {
this.plugin = plugin;
this.flagParser = new WorldGuardFlagParser(plugin);
checkWorldGuard();
}
private void checkWorldGuard() {
this.worldGuardEnabled = Bukkit.getPluginManager().getPlugin("WorldGuard") != null
&& Bukkit.getPluginManager().isPluginEnabled("WorldGuard");
if (worldGuardEnabled) {
plugin.loLogger().info("WorldGuard integration enabled - auto-region creation active");
}
}
/**
* Creates a WorldGuard region for a mine if enabled in config.
*/
public String createRegion(String mineName, MineConfig config) {
if (!worldGuardEnabled) {
return null;
}
WorldGuardConfig wgConfig = config.worldGuard();
if (wgConfig == null || !wgConfig.enabled()) {
return null;
}
String regionName = wgConfig.generateRegionName(mineName);
try {
RegionManager regionManager = getRegionManager(config.worldName());
if (regionManager == null) {
return null;
}
if (regionManager.hasRegion(regionName)) {
plugin.loLogger().info("WorldGuard region already exists: " + regionName);
return regionName;
}
ProtectedCuboidRegion region = createRegionFromCuboids(regionName, config);
if (region == null) {
plugin.loLogger().warn("Failed to create region for mine " + mineName + ": no valid regions");
return null;
}
applyOwnersAndMembers(region, wgConfig);
applyFlags(region, wgConfig.flags());
regionManager.addRegion(region);
plugin.loLogger().info("Created WorldGuard region '" + regionName + "' for mine " + mineName);
return regionName;
} catch (Exception e) {
plugin.loLogger().error("Failed to create WorldGuard region for mine " + mineName + ": " + e.getMessage());
e.printStackTrace();
return null;
}
}
/**
* Updates an existing WorldGuard region when mine regions change.
*/
public boolean updateRegion(String mineName, MineConfig config) {
if (!worldGuardEnabled) {
return false;
}
WorldGuardConfig wgConfig = config.worldGuard();
if (wgConfig == null || !wgConfig.enabled()) {
return false;
}
String regionName = wgConfig.generateRegionName(mineName);
try {
RegionManager regionManager = getRegionManager(config.worldName());
if (regionManager == null) {
return false;
}
if (regionManager.hasRegion(regionName)) {
regionManager.removeRegion(regionName);
}
return createRegion(mineName, config) != null;
} catch (Exception e) {
plugin.loLogger().error("Failed to update WorldGuard region: " + e.getMessage());
return false;
}
}
/**
* Deletes a WorldGuard region for a mine.
*/
public boolean deleteRegion(String mineName, MineConfig config) {
if (!worldGuardEnabled) {
return false;
}
WorldGuardConfig wgConfig = config.worldGuard();
if (wgConfig == null) {
return false;
}
String regionName = wgConfig.generateRegionName(mineName);
try {
RegionManager regionManager = getRegionManager(config.worldName());
if (regionManager == null) {
return false;
}
if (regionManager.hasRegion(regionName)) {
regionManager.removeRegion(regionName);
plugin.loLogger().info("Deleted WorldGuard region: " + regionName);
return true;
}
return false;
} catch (Exception e) {
plugin.loLogger().error("Failed to delete WorldGuard region: " + e.getMessage());
return false;
}
}
private RegionManager getRegionManager(String worldName) {
World world = Bukkit.getWorld(worldName);
if (world == null) {
return null;
}
return WorldGuard.getInstance()
.getPlatform()
.getRegionContainer()
.get(com.sk89q.worldedit.bukkit.BukkitAdapter.adapt(world));
}
private ProtectedCuboidRegion createRegionFromCuboids(String regionName, MineConfig config) {
List<Cuboid> regions = config.region().regions();
if (regions.isEmpty()) {
return null;
}
Cuboid first = regions.get(0);
BlockVector3 min = BlockVector3.at(first.getMinX(), first.getMinY(), first.getMinZ());
BlockVector3 max = BlockVector3.at(first.getMaxX(), first.getMaxY(), first.getMaxZ());
ProtectedCuboidRegion mainRegion = new ProtectedCuboidRegion(regionName, min, max);
if (regions.size() > 1) {
plugin.loLogger().warn("Mine " + regionName + " has multiple regions - " +
"only the first region is fully protected by WorldGuard");
}
return mainRegion;
}
private void applyOwnersAndMembers(ProtectedCuboidRegion region, WorldGuardConfig wgConfig) {
// Set owners
for (String owner : wgConfig.owners()) {
if (owner.startsWith("uuid:")) {
try {
UUID uuid = UUID.fromString(owner.substring(5));
region.getOwners().addPlayer(uuid);
} catch (IllegalArgumentException e) {
plugin.loLogger().warn("Invalid owner UUID: " + owner);
}
} else {
region.getOwners().addPlayer(owner);
}
}
// Set members
for (String member : wgConfig.members()) {
if (member.startsWith("uuid:")) {
try {
UUID uuid = UUID.fromString(member.substring(5));
region.getMembers().addPlayer(uuid);
} catch (IllegalArgumentException e) {
plugin.loLogger().warn("Invalid member UUID: " + member);
}
} else {
region.getMembers().addPlayer(member);
}
}
}
private void applyFlags(ProtectedCuboidRegion region, List<String> flags) {
for (String flagEntry : flags) {
flagParser.parseAndSetFlag(region, flagEntry);
}
}
public boolean isWorldGuardEnabled() {
return worldGuardEnabled;
}
}