chore: rewrite ARCHITECTURE, enable tests via MockBukkit, checkstyle for tests, cleanup bin/libs
This commit is contained in:
parent
a0c1ab8ca1
commit
e8d516020c
53 changed files with 1093 additions and 1410 deletions
966
ARCHITECTURE.md
966
ARCHITECTURE.md
File diff suppressed because it is too large
Load diff
|
|
@ -41,9 +41,13 @@ dependencies {
|
||||||
testImplementation("io.kotest:kotest-property:5.9.1")
|
testImplementation("io.kotest:kotest-property:5.9.1")
|
||||||
testImplementation("org.mockito:mockito-core:5.14.2")
|
testImplementation("org.mockito:mockito-core:5.14.2")
|
||||||
testImplementation("org.mockito:mockito-inline:5.2.0")
|
testImplementation("org.mockito:mockito-inline:5.2.0")
|
||||||
testImplementation("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
|
testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.110.0") {
|
||||||
|
exclude(group = "org.junit.jupiter", module = "junit-jupiter-api")
|
||||||
|
}
|
||||||
|
testImplementation("io.papermc.paper:paper-api:1.21.11-R0.1-SNAPSHOT")
|
||||||
testImplementation("net.kyori:adventure-api:4.17.0")
|
testImplementation("net.kyori:adventure-api:4.17.0")
|
||||||
testImplementation("net.kyori:adventure-text-minimessage:4.17.0")
|
testImplementation("net.kyori:adventure-text-minimessage:4.17.0")
|
||||||
|
testImplementation("com.sk89q.worldguard:worldguard-bukkit:7.0.13")
|
||||||
}
|
}
|
||||||
|
|
||||||
checkstyle {
|
checkstyle {
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,6 @@
|
||||||
<property name="severity" value="error"/>
|
<property name="severity" value="error"/>
|
||||||
<property name="fileExtensions" value="java"/>
|
<property name="fileExtensions" value="java"/>
|
||||||
|
|
||||||
<module name="BeforeExecutionExclusionFileFilter">
|
|
||||||
<property name="fileNamePattern" value=".*[\\/]src[\\/]test[\\/].*"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<module name="SuppressWarningsFilter"/>
|
<module name="SuppressWarningsFilter"/>
|
||||||
|
|
||||||
<module name="LineLength">
|
<module name="LineLength">
|
||||||
|
|
@ -24,7 +20,7 @@
|
||||||
<module name="SuppressWarningsHolder"/>
|
<module name="SuppressWarningsHolder"/>
|
||||||
|
|
||||||
<module name="MethodLength">
|
<module name="MethodLength">
|
||||||
<property name="max" value="80"/>
|
<property name="max" value="30"/>
|
||||||
<property name="countEmpty" value="false"/>
|
<property name="countEmpty" value="false"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package dev.loki.lomines.command.admin.info;
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.core.mine.model.Mine;
|
import dev.loki.lomines.core.mine.model.Mine;
|
||||||
import dev.loki.lomines.data.config.block.BlockKey;
|
import dev.loki.lomines.data.config.block.BlockKey;
|
||||||
|
import dev.loki.lomines.data.config.model.MineConfig;
|
||||||
import dev.loki.lomines.util.location.geo.Cuboid;
|
import dev.loki.lomines.util.location.geo.Cuboid;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
@ -40,8 +41,16 @@ public class InfoCommand {
|
||||||
sender.sendMessage(Component.text("§7Блоков: §f" + mine.getBlocks() + "§7/§f" + mine.getTotalVolume() +
|
sender.sendMessage(Component.text("§7Блоков: §f" + mine.getBlocks() + "§7/§f" + mine.getTotalVolume() +
|
||||||
" §7(§f" + String.format("%.1f", mine.getPercentFilled()) + "%§7)"));
|
" §7(§f" + String.format("%.1f", mine.getPercentFilled()) + "%§7)"));
|
||||||
|
|
||||||
|
printRegions(sender, mine.getRegions());
|
||||||
|
printBlocks(sender, config.blocks().weights());
|
||||||
|
printResetAndTeleport(sender, config);
|
||||||
|
|
||||||
|
sender.sendMessage(Component.text("§6§lНаграды: §f" + config.rewards().entries().size() + " записей"));
|
||||||
|
sender.sendMessage(Component.text("§8§m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printRegions(CommandSender sender, List<Cuboid> regions) {
|
||||||
sender.sendMessage(Component.text("§6§lРегионы:"));
|
sender.sendMessage(Component.text("§6§lРегионы:"));
|
||||||
List<Cuboid> regions = mine.getRegions();
|
|
||||||
for (int i = 0; i < regions.size(); i++) {
|
for (int i = 0; i < regions.size(); i++) {
|
||||||
Cuboid r = regions.get(i);
|
Cuboid r = regions.get(i);
|
||||||
sender.sendMessage(Component.text("§7 #" + (i + 1) + ": §f" +
|
sender.sendMessage(Component.text("§7 #" + (i + 1) + ": §f" +
|
||||||
|
|
@ -50,8 +59,10 @@ public class InfoCommand {
|
||||||
" §7(§f" + r.getVolume() + " §7блоков)"));
|
" §7(§f" + r.getVolume() + " §7блоков)"));
|
||||||
}
|
}
|
||||||
sender.sendMessage(Component.text(""));
|
sender.sendMessage(Component.text(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printBlocks(CommandSender sender, Map<BlockKey, Double> weights) {
|
||||||
sender.sendMessage(Component.text("§6§lБлоки:"));
|
sender.sendMessage(Component.text("§6§lБлоки:"));
|
||||||
Map<BlockKey, Double> weights = config.blocks().weights();
|
|
||||||
weights.entrySet().stream()
|
weights.entrySet().stream()
|
||||||
.sorted((a, b) -> Double.compare(b.getValue(), a.getValue()))
|
.sorted((a, b) -> Double.compare(b.getValue(), a.getValue()))
|
||||||
.limit(10)
|
.limit(10)
|
||||||
|
|
@ -60,7 +71,9 @@ public class InfoCommand {
|
||||||
if (weights.size() > 10) {
|
if (weights.size() > 10) {
|
||||||
sender.sendMessage(Component.text("§7 ... и ещё " + (weights.size() - 10) + " блоков"));
|
sender.sendMessage(Component.text("§7 ... и ещё " + (weights.size() - 10) + " блоков"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printResetAndTeleport(CommandSender sender, MineConfig config) {
|
||||||
sender.sendMessage(Component.text("§6§lНастройки сброса:"));
|
sender.sendMessage(Component.text("§6§lНастройки сброса:"));
|
||||||
sender.sendMessage(Component.text("§7 Интервал: §f" + config.reset().intervalDisplay()));
|
sender.sendMessage(Component.text("§7 Интервал: §f" + config.reset().intervalDisplay()));
|
||||||
sender.sendMessage(Component.text("§7 Триггер по %: §f" +
|
sender.sendMessage(Component.text("§7 Триггер по %: §f" +
|
||||||
|
|
@ -71,9 +84,6 @@ public class InfoCommand {
|
||||||
(config.teleport().enabled() ? "§aустановлена" : "§7не задана")));
|
(config.teleport().enabled() ? "§aустановлена" : "§7не задана")));
|
||||||
sender.sendMessage(Component.text("§7 Точка спавна: §f" +
|
sender.sendMessage(Component.text("§7 Точка спавна: §f" +
|
||||||
(config.playerSpawn().enabled() ? "§aустановлена" : "§7используется точка телепорта")));
|
(config.playerSpawn().enabled() ? "§aустановлена" : "§7используется точка телепорта")));
|
||||||
|
|
||||||
sender.sendMessage(Component.text("§6§lНаграды: §f" + config.rewards().entries().size() + " записей"));
|
|
||||||
sender.sendMessage(Component.text("§8§m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatBlockKey(BlockKey key) {
|
private String formatBlockKey(BlockKey key) {
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,20 @@ public final class RegionActionHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cuboid newRegion = resolveNewRegion(player, mine);
|
||||||
|
if (newRegion == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Cuboid> currentRegions = new ArrayList<>(mine.getRegions());
|
||||||
|
currentRegions.add(newRegion);
|
||||||
|
|
||||||
|
updateMineRegions(mine, new RegionConfig(currentRegions));
|
||||||
|
|
||||||
|
sendRegionAdded(player, newRegion, currentRegions.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cuboid resolveNewRegion(Player player, Mine mine) {
|
||||||
var wandManager = plugin.getGroupWandManager();
|
var wandManager = plugin.getGroupWandManager();
|
||||||
var session = wandManager.getSession(player.getUniqueId());
|
var session = wandManager.getSession(player.getUniqueId());
|
||||||
int slot = session.getActiveSlot();
|
int slot = session.getActiveSlot();
|
||||||
|
|
@ -40,7 +54,7 @@ public final class RegionActionHandler {
|
||||||
var pos2 = session.getPos2(slot);
|
var pos2 = session.getPos2(slot);
|
||||||
if (pos1 == null || pos2 == null) {
|
if (pos1 == null || pos2 == null) {
|
||||||
player.sendMessage(Component.text("§cВыделите регион палочкой! ЛКМ - 1-я точка, ПКМ - 2-я точка"));
|
player.sendMessage(Component.text("§cВыделите регион палочкой! ЛКМ - 1-я точка, ПКМ - 2-я точка"));
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
Cuboid newRegion = new Cuboid(pos1, pos2);
|
Cuboid newRegion = new Cuboid(pos1, pos2);
|
||||||
String mineWorld = mine.getConfig().region().worldName();
|
String mineWorld = mine.getConfig().region().worldName();
|
||||||
|
|
@ -48,21 +62,17 @@ public final class RegionActionHandler {
|
||||||
|
|
||||||
if (!mineWorld.equals(regionWorld)) {
|
if (!mineWorld.equals(regionWorld)) {
|
||||||
player.sendMessage(Component.text("§cРегион должен быть в мире §f" + mineWorld + "§c, а не §f" + regionWorld));
|
player.sendMessage(Component.text("§cРегион должен быть в мире §f" + mineWorld + "§c, а не §f" + regionWorld));
|
||||||
return;
|
return null;
|
||||||
|
}
|
||||||
|
session.clearCorners(slot);
|
||||||
|
return newRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Cuboid> currentRegions = new ArrayList<>(mine.getRegions());
|
private void sendRegionAdded(Player player, Cuboid newRegion, int count) {
|
||||||
currentRegions.add(newRegion);
|
player.sendMessage(Component.text("§aДобавлен регион #" + count));
|
||||||
|
|
||||||
var newRegionConfig = new RegionConfig(currentRegions);
|
|
||||||
updateMineRegions(mine, newRegionConfig);
|
|
||||||
|
|
||||||
player.sendMessage(Component.text("§aДобавлен регион #" + currentRegions.size()));
|
|
||||||
player.sendMessage(Component.text("§7От: §f" + newRegion.getMinX() + ", " + newRegion.getMinY() + ", " + newRegion.getMinZ()));
|
player.sendMessage(Component.text("§7От: §f" + newRegion.getMinX() + ", " + newRegion.getMinY() + ", " + newRegion.getMinZ()));
|
||||||
player.sendMessage(Component.text("§7До: §f" + newRegion.getMaxX() + ", " + newRegion.getMaxY() + ", " + newRegion.getMaxZ()));
|
player.sendMessage(Component.text("§7До: §f" + newRegion.getMaxX() + ", " + newRegion.getMaxY() + ", " + newRegion.getMaxZ()));
|
||||||
player.sendMessage(Component.text("§7Объём: §f" + newRegion.getVolume() + " §7блоков"));
|
player.sendMessage(Component.text("§7Объём: §f" + newRegion.getVolume() + " §7блоков"));
|
||||||
|
|
||||||
session.clearCorners(slot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeRegion(CommandSender sender, String mineName, int index) {
|
public void removeRegion(CommandSender sender, String mineName, int index) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,14 @@ public class RegionCommands {
|
||||||
|
|
||||||
public void handle(CommandSender sender, String subcommand, String[] args) {
|
public void handle(CommandSender sender, String subcommand, String[] args) {
|
||||||
switch (subcommand.toLowerCase()) {
|
switch (subcommand.toLowerCase()) {
|
||||||
case "regions" -> {
|
case "regions" -> handleRegions(sender, args);
|
||||||
|
case "addregion" -> handleAddRegion(sender, args);
|
||||||
|
case "removeregion" -> handleRemoveRegion(sender, args);
|
||||||
|
default -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRegions(CommandSender sender, String[] args) {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
sender.sendMessage(Component.text("Usage: /lm regions <mine>", NamedTextColor.RED));
|
sender.sendMessage(Component.text("Usage: /lm regions <mine>", NamedTextColor.RED));
|
||||||
return;
|
return;
|
||||||
|
|
@ -48,14 +55,16 @@ public class RegionCommands {
|
||||||
}
|
}
|
||||||
sender.sendMessage(Component.text("§8§m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
|
sender.sendMessage(Component.text("§8§m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
|
||||||
}
|
}
|
||||||
case "addregion" -> {
|
|
||||||
|
private void handleAddRegion(CommandSender sender, String[] args) {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
sender.sendMessage(Component.text("Usage: /lm addregion <mine>", NamedTextColor.RED));
|
sender.sendMessage(Component.text("Usage: /lm addregion <mine>", NamedTextColor.RED));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionHandler.addRegion(sender, args[0]);
|
actionHandler.addRegion(sender, args[0]);
|
||||||
}
|
}
|
||||||
case "removeregion" -> {
|
|
||||||
|
private void handleRemoveRegion(CommandSender sender, String[] args) {
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
sender.sendMessage(Component.text("Usage: /lm removeregion <mine> <index>", NamedTextColor.RED));
|
sender.sendMessage(Component.text("Usage: /lm removeregion <mine> <index>", NamedTextColor.RED));
|
||||||
return;
|
return;
|
||||||
|
|
@ -67,7 +76,4 @@ public class RegionCommands {
|
||||||
sender.sendMessage(Component.text("Индекс должен быть числом: " + args[1], NamedTextColor.RED));
|
sender.sendMessage(Component.text("Индекс должен быть числом: " + args[1], NamedTextColor.RED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,28 +25,41 @@ public class AdminCommands {
|
||||||
|
|
||||||
public void handle(CommandSender sender, String subcommand, String[] args) {
|
public void handle(CommandSender sender, String subcommand, String[] args) {
|
||||||
switch (subcommand.toLowerCase()) {
|
switch (subcommand.toLowerCase()) {
|
||||||
case "create" -> {
|
case "create" -> handleCreate(sender, args);
|
||||||
|
case "delete" -> handleDelete(sender, args);
|
||||||
|
case "edit" -> handleEdit(sender, args);
|
||||||
|
case "reset" -> handleReset(sender, args);
|
||||||
|
case "reload" -> actionHandler.reload(sender);
|
||||||
|
case "list" -> handleList(sender);
|
||||||
|
default -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleCreate(CommandSender sender, String[] args) {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
sender.sendMessage(Component.text("Usage: /lm create <name>"));
|
sender.sendMessage(Component.text("Usage: /lm create <name>"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionHandler.create(sender, args[0]);
|
actionHandler.create(sender, args[0]);
|
||||||
}
|
}
|
||||||
case "delete" -> {
|
|
||||||
|
private void handleDelete(CommandSender sender, String[] args) {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
sender.sendMessage(Component.text("Usage: /lm delete <name>"));
|
sender.sendMessage(Component.text("Usage: /lm delete <name>"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionHandler.delete(sender, args[0]);
|
actionHandler.delete(sender, args[0]);
|
||||||
}
|
}
|
||||||
case "edit" -> {
|
|
||||||
|
private void handleEdit(CommandSender sender, String[] args) {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
sender.sendMessage(Component.text("Usage: /lm edit <mine>"));
|
sender.sendMessage(Component.text("Usage: /lm edit <mine>"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionHandler.edit(sender, args[0]);
|
actionHandler.edit(sender, args[0]);
|
||||||
}
|
}
|
||||||
case "reset" -> {
|
|
||||||
|
private void handleReset(CommandSender sender, String[] args) {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
sender.sendMessage(Component.text("Usage: /lm reset <mine> [silent]"));
|
sender.sendMessage(Component.text("Usage: /lm reset <mine> [silent]"));
|
||||||
return;
|
return;
|
||||||
|
|
@ -54,8 +67,8 @@ public class AdminCommands {
|
||||||
boolean silent = args.length > 1 && (args[1].equalsIgnoreCase("true") || args[1].equalsIgnoreCase("silent"));
|
boolean silent = args.length > 1 && (args[1].equalsIgnoreCase("true") || args[1].equalsIgnoreCase("silent"));
|
||||||
actionHandler.reset(sender, args[0], silent);
|
actionHandler.reset(sender, args[0], silent);
|
||||||
}
|
}
|
||||||
case "reload" -> actionHandler.reload(sender);
|
|
||||||
case "list" -> {
|
private void handleList(CommandSender sender) {
|
||||||
Collection<Mine> allMines = mines.getAll();
|
Collection<Mine> allMines = mines.getAll();
|
||||||
if (allMines.isEmpty()) {
|
if (allMines.isEmpty()) {
|
||||||
sender.sendMessage(Component.text("No mines found"));
|
sender.sendMessage(Component.text("No mines found"));
|
||||||
|
|
@ -67,9 +80,6 @@ public class AdminCommands {
|
||||||
sender.sendMessage(Component.text("- " + mine.getName() + " " + status));
|
sender.sendMessage(Component.text("- " + mine.getName() + " " + status));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatMineStatus(Mine mine) {
|
private String formatMineStatus(Mine mine) {
|
||||||
int blocks = mine.getBlocks();
|
int blocks = mine.getBlocks();
|
||||||
|
|
|
||||||
|
|
@ -23,27 +23,51 @@ public class CopyCommand {
|
||||||
String fromMineName = args[0];
|
String fromMineName = args[0];
|
||||||
String toMineName = args[1];
|
String toMineName = args[1];
|
||||||
|
|
||||||
|
MinePair pair = resolveMines(sender, fromMineName, toMineName);
|
||||||
|
if (pair == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceConfig = pair.fromMine().getConfig();
|
||||||
|
|
||||||
|
MineConfig newTargetConfig = buildCopiedConfig(pair.toMine(), sourceConfig);
|
||||||
|
|
||||||
|
try {
|
||||||
|
plugin.getMines().updateMineConfig(pair.toMine().getName(), newTargetConfig);
|
||||||
|
} catch (Exception e) {
|
||||||
|
sender.sendMessage(Component.text("Ошибка сохранения: " + e.getMessage(), NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCopySummary(sender, pair.fromMine(), pair.toMine(), sourceConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record MinePair(Mine fromMine, Mine toMine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private MinePair resolveMines(CommandSender sender, String fromMineName, String toMineName) {
|
||||||
Mine fromMine = plugin.getMines().find(fromMineName).orElse(null);
|
Mine fromMine = plugin.getMines().find(fromMineName).orElse(null);
|
||||||
if (fromMine == null) {
|
if (fromMine == null) {
|
||||||
sender.sendMessage(Component.text("Исходная шахта не найдена: " + fromMineName, NamedTextColor.RED));
|
sender.sendMessage(Component.text("Исходная шахта не найдена: " + fromMineName, NamedTextColor.RED));
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mine toMine = plugin.getMines().find(toMineName).orElse(null);
|
Mine toMine = plugin.getMines().find(toMineName).orElse(null);
|
||||||
if (toMine == null) {
|
if (toMine == null) {
|
||||||
sender.sendMessage(Component.text("Целевая шахта не найдена: " + toMineName, NamedTextColor.RED));
|
sender.sendMessage(Component.text("Целевая шахта не найдена: " + toMineName, NamedTextColor.RED));
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromMine.getName().equalsIgnoreCase(toMine.getName())) {
|
if (fromMine.getName().equalsIgnoreCase(toMine.getName())) {
|
||||||
sender.sendMessage(Component.text("Нельзя копировать шахту саму в себя!", NamedTextColor.RED));
|
sender.sendMessage(Component.text("Нельзя копировать шахту саму в себя!", NamedTextColor.RED));
|
||||||
return;
|
return null;
|
||||||
|
}
|
||||||
|
return new MinePair(fromMine, toMine);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sourceConfig = fromMine.getConfig();
|
private MineConfig buildCopiedConfig(Mine toMine, MineConfig sourceConfig) {
|
||||||
var targetConfig = toMine.getConfig();
|
var targetConfig = toMine.getConfig();
|
||||||
|
return MineConfig.builder(toMine.getName())
|
||||||
MineConfig newTargetConfig = MineConfig.builder(toMine.getName())
|
|
||||||
.region(targetConfig.region())
|
.region(targetConfig.region())
|
||||||
.blocks(sourceConfig.blocks())
|
.blocks(sourceConfig.blocks())
|
||||||
.reset(sourceConfig.reset())
|
.reset(sourceConfig.reset())
|
||||||
|
|
@ -53,14 +77,9 @@ public class CopyCommand {
|
||||||
.worldGuard(sourceConfig.worldGuard())
|
.worldGuard(sourceConfig.worldGuard())
|
||||||
.playerSpawn(sourceConfig.playerSpawn())
|
.playerSpawn(sourceConfig.playerSpawn())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try {
|
|
||||||
plugin.getMines().updateMineConfig(toMine.getName(), newTargetConfig);
|
|
||||||
} catch (Exception e) {
|
|
||||||
sender.sendMessage(Component.text("Ошибка сохранения: " + e.getMessage(), NamedTextColor.RED));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendCopySummary(CommandSender sender, Mine fromMine, Mine toMine, MineConfig sourceConfig) {
|
||||||
sender.sendMessage(Component.text("§aКонфигурация скопирована из §f" + fromMine.getName() +
|
sender.sendMessage(Component.text("§aКонфигурация скопирована из §f" + fromMine.getName() +
|
||||||
" §aв §f" + toMine.getName()));
|
" §aв §f" + toMine.getName()));
|
||||||
sender.sendMessage(Component.text("§7Скопировано:"));
|
sender.sendMessage(Component.text("§7Скопировано:"));
|
||||||
|
|
|
||||||
|
|
@ -40,18 +40,7 @@ public final class TeleportActionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = mine.getConfig();
|
var config = mine.getConfig();
|
||||||
var newTeleport = TeleportConfig.at(player.getLocation());
|
var updatedConfig = withTeleport(config, TeleportConfig.at(player.getLocation()));
|
||||||
|
|
||||||
var updatedConfig = MineConfig.builder(mineName)
|
|
||||||
.region(config.region())
|
|
||||||
.blocks(config.blocks())
|
|
||||||
.reset(config.reset())
|
|
||||||
.rewards(config.rewards())
|
|
||||||
.teleport(newTeleport)
|
|
||||||
.ui(config.ui())
|
|
||||||
.worldGuard(config.worldGuard())
|
|
||||||
.playerSpawn(config.playerSpawn())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
||||||
sender.sendMessage(MessageFormatter.success("Teleport location for mine '" + mineName + "' set to your current position"));
|
sender.sendMessage(MessageFormatter.success("Teleport location for mine '" + mineName + "' set to your current position"));
|
||||||
|
|
@ -76,18 +65,7 @@ public final class TeleportActionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = mine.getConfig();
|
var config = mine.getConfig();
|
||||||
var newSpawn = PlayerSpawnConfig.at(player.getLocation());
|
var updatedConfig = withPlayerSpawn(config, PlayerSpawnConfig.at(player.getLocation()));
|
||||||
|
|
||||||
var updatedConfig = MineConfig.builder(mineName)
|
|
||||||
.region(config.region())
|
|
||||||
.blocks(config.blocks())
|
|
||||||
.reset(config.reset())
|
|
||||||
.rewards(config.rewards())
|
|
||||||
.teleport(config.teleport())
|
|
||||||
.ui(config.ui())
|
|
||||||
.worldGuard(config.worldGuard())
|
|
||||||
.playerSpawn(newSpawn)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
||||||
sender.sendMessage(MessageFormatter.success("Safe spawn location for mine '" + mineName + "' set to your current position"));
|
sender.sendMessage(MessageFormatter.success("Safe spawn location for mine '" + mineName + "' set to your current position"));
|
||||||
|
|
@ -108,16 +86,7 @@ public final class TeleportActionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = mine.getConfig();
|
var config = mine.getConfig();
|
||||||
var updatedConfig = MineConfig.builder(mineName)
|
var updatedConfig = withPlayerSpawn(config, PlayerSpawnConfig.disabled());
|
||||||
.region(config.region())
|
|
||||||
.blocks(config.blocks())
|
|
||||||
.reset(config.reset())
|
|
||||||
.rewards(config.rewards())
|
|
||||||
.teleport(config.teleport())
|
|
||||||
.ui(config.ui())
|
|
||||||
.worldGuard(config.worldGuard())
|
|
||||||
.playerSpawn(PlayerSpawnConfig.disabled())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
||||||
sender.sendMessage(MessageFormatter.success("Spawn location for mine '" + mineName + "' cleared"));
|
sender.sendMessage(MessageFormatter.success("Spawn location for mine '" + mineName + "' cleared"));
|
||||||
|
|
@ -128,6 +97,32 @@ public final class TeleportActionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MineConfig withTeleport(MineConfig config, TeleportConfig teleport) {
|
||||||
|
return MineConfig.builder(config.name())
|
||||||
|
.region(config.region())
|
||||||
|
.blocks(config.blocks())
|
||||||
|
.reset(config.reset())
|
||||||
|
.rewards(config.rewards())
|
||||||
|
.teleport(teleport)
|
||||||
|
.ui(config.ui())
|
||||||
|
.worldGuard(config.worldGuard())
|
||||||
|
.playerSpawn(config.playerSpawn())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MineConfig withPlayerSpawn(MineConfig config, PlayerSpawnConfig spawn) {
|
||||||
|
return MineConfig.builder(config.name())
|
||||||
|
.region(config.region())
|
||||||
|
.blocks(config.blocks())
|
||||||
|
.reset(config.reset())
|
||||||
|
.rewards(config.rewards())
|
||||||
|
.teleport(config.teleport())
|
||||||
|
.ui(config.ui())
|
||||||
|
.worldGuard(config.worldGuard())
|
||||||
|
.playerSpawn(spawn)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
public String formatLocation(Location loc) {
|
public String formatLocation(Location loc) {
|
||||||
return String.format("%.1f, %.1f, %.1f in %s",
|
return String.format("%.1f, %.1f, %.1f in %s",
|
||||||
loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName());
|
loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName());
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package dev.loki.lomines.command.admin.stats;
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.core.mine.model.Mine;
|
import dev.loki.lomines.core.mine.model.Mine;
|
||||||
import dev.loki.lomines.core.mine.registry.Mines;
|
import dev.loki.lomines.core.mine.registry.Mines;
|
||||||
import dev.loki.lomines.data.stats.model.Leaderboard;
|
|
||||||
import dev.loki.lomines.data.stats.model.LeaderboardEntry;
|
import dev.loki.lomines.data.stats.model.LeaderboardEntry;
|
||||||
import dev.loki.lomines.util.ErrorHandler;
|
import dev.loki.lomines.util.ErrorHandler;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
@ -77,29 +76,37 @@ public final class LeaderboardRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderTopCommand(CommandSender sender, String arg1, String arg2, Mines mines, LoMinesPlugin plugin) {
|
public static void renderTopCommand(CommandSender sender, String arg1, String arg2, Mines mines, LoMinesPlugin plugin) {
|
||||||
|
TopRequest req = parseTopRequest(arg1, arg2);
|
||||||
|
if (req.mineName() != null) {
|
||||||
|
renderMineTop(sender, req.mineName(), req.limit(), mines, plugin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<LeaderboardEntry> rows = plugin.getStatsManager().getLeaderboard().getTopTotal(req.limit());
|
||||||
|
sender.sendMessage(Component.text("=== Общий топ ===", NamedTextColor.GOLD));
|
||||||
|
sendTopRows(sender, rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record TopRequest(int limit, String mineName) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TopRequest parseTopRequest(String arg1, String arg2) {
|
||||||
String a = arg1 == null ? "" : arg1.trim();
|
String a = arg1 == null ? "" : arg1.trim();
|
||||||
String b = arg2 == null ? "" : arg2.trim();
|
String b = arg2 == null ? "" : arg2.trim();
|
||||||
int limit;
|
|
||||||
String mineName;
|
|
||||||
if (a.isEmpty()) {
|
if (a.isEmpty()) {
|
||||||
limit = clampLimit(10);
|
return new TopRequest(clampLimit(10), null);
|
||||||
mineName = null;
|
}
|
||||||
} else if (b.isEmpty()) {
|
if (b.isEmpty()) {
|
||||||
Integer asLimit = tryParsePositiveInt(a);
|
Integer asLimit = tryParsePositiveInt(a);
|
||||||
if (asLimit != null) {
|
if (asLimit != null) {
|
||||||
limit = clampLimit(asLimit);
|
return new TopRequest(clampLimit(asLimit), null);
|
||||||
mineName = null;
|
}
|
||||||
} else {
|
return new TopRequest(clampLimit(10), a);
|
||||||
limit = clampLimit(10);
|
|
||||||
mineName = a;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
mineName = a;
|
|
||||||
Integer limParsed = tryParsePositiveInt(b);
|
Integer limParsed = tryParsePositiveInt(b);
|
||||||
limit = clampLimit(limParsed != null ? limParsed : 10);
|
return new TopRequest(clampLimit(limParsed != null ? limParsed : 10), a);
|
||||||
}
|
}
|
||||||
Leaderboard lb = plugin.getStatsManager().getLeaderboard();
|
|
||||||
if (mineName != null) {
|
private static void renderMineTop(CommandSender sender, String mineName, int limit, Mines mines, LoMinesPlugin plugin) {
|
||||||
var found = mines.find(mineName);
|
var found = mines.find(mineName);
|
||||||
if (found.isEmpty()) {
|
if (found.isEmpty()) {
|
||||||
sender.sendMessage(Component.text("Шахта не найдена: " + mineName, NamedTextColor.RED));
|
sender.sendMessage(Component.text("Шахта не найдена: " + mineName, NamedTextColor.RED));
|
||||||
|
|
@ -107,13 +114,8 @@ public final class LeaderboardRenderer {
|
||||||
}
|
}
|
||||||
Mine m = found.get();
|
Mine m = found.get();
|
||||||
String key = m.getName();
|
String key = m.getName();
|
||||||
List<LeaderboardEntry> rows = lb.getTopByMine(key, limit);
|
List<LeaderboardEntry> rows = plugin.getStatsManager().getLeaderboard().getTopByMine(key, limit);
|
||||||
sender.sendMessage(Component.text("=== Топ по шахте \u00ab" + key + "\u00bb ===", NamedTextColor.GOLD));
|
sender.sendMessage(Component.text("=== Топ по шахте \u00ab" + key + "\u00bb ===", NamedTextColor.GOLD));
|
||||||
sendTopRows(sender, rows);
|
sendTopRows(sender, rows);
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<LeaderboardEntry> rows = lb.getTopTotal(limit);
|
|
||||||
sender.sendMessage(Component.text("=== Общий топ ===", NamedTextColor.GOLD));
|
|
||||||
sendTopRows(sender, rows);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,20 @@ public class StatsCommands {
|
||||||
|
|
||||||
public void handle(CommandSender sender, String subcommand, String[] args) {
|
public void handle(CommandSender sender, String subcommand, String[] args) {
|
||||||
switch (subcommand.toLowerCase()) {
|
switch (subcommand.toLowerCase()) {
|
||||||
case "stats" -> {
|
case "stats" -> handleStats(sender, args);
|
||||||
|
case "top" -> {
|
||||||
|
if (isStatsDisabled(sender)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String arg1 = args.length > 0 ? args[0] : "";
|
||||||
|
String arg2 = args.length > 1 ? args[1] : "";
|
||||||
|
LeaderboardRenderer.renderTopCommand(sender, arg1, arg2, mines, plugin);
|
||||||
|
}
|
||||||
|
default -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleStats(CommandSender sender, String[] args) {
|
||||||
if (isStatsDisabled(sender)) {
|
if (isStatsDisabled(sender)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -56,17 +69,6 @@ public class StatsCommands {
|
||||||
.forEach(e -> sender.sendMessage(Component.text(
|
.forEach(e -> sender.sendMessage(Component.text(
|
||||||
" " + e.getKey() + ": " + e.getValue(), NamedTextColor.DARK_AQUA)));
|
" " + e.getKey() + ": " + e.getValue(), NamedTextColor.DARK_AQUA)));
|
||||||
}
|
}
|
||||||
case "top" -> {
|
|
||||||
if (isStatsDisabled(sender)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String arg1 = args.length > 0 ? args[0] : "";
|
|
||||||
String arg2 = args.length > 1 ? args[1] : "";
|
|
||||||
LeaderboardRenderer.renderTopCommand(sender, arg1, arg2, mines, plugin);
|
|
||||||
}
|
|
||||||
default -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isStatsDisabled(CommandSender sender) {
|
private boolean isStatsDisabled(CommandSender sender) {
|
||||||
if (!plugin.getConfig().getBoolean("statistics-enabled", true)) {
|
if (!plugin.getConfig().getBoolean("statistics-enabled", true)) {
|
||||||
|
|
|
||||||
|
|
@ -35,19 +35,8 @@ public class TeleportCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = mine.getConfig();
|
Location target = resolveTarget(player, mine);
|
||||||
Location target;
|
if (target == null) {
|
||||||
|
|
||||||
if (config.teleport().enabled() && config.teleport().getLocation().isPresent()) {
|
|
||||||
target = config.teleport().getLocation().get();
|
|
||||||
} else if (!mine.getRegions().isEmpty()) {
|
|
||||||
Cuboid region = mine.getRegions().get(0);
|
|
||||||
double centerX = (region.getMinX() + region.getMaxX()) / 2.0 + 0.5;
|
|
||||||
double centerZ = (region.getMinZ() + region.getMaxZ()) / 2.0 + 0.5;
|
|
||||||
double centerY = region.getMaxY() + 1;
|
|
||||||
target = new Location(region.getWorld(), centerX, centerY, centerZ);
|
|
||||||
} else {
|
|
||||||
player.sendMessage(Component.text("У шахты нет настроенной точки телепорта!", NamedTextColor.RED));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,4 +44,20 @@ public class TeleportCommand {
|
||||||
player.sendMessage(Component.text("§aТелепортировано к шахте §f" + mine.getName() +
|
player.sendMessage(Component.text("§aТелепортировано к шахте §f" + mine.getName() +
|
||||||
" §a(§f" + String.format("%.0f, %.0f, %.0f", target.getX(), target.getY(), target.getZ()) + "§a)"));
|
" §a(§f" + String.format("%.0f, %.0f, %.0f", target.getX(), target.getY(), target.getZ()) + "§a)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Location resolveTarget(Player player, Mine mine) {
|
||||||
|
var config = mine.getConfig();
|
||||||
|
if (config.teleport().enabled() && config.teleport().getLocation().isPresent()) {
|
||||||
|
return config.teleport().getLocation().get();
|
||||||
|
}
|
||||||
|
if (!mine.getRegions().isEmpty()) {
|
||||||
|
Cuboid region = mine.getRegions().get(0);
|
||||||
|
double centerX = (region.getMinX() + region.getMaxX()) / 2.0 + 0.5;
|
||||||
|
double centerZ = (region.getMinZ() + region.getMaxZ()) / 2.0 + 0.5;
|
||||||
|
double centerY = region.getMaxY() + 1;
|
||||||
|
return new Location(region.getWorld(), centerX, centerY, centerZ);
|
||||||
|
}
|
||||||
|
player.sendMessage(Component.text("У шахты нет настроенной точки телепорта!", NamedTextColor.RED));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
/**
|
|
||||||
* Core components of the LoMines plugin.
|
|
||||||
* <p>
|
|
||||||
* This package contains the main plugin class and core system classes:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code LoMinesPlugin} - Main plugin class extending LoPlugin</li>
|
|
||||||
* <li>{@code Mines} - Registry for managing all active mines</li>
|
|
||||||
* <li>{@code Mine} - Representation of a single mine with its configuration and state</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
package dev.loki.lomines.core.common;
|
|
||||||
|
|
@ -44,6 +44,7 @@ public final class Mines {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(String name, Location corner1, Location corner2) throws IOException {
|
public void create(String name, Location corner1, Location corner2) throws IOException {
|
||||||
|
name = name.toLowerCase().trim();
|
||||||
if (repository.exists(name)) {
|
if (repository.exists(name)) {
|
||||||
throw new IllegalArgumentException("Mine already exists: " + name);
|
throw new IllegalArgumentException("Mine already exists: " + name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,13 @@ public final class BlockConfigLoader {
|
||||||
yaml.getString("blocks.fill-mode", "CUBOID").toUpperCase()
|
yaml.getString("blocks.fill-mode", "CUBOID").toUpperCase()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Parse mask config if applicable
|
return new BlockConfig(weights, fillMode, parseMaskConfig(yaml, fillMode));
|
||||||
BlockConfig.MaskConfig mask = null;
|
}
|
||||||
if (fillMode == FillMode.MASK) {
|
|
||||||
|
private BlockConfig.MaskConfig parseMaskConfig(YamlConfiguration yaml, FillMode fillMode) {
|
||||||
|
if (fillMode != FillMode.MASK) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
String markerStr = yaml.getString("blocks.mask.marker", "pink_concrete");
|
String markerStr = yaml.getString("blocks.mask.marker", "pink_concrete");
|
||||||
BlockKey marker = BlockKey.deserialize(markerStr);
|
BlockKey marker = BlockKey.deserialize(markerStr);
|
||||||
|
|
||||||
|
|
@ -54,10 +58,7 @@ public final class BlockConfigLoader {
|
||||||
positions.put(pos, true);
|
positions.put(pos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = new BlockConfig.MaskConfig(marker, positions);
|
return new BlockConfig.MaskConfig(marker, positions);
|
||||||
}
|
|
||||||
|
|
||||||
return new BlockConfig(weights, fillMode, mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -22,44 +22,14 @@ public final class WorldGuardConfigLoader {
|
||||||
* Supports any WorldGuard flags. Default: block-break=allow.
|
* Supports any WorldGuard flags. Default: block-break=allow.
|
||||||
*/
|
*/
|
||||||
public WorldGuardConfig parse(YamlConfiguration yaml) {
|
public WorldGuardConfig parse(YamlConfiguration yaml) {
|
||||||
ConfigurationSection wgSection = yaml.getConfigurationSection("worldguard");
|
if (!isEnabled(yaml)) {
|
||||||
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();
|
return WorldGuardConfig.disabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> owners = yaml.getStringList("worldguard.owners");
|
List<String> owners = resolveOwners(yaml);
|
||||||
if (owners.isEmpty()) {
|
List<String> members = resolveMembers(yaml);
|
||||||
owners = defaults.getStringList("worldguard.owners");
|
List<String> flags = resolveFlags(yaml);
|
||||||
}
|
boolean protect = resolveProtect(yaml);
|
||||||
|
|
||||||
List<String> members = yaml.getStringList("worldguard.members");
|
|
||||||
if (members.isEmpty()) {
|
|
||||||
members = defaults.getStringList("worldguard.members");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support any WorldGuard flags. Default: only block-break=allow
|
|
||||||
List<String> flags = yaml.getStringList("worldguard.flags");
|
|
||||||
if (flags.isEmpty()) {
|
|
||||||
flags = defaults.getStringList("worldguard.flags");
|
|
||||||
}
|
|
||||||
if (flags.isEmpty()) {
|
|
||||||
flags = List.of("block-break=allow");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean protect = yaml.getBoolean("worldguard.protect-on-create",
|
|
||||||
defaults.getBoolean("worldguard.protect-on-create", true));
|
|
||||||
|
|
||||||
String tmpl = yaml.getString("worldguard.region-template",
|
String tmpl = yaml.getString("worldguard.region-template",
|
||||||
defaults.getString("worldguard.region-template", "{mine_name}_{random_4}"));
|
defaults.getString("worldguard.region-template", "{mine_name}_{random_4}"));
|
||||||
|
|
||||||
|
|
@ -73,6 +43,50 @@ public final class WorldGuardConfigLoader {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isEnabled(YamlConfiguration yaml) {
|
||||||
|
ConfigurationSection wgSection = yaml.getConfigurationSection("worldguard");
|
||||||
|
if (wgSection == null) {
|
||||||
|
boolean defaultEnabled = defaults.getBoolean("worldguard.enabled", false);
|
||||||
|
if (!defaultEnabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return yaml.getBoolean("worldguard.enabled", defaults.getBoolean("worldguard.enabled", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> resolveOwners(YamlConfiguration yaml) {
|
||||||
|
List<String> owners = yaml.getStringList("worldguard.owners");
|
||||||
|
if (owners.isEmpty()) {
|
||||||
|
owners = defaults.getStringList("worldguard.owners");
|
||||||
|
}
|
||||||
|
return owners;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> resolveMembers(YamlConfiguration yaml) {
|
||||||
|
List<String> members = yaml.getStringList("worldguard.members");
|
||||||
|
if (members.isEmpty()) {
|
||||||
|
members = defaults.getStringList("worldguard.members");
|
||||||
|
}
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> resolveFlags(YamlConfiguration yaml) {
|
||||||
|
// Support any WorldGuard flags. Default: only block-break=allow
|
||||||
|
List<String> flags = yaml.getStringList("worldguard.flags");
|
||||||
|
if (flags.isEmpty()) {
|
||||||
|
flags = defaults.getStringList("worldguard.flags");
|
||||||
|
}
|
||||||
|
if (flags.isEmpty()) {
|
||||||
|
flags = List.of("block-break=allow");
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean resolveProtect(YamlConfiguration yaml) {
|
||||||
|
return yaml.getBoolean("worldguard.protect-on-create",
|
||||||
|
defaults.getBoolean("worldguard.protect-on-create", true));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves WorldGuard configuration to YAML.
|
* Saves WorldGuard configuration to YAML.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,31 @@ public final class RewardConfigLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
private RewardEntry parseRewardEntry(Map<?, ?> map) {
|
private RewardEntry parseRewardEntry(Map<?, ?> map) {
|
||||||
|
List<BlockKey> blocks = parseBlocks(map.get("blocks"));
|
||||||
|
List<ItemReward> items = parseItems(map.get("items"));
|
||||||
|
List<String> commands = parseCommands(map.get("commands"));
|
||||||
|
Object preventDropsObj = map.get("prevent-drops");
|
||||||
|
boolean preventDrops = preventDropsObj instanceof Boolean b && b;
|
||||||
|
|
||||||
|
Object chanceObj = map.get("chance");
|
||||||
|
double chance = chanceObj instanceof Number n ? n.doubleValue() : 0.0;
|
||||||
|
return new RewardEntry(blocks, chance, items, commands, preventDrops);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BlockKey> parseBlocks(Object rawBlocks) {
|
||||||
List<BlockKey> blocks = new ArrayList<>();
|
List<BlockKey> blocks = new ArrayList<>();
|
||||||
List<?> blockList = (List<?>) map.get("blocks");
|
List<?> blockList = (List<?>) rawBlocks;
|
||||||
if (blockList != null) {
|
if (blockList != null) {
|
||||||
for (Object b : blockList) {
|
for (Object b : blockList) {
|
||||||
blocks.add(BlockKey.deserialize(b.toString()));
|
blocks.add(BlockKey.deserialize(b.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ItemReward> parseItems(Object rawItems) {
|
||||||
List<ItemReward> items = new ArrayList<>();
|
List<ItemReward> items = new ArrayList<>();
|
||||||
List<?> itemList = (List<?>) map.get("items");
|
List<?> itemList = (List<?>) rawItems;
|
||||||
if (itemList != null) {
|
if (itemList != null) {
|
||||||
for (Object i : itemList) {
|
for (Object i : itemList) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -53,9 +68,11 @@ public final class RewardConfigLoader {
|
||||||
items.add(parseItemReward(itemMap));
|
items.add(parseItemReward(itemMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> parseCommands(Object commandsObj) {
|
||||||
List<String> commands = new ArrayList<>();
|
List<String> commands = new ArrayList<>();
|
||||||
Object commandsObj = map.get("commands");
|
|
||||||
if (commandsObj instanceof List<?> list) {
|
if (commandsObj instanceof List<?> list) {
|
||||||
for (Object obj : list) {
|
for (Object obj : list) {
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
|
|
@ -63,12 +80,7 @@ public final class RewardConfigLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object preventDropsObj = map.get("prevent-drops");
|
return commands;
|
||||||
boolean preventDrops = preventDropsObj instanceof Boolean b && b;
|
|
||||||
|
|
||||||
Object chanceObj = map.get("chance");
|
|
||||||
double chance = chanceObj instanceof Number n ? n.doubleValue() : 0.0;
|
|
||||||
return new RewardEntry(blocks, chance, items, commands, preventDrops);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemReward parseItemReward(Map<String, Object> map) {
|
private ItemReward parseItemReward(Map<String, Object> map) {
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,13 @@ public final class RewardParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < rewardsList.size(); i++) {
|
for (int i = 0; i < rewardsList.size(); i++) {
|
||||||
Object rewardObj = rewardsList.get(i);
|
rewards.add(parseRewardAt(rewardsList.get(i), i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rewards;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Reward parseRewardAt(Object rewardObj, int i) throws ConfigParseException {
|
||||||
if (!(rewardObj instanceof Map)) {
|
if (!(rewardObj instanceof Map)) {
|
||||||
throw new ConfigParseException(
|
throw new ConfigParseException(
|
||||||
"Invalid reward at index " + i + ": expected map, got " +
|
"Invalid reward at index " + i + ": expected map, got " +
|
||||||
|
|
@ -42,8 +47,7 @@ public final class RewardParser {
|
||||||
Map<String, Object> rewardMap = (Map<String, Object>) rewardObj;
|
Map<String, Object> rewardMap = (Map<String, Object>) rewardObj;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Reward reward = entryParser.parseReward(rewardMap);
|
return entryParser.parseReward(rewardMap);
|
||||||
rewards.add(reward);
|
|
||||||
} catch (ConfigParseException e) {
|
} catch (ConfigParseException e) {
|
||||||
throw new ConfigParseException(
|
throw new ConfigParseException(
|
||||||
"Error parsing reward at index " + i + ": " + e.getMessage(),
|
"Error parsing reward at index " + i + ": " + e.getMessage(),
|
||||||
|
|
@ -51,7 +55,4 @@ public final class RewardParser {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rewards;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,19 @@ public final class StatsPersistence {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String uuidString : playersSection.getKeys(false)) {
|
for (String uuidString : playersSection.getKeys(false)) {
|
||||||
|
loadPlayer(stats, uuidString, playersSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.getLogger().info("Loaded statistics for " + stats.size() + " player(s)");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPlayer(Map<UUID, PlayerStats> stats, String uuidString, ConfigurationSection playersSection) {
|
||||||
try {
|
try {
|
||||||
UUID playerId = UUID.fromString(uuidString);
|
UUID playerId = UUID.fromString(uuidString);
|
||||||
ConfigurationSection playerSection = playersSection.getConfigurationSection(uuidString);
|
ConfigurationSection playerSection = playersSection.getConfigurationSection(uuidString);
|
||||||
|
|
||||||
if (playerSection == null) {
|
if (playerSection == null) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerStats playerStats = stats.computeIfAbsent(playerId, PlayerStats::new);
|
PlayerStats playerStats = stats.computeIfAbsent(playerId, PlayerStats::new);
|
||||||
|
|
@ -68,9 +75,6 @@ public final class StatsPersistence {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.getLogger().info("Loaded statistics for " + stats.size() + " player(s)");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(Map<UUID, PlayerStats> stats) throws IOException {
|
public void save(Map<UUID, PlayerStats> stats) throws IOException {
|
||||||
YamlConfiguration yaml = new YamlConfiguration();
|
YamlConfiguration yaml = new YamlConfiguration();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,20 @@ public final class GroupCreateGui {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreationResult result = createSlots(plugin, player, session, base);
|
||||||
|
if (result.created() == 0) {
|
||||||
|
player.sendMessage(Component.text("Нет готовых слотов (2 точки в каждом).", NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
player.sendMessage(Component.text(
|
||||||
|
"Создано шахт: " + result.created() + (result.skipped() > 0 ? " (пропущено: " + result.skipped() + ")" : ""),
|
||||||
|
NamedTextColor.GREEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
private record CreationResult(int created, int skipped) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CreationResult createSlots(LoMinesPlugin plugin, Player player, GroupWandSession session, String base) {
|
||||||
Mines mines = plugin.getMines();
|
Mines mines = plugin.getMines();
|
||||||
int created = 0;
|
int created = 0;
|
||||||
int skipped = 0;
|
int skipped = 0;
|
||||||
|
|
@ -115,13 +129,6 @@ public final class GroupCreateGui {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return new CreationResult(created, skipped);
|
||||||
if (created == 0) {
|
|
||||||
player.sendMessage(Component.text("Нет готовых слотов (2 точки в каждом).", NamedTextColor.RED));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
player.sendMessage(Component.text(
|
|
||||||
"Создано шахт: " + created + (skipped > 0 ? " (пропущено: " + skipped + ")" : ""),
|
|
||||||
NamedTextColor.GREEN));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,19 +30,32 @@ public final class BlockWeightEditor {
|
||||||
Map<BlockKey, Double> weights = new java.util.HashMap<>(config.weights());
|
Map<BlockKey, Double> weights = new java.util.HashMap<>(config.weights());
|
||||||
double currentWeight = weights.getOrDefault(blockKey, 0.0) * 100.0;
|
double currentWeight = weights.getOrDefault(blockKey, 0.0) * 100.0;
|
||||||
|
|
||||||
double delta = 0;
|
double newWeight = Math.max(0, Math.min(100,
|
||||||
if (leftClick && shiftClick) {
|
currentWeight + computeDelta(leftClick, shiftClick, rightClick)));
|
||||||
delta = 1.0;
|
|
||||||
} else if (rightClick && shiftClick) {
|
applyWeightChange(player, blockKey, weights, newWeight, rightClick, shiftClick);
|
||||||
delta = -1.0;
|
|
||||||
} else if (leftClick) {
|
BlocksGui.refresh(player, player.getOpenInventory().getTopInventory(), mineName, plugin);
|
||||||
delta = 5.0;
|
|
||||||
} else if (rightClick) {
|
|
||||||
delta = -5.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double newWeight = Math.max(0, Math.min(100, currentWeight + delta));
|
private static double computeDelta(boolean leftClick, boolean shiftClick, boolean rightClick) {
|
||||||
|
if (leftClick && shiftClick) {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
if (rightClick && shiftClick) {
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
if (leftClick) {
|
||||||
|
return 5.0;
|
||||||
|
}
|
||||||
|
if (rightClick) {
|
||||||
|
return -5.0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyWeightChange(Player player, BlockKey blockKey, Map<BlockKey, Double> weights,
|
||||||
|
double newWeight, boolean rightClick, boolean shiftClick) {
|
||||||
if (rightClick && shiftClick && newWeight <= 0.1) {
|
if (rightClick && shiftClick && newWeight <= 0.1) {
|
||||||
weights.remove(blockKey);
|
weights.remove(blockKey);
|
||||||
player.sendMessage(Component.text(
|
player.sendMessage(Component.text(
|
||||||
|
|
@ -53,8 +66,6 @@ public final class BlockWeightEditor {
|
||||||
"\u00a7a\u0412\u0435\u0441 \u00a7f" + blockKey.serialize() + " \u00a7a\u0438\u0437\u043c\u0435\u043d\u0435\u043d: \u00a7f"
|
"\u00a7a\u0412\u0435\u0441 \u00a7f" + blockKey.serialize() + " \u00a7a\u0438\u0437\u043c\u0435\u043d\u0435\u043d: \u00a7f"
|
||||||
+ String.format("%.1f%%", newWeight)));
|
+ String.format("%.1f%%", newWeight)));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlocksGui.refresh(player, player.getOpenInventory().getTopInventory(), mineName, plugin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockKey getBlockAtSlot(Inventory inv, int slot, LoMinesPlugin plugin, String mineName) {
|
public static BlockKey getBlockAtSlot(Inventory inv, int slot, LoMinesPlugin plugin, String mineName) {
|
||||||
|
|
|
||||||
|
|
@ -87,14 +87,7 @@ public final class ResetGui {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawSlot == SLOT_MESSAGE) {
|
if (rawSlot == SLOT_MESSAGE) {
|
||||||
if (leftClick) {
|
return handleMessageSlot(plugin, player, mineName, leftClick, rightClick);
|
||||||
player.sendMessage(Component.text("§eВведите сообщение в чат (или 'cancel' для отмены):"));
|
|
||||||
player.closeInventory();
|
|
||||||
} else if (rightClick) {
|
|
||||||
player.sendMessage(Component.text("§cСообщение очищено."));
|
|
||||||
refresh(player, player.getOpenInventory().getTopInventory(), mineName, plugin);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawSlot == SLOT_COMMANDS && leftClick) {
|
if (rawSlot == SLOT_COMMANDS && leftClick) {
|
||||||
|
|
@ -105,6 +98,18 @@ public final class ResetGui {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean handleMessageSlot(LoMinesPlugin plugin, Player player, String mineName,
|
||||||
|
boolean leftClick, boolean rightClick) {
|
||||||
|
if (leftClick) {
|
||||||
|
player.sendMessage(Component.text("§eВведите сообщение в чат (или 'cancel' для отмены):"));
|
||||||
|
player.closeInventory();
|
||||||
|
} else if (rightClick) {
|
||||||
|
player.sendMessage(Component.text("§cСообщение очищено."));
|
||||||
|
refresh(player, player.getOpenInventory().getTopInventory(), mineName, plugin);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static void adjustInterval(LoMinesPlugin plugin, Player player, String mineName,
|
private static void adjustInterval(LoMinesPlugin plugin, Player player, String mineName,
|
||||||
boolean leftClick, boolean rightClick, boolean shiftClick) {
|
boolean leftClick, boolean rightClick, boolean shiftClick) {
|
||||||
int delta = 0;
|
int delta = 0;
|
||||||
|
|
|
||||||
|
|
@ -81,11 +81,11 @@ public final class MineEditGui {
|
||||||
if (rawSlot < 0 || rawSlot >= SIZE) {
|
if (rawSlot < 0 || rawSlot >= SIZE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (rawSlot) {
|
return handleNavigationSlot(plugin, player, mineName, rawSlot);
|
||||||
case SLOT_BACK -> {
|
|
||||||
player.closeInventory();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean handleNavigationSlot(LoMinesPlugin plugin, Player player, String mineName, int rawSlot) {
|
||||||
|
switch (rawSlot) {
|
||||||
case SLOT_BLOCKS -> {
|
case SLOT_BLOCKS -> {
|
||||||
BlocksGui.open(plugin, player, mineName);
|
BlocksGui.open(plugin, player, mineName);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -98,6 +98,22 @@ public final class MineEditGui {
|
||||||
RewardsGui.open(plugin, player, mineName);
|
RewardsGui.open(plugin, player, mineName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case SLOT_DELETE -> {
|
||||||
|
ConfirmDeleteGui.open(plugin, player, mineName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
return handleInfoSlot(player, mineName, rawSlot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean handleInfoSlot(Player player, String mineName, int rawSlot) {
|
||||||
|
switch (rawSlot) {
|
||||||
|
case SLOT_BACK -> {
|
||||||
|
player.closeInventory();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
case SLOT_TELEPORT -> {
|
case SLOT_TELEPORT -> {
|
||||||
player.sendMessage(Component.text("Используйте команды /lm setteleport и /lm setspawn", NamedTextColor.YELLOW));
|
player.sendMessage(Component.text("Используйте команды /lm setteleport и /lm setspawn", NamedTextColor.YELLOW));
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -111,10 +127,6 @@ public final class MineEditGui {
|
||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case SLOT_DELETE -> {
|
|
||||||
ConfirmDeleteGui.open(plugin, player, mineName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case SLOT_INFO, SLOT_REGIONS -> {
|
case SLOT_INFO, SLOT_REGIONS -> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,14 @@ public final class WorldGuardRegionService {
|
||||||
}
|
}
|
||||||
String regionName = wgConfig.generateRegionName(mineName);
|
String regionName = wgConfig.generateRegionName(mineName);
|
||||||
try {
|
try {
|
||||||
|
return createRegionInManager(mineName, config, regionName, wgConfig);
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.getLogger().severe("Failed to create WorldGuard region for mine " + mineName + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createRegionInManager(String mineName, MineConfig config, String regionName, WorldGuardConfig wgConfig) {
|
||||||
RegionManager regionManager = getRegionManager(config.worldName());
|
RegionManager regionManager = getRegionManager(config.worldName());
|
||||||
if (regionManager == null) {
|
if (regionManager == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -63,10 +71,6 @@ public final class WorldGuardRegionService {
|
||||||
regionManager.addRegion(region);
|
regionManager.addRegion(region);
|
||||||
plugin.getLogger().info("Created WorldGuard region '" + regionName + "' for mine " + mineName);
|
plugin.getLogger().info("Created WorldGuard region '" + regionName + "' for mine " + mineName);
|
||||||
return regionName;
|
return regionName;
|
||||||
} catch (Exception e) {
|
|
||||||
plugin.getLogger().severe("Failed to create WorldGuard region for mine " + mineName + ": " + e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean updateRegion(String mineName, MineConfig config) {
|
public boolean updateRegion(String mineName, MineConfig config) {
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,17 @@ public final class PlayerInteractListener implements Listener {
|
||||||
|
|
||||||
if (action == Action.LEFT_CLICK_BLOCK && event.hasBlock()) {
|
if (action == Action.LEFT_CLICK_BLOCK && event.hasBlock()) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
Block block = event.getClickedBlock();
|
handleLeftClick(player, event.getClickedBlock());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == Action.RIGHT_CLICK_BLOCK && !player.isSneaking()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
handleRightClick(player, event.getClickedBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleLeftClick(Player player, Block block) {
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -60,12 +70,9 @@ public final class PlayerInteractListener implements Listener {
|
||||||
|
|
||||||
// Start showing particles when selection is made
|
// Start showing particles when selection is made
|
||||||
plugin.getWandParticleService().startShowingParticles(player);
|
plugin.getWandParticleService().startShowingParticles(player);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == Action.RIGHT_CLICK_BLOCK && !player.isSneaking()) {
|
private void handleRightClick(Player player, Block block) {
|
||||||
event.setCancelled(true);
|
|
||||||
Block block = event.getClickedBlock();
|
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +85,6 @@ public final class PlayerInteractListener implements Listener {
|
||||||
// Start showing particles when selection is made
|
// Start showing particles when selection is made
|
||||||
plugin.getWandParticleService().startShowingParticles(player);
|
plugin.getWandParticleService().startShowingParticles(player);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts/stops particle visualization when player switches items.
|
* Starts/stops particle visualization when player switches items.
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ public final class LocationParser {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return buildLocation(matcher, locationString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Location buildLocation(Matcher matcher, String locationString) throws ConfigParseException {
|
||||||
try {
|
try {
|
||||||
String worldName = matcher.group(1);
|
String worldName = matcher.group(1);
|
||||||
double x = Double.parseDouble(matcher.group(2));
|
double x = Double.parseDouble(matcher.group(2));
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@ public final class SafeTeleportUtil {
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return findFallbackSafe(world, x, y, z, yaw, pitch, maxUpOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Location findFallbackSafe(World world, int x, int y, int z, float yaw, float pitch, int maxUpOffset) {
|
||||||
Location result = findNearbySafe(world, x, y, z, yaw, pitch);
|
Location result = findNearbySafe(world, x, y, z, yaw, pitch);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@ import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
|
|
||||||
|
|
@ -10,41 +10,47 @@ import dev.loki.lomines.util.location.geo.Cuboid;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for Mine class, specifically testing BlockSetter creation logic.
|
* Unit tests for Mine class, specifically testing BlockSetter creation logic.
|
||||||
*/
|
*/
|
||||||
@Disabled("Paper API RegistryAccess not available in unit tests")
|
|
||||||
class MineTest {
|
class MineTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private LoMinesPlugin plugin;
|
private LoMinesPlugin plugin;
|
||||||
|
|
||||||
@Mock
|
private ServerMock server;
|
||||||
private World world;
|
private World world;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
MockitoAnnotations.openMocks(this);
|
MockitoAnnotations.openMocks(this);
|
||||||
when(world.getName()).thenReturn("world");
|
server = MockBukkit.mock();
|
||||||
|
server.addSimpleWorld("world");
|
||||||
|
world = server.getWorld("world");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
MockBukkit.unmock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateBlockSetter_WithOraxenPrefix_CreatesBukkitBlockSetter() {
|
void testCreateBlockSetterWithOraxenPrefixCreatesBukkitBlockSetter() {
|
||||||
// Oraxen integration is disabled — constructor throws IllegalArgumentException
|
// Oraxen integration is disabled — constructor throws IllegalArgumentException
|
||||||
Map<BlockKey, Double> blocks = new HashMap<>();
|
Map<BlockKey, Double> blocks = new HashMap<>();
|
||||||
blocks.put(new BlockKey.Oraxen("custom_ore"), 50.0);
|
blocks.put(new BlockKey.Oraxen("custom_ore"), 50.0);
|
||||||
|
|
@ -59,7 +65,7 @@ class MineTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateBlockSetter_WithItemsAdderPrefix_CreatesBukkitBlockSetter() {
|
void testCreateBlockSetterWithItemsAdderPrefixCreatesBukkitBlockSetter() {
|
||||||
// ItemsAdder integration is disabled — constructor throws IllegalArgumentException
|
// ItemsAdder integration is disabled — constructor throws IllegalArgumentException
|
||||||
Map<BlockKey, Double> blocks = new HashMap<>();
|
Map<BlockKey, Double> blocks = new HashMap<>();
|
||||||
blocks.put(new BlockKey.ItemsAdder("custom_block"), 60.0);
|
blocks.put(new BlockKey.ItemsAdder("custom_block"), 60.0);
|
||||||
|
|
@ -73,7 +79,7 @@ class MineTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateBlockSetter_WithoutPrefix_CreatesBukkitBlockSetter() {
|
void testCreateBlockSetterWithoutPrefixCreatesBukkitBlockSetter() {
|
||||||
Map<BlockKey, Double> blocks = new HashMap<>();
|
Map<BlockKey, Double> blocks = new HashMap<>();
|
||||||
blocks.put(new BlockKey.Vanilla(Material.STONE), 50.0);
|
blocks.put(new BlockKey.Vanilla(Material.STONE), 50.0);
|
||||||
blocks.put(new BlockKey.Vanilla(Material.COAL_ORE), 30.0);
|
blocks.put(new BlockKey.Vanilla(Material.COAL_ORE), 30.0);
|
||||||
|
|
@ -89,7 +95,7 @@ class MineTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateBlockSetter_WithEmptyBlocks_ThrowsException() {
|
void testCreateBlockSetterWithEmptyBlocksThrowsException() {
|
||||||
Map<BlockKey, Double> blocks = new HashMap<>();
|
Map<BlockKey, Double> blocks = new HashMap<>();
|
||||||
|
|
||||||
assertThrows(
|
assertThrows(
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@ class MineTickerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testConstruction_WithValidParameters_DoesNotThrow() {
|
void testConstructionWithValidParametersDoesNotThrow() {
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
assertDoesNotThrow(() -> new MineTicker(mines, plugin));
|
assertDoesNotThrow(() -> new MineTicker(mines, plugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testStop_WhenNotRunning_DoesNotThrow() {
|
void testStopWhenNotRunningDoesNotThrow() {
|
||||||
// Arrange
|
// Arrange
|
||||||
MineTicker ticker = new MineTicker(mines, plugin);
|
MineTicker ticker = new MineTicker(mines, plugin);
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ class MineTickerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMultipleStops_DoNotThrow() {
|
void testMultipleStopsDoNotThrow() {
|
||||||
// Arrange
|
// Arrange
|
||||||
MineTicker ticker = new MineTicker(mines, plugin);
|
MineTicker ticker = new MineTicker(mines, plugin);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,12 @@ package dev.loki.lomines.core;
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.core.mine.model.Mine;
|
import dev.loki.lomines.core.mine.model.Mine;
|
||||||
import dev.loki.lomines.core.mine.registry.Mines;
|
import dev.loki.lomines.core.mine.registry.Mines;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
@ -23,19 +16,13 @@ import java.nio.file.Path;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.mockStatic;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@Disabled("WorldGuard dependency not available in unit tests")
|
|
||||||
class MinesLifecycleTest {
|
class MinesLifecycleTest {
|
||||||
|
|
||||||
@TempDir
|
@TempDir
|
||||||
|
|
@ -43,43 +30,25 @@ class MinesLifecycleTest {
|
||||||
|
|
||||||
private Mines mines;
|
private Mines mines;
|
||||||
private LoMinesPlugin plugin;
|
private LoMinesPlugin plugin;
|
||||||
private BukkitScheduler scheduler;
|
private ServerMock server;
|
||||||
private MockedStatic<Bukkit> globalBukkit;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
globalBukkit = mockStatic(Bukkit.class);
|
server = MockBukkit.mock();
|
||||||
|
server.addSimpleWorld("world");
|
||||||
org.bukkit.plugin.PluginManager pluginManager = mock(org.bukkit.plugin.PluginManager.class);
|
|
||||||
Server server = mock(Server.class);
|
|
||||||
World world = mock(World.class);
|
|
||||||
BlockData blockData = mock(BlockData.class);
|
|
||||||
|
|
||||||
globalBukkit.when(Bukkit::getPluginManager).thenReturn(pluginManager);
|
|
||||||
globalBukkit.when(Bukkit::getServer).thenReturn(server);
|
|
||||||
globalBukkit.when(() -> Bukkit.getWorld(anyString())).thenReturn(world);
|
|
||||||
globalBukkit.when(() -> Bukkit.createBlockData(any(Material.class))).thenReturn(blockData);
|
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
|
|
||||||
plugin = mock(LoMinesPlugin.class);
|
plugin = mock(LoMinesPlugin.class);
|
||||||
Logger logger = mock(Logger.class);
|
Logger logger = mock(Logger.class);
|
||||||
scheduler = mock(BukkitScheduler.class);
|
|
||||||
|
|
||||||
when(plugin.getDataFolder()).thenReturn(tempDir.toFile());
|
when(plugin.getDataFolder()).thenReturn(tempDir.toFile());
|
||||||
when(plugin.getLogger()).thenReturn(logger);
|
when(plugin.getLogger()).thenReturn(logger);
|
||||||
|
|
||||||
globalBukkit.when(Bukkit::getScheduler).thenReturn(scheduler);
|
|
||||||
BukkitTask task = mock(BukkitTask.class);
|
|
||||||
when(scheduler.runTaskTimer(any(), any(Runnable.class), anyLong(), anyLong())).thenReturn(task);
|
|
||||||
|
|
||||||
mines = new Mines(plugin);
|
mines = new Mines(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void tearDown() {
|
void tearDown() {
|
||||||
if (globalBukkit != null) {
|
MockBukkit.unmock();
|
||||||
globalBukkit.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -97,9 +66,9 @@ class MinesLifecycleTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateMineCreatesFolder() throws IOException {
|
void testCreateMineCreatesFolder() throws IOException {
|
||||||
assertFalse(Files.exists(tempDir.resolve("mines")));
|
|
||||||
mines.create("testmine");
|
|
||||||
assertTrue(Files.isDirectory(tempDir.resolve("mines")));
|
assertTrue(Files.isDirectory(tempDir.resolve("mines")));
|
||||||
|
mines.create("testmine");
|
||||||
|
assertTrue(Files.exists(tempDir.resolve("mines/testmine.yml")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,12 @@ package dev.loki.lomines.core;
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.core.mine.model.Mine;
|
import dev.loki.lomines.core.mine.model.Mine;
|
||||||
import dev.loki.lomines.core.mine.registry.Mines;
|
import dev.loki.lomines.core.mine.registry.Mines;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
@ -25,15 +18,9 @@ import java.util.logging.Logger;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.mockStatic;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@Disabled("WorldGuard dependency not available in unit tests")
|
|
||||||
class MinesLoadingTest {
|
class MinesLoadingTest {
|
||||||
|
|
||||||
private static final String FULL_YAML = """
|
private static final String FULL_YAML = """
|
||||||
|
|
@ -61,43 +48,25 @@ class MinesLoadingTest {
|
||||||
|
|
||||||
private Mines mines;
|
private Mines mines;
|
||||||
private LoMinesPlugin plugin;
|
private LoMinesPlugin plugin;
|
||||||
private BukkitScheduler scheduler;
|
private ServerMock server;
|
||||||
private MockedStatic<Bukkit> globalBukkit;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
globalBukkit = mockStatic(Bukkit.class);
|
server = MockBukkit.mock();
|
||||||
|
server.addSimpleWorld("world");
|
||||||
org.bukkit.plugin.PluginManager pluginManager = mock(org.bukkit.plugin.PluginManager.class);
|
|
||||||
Server server = mock(Server.class);
|
|
||||||
World world = mock(World.class);
|
|
||||||
BlockData blockData = mock(BlockData.class);
|
|
||||||
|
|
||||||
globalBukkit.when(Bukkit::getPluginManager).thenReturn(pluginManager);
|
|
||||||
globalBukkit.when(Bukkit::getServer).thenReturn(server);
|
|
||||||
globalBukkit.when(() -> Bukkit.getWorld(anyString())).thenReturn(world);
|
|
||||||
globalBukkit.when(() -> Bukkit.createBlockData(any(Material.class))).thenReturn(blockData);
|
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
|
|
||||||
plugin = mock(LoMinesPlugin.class);
|
plugin = mock(LoMinesPlugin.class);
|
||||||
Logger logger = mock(Logger.class);
|
Logger logger = mock(Logger.class);
|
||||||
scheduler = mock(BukkitScheduler.class);
|
|
||||||
|
|
||||||
when(plugin.getDataFolder()).thenReturn(tempDir.toFile());
|
when(plugin.getDataFolder()).thenReturn(tempDir.toFile());
|
||||||
when(plugin.getLogger()).thenReturn(logger);
|
when(plugin.getLogger()).thenReturn(logger);
|
||||||
|
|
||||||
globalBukkit.when(Bukkit::getScheduler).thenReturn(scheduler);
|
|
||||||
BukkitTask task = mock(BukkitTask.class);
|
|
||||||
when(scheduler.runTaskTimer(any(), any(Runnable.class), anyLong(), anyLong())).thenReturn(task);
|
|
||||||
|
|
||||||
mines = new Mines(plugin);
|
mines = new Mines(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void tearDown() {
|
void tearDown() {
|
||||||
if (globalBukkit != null) {
|
MockBukkit.unmock();
|
||||||
globalBukkit.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,13 @@
|
||||||
package dev.loki.lomines.core;
|
package dev.loki.lomines.core;
|
||||||
|
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.core.mine.model.Mine;
|
|
||||||
import dev.loki.lomines.core.mine.registry.Mines;
|
import dev.loki.lomines.core.mine.registry.Mines;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.plugin.PluginManager;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
@ -25,19 +16,15 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.mockStatic;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for Mines registry.
|
* Unit tests for Mines registry.
|
||||||
*/
|
*/
|
||||||
@Disabled("WorldGuard dependency not available in unit tests")
|
|
||||||
class MinesTest {
|
class MinesTest {
|
||||||
|
|
||||||
@TempDir
|
@TempDir
|
||||||
|
|
@ -45,43 +32,25 @@ class MinesTest {
|
||||||
|
|
||||||
private Mines mines;
|
private Mines mines;
|
||||||
private LoMinesPlugin plugin;
|
private LoMinesPlugin plugin;
|
||||||
private BukkitScheduler scheduler;
|
private ServerMock server;
|
||||||
private MockedStatic<Bukkit> globalBukkit;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
globalBukkit = mockStatic(Bukkit.class);
|
server = MockBukkit.mock();
|
||||||
|
server.addSimpleWorld("world");
|
||||||
PluginManager pluginManager = mock(PluginManager.class);
|
|
||||||
Server server = mock(Server.class);
|
|
||||||
World world = mock(World.class);
|
|
||||||
BlockData blockData = mock(BlockData.class);
|
|
||||||
|
|
||||||
globalBukkit.when(Bukkit::getPluginManager).thenReturn(pluginManager);
|
|
||||||
globalBukkit.when(Bukkit::getServer).thenReturn(server);
|
|
||||||
globalBukkit.when(() -> Bukkit.getWorld(anyString())).thenReturn(world);
|
|
||||||
globalBukkit.when(() -> Bukkit.createBlockData(any(Material.class))).thenReturn(blockData);
|
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
|
|
||||||
plugin = mock(LoMinesPlugin.class);
|
plugin = mock(LoMinesPlugin.class);
|
||||||
Logger logger = mock(Logger.class);
|
Logger logger = mock(Logger.class);
|
||||||
scheduler = mock(BukkitScheduler.class);
|
|
||||||
|
|
||||||
when(plugin.getDataFolder()).thenReturn(tempDir.toFile());
|
when(plugin.getDataFolder()).thenReturn(tempDir.toFile());
|
||||||
when(plugin.getLogger()).thenReturn(logger);
|
when(plugin.getLogger()).thenReturn(logger);
|
||||||
|
|
||||||
globalBukkit.when(Bukkit::getScheduler).thenReturn(scheduler);
|
|
||||||
BukkitTask task = mock(BukkitTask.class);
|
|
||||||
when(scheduler.runTaskTimer(any(), any(Runnable.class), anyLong(), anyLong())).thenReturn(task);
|
|
||||||
|
|
||||||
mines = new Mines(plugin);
|
mines = new Mines(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void tearDown() {
|
void tearDown() {
|
||||||
if (globalBukkit != null) {
|
MockBukkit.unmock();
|
||||||
globalBukkit.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class LeaderboardPositionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetPosition_ReturnsCorrectPosition() {
|
void testGetPositionReturnsCorrectPosition() {
|
||||||
UUID player1 = UUID.randomUUID();
|
UUID player1 = UUID.randomUUID();
|
||||||
UUID player2 = UUID.randomUUID();
|
UUID player2 = UUID.randomUUID();
|
||||||
UUID player3 = UUID.randomUUID();
|
UUID player3 = UUID.randomUUID();
|
||||||
|
|
@ -45,13 +45,13 @@ class LeaderboardPositionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetPosition_ReturnsMinusOneForNonExistentPlayer() {
|
void testGetPositionReturnsMinusOneForNonExistentPlayer() {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
assertEquals(-1, leaderboard.getPosition(playerId), "Should return -1 for non-existent player");
|
assertEquals(-1, leaderboard.getPosition(playerId), "Should return -1 for non-existent player");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetPosition_ReturnsMinusOneForZeroBlocks() {
|
void testGetPositionReturnsMinusOneForZeroBlocks() {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
statsManager.getOrCreate(playerId).setTotalBlocks(0);
|
statsManager.getOrCreate(playerId).setTotalBlocks(0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class LeaderboardQueryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopByMine_SortedDescending() {
|
void testGetTopByMineSortedDescending() {
|
||||||
UUID player1 = UUID.randomUUID();
|
UUID player1 = UUID.randomUUID();
|
||||||
UUID player2 = UUID.randomUUID();
|
UUID player2 = UUID.randomUUID();
|
||||||
UUID player3 = UUID.randomUUID();
|
UUID player3 = UUID.randomUUID();
|
||||||
|
|
@ -49,7 +49,7 @@ class LeaderboardQueryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopByMine_FiltersZeroBlocks() {
|
void testGetTopByMineFiltersZeroBlocks() {
|
||||||
UUID player1 = UUID.randomUUID();
|
UUID player1 = UUID.randomUUID();
|
||||||
UUID player2 = UUID.randomUUID();
|
UUID player2 = UUID.randomUUID();
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ class LeaderboardQueryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopByMine_OnlyIncludesSpecificMine() {
|
void testGetTopByMineOnlyIncludesSpecificMine() {
|
||||||
UUID player1 = UUID.randomUUID();
|
UUID player1 = UUID.randomUUID();
|
||||||
UUID player2 = UUID.randomUUID();
|
UUID player2 = UUID.randomUUID();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,13 @@ class LeaderboardTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopTotal_EmptyStats() {
|
void testGetTopTotalEmptyStats() {
|
||||||
List<LeaderboardEntry> top = leaderboard.getTopTotal(10);
|
List<LeaderboardEntry> top = leaderboard.getTopTotal(10);
|
||||||
assertTrue(top.isEmpty(), "Top list should be empty when no stats exist");
|
assertTrue(top.isEmpty(), "Top list should be empty when no stats exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopTotal_SinglePlayer() {
|
void testGetTopTotalSinglePlayer() {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
PlayerStats stats = statsManager.getOrCreate(playerId);
|
PlayerStats stats = statsManager.getOrCreate(playerId);
|
||||||
stats.setTotalBlocks(100);
|
stats.setTotalBlocks(100);
|
||||||
|
|
@ -57,7 +57,7 @@ class LeaderboardTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopTotal_SortedDescending() {
|
void testGetTopTotalSortedDescending() {
|
||||||
UUID player1 = UUID.randomUUID();
|
UUID player1 = UUID.randomUUID();
|
||||||
UUID player2 = UUID.randomUUID();
|
UUID player2 = UUID.randomUUID();
|
||||||
UUID player3 = UUID.randomUUID();
|
UUID player3 = UUID.randomUUID();
|
||||||
|
|
@ -74,7 +74,7 @@ class LeaderboardTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopTotal_LimitRespected() {
|
void testGetTopTotalLimitRespected() {
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
statsManager.getOrCreate(playerId).setTotalBlocks(i + 1);
|
statsManager.getOrCreate(playerId).setTotalBlocks(i + 1);
|
||||||
|
|
@ -85,7 +85,7 @@ class LeaderboardTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopTotal_FiltersZeroBlocks() {
|
void testGetTopTotalFiltersZeroBlocks() {
|
||||||
UUID player1 = UUID.randomUUID();
|
UUID player1 = UUID.randomUUID();
|
||||||
UUID player2 = UUID.randomUUID();
|
UUID player2 = UUID.randomUUID();
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ class LeaderboardTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetTopTotal_CachingWorks() {
|
void testGetTopTotalCachingWorks() {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
statsManager.getOrCreate(playerId).setTotalBlocks(100);
|
statsManager.getOrCreate(playerId).setTotalBlocks(100);
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ class LeaderboardTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInvalidateCache_ClearsCache() {
|
void testInvalidateCacheClearsCache() {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
statsManager.getOrCreate(playerId).setTotalBlocks(100);
|
statsManager.getOrCreate(playerId).setTotalBlocks(100);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package dev.loki.lomines.data;
|
package dev.loki.lomines.data;
|
||||||
|
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.data.stats.model.PlayerStats;
|
|
||||||
import dev.loki.lomines.data.stats.service.StatsManager;
|
import dev.loki.lomines.data.stats.service.StatsManager;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
|
|
@ -11,7 +10,6 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package dev.loki.lomines.data;
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.data.stats.model.PlayerStats;
|
import dev.loki.lomines.data.stats.model.PlayerStats;
|
||||||
import dev.loki.lomines.data.stats.service.StatsManager;
|
import dev.loki.lomines.data.stats.service.StatsManager;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.mockito.MockedStatic;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ import dev.loki.lomines.data.config.reset.ResetConfig;
|
||||||
import dev.loki.lomines.data.config.reward.RewardConfig;
|
import dev.loki.lomines.data.config.reward.RewardConfig;
|
||||||
import dev.loki.lomines.data.config.teleport.TeleportConfig;
|
import dev.loki.lomines.data.config.teleport.TeleportConfig;
|
||||||
import dev.loki.lomines.data.config.ui.UIConfig;
|
import dev.loki.lomines.data.config.ui.UIConfig;
|
||||||
import dev.loki.lomines.util.location.geo.Cuboid;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
import org.mockito.Mockito;
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -25,26 +25,40 @@ import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@Disabled("Paper API RegistryAccess not available in unit tests")
|
|
||||||
class MineConfigTest {
|
class MineConfigTest {
|
||||||
|
|
||||||
|
private ServerMock server;
|
||||||
|
private World world;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
server = MockBukkit.mock();
|
||||||
|
server.addSimpleWorld("world");
|
||||||
|
world = server.getWorld("world");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
MockBukkit.unmock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegionConfig testRegion() {
|
||||||
|
Location loc1 = new Location(world, 0, 64, 0);
|
||||||
|
Location loc2 = new Location(world, 10, 74, 10);
|
||||||
|
return RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockConfig testBlocks() {
|
||||||
|
Map<BlockKey, Double> weights = new HashMap<>();
|
||||||
|
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||||
|
return new BlockConfig(weights, FillMode.CUBOID, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBuilder() {
|
void testBuilder() {
|
||||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
RegionConfig region = testRegion();
|
||||||
World world = mock(World.class);
|
BlockConfig blocks = testBlocks();
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
|
||||||
|
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
|
||||||
Location loc2 = new Location(world, 10, 74, 10);
|
|
||||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
|
||||||
|
|
||||||
Map<BlockKey, Double> weights = new HashMap<>();
|
|
||||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
|
||||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
|
||||||
|
|
||||||
MineConfig config = MineConfig.builder("testmine")
|
MineConfig config = MineConfig.builder("testmine")
|
||||||
.region(region)
|
.region(region)
|
||||||
|
|
@ -59,22 +73,11 @@ class MineConfigTest {
|
||||||
assertEquals(1, config.region().regionCount());
|
assertEquals(1, config.region().regionCount());
|
||||||
assertEquals(1, config.blocks().blockCount());
|
assertEquals(1, config.blocks().blockCount());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDefaultsFactory() {
|
void testDefaultsFactory() {
|
||||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
RegionConfig region = testRegion();
|
||||||
World world = mock(World.class);
|
BlockConfig blocks = testBlocks();
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
|
||||||
|
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
|
||||||
Location loc2 = new Location(world, 10, 74, 10);
|
|
||||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
|
||||||
|
|
||||||
Map<BlockKey, Double> weights = new HashMap<>();
|
|
||||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
|
||||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
|
||||||
|
|
||||||
MineConfig config = MineConfigDefaults.defaults("mymine", region, blocks);
|
MineConfig config = MineConfigDefaults.defaults("mymine", region, blocks);
|
||||||
|
|
||||||
|
|
@ -84,22 +87,11 @@ class MineConfigTest {
|
||||||
assertNotNull(config.teleport());
|
assertNotNull(config.teleport());
|
||||||
assertNotNull(config.ui());
|
assertNotNull(config.ui());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNameNormalized() {
|
void testNameNormalized() {
|
||||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
RegionConfig region = testRegion();
|
||||||
World world = mock(World.class);
|
BlockConfig blocks = testBlocks();
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
|
||||||
|
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
|
||||||
Location loc2 = new Location(world, 10, 74, 10);
|
|
||||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
|
||||||
|
|
||||||
Map<BlockKey, Double> weights = new HashMap<>();
|
|
||||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
|
||||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
|
||||||
|
|
||||||
MineConfig config = MineConfig.builder("TestMine_123 ")
|
MineConfig config = MineConfig.builder("TestMine_123 ")
|
||||||
.region(region)
|
.region(region)
|
||||||
|
|
@ -108,22 +100,15 @@ class MineConfigTest {
|
||||||
|
|
||||||
assertEquals("testmine_123", config.name());
|
assertEquals("testmine_123", config.name());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testWorldNameDelegation() {
|
void testWorldNameDelegation() {
|
||||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
server.addSimpleWorld("nether");
|
||||||
World world = mock(World.class);
|
World nether = server.getWorld("nether");
|
||||||
when(world.getName()).thenReturn("nether");
|
Location loc1 = new Location(nether, 0, 64, 0);
|
||||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("nether")).thenReturn(world);
|
Location loc2 = new Location(nether, 10, 74, 10);
|
||||||
|
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
|
||||||
Location loc2 = new Location(world, 10, 74, 10);
|
|
||||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||||
|
BlockConfig blocks = testBlocks();
|
||||||
Map<BlockKey, Double> weights = new HashMap<>();
|
|
||||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
|
||||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
|
||||||
|
|
||||||
MineConfig config = MineConfig.builder("test")
|
MineConfig config = MineConfig.builder("test")
|
||||||
.region(region)
|
.region(region)
|
||||||
|
|
@ -132,5 +117,4 @@ class MineConfigTest {
|
||||||
|
|
||||||
assertEquals("nether", config.worldName());
|
assertEquals("nether", config.worldName());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,47 @@ import dev.loki.lomines.data.config.region.RegionConfig;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
import org.mockito.Mockito;
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
class MineConfigValidationTest {
|
class MineConfigValidationTest {
|
||||||
|
|
||||||
|
private ServerMock server;
|
||||||
|
private World world;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
server = MockBukkit.mock();
|
||||||
|
server.addSimpleWorld("world");
|
||||||
|
world = server.getWorld("world");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
MockBukkit.unmock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegionConfig testRegion() {
|
||||||
|
Location loc1 = new Location(world, 0, 64, 0);
|
||||||
|
Location loc2 = new Location(world, 10, 74, 10);
|
||||||
|
return RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockConfig testBlocks() {
|
||||||
|
Map<BlockKey, Double> weights = new HashMap<>();
|
||||||
|
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||||
|
return new BlockConfig(weights, FillMode.CUBOID, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNullNameThrows() {
|
void testNullNameThrows() {
|
||||||
assertThrows(NullPointerException.class, () ->
|
assertThrows(NullPointerException.class, () ->
|
||||||
|
|
@ -30,20 +56,9 @@ class MineConfigValidationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled("Paper API RegistryAccess not available in unit tests")
|
|
||||||
void testBlankNameThrows() {
|
void testBlankNameThrows() {
|
||||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
RegionConfig region = testRegion();
|
||||||
World world = mock(World.class);
|
BlockConfig blocks = testBlocks();
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
|
||||||
|
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
|
||||||
Location loc2 = new Location(world, 10, 74, 10);
|
|
||||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
|
||||||
|
|
||||||
Map<BlockKey, Double> weights = new HashMap<>();
|
|
||||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
|
||||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
|
||||||
|
|
||||||
assertThrows(IllegalArgumentException.class, () ->
|
assertThrows(IllegalArgumentException.class, () ->
|
||||||
MineConfig.builder(" ")
|
MineConfig.builder(" ")
|
||||||
|
|
@ -51,14 +66,10 @@ class MineConfigValidationTest {
|
||||||
.blocks(blocks)
|
.blocks(blocks)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled("Paper API RegistryAccess not available in unit tests")
|
|
||||||
void testNullRegionThrows() {
|
void testNullRegionThrows() {
|
||||||
Map<BlockKey, Double> weights = new HashMap<>();
|
BlockConfig blocks = testBlocks();
|
||||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
|
||||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
|
||||||
|
|
||||||
assertThrows(NullPointerException.class, () ->
|
assertThrows(NullPointerException.class, () ->
|
||||||
MineConfig.builder("test")
|
MineConfig.builder("test")
|
||||||
|
|
@ -69,14 +80,7 @@ class MineConfigValidationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNullBlocksThrows() {
|
void testNullBlocksThrows() {
|
||||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
RegionConfig region = testRegion();
|
||||||
World world = mock(World.class);
|
|
||||||
when(world.getName()).thenReturn("world");
|
|
||||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
|
||||||
|
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
|
||||||
Location loc2 = new Location(world, 10, 74, 10);
|
|
||||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
|
||||||
|
|
||||||
assertThrows(NullPointerException.class, () ->
|
assertThrows(NullPointerException.class, () ->
|
||||||
MineConfig.builder("test")
|
MineConfig.builder("test")
|
||||||
|
|
@ -84,5 +88,4 @@ class MineConfigValidationTest {
|
||||||
.blocks(null)
|
.blocks(null)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
package dev.loki.lomines.data.config.block;
|
package dev.loki.lomines.data.config.block;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -13,9 +16,20 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
@Disabled("Paper API RegistryAccess not available in unit tests")
|
|
||||||
class BlockConfigTest {
|
class BlockConfigTest {
|
||||||
|
|
||||||
|
private ServerMock server;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
server = MockBukkit.mock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
MockBukkit.unmock();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testValidConfig() {
|
void testValidConfig() {
|
||||||
Map<BlockKey, Double> weights = new HashMap<>();
|
Map<BlockKey, Double> weights = new HashMap<>();
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,31 @@
|
||||||
package dev.loki.lomines.data.config.block;
|
package dev.loki.lomines.data.config.block;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.ServerMock;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
@Disabled("Paper API RegistryAccess not available in unit tests")
|
|
||||||
class BlockKeyTest {
|
class BlockKeyTest {
|
||||||
|
|
||||||
|
private ServerMock server;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
server = MockBukkit.mock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
MockBukkit.unmock();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testVanillaSerialization() {
|
void testVanillaSerialization() {
|
||||||
BlockKey.Vanilla stone = new BlockKey.Vanilla(Material.STONE);
|
BlockKey.Vanilla stone = new BlockKey.Vanilla(Material.STONE);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
class UIConfigTest {
|
class UIConfigTest {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import java.util.Collections;
|
||||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.atLeast;
|
import static org.mockito.Mockito.atLeast;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
@ -38,7 +37,7 @@ class ChunkUtilsRefreshTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUpdateChunks_withLargeRegion() {
|
void testUpdateChunksWithLargeRegion() {
|
||||||
Location loc1 = new Location(world, 0, 0, 0);
|
Location loc1 = new Location(world, 0, 0, 0);
|
||||||
Location loc2 = new Location(world, 100, 100, 100);
|
Location loc2 = new Location(world, 100, 100, 100);
|
||||||
when(world.getChunkAt(anyInt(), anyInt())).thenReturn(chunk);
|
when(world.getChunkAt(anyInt(), anyInt())).thenReturn(chunk);
|
||||||
|
|
@ -52,7 +51,7 @@ class ChunkUtilsRefreshTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUpdateChunks_withNoPlayers() {
|
void testUpdateChunksWithNoPlayers() {
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
Location loc1 = new Location(world, 0, 64, 0);
|
||||||
Location loc2 = new Location(world, 5, 70, 5);
|
Location loc2 = new Location(world, 5, 70, 5);
|
||||||
when(world.getChunkAt(anyInt(), anyInt())).thenReturn(chunk);
|
when(world.getChunkAt(anyInt(), anyInt())).thenReturn(chunk);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.atLeast;
|
import static org.mockito.Mockito.atLeast;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
@ -43,14 +42,14 @@ class ChunkUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUpdateChunks_withNullRegion_throwsException() {
|
void testUpdateChunksWithNullRegionThrowsException() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
ChunkUtils.updateChunks(null);
|
ChunkUtils.updateChunks(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUpdateChunks_withSingleChunkRegion() {
|
void testUpdateChunksWithSingleChunkRegion() {
|
||||||
// Create a small region within a single chunk
|
// Create a small region within a single chunk
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
Location loc1 = new Location(world, 0, 64, 0);
|
||||||
Location loc2 = new Location(world, 5, 70, 5);
|
Location loc2 = new Location(world, 5, 70, 5);
|
||||||
|
|
@ -69,7 +68,7 @@ class ChunkUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUpdateChunks_withMultipleChunks() {
|
void testUpdateChunksWithMultipleChunks() {
|
||||||
// Create a region spanning multiple chunks (16 blocks per chunk)
|
// Create a region spanning multiple chunks (16 blocks per chunk)
|
||||||
Location loc1 = new Location(world, 0, 64, 0);
|
Location loc1 = new Location(world, 0, 64, 0);
|
||||||
Location loc2 = new Location(world, 32, 70, 32);
|
Location loc2 = new Location(world, 32, 70, 32);
|
||||||
|
|
@ -88,7 +87,7 @@ class ChunkUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUpdateChunks_withNegativeCoordinates() {
|
void testUpdateChunksWithNegativeCoordinates() {
|
||||||
// Test with negative coordinates
|
// Test with negative coordinates
|
||||||
Location loc1 = new Location(world, -16, 64, -16);
|
Location loc1 = new Location(world, -16, 64, -16);
|
||||||
Location loc2 = new Location(world, -1, 70, -1);
|
Location loc2 = new Location(world, -1, 70, -1);
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import org.mockito.Mockito;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.mockStatic;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
class LocationParserErrorTest {
|
class LocationParserErrorTest {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import dev.loki.lomines.util.format.TimeFormatter;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
class TimeFormatterTest {
|
class TimeFormatterTest {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import org.junit.jupiter.api.Test;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class SelectionManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getSelection_createsNewSelectionIfNotExists() {
|
void getSelectionCreatesNewSelectionIfNotExists() {
|
||||||
Selection selection = manager.getSelection(playerId);
|
Selection selection = manager.getSelection(playerId);
|
||||||
|
|
||||||
assertNotNull(selection);
|
assertNotNull(selection);
|
||||||
|
|
@ -34,7 +34,7 @@ class SelectionManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getSelection_returnsSameInstanceOnMultipleCalls() {
|
void getSelectionReturnsSameInstanceOnMultipleCalls() {
|
||||||
Selection first = manager.getSelection(playerId);
|
Selection first = manager.getSelection(playerId);
|
||||||
Selection second = manager.getSelection(playerId);
|
Selection second = manager.getSelection(playerId);
|
||||||
|
|
||||||
|
|
@ -42,21 +42,21 @@ class SelectionManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getSelection_throwsExceptionForNullPlayerId() {
|
void getSelectionThrowsExceptionForNullPlayerId() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
manager.getSelection(null);
|
manager.getSelection(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void findSelection_returnsEmptyWhenNotExists() {
|
void findSelectionReturnsEmptyWhenNotExists() {
|
||||||
Optional<Selection> result = manager.findSelection(playerId);
|
Optional<Selection> result = manager.findSelection(playerId);
|
||||||
|
|
||||||
assertTrue(result.isEmpty());
|
assertTrue(result.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void findSelection_returnsSelectionWhenExists() {
|
void findSelectionReturnsSelectionWhenExists() {
|
||||||
Selection created = manager.getSelection(playerId);
|
Selection created = manager.getSelection(playerId);
|
||||||
Optional<Selection> found = manager.findSelection(playerId);
|
Optional<Selection> found = manager.findSelection(playerId);
|
||||||
|
|
||||||
|
|
@ -65,33 +65,33 @@ class SelectionManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void findSelection_throwsExceptionForNullPlayerId() {
|
void findSelectionThrowsExceptionForNullPlayerId() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
manager.findSelection(null);
|
manager.findSelection(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void hasSelection_returnsFalseWhenNotExists() {
|
void hasSelectionReturnsFalseWhenNotExists() {
|
||||||
assertFalse(manager.hasSelection(playerId));
|
assertFalse(manager.hasSelection(playerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void hasSelection_returnsTrueWhenExists() {
|
void hasSelectionReturnsTrueWhenExists() {
|
||||||
manager.getSelection(playerId);
|
manager.getSelection(playerId);
|
||||||
|
|
||||||
assertTrue(manager.hasSelection(playerId));
|
assertTrue(manager.hasSelection(playerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void hasSelection_throwsExceptionForNullPlayerId() {
|
void hasSelectionThrowsExceptionForNullPlayerId() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
manager.hasSelection(null);
|
manager.hasSelection(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void clearSelection_removesSelection() {
|
void clearSelectionRemovesSelection() {
|
||||||
manager.getSelection(playerId);
|
manager.getSelection(playerId);
|
||||||
assertTrue(manager.hasSelection(playerId));
|
assertTrue(manager.hasSelection(playerId));
|
||||||
|
|
||||||
|
|
@ -101,14 +101,14 @@ class SelectionManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void clearSelection_doesNothingWhenSelectionNotExists() {
|
void clearSelectionDoesNothingWhenSelectionNotExists() {
|
||||||
assertDoesNotThrow(() -> {
|
assertDoesNotThrow(() -> {
|
||||||
manager.clearSelection(playerId);
|
manager.clearSelection(playerId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void clearSelection_throwsExceptionForNullPlayerId() {
|
void clearSelectionThrowsExceptionForNullPlayerId() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
manager.clearSelection(null);
|
manager.clearSelection(null);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,14 @@
|
||||||
package dev.loki.lomines.util.selection;
|
package dev.loki.lomines.util.selection;
|
||||||
|
|
||||||
import dev.loki.lomines.util.location.geo.Cuboid;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
|
||||||
29
todo.md
29
todo.md
|
|
@ -1,7 +1,7 @@
|
||||||
# LoMines — План реструктуризации и улучшения качества
|
# LoMines — План реструктуризации и улучшения качества
|
||||||
|
|
||||||
> **Обновлено:** 2026-07-06
|
> **Обновлено:** 2026-08-12
|
||||||
> **Цели:** Разбивка на подпапки (≤3 файла), лимит 150 строк/файл, Checkstyle
|
> **Цели:** Разбивка на подпапки (≤3 файла), лимит 150 строк/файл, Checkstyle, тестовое покрытие
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -574,3 +574,28 @@ dev.loki.lomines/
|
||||||
- **0 файлов >150 строк**
|
- **0 файлов >150 строк**
|
||||||
- **0 папок >3 файлов**
|
- **0 папок >3 файлов**
|
||||||
- **145 main + 31 test = 176 файлов**
|
- **145 main + 31 test = 176 файлов**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Постреструктуризационные задачи завершены (2026-08-12)
|
||||||
|
|
||||||
|
### Docs
|
||||||
|
- `ARCHITECTURE.md` полностью переписан под реальный код: `dev.loki.lomines`, `extends JavaPlugin`, без lolib/LoAPI (ранее описывал Kotlin-версию)
|
||||||
|
- Удалён устаревший `core/common/package-info.java` (ссылался на `LoPlugin`, `Mines`/`Mine` в `core.common`) — пакет был пустым
|
||||||
|
|
||||||
|
### Checkstyle
|
||||||
|
- `BeforeExecutionExclusionFileFilter` (исключавший `src/test`) убран — тесты теперь проверяются
|
||||||
|
- `MethodLength` 80 → 30
|
||||||
|
- Исправлены нарушения: 23 в main (выделение private-методов) + 60 в test (unused imports, camelCase для тестов)
|
||||||
|
|
||||||
|
### Тесты: MockBukkit
|
||||||
|
- Подключён `org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.110.0` (testImplementation)
|
||||||
|
- `testImplementation` paper-api приведён к `1.21.11-R0.1-SNAPSHOT` (требование MockBukkit), `compileOnly` остаётся `1.21.4`
|
||||||
|
- Включены все 48 ранее отключённых тестов: `BlockKeyTest`, `BlockConfigTest`, `MineTest`, `MineConfigTest`, `MineConfigValidationTest`, `MinesTest`, `MinesLoadingTest`, `MinesLifecycleTest`
|
||||||
|
- **Итог: 184 теста, 0 skipped, 0 failures**
|
||||||
|
|
||||||
|
### Багфикс
|
||||||
|
- `Mines.create("TestMine")` сохранял `testmine.yml` (record нормализует имя в lowercase), но загружал `TestMine.yml` → `IOException`. Исправлено нормализацией имени в `Mines.create` (`name.toLowerCase().trim()`)
|
||||||
|
|
||||||
|
### Cleanup
|
||||||
|
- Удалены `bin/` (Eclipse output, был gitignored) и `libs/` (содержал только `.gitkeep`)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue