feat: 完善 TPA 并整理插件配置

This commit is contained in:
2026-07-31 19:07:50 +08:00
parent 2cad93de9a
commit 5c760b26c6
23 changed files with 1289 additions and 882 deletions
@@ -5,6 +5,7 @@ import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -60,7 +61,8 @@ public class BlocksMenuCommand extends BaseCommand implements Listener {
private void openMenu(Player player) {
Inventory menu = new BlocksMenuHolder(getLang().getString("blocks-menu.title")).getInventory();
var sectionsConfig = plugin.getConfig().getConfigurationSection("blocks-menu.sections");
FileConfiguration menuConfig = plugin.getFeatureConfigManager().getBlocksMenuConfig();
var sectionsConfig = menuConfig.getConfigurationSection("sections");
if (sectionsConfig != null) {
int visibleSections = renderSections(menu, player, sectionsConfig);
if (visibleSections > 1) {
@@ -75,7 +77,7 @@ public class BlocksMenuCommand extends BaseCommand implements Listener {
return;
}
var itemsConfig = plugin.getConfig().getConfigurationSection("blocks-menu.items");
var itemsConfig = menuConfig.getConfigurationSection("items");
if (itemsConfig == null) {
return;
}
@@ -253,66 +255,69 @@ public class BlocksMenuCommand extends BaseCommand implements Listener {
}
private void addConfigDefaults() {
plugin.getConfig().addDefault("blocks-menu.layout-version", 2);
FileConfiguration config = plugin.getFeatureConfigManager().getBlocksMenuConfig();
config.addDefault("config-version", 1);
config.addDefault("layout-version", 2);
addMenuItemDefaults("blocks-menu.sections.blocks.items.workbench", 10, "CRAFTING_TABLE",
addMenuItemDefaults(config, "sections.blocks.items.workbench", 10, "CRAFTING_TABLE",
"essentialsc.command.workbench", "workbench");
addMenuItemDefaults("blocks-menu.sections.blocks.items.enderchest", 11, "ENDER_CHEST",
addMenuItemDefaults(config, "sections.blocks.items.enderchest", 11, "ENDER_CHEST",
"essentialsc.command.enderchest", "enderchest");
addMenuItemDefaults("blocks-menu.sections.blocks.items.anvil", 12, "ANVIL",
addMenuItemDefaults(config, "sections.blocks.items.anvil", 12, "ANVIL",
"essentialsc.command.anvil", "anvil");
addMenuItemDefaults("blocks-menu.sections.blocks.items.grindstone", 19, "GRINDSTONE",
addMenuItemDefaults(config, "sections.blocks.items.grindstone", 19, "GRINDSTONE",
"essentialsc.command.grindstone", "grindstone");
addMenuItemDefaults("blocks-menu.sections.blocks.items.smithingtable", 20, "SMITHING_TABLE",
addMenuItemDefaults(config, "sections.blocks.items.smithingtable", 20, "SMITHING_TABLE",
"essentialsc.command.smithingtable", "smithingtable");
addMenuItemDefaults("blocks-menu.sections.blocks.items.stonecutter", 21, "STONECUTTER",
addMenuItemDefaults(config, "sections.blocks.items.stonecutter", 21, "STONECUTTER",
"essentialsc.command.stonecutter", "stonecutter");
addMenuItemDefaults("blocks-menu.sections.blocks.items.loom", 28, "LOOM",
addMenuItemDefaults(config, "sections.blocks.items.loom", 28, "LOOM",
"essentialsc.command.loom", "loom");
addMenuItemDefaults("blocks-menu.sections.blocks.items.cartographytable", 29, "CARTOGRAPHY_TABLE",
addMenuItemDefaults(config, "sections.blocks.items.cartographytable", 29, "CARTOGRAPHY_TABLE",
"essentialsc.command.cartographytable", "cartographytable");
addMenuItemDefaults("blocks-menu.sections.shortcuts.items.nightvision", 14, "TINTED_GLASS",
addMenuItemDefaults(config, "sections.shortcuts.items.nightvision", 14, "TINTED_GLASS",
"essentialsc.command.nightvision", "nightvision");
addMenuItemDefaults("blocks-menu.sections.shortcuts.items.glow", 15, "GLOWSTONE",
addMenuItemDefaults(config, "sections.shortcuts.items.glow", 15, "GLOWSTONE",
"essentialsc.command.glow", "glow");
plugin.getConfig().options().copyDefaults(true);
migrateLayoutIfNeeded();
plugin.saveConfig();
config.options().copyDefaults(true);
migrateLayoutIfNeeded(config);
plugin.getFeatureConfigManager().saveBlocksMenuConfig();
}
private void migrateLayoutIfNeeded() {
boolean hasStoredLayoutVersion = plugin.getConfig().contains("blocks-menu.layout-version", true);
if (hasStoredLayoutVersion && plugin.getConfig().getInt("blocks-menu.layout-version", 0) >= 2) {
private void migrateLayoutIfNeeded(FileConfiguration config) {
boolean hasStoredLayoutVersion = config.contains("layout-version", true);
if (hasStoredLayoutVersion && config.getInt("layout-version", 0) >= 2) {
return;
}
applySlot("blocks", "workbench", 10);
applySlot("blocks", "enderchest", 11);
applySlot("blocks", "anvil", 12);
applySlot("blocks", "grindstone", 19);
applySlot("blocks", "smithingtable", 20);
applySlot("blocks", "stonecutter", 21);
applySlot("blocks", "loom", 28);
applySlot("blocks", "cartographytable", 29);
applySlot("shortcuts", "nightvision", 14);
applySlot("shortcuts", "glow", 15);
applySlot(config, "blocks", "workbench", 10);
applySlot(config, "blocks", "enderchest", 11);
applySlot(config, "blocks", "anvil", 12);
applySlot(config, "blocks", "grindstone", 19);
applySlot(config, "blocks", "smithingtable", 20);
applySlot(config, "blocks", "stonecutter", 21);
applySlot(config, "blocks", "loom", 28);
applySlot(config, "blocks", "cartographytable", 29);
applySlot(config, "shortcuts", "nightvision", 14);
applySlot(config, "shortcuts", "glow", 15);
plugin.getConfig().set("blocks-menu.sections.blocks.title-item", null);
plugin.getConfig().set("blocks-menu.sections.shortcuts.title-item", null);
plugin.getConfig().set("blocks-menu.layout-version", 2);
config.set("sections.blocks.title-item", null);
config.set("sections.shortcuts.title-item", null);
config.set("layout-version", 2);
}
private void applySlot(String section, String key, int slot) {
plugin.getConfig().set("blocks-menu.sections." + section + ".items." + key + ".slot", slot);
private void applySlot(FileConfiguration config, String section, String key, int slot) {
config.set("sections." + section + ".items." + key + ".slot", slot);
}
private void addMenuItemDefaults(String path, int slot, String material, String permission, String command) {
plugin.getConfig().addDefault(path + ".slot", slot);
plugin.getConfig().addDefault(path + ".material", material);
plugin.getConfig().addDefault(path + ".permission", permission);
plugin.getConfig().addDefault(path + ".command", command);
private void addMenuItemDefaults(FileConfiguration config, String path, int slot, String material,
String permission, String command) {
config.addDefault(path + ".slot", slot);
config.addDefault(path + ".material", material);
config.addDefault(path + ".permission", permission);
config.addDefault(path + ".command", command);
}
private record MenuItem(int slot, Material material, String name, List<String> lore, String commandKey) {
@@ -34,6 +34,7 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
}
plugin.reloadConfig();
EssentialsC.getLangManager().reload();
plugin.getFeatureConfigManager().reload();
plugin.getModuleManager().reload();
CommandRegistry.clearCache();
plugin.reloadRuntimeModules();
@@ -55,6 +56,7 @@ public class HelpCommand extends BaseCommand implements TabCompleter {
}
plugin.reloadConfig();
EssentialsC.getLangManager().reload();
plugin.getFeatureConfigManager().reload();
plugin.getModuleManager().reload();
CommandRegistry.clearCache();
plugin.reloadRuntimeModules();
@@ -1,7 +1,6 @@
package cn.infstar.essentialsC.commands;
import cn.infstar.essentialsC.teleport.TeleportRequestManager;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
@@ -20,17 +19,17 @@ public final class TpAcceptCommand extends BaseCommand implements TabCompleter {
@Override
protected boolean execute(Player player, String[] args) {
if (args.length > 1) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.usage-tpaccept"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.usage-tpaccept"));
return true;
}
TeleportRequestManager manager = plugin.getTeleportRequestManager();
if (manager == null) {
player.sendMessage(getLang().getPrefixedString("messages.module-disabled"));
player.sendMessage(getLang().getPrefixedComponent("messages.module-disabled"));
return true;
}
if (manager.isIgnoringRequests(player)) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.ignoring-requests"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.ignoring-requests"));
return true;
}
@@ -39,7 +38,9 @@ public final class TpAcceptCommand extends BaseCommand implements TabCompleter {
args.length == 0 ? null : args[0]
);
if (request.isEmpty()) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.no-request"));
player.sendMessage(args.length == 0
? getLang().getPrefixedComponent("tpa.messages.no-request")
: getLang().getPrefixedComponent("tpa.messages.invalid-request", Map.of("requester", args[0])));
return true;
}
@@ -47,28 +48,18 @@ public final class TpAcceptCommand extends BaseCommand implements TabCompleter {
Map<String, String> placeholders = manager.placeholders(accepted);
TeleportRequestManager.TeleportResult result = manager.accept(player, accepted);
if (result.status() == TeleportRequestManager.TeleportResult.Status.EXPIRED) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.expired", placeholders));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.expired", placeholders));
return true;
}
if (result.status() == TeleportRequestManager.TeleportResult.Status.PLAYER_OFFLINE) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.player-offline", placeholders));
return true;
}
if (result.status() == TeleportRequestManager.TeleportResult.Status.ALREADY_WARMING_UP) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.already-warming-up", placeholders));
return true;
}
if (result.status() == TeleportRequestManager.TeleportResult.Status.ON_COOLDOWN) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.accept-cooldown",
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.accept-cooldown",
Map.of("seconds", String.valueOf(result.cooldownSeconds()))));
return true;
}
player.sendMessage(getLang().getPrefixedString("tpa.messages.accepted-target", placeholders));
Player requester = Bukkit.getPlayer(accepted.requesterId());
if (requester != null && requester.isOnline()) {
requester.sendMessage(getLang().getPrefixedString("tpa.messages.accepted-sender", placeholders));
}
return true;
}
@@ -1,7 +1,6 @@
package cn.infstar.essentialsC.commands;
import cn.infstar.essentialsC.teleport.TeleportRequestManager;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
@@ -20,17 +19,17 @@ public final class TpDenyCommand extends BaseCommand implements TabCompleter {
@Override
protected boolean execute(Player player, String[] args) {
if (args.length > 1) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.usage-tpdeny"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.usage-tpdeny"));
return true;
}
TeleportRequestManager manager = plugin.getTeleportRequestManager();
if (manager == null) {
player.sendMessage(getLang().getPrefixedString("messages.module-disabled"));
player.sendMessage(getLang().getPrefixedComponent("messages.module-disabled"));
return true;
}
if (manager.isIgnoringRequests(player)) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.ignoring-requests"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.ignoring-requests"));
return true;
}
@@ -39,23 +38,19 @@ public final class TpDenyCommand extends BaseCommand implements TabCompleter {
args.length == 0 ? null : args[0]
);
if (request.isEmpty()) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.no-request"));
player.sendMessage(args.length == 0
? getLang().getPrefixedComponent("tpa.messages.no-request")
: getLang().getPrefixedComponent("tpa.messages.invalid-request", Map.of("requester", args[0])));
return true;
}
TeleportRequestManager.TeleportRequest denied = request.get();
TeleportRequestManager.TeleportResult result = manager.deny(player, denied);
if (result.status() == TeleportRequestManager.TeleportResult.Status.EXPIRED) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.expired", manager.placeholders(denied)));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.expired", manager.placeholders(denied)));
return true;
}
Map<String, String> placeholders = manager.placeholders(denied);
player.sendMessage(getLang().getPrefixedString("tpa.messages.denied-target", placeholders));
Player requester = Bukkit.getPlayer(denied.requesterId());
if (requester != null && requester.isOnline()) {
requester.sendMessage(getLang().getPrefixedString("tpa.messages.denied-sender", placeholders));
}
return true;
}
@@ -13,12 +13,12 @@ public final class TpIgnoreCommand extends BaseCommand {
protected boolean execute(Player player, String[] args) {
TeleportRequestManager manager = plugin.getTeleportRequestManager();
if (manager == null) {
player.sendMessage(getLang().getPrefixedString("messages.module-disabled"));
player.sendMessage(getLang().getPrefixedComponent("messages.module-disabled"));
return true;
}
boolean ignoring = manager.toggleIgnoringRequests(player);
player.sendMessage(getLang().getPrefixedString(ignoring
player.sendMessage(getLang().getPrefixedComponent(ignoring
? "tpa.messages.ignore-enabled"
: "tpa.messages.ignore-disabled"));
return true;
@@ -3,8 +3,6 @@ package cn.infstar.essentialsC.commands;
import cn.infstar.essentialsC.teleport.TeleportRequestManager;
import org.bukkit.entity.Player;
import java.util.Map;
public final class TpaAllCommand extends BaseCommand {
public TpaAllCommand() {
@@ -14,32 +12,27 @@ public final class TpaAllCommand extends BaseCommand {
@Override
protected boolean execute(Player player, String[] args) {
if (args.length != 0) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.usage-tpaall"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.usage-tpaall"));
return true;
}
TeleportRequestManager manager = plugin.getTeleportRequestManager();
if (manager == null) {
player.sendMessage(getLang().getPrefixedString("messages.module-disabled"));
player.sendMessage(getLang().getPrefixedComponent("messages.module-disabled"));
return true;
}
if (manager.isIgnoringRequests(player)) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.ignoring-requests"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.ignoring-requests"));
return true;
}
int sent = manager.sendTeleportAllRequest(player, target -> !VanishCommand.isVanished(target));
if (sent < 0) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.send-cooldown",
Map.of("seconds", String.valueOf(manager.getSendCooldownSeconds(player)))));
return true;
}
int sent = manager.sendTeleportAllRequest(player);
if (sent <= 0) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.tpaall-no-targets"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.tpaall-no-targets"));
return true;
}
player.sendMessage(getLang().getPrefixedString("tpa.messages.tpaall-sent"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.tpaall-sent"));
return true;
}
}
@@ -1,11 +1,6 @@
package cn.infstar.essentialsC.commands;
import cn.infstar.essentialsC.teleport.TeleportRequestManager;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -15,7 +10,6 @@ import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class TpaCommand extends BaseCommand implements TabCompleter {
@@ -30,7 +24,7 @@ public class TpaCommand extends BaseCommand implements TabCompleter {
protected boolean sendRequest(Player player, String[] args, TeleportRequestManager.TeleportRequest.Type type) {
if (args.length != 1) {
player.sendMessage(getLang().getPrefixedString(type == TeleportRequestManager.TeleportRequest.Type.TPA
player.sendMessage(getLang().getPrefixedComponent(type == TeleportRequestManager.TeleportRequest.Type.TPA
? "tpa.messages.usage-tpa"
: "tpa.messages.usage-tpahere"));
return true;
@@ -38,82 +32,73 @@ public class TpaCommand extends BaseCommand implements TabCompleter {
TeleportRequestManager manager = plugin.getTeleportRequestManager();
if (manager == null) {
player.sendMessage(getLang().getPrefixedString("messages.module-disabled"));
player.sendMessage(getLang().getPrefixedComponent("messages.module-disabled"));
return true;
}
if (manager.isIgnoringRequests(player)) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.ignoring-requests"));
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.ignoring-requests"));
return true;
}
Player target = Bukkit.getPlayerExact(args[0]);
if (target == null || !target.isOnline() || VanishCommand.isVanished(target)) {
player.sendMessage(getLang().getPrefixedString("messages.player-not-found", Map.of("player", args[0])));
if (args[0].equalsIgnoreCase(player.getName())) {
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.self"));
return true;
}
if (target.getUniqueId().equals(player.getUniqueId())) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.self"));
int remainingCooldown = manager.getRemainingSendCooldownSeconds(player);
if (remainingCooldown > 0) {
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.send-cooldown",
Map.of("seconds", String.valueOf(remainingCooldown))));
return true;
}
Player target = manager.findOnlinePlayer(args[0], onlinePlayer ->
!onlinePlayer.getUniqueId().equals(player.getUniqueId()) && !manager.isVanished(onlinePlayer)
).orElse(null);
if (target == null || !target.isOnline()) {
player.sendMessage(getLang().getPrefixedComponent("messages.player-not-found", Map.of("player", args[0])));
return true;
}
TeleportRequestManager.CreateRequestResult createdRequest = manager.createRequest(player, target, type);
if (createdRequest.status() == TeleportRequestManager.CreateRequestStatus.DUPLICATE) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.duplicate-request", Map.of("target", target.getName())));
return true;
}
if (createdRequest.status() == TeleportRequestManager.CreateRequestStatus.ON_COOLDOWN) {
player.sendMessage(getLang().getPrefixedString("tpa.messages.send-cooldown",
player.sendMessage(getLang().getPrefixedComponent("tpa.messages.send-cooldown",
Map.of("seconds", String.valueOf(createdRequest.cooldownSeconds()))));
return true;
}
TeleportRequestManager.TeleportRequest request = createdRequest.request();
Map<String, String> placeholders = manager.placeholders(request);
player.sendMessage(getLang().getPrefixedString(type == TeleportRequestManager.TeleportRequest.Type.TPA
player.sendMessage(getLang().getPrefixedComponent(type == TeleportRequestManager.TeleportRequest.Type.TPA
? "tpa.messages.sent-tpa"
: "tpa.messages.sent-tpahere", placeholders));
if (createdRequest.status() == TeleportRequestManager.CreateRequestStatus.IGNORED) {
if (createdRequest.status() == TeleportRequestManager.CreateRequestStatus.IGNORED
|| createdRequest.status() == TeleportRequestManager.CreateRequestStatus.DUPLICATE) {
return true;
}
target.sendMessage(getLang().getPrefixedString(type == TeleportRequestManager.TeleportRequest.Type.TPA
target.sendMessage(getLang().getPrefixedComponent(type == TeleportRequestManager.TeleportRequest.Type.TPA
? "tpa.messages.received-tpa"
: "tpa.messages.received-tpahere", placeholders));
manager.playRequestReceivedSound(target);
sendResponseHint(target, request, placeholders);
manager.sendResponseHint(target, placeholders);
return true;
}
private void sendResponseHint(Player target, TeleportRequestManager.TeleportRequest request, Map<String, String> placeholders) {
String requesterName = request.requesterName();
String acceptCommand = "/tpaccept " + requesterName;
String denyCommand = "/tpdeny " + requesterName;
Component hint = LegacyComponentSerializer.legacySection()
.deserialize(getLang().getPrefixedString("tpa.messages.response-hint", placeholders));
Component accept = LegacyComponentSerializer.legacySection()
.deserialize(getLang().getString("tpa.messages.accept-button"))
.clickEvent(ClickEvent.runCommand(acceptCommand))
.hoverEvent(HoverEvent.showText(Component.text(acceptCommand, NamedTextColor.GREEN)));
Component deny = LegacyComponentSerializer.legacySection()
.deserialize(getLang().getString("tpa.messages.deny-button"))
.clickEvent(ClickEvent.runCommand(denyCommand))
.hoverEvent(HoverEvent.showText(Component.text(denyCommand, NamedTextColor.RED)));
target.sendMessage(hint.append(Component.space()).append(accept).append(Component.space()).append(deny));
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
if (args.length != 1 || !(sender instanceof Player player)) {
return List.of();
}
TeleportRequestManager manager = plugin.getTeleportRequestManager();
if (manager == null) {
return List.of();
}
String partial = args[0].toLowerCase();
List<String> completions = new ArrayList<>();
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (!onlinePlayer.getUniqueId().equals(player.getUniqueId())
&& !VanishCommand.isVanished(onlinePlayer)
&& !manager.isVanished(onlinePlayer)
&& onlinePlayer.getName().toLowerCase().startsWith(partial)) {
completions.add(onlinePlayer.getName());
}