fix(settings): use Purpur dialog API
Release / release (push) Successful in 5m29s
CI / build (push) Successful in 1m28s

This commit is contained in:
dmg
2026-08-24 11:25:01 -04:00
parent b6bbf9183a
commit 29413d36b3
14 changed files with 366 additions and 243 deletions
@@ -24,7 +24,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import net.md_5.bungee.api.dialog.Dialog;
import net.kyori.adventure.dialog.DialogLike;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
@@ -186,10 +186,12 @@ final class BaseSettingsCommandTest {
when(player.getUniqueId()).thenReturn(playerId);
when(player.getName()).thenReturn("Host");
PlayerInventory inventory = mock(PlayerInventory.class);
ItemStack firstStack = item(Material.DIAMOND, 64);
ItemStack secondStack = item(Material.DIAMOND, 64);
when(player.getInventory()).thenReturn(inventory);
when(inventory.getStorageContents()).thenReturn(new ItemStack[] {
new ItemStack(Material.DIAMOND, 64),
new ItemStack(Material.DIAMOND, 64)
firstStack,
secondStack
});
PlayerState current = PlayerState.newPlayer(playerId, "Host")
@@ -227,10 +229,9 @@ final class BaseSettingsCommandTest {
when(player.getUniqueId()).thenReturn(playerId);
when(player.getName()).thenReturn("Builder");
PlayerInventory inventory = mock(PlayerInventory.class);
ItemStack currency = item(Material.DIAMOND_BLOCK, 64);
when(player.getInventory()).thenReturn(inventory);
when(inventory.getStorageContents()).thenReturn(new ItemStack[] {
new ItemStack(Material.DIAMOND_BLOCK, 64)
});
when(inventory.getStorageContents()).thenReturn(new ItemStack[] {currency});
PlayerState owner = PlayerState.newPlayer(playerId, "Builder")
.withAdministrativeLevels(4, 0, 0, 0, 0, false, false, true)
.withBase(
@@ -264,10 +265,9 @@ final class BaseSettingsCommandTest {
when(player.getUniqueId()).thenReturn(playerId);
when(player.getName()).thenReturn("Builder");
PlayerInventory inventory = mock(PlayerInventory.class);
ItemStack currency = item(Material.NETHERITE_BLOCK, 16);
when(player.getInventory()).thenReturn(inventory);
when(inventory.getStorageContents()).thenReturn(new ItemStack[] {
new ItemStack(Material.NETHERITE_BLOCK, 16)
});
when(inventory.getStorageContents()).thenReturn(new ItemStack[] {currency});
BaseStateManager stateManager = mock(BaseStateManager.class);
when(stateManager.player(playerId, "Builder"))
.thenReturn(PlayerState.newPlayer(playerId, "Builder"));
@@ -429,10 +429,9 @@ final class BaseSettingsCommandTest {
when(player.getUniqueId()).thenReturn(playerId);
when(player.getName()).thenReturn("Builder");
PlayerInventory inventory = mock(PlayerInventory.class);
ItemStack currency = item(Material.DIAMOND_BLOCK, 64);
when(player.getInventory()).thenReturn(inventory);
when(inventory.getStorageContents()).thenReturn(new ItemStack[] {
new ItemStack(Material.DIAMOND_BLOCK, 64)
});
when(inventory.getStorageContents()).thenReturn(new ItemStack[] {currency});
PlayerState owner = PlayerState.newPlayer(playerId, "Builder")
.withAdministrativeLevels(4, 0, 0, 0, 0, false, false, true)
.withBase(
@@ -554,14 +553,16 @@ final class BaseSettingsCommandTest {
BaseSettingsCommand command = new BaseSettingsCommand(
stateManager,
new PluginSettingsProvider(PluginSettings.from(Map.of())),
mock(BaseFlightController.class)
mock(BaseFlightController.class),
null,
(owner, pocket) -> null
);
command.onCommand(player, null, "basesettings", new String[0]);
command.onCommand(player, null, "homesettings", new String[] {"ui"});
command.onCommand(player, null, "basesettings", new String[] {"status"});
verify(player, times(2)).showDialog(any(Dialog.class));
verify(player, times(2)).showDialog((DialogLike) null);
verify(player).sendMessage(ChatColor.GOLD + "=== Base Progress ===");
verify(player).sendMessage(
org.mockito.ArgumentMatchers.<String>argThat(message ->
@@ -582,6 +583,18 @@ final class BaseSettingsCommandTest {
);
}
private static ItemStack item(Material material, int amount) {
ItemStack item = mock(ItemStack.class);
ItemStack copy = mock(ItemStack.class);
when(item.getType()).thenReturn(material);
when(item.getAmount()).thenReturn(amount);
when(item.clone()).thenReturn(copy);
when(copy.getType()).thenReturn(material);
when(copy.getAmount()).thenReturn(amount);
when(copy.clone()).thenReturn(copy);
return item;
}
private static CommandResult execute(PlayerState current, String... arguments) {
Player player = mock(Player.class);
when(player.getUniqueId()).thenReturn(current.playerId());
@@ -1,5 +1,6 @@
package games.dmg.spigotbase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -9,14 +10,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import net.md_5.bungee.api.dialog.ConfirmationDialog;
import net.md_5.bungee.api.dialog.Dialog;
import net.md_5.bungee.api.dialog.DialogListDialog;
import net.md_5.bungee.api.dialog.MultiActionDialog;
import net.md_5.bungee.api.dialog.NoticeDialog;
import net.md_5.bungee.api.dialog.action.Action;
import net.md_5.bungee.api.dialog.action.ActionButton;
import net.md_5.bungee.api.dialog.action.RunCommandAction;
import org.junit.jupiter.api.Test;
final class BaseSettingsDialogFactoryTest {
@@ -42,12 +35,15 @@ final class BaseSettingsDialogFactoryTest {
PocketBaseBiome.PLAINS
);
Dialog dialog = new BaseSettingsDialogFactory(
PluginSettings.from(Map.of())
).create(owner, pocket);
BaseSettingsDialogFactory.DialogSpec specification =
new BaseSettingsDialogFactory(PluginSettings.from(Map.of()))
.specification(owner, pocket);
DialogListDialog root = assertInstanceOf(DialogListDialog.class, dialog);
assertTrue(root.getBase().body().get(0).toString().contains("Base 4/4"));
BaseSettingsDialogFactory.ListSpec root = assertInstanceOf(
BaseSettingsDialogFactory.ListSpec.class,
specification
);
assertTrue(root.content().message().contains("Base 4/4"));
List<String> commands = commands(root);
assertTrue(commands.contains("/basesettings status"));
assertTrue(commands.contains("/basesettings visitors blocked"));
@@ -72,23 +68,19 @@ final class BaseSettingsDialogFactoryTest {
Instant.EPOCH
);
DialogListDialog root = assertInstanceOf(
DialogListDialog.class,
new BaseSettingsDialogFactory(PluginSettings.from(Map.of())).create(
BaseSettingsDialogFactory.ListSpec root = assertInstanceOf(
BaseSettingsDialogFactory.ListSpec.class,
new BaseSettingsDialogFactory(PluginSettings.from(Map.of())).specification(
owner,
PocketBaseState.locked(playerId)
)
);
ConfirmationDialog upgrade = assertInstanceOf(
ConfirmationDialog.class,
BaseSettingsDialogFactory.ConfirmationSpec upgrade = assertInstanceOf(
BaseSettingsDialogFactory.ConfirmationSpec.class,
root.dialogs().get(2)
);
RunCommandAction action = assertInstanceOf(
RunCommandAction.class,
upgrade.yes().action()
);
assertTrue(action.template().equals("/basesettings upgrade"));
assertEquals("/basesettings upgrade", upgrade.confirm().command());
}
@Test
@@ -96,20 +88,19 @@ final class BaseSettingsDialogFactoryTest {
UUID playerId = UUID.randomUUID();
PlayerState owner = PlayerState.newPlayer(playerId, "Newcomer");
DialogListDialog root = assertInstanceOf(
DialogListDialog.class,
new BaseSettingsDialogFactory(PluginSettings.from(Map.of())).create(
BaseSettingsDialogFactory.ListSpec root = assertInstanceOf(
BaseSettingsDialogFactory.ListSpec.class,
new BaseSettingsDialogFactory(PluginSettings.from(Map.of())).specification(
owner,
PocketBaseState.locked(playerId)
)
);
MultiActionDialog controls = assertInstanceOf(
MultiActionDialog.class,
BaseSettingsDialogFactory.MultiSpec controls = assertInstanceOf(
BaseSettingsDialogFactory.MultiSpec.class,
root.dialogs().get(0)
);
List<String> labels = controls.actions().stream()
.map(ActionButton::label)
.map(Object::toString)
.map(BaseSettingsDialogFactory.ButtonSpec::label)
.toList();
assertTrue(labels.stream().anyMatch(label -> label.contains("Visitors: Locked")));
@@ -119,34 +110,28 @@ final class BaseSettingsDialogFactoryTest {
assertTrue(labels.stream().anyMatch(label -> label.contains("Spawnable Overlay: Locked")));
}
private static List<String> commands(Dialog dialog) {
private static List<String> commands(
BaseSettingsDialogFactory.DialogSpec specification
) {
List<String> commands = new ArrayList<>();
collect(dialog, commands);
collect(specification, commands);
return commands;
}
private static void collect(Dialog dialog, List<String> commands) {
if (dialog instanceof DialogListDialog list) {
private static void collect(
BaseSettingsDialogFactory.DialogSpec specification,
List<String> commands
) {
if (specification instanceof BaseSettingsDialogFactory.ListSpec list) {
list.dialogs().forEach(child -> collect(child, commands));
collect(list.exitAction(), commands);
} else if (dialog instanceof MultiActionDialog actions) {
actions.actions().forEach(button -> collect(button, commands));
collect(actions.exitAction(), commands);
} else if (dialog instanceof ConfirmationDialog confirmation) {
collect(confirmation.yes(), commands);
collect(confirmation.no(), commands);
} else if (dialog instanceof NoticeDialog notice) {
collect(notice.action(), commands);
}
}
private static void collect(ActionButton button, List<String> commands) {
if (button == null) {
return;
}
Action action = button.action();
if (action instanceof RunCommandAction command) {
commands.add(command.template());
} else if (specification instanceof BaseSettingsDialogFactory.MultiSpec multi) {
multi.actions().forEach(button -> commands.add(button.command()));
} else if (specification
instanceof BaseSettingsDialogFactory.ConfirmationSpec confirmation) {
commands.add(confirmation.confirm().command());
} else if (specification instanceof BaseSettingsDialogFactory.NoticeSpec notice
&& notice.action() != null) {
commands.add(notice.action().command());
}
}
}
@@ -37,6 +37,7 @@ final class PocketBaseControllerTest {
World world = mock(World.class);
Block clicked = block(world, -2, 66, 0, Material.DIAMOND_BLOCK);
PlayerInteractEvent event = mock(PlayerInteractEvent.class);
ItemStack activator = item(Material.FLINT_AND_STEEL);
BaseStateManager baseStates = mock(BaseStateManager.class);
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
PluginSettings settings = PluginSettings.from(Map.of());
@@ -49,7 +50,7 @@ final class PocketBaseControllerTest {
when(event.getPlayer()).thenReturn(owner);
when(event.getAction()).thenReturn(Action.RIGHT_CLICK_BLOCK);
when(event.getClickedBlock()).thenReturn(clicked);
when(event.getItem()).thenReturn(new ItemStack(Material.FLINT_AND_STEEL));
when(event.getItem()).thenReturn(activator);
when(world.getUID()).thenReturn(worldId);
when(world.getName()).thenReturn("world");
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
@@ -98,6 +99,7 @@ final class PocketBaseControllerTest {
World world = mock(World.class);
Block clicked = block(world, 8, 67, 8, Material.DIAMOND_BLOCK);
PlayerInteractEvent event = mock(PlayerInteractEvent.class);
ItemStack activator = item(Material.FLINT_AND_STEEL);
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
PluginSettings settings = PluginSettings.from(Map.of());
@@ -105,7 +107,7 @@ final class PocketBaseControllerTest {
when(event.getPlayer()).thenReturn(owner);
when(event.getAction()).thenReturn(Action.RIGHT_CLICK_BLOCK);
when(event.getClickedBlock()).thenReturn(clicked);
when(event.getItem()).thenReturn(new ItemStack(Material.FLINT_AND_STEEL));
when(event.getItem()).thenReturn(activator);
when(world.getUID()).thenReturn(worldId);
when(world.getName()).thenReturn("pocket");
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
@@ -152,6 +154,7 @@ final class PocketBaseControllerTest {
World world = mock(World.class);
Block clicked = block(world, 30, 67, 8, Material.DIAMOND_BLOCK);
PlayerInteractEvent event = mock(PlayerInteractEvent.class);
ItemStack activator = item(Material.FLINT_AND_STEEL);
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
PluginSettings settings = PluginSettings.from(Map.of());
@@ -159,7 +162,7 @@ final class PocketBaseControllerTest {
when(event.getPlayer()).thenReturn(owner);
when(event.getAction()).thenReturn(Action.RIGHT_CLICK_BLOCK);
when(event.getClickedBlock()).thenReturn(clicked);
when(event.getItem()).thenReturn(new ItemStack(Material.FLINT_AND_STEEL));
when(event.getItem()).thenReturn(activator);
when(world.getUID()).thenReturn(worldId);
when(world.getName()).thenReturn("pocket");
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
@@ -227,6 +230,12 @@ final class PocketBaseControllerTest {
verify(event).setCancelled(true);
}
private static ItemStack item(Material material) {
ItemStack item = mock(ItemStack.class);
when(item.getType()).thenReturn(material);
return item;
}
private static Block block(
World world,
int x,