feat: 添加潜影盒快捷打开和末影箱自定义标题功能
This commit is contained in:
@@ -1,143 +0,0 @@
|
||||
package cn.infstar.essentialsC.commands;
|
||||
|
||||
import cn.infstar.essentialsC.EssentialsC;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
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.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class AdminMenuCommand extends BaseCommand implements Listener {
|
||||
|
||||
private static final int MENU_SIZE = 27;
|
||||
|
||||
public AdminMenuCommand() {
|
||||
super("essentialsc.command.admin");
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull Player player, String[] args) {
|
||||
openMenu(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void openMenu(Player player) {
|
||||
String title = plugin.getConfig().getString("admin-menu.title", "&6EssentialsC 管理菜单");
|
||||
Inventory menu = Bukkit.createInventory(null, MENU_SIZE, translateColor(title));
|
||||
|
||||
// 从配置中读取所有物品
|
||||
var itemsConfig = plugin.getConfig().getConfigurationSection("admin-menu.items");
|
||||
if (itemsConfig == null) return;
|
||||
|
||||
for (String key : itemsConfig.getKeys(false)) {
|
||||
var section = itemsConfig.getConfigurationSection(key);
|
||||
if (section == null) continue;
|
||||
|
||||
int slot = section.getInt("slot");
|
||||
Material material = Material.matchMaterial(section.getString("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());
|
||||
|
||||
addItem(menu, slot, material, name, lore);
|
||||
}
|
||||
|
||||
player.openInventory(menu);
|
||||
}
|
||||
|
||||
private String translateColor(String text) {
|
||||
return text.replace("&", "§");
|
||||
}
|
||||
|
||||
private void addItem(Inventory inv, int slot, Material material, String name, java.util.List<String> lore) {
|
||||
ItemStack item = new ItemStack(material);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(name);
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
inv.setItem(slot, item);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMenuClick(InventoryClickEvent event) {
|
||||
// 检查是否是管理员菜单
|
||||
String configTitle = translateColor(plugin.getConfig().getString("admin-menu.title", "&6EssentialsC 管理菜单"));
|
||||
if (!event.getView().getTitle().equals(configTitle)) return;
|
||||
if (!(event.getWhoClicked() instanceof Player player)) return;
|
||||
|
||||
// 取消事件,防止拿出物品
|
||||
event.setCancelled(true);
|
||||
|
||||
ItemStack clicked = event.getCurrentItem();
|
||||
if (clicked == null || !clicked.hasItemMeta()) return;
|
||||
|
||||
String displayName = clicked.getItemMeta().getDisplayName();
|
||||
|
||||
// 从配置中读取所有物品配置,通过名称匹配
|
||||
var itemsConfig = plugin.getConfig().getConfigurationSection("admin-menu.items");
|
||||
if (itemsConfig == null) return;
|
||||
|
||||
for (String key : itemsConfig.getKeys(false)) {
|
||||
var section = itemsConfig.getConfigurationSection(key);
|
||||
if (section == null) continue;
|
||||
|
||||
String itemName = translateColor(section.getString("name", ""));
|
||||
if (!displayName.equals(itemName)) continue;
|
||||
|
||||
// 找到匹配的物品,执行对应操作
|
||||
switch (key) {
|
||||
case "time-control" -> {
|
||||
if (event.isLeftClick()) player.getWorld().setTime(1000);
|
||||
else player.getWorld().setTime(13000);
|
||||
player.sendMessage(getLang().getString("admin-time-set"));
|
||||
}
|
||||
case "weather-control" -> {
|
||||
if (event.isLeftClick()) player.getWorld().setStorm(false);
|
||||
else player.getWorld().setStorm(true);
|
||||
player.sendMessage(getLang().getString("admin-weather-set"));
|
||||
}
|
||||
case "heal-self" -> {
|
||||
player.setHealth(player.getMaxHealth());
|
||||
player.setFoodLevel(20);
|
||||
player.sendMessage(getLang().getString("admin-heal-success"));
|
||||
}
|
||||
case "feed-self" -> {
|
||||
player.setFoodLevel(20);
|
||||
player.setSaturation(20f);
|
||||
player.sendMessage(getLang().getString("admin-feed-success"));
|
||||
}
|
||||
case "repair-hand" -> {
|
||||
var item = player.getInventory().getItemInMainHand();
|
||||
if (item.getItemMeta() instanceof org.bukkit.inventory.meta.Damageable d) {
|
||||
d.setDamage(0);
|
||||
item.setItemMeta((org.bukkit.inventory.meta.ItemMeta) d);
|
||||
player.sendMessage(getLang().getString("admin-repair-success"));
|
||||
}
|
||||
}
|
||||
case "vanish" -> {
|
||||
HelpCommand.COMMAND_CACHE.get("vanish").execute(player, new String[]{});
|
||||
openMenu(player); // 刷新菜单
|
||||
}
|
||||
case "reload" -> {
|
||||
plugin.reloadConfig();
|
||||
EssentialsC.getLangManager().reload();
|
||||
player.sendMessage(getLang().getString("admin-reload-success"));
|
||||
}
|
||||
}
|
||||
break; // 找到后退出循环
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,8 @@ public class AnvilCommand extends BaseCommand {
|
||||
|
||||
@Override
|
||||
protected boolean execute(Player player, String[] args) {
|
||||
// 使用 Paper API 打开铁砧(标题跟随客户端语言)
|
||||
player.openAnvil(null, true);
|
||||
player.sendMessage(getLang().getString("anvil-opened"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package cn.infstar.essentialsC.commands;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
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.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 final NamespacedKey blockKey;
|
||||
|
||||
public BlocksMenuCommand() {
|
||||
super("essentialsc.command.blocks");
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
blockKey = new NamespacedKey(plugin, "block_key");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull 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));
|
||||
|
||||
// 从配置中读取所有物品
|
||||
var itemsConfig = plugin.getConfig().getConfigurationSection("blocks-menu.items");
|
||||
if (itemsConfig == null) return;
|
||||
|
||||
for (String key : itemsConfig.getKeys(false)) {
|
||||
var section = itemsConfig.getConfigurationSection(key);
|
||||
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;
|
||||
|
||||
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());
|
||||
|
||||
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();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(name);
|
||||
meta.setLore(lore);
|
||||
meta.getPersistentDataContainer().set(this.blockKey, PersistentDataType.STRING, key);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
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;
|
||||
|
||||
event.setCancelled(true);
|
||||
ItemStack clicked = event.getCurrentItem();
|
||||
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[]{});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放对应方块的打开音效(优先使用交互音效)
|
||||
*/
|
||||
private void playBlockOpenSound(Player player, String key) {
|
||||
org.bukkit.Sound sound = switch (key) {
|
||||
case "workbench" -> org.bukkit.Sound.BLOCK_WOOD_HIT;
|
||||
case "anvil" -> org.bukkit.Sound.BLOCK_ANVIL_USE;
|
||||
case "cartographytable" -> org.bukkit.Sound.UI_CARTOGRAPHY_TABLE_TAKE_RESULT;
|
||||
case "grindstone" -> org.bukkit.Sound.BLOCK_GRINDSTONE_USE;
|
||||
case "loom" -> org.bukkit.Sound.UI_LOOM_TAKE_RESULT;
|
||||
case "smithingtable" -> org.bukkit.Sound.BLOCK_SMITHING_TABLE_USE;
|
||||
case "stonecutter" -> org.bukkit.Sound.BLOCK_STONE_HIT;
|
||||
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("&", "§");
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package cn.infstar.essentialsC.commands;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class EnchantingTableCommand extends BaseCommand {
|
||||
|
||||
public EnchantingTableCommand() {
|
||||
super("essentialsc.command.enchantingtable");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(Player player, String[] args) {
|
||||
player.openEnchanting(null, true);
|
||||
player.sendMessage(getLang().getString("enchantingtable-opened"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.infstar.essentialsC.commands;
|
||||
|
||||
import cn.infstar.essentialsC.EssentialsC;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class EnderChestCommand extends BaseCommand {
|
||||
@@ -10,7 +11,18 @@ public class EnderChestCommand extends BaseCommand {
|
||||
|
||||
@Override
|
||||
protected boolean execute(Player player, String[] args) {
|
||||
// 打开玩家的末影箱(标题由客户端决定)
|
||||
EssentialsC plugin = EssentialsC.getInstance();
|
||||
|
||||
// 如果启用了 ProtocolLib,使用自定义标题
|
||||
if (plugin.isProtocolLibEnabled()) {
|
||||
// 从配置读取标题
|
||||
String title = plugin.getConfig().getString("enderchest.title", "&5随身末影箱");
|
||||
|
||||
// 标记下一个打开的 inventory 需要修改标题
|
||||
plugin.getInventoryTitleListener().markForTitleChange(player, title);
|
||||
}
|
||||
|
||||
// 直接打开玩家的末影箱(参考 EssentialsX 实现)
|
||||
player.openInventory(player.getEnderChest());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
static {
|
||||
COMMAND_CACHE.put("workbench", new WorkbenchCommand());
|
||||
COMMAND_CACHE.put("anvil", new AnvilCommand());
|
||||
COMMAND_CACHE.put("enchantingtable", new EnchantingTableCommand());
|
||||
COMMAND_CACHE.put("cartographytable", new CartographyTableCommand());
|
||||
COMMAND_CACHE.put("grindstone", new GrindstoneCommand());
|
||||
COMMAND_CACHE.put("loom", new LoomCommand());
|
||||
@@ -36,7 +35,7 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
COMMAND_CACHE.put("seen", new SeenCommand());
|
||||
COMMAND_CACHE.put("feed", new FeedCommand());
|
||||
COMMAND_CACHE.put("repair", new RepairCommand());
|
||||
COMMAND_CACHE.put("admin", new AdminMenuCommand());
|
||||
COMMAND_CACHE.put("blocks", new BlocksMenuCommand());
|
||||
}
|
||||
|
||||
public HelpCommand() {
|
||||
@@ -49,14 +48,7 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
String subCommand = args[0].toLowerCase();
|
||||
|
||||
// 管理相关
|
||||
if (subCommand.equals("admin")) {
|
||||
if (!player.hasPermission("essentialsc.command.admin")) {
|
||||
player.sendMessage(getLang().getString("messages.no-permission"));
|
||||
return true;
|
||||
}
|
||||
COMMAND_CACHE.get("admin").execute(player, new String[]{});
|
||||
return true;
|
||||
} else if (subCommand.equals("reload")) {
|
||||
if (subCommand.equals("reload")) {
|
||||
if (!player.hasPermission("essentialsc.command.reload")) {
|
||||
player.sendMessage(getLang().getString("messages.no-permission"));
|
||||
return true;
|
||||
@@ -119,10 +111,6 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
blockCommands.append(lang.getString("help.commands.anvil")).append("\n");
|
||||
hasBlockCommands = true;
|
||||
}
|
||||
if (player.hasPermission("essentialsc.command.enchantingtable")) {
|
||||
blockCommands.append(lang.getString("help.commands.enchantingtable")).append("\n");
|
||||
hasBlockCommands = true;
|
||||
}
|
||||
if (player.hasPermission("essentialsc.command.cartographytable")) {
|
||||
blockCommands.append(lang.getString("help.commands.cartographytable")).append("\n");
|
||||
hasBlockCommands = true;
|
||||
@@ -182,10 +170,6 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
otherCommands.append(lang.getString("help.commands.seen")).append("\n");
|
||||
hasOtherCommands = true;
|
||||
}
|
||||
if (player.hasPermission("essentialsc.command.admin")) {
|
||||
otherCommands.append(lang.getString("help.commands.admin")).append("\n");
|
||||
hasOtherCommands = true;
|
||||
}
|
||||
|
||||
if (hasOtherCommands) {
|
||||
player.sendMessage(lang.getString("help.section-other"));
|
||||
@@ -203,7 +187,6 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
private String getActualCommand(String alias) {
|
||||
return switch (alias) {
|
||||
case "wb" -> "workbench";
|
||||
case "enchant", "et" -> "enchantingtable";
|
||||
case "cartography", "ct" -> "cartographytable";
|
||||
case "gs" -> "grindstone";
|
||||
case "smithing", "st" -> "smithingtable";
|
||||
@@ -231,14 +214,11 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
|
||||
|
||||
// 所有可能的子命令及其权限(包括别名)
|
||||
String[][] subCommands = {
|
||||
{"admin", "essentialsc.command.admin"},
|
||||
{"reload", "essentialsc.command.reload"},
|
||||
{"blocks", "essentialsc.command.blocks"},
|
||||
{"workbench", "essentialsc.command.workbench"},
|
||||
{"wb", "essentialsc.command.workbench"},
|
||||
{"anvil", "essentialsc.command.anvil"},
|
||||
{"enchantingtable", "essentialsc.command.enchantingtable"},
|
||||
{"enchant", "essentialsc.command.enchantingtable"},
|
||||
{"et", "essentialsc.command.enchantingtable"},
|
||||
{"cartographytable", "essentialsc.command.cartographytable"},
|
||||
{"cartography", "essentialsc.command.cartographytable"},
|
||||
{"ct", "essentialsc.command.cartographytable"},
|
||||
|
||||
Reference in New Issue
Block a user