fix: use inventory holders for menus and rework shulker box handling
This commit is contained in:
@@ -6,7 +6,6 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class BaseCommand implements CommandExecutor {
|
||||
|
||||
@@ -32,7 +31,7 @@ public abstract class BaseCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (sender instanceof Player player) {
|
||||
if (!player.hasPermission(permission)) {
|
||||
String message = getLang().getString("messages.no-permission",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.infstar.essentialsC.commands;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -8,61 +9,83 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BlocksMenuCommand extends BaseCommand implements Listener {
|
||||
|
||||
|
||||
private static final int MENU_SIZE = 36;
|
||||
private static boolean listenerRegistered = false;
|
||||
|
||||
private final NamespacedKey blockKey;
|
||||
|
||||
|
||||
private static final class BlocksMenuHolder implements InventoryHolder {
|
||||
private final Inventory inventory;
|
||||
|
||||
private BlocksMenuHolder(String title) {
|
||||
this.inventory = Bukkit.createInventory(this, MENU_SIZE, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
}
|
||||
|
||||
public BlocksMenuCommand() {
|
||||
super("essentialsc.command.blocks");
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
blockKey = new NamespacedKey(plugin, "block_key");
|
||||
if (!listenerRegistered) {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
listenerRegistered = true;
|
||||
}
|
||||
this.blockKey = new NamespacedKey(plugin, "block_key");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull Player player, String[] args) {
|
||||
protected boolean execute(Player player, String[] args) {
|
||||
openMenu(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void openMenu(Player player) {
|
||||
String title = plugin.getConfig().getString("blocks-menu.title", "&6&lEssentialsC &8- &e&l功能方块菜单");
|
||||
Inventory menu = Bukkit.createInventory(null, MENU_SIZE, translateColor(title));
|
||||
|
||||
// 从配置中读取所有物品
|
||||
String title = plugin.getConfig().getString("blocks-menu.title", "&6&lEssentialsC &8- &e&l鍔熻兘鏂瑰潡鑿滃崟");
|
||||
Inventory menu = new BlocksMenuHolder(translateColor(title)).getInventory();
|
||||
|
||||
var itemsConfig = plugin.getConfig().getConfigurationSection("blocks-menu.items");
|
||||
if (itemsConfig == null) return;
|
||||
|
||||
if (itemsConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : itemsConfig.getKeys(false)) {
|
||||
var section = itemsConfig.getConfigurationSection(key);
|
||||
if (section == null) continue;
|
||||
|
||||
// 检查权限
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String permission = section.getString("permission");
|
||||
if (permission != null && !player.hasPermission(permission)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int slot = section.getInt("slot");
|
||||
Material material = Material.matchMaterial(section.getString("material", "STONE"));
|
||||
if (material == null) material = Material.STONE;
|
||||
|
||||
if (material == null) {
|
||||
material = Material.STONE;
|
||||
}
|
||||
|
||||
String name = translateColor(section.getString("name", "&fItem"));
|
||||
java.util.List<String> lore = section.getStringList("lore").stream()
|
||||
.map(this::translateColor)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
|
||||
.toList();
|
||||
|
||||
addItem(menu, slot, material, name, lore, key);
|
||||
}
|
||||
|
||||
|
||||
player.openInventory(menu);
|
||||
}
|
||||
|
||||
|
||||
private void addItem(Inventory inv, int slot, Material material, String name, java.util.List<String> lore, String key) {
|
||||
ItemStack item = new ItemStack(material);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
@@ -74,33 +97,30 @@ public class BlocksMenuCommand extends BaseCommand implements Listener {
|
||||
}
|
||||
inv.setItem(slot, item);
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onMenuClick(InventoryClickEvent event) {
|
||||
// 动态获取配置的标题
|
||||
String configTitle = plugin.getConfig().getString("blocks-menu.title", "&6&lEssentialsC &8- &e&l功能方块菜单");
|
||||
String actualTitle = translateColor(configTitle);
|
||||
|
||||
if (!event.getView().getTitle().equals(actualTitle)) return;
|
||||
if (!(event.getWhoClicked() instanceof Player player)) return;
|
||||
|
||||
if (!(event.getView().getTopInventory().getHolder(false) instanceof BlocksMenuHolder)) {
|
||||
return;
|
||||
}
|
||||
if (!(event.getWhoClicked() instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
ItemStack clicked = event.getCurrentItem();
|
||||
if (clicked == null || !clicked.hasItemMeta()) return;
|
||||
|
||||
if (clicked == null || !clicked.hasItemMeta()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemMeta meta = clicked.getItemMeta();
|
||||
String key = meta.getPersistentDataContainer().get(this.blockKey, PersistentDataType.STRING);
|
||||
|
||||
// 点击后执行对应命令并播放音效(如果有)
|
||||
if (key != null && HelpCommand.COMMAND_CACHE.containsKey(key)) {
|
||||
playBlockOpenSound(player, key);
|
||||
HelpCommand.COMMAND_CACHE.get(key).execute(player, new String[]{});
|
||||
HelpCommand.COMMAND_CACHE.get(key).execute(player, new String[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放对应方块的打开音效(优先使用交互音效)
|
||||
*/
|
||||
|
||||
private void playBlockOpenSound(Player player, String key) {
|
||||
org.bukkit.Sound sound = switch (key) {
|
||||
case "workbench" -> org.bukkit.Sound.BLOCK_WOOD_HIT;
|
||||
@@ -113,16 +133,13 @@ public class BlocksMenuCommand extends BaseCommand implements Listener {
|
||||
case "enderchest" -> org.bukkit.Sound.BLOCK_ENDER_CHEST_OPEN;
|
||||
default -> null;
|
||||
};
|
||||
|
||||
|
||||
if (sound != null) {
|
||||
player.playSound(player.getLocation(), sound, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换颜色代码 & -> §
|
||||
*/
|
||||
|
||||
private String translateColor(String text) {
|
||||
return text.replace("&", "§");
|
||||
return text == null ? "" : ChatColor.translateAlternateColorCodes('&', text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,8 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
@@ -44,7 +42,7 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull Player player, String[] args) {
|
||||
protected boolean execute(Player player, String[] args) {
|
||||
return handleCommand(player, player, args);
|
||||
}
|
||||
|
||||
@@ -223,11 +221,14 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
* 获取命令对应的权限节点
|
||||
*/
|
||||
private String getPermissionForCommand(String command) {
|
||||
if (command.equals("mobdrops")) {
|
||||
return "essentialsc.mobdrops.enderman";
|
||||
}
|
||||
return "essentialsc.command." + command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> completions = new ArrayList<>();
|
||||
String partial = args[0].toLowerCase();
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
@@ -15,6 +16,19 @@ import java.util.Arrays;
|
||||
* /mobdrops - 打开控制菜单
|
||||
*/
|
||||
public class MobDropCommand extends BaseCommand {
|
||||
|
||||
public static final class MobDropMenuHolder implements InventoryHolder {
|
||||
private final Inventory inventory;
|
||||
|
||||
public MobDropMenuHolder(String title) {
|
||||
this.inventory = Bukkit.createInventory(this, 27, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
}
|
||||
|
||||
public MobDropCommand() {
|
||||
super("essentialsc.mobdrops.enderman");
|
||||
@@ -34,7 +48,7 @@ public class MobDropCommand extends BaseCommand {
|
||||
boolean endermanEnabled = plugin.getConfig().getBoolean("mob-drops.enderman.enabled", true);
|
||||
|
||||
// 创建菜单
|
||||
Inventory menu = Bukkit.createInventory(null, 27, "§6§l生物掉落控制");
|
||||
Inventory menu = new MobDropMenuHolder("§6§l生物掉落控制").getInventory();
|
||||
|
||||
// 末影人控制项
|
||||
ItemStack endermanItem = new ItemStack(Material.ENDER_PEARL);
|
||||
|
||||
Reference in New Issue
Block a user