From 4b68b00f1381621cff9ce421a80c438a005d91b3 Mon Sep 17 00:00:00 2001 From: MineSunshineone Date: Sun, 19 Jan 2025 21:31:19 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E5=AE=9E=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../landmark/listener/PlayerListener.java | 23 ----- .../landmark/manager/LandmarkManager.java | 94 ------------------- .../landmark/model/Landmark.java | 9 -- 3 files changed, 126 deletions(-) diff --git a/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java b/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java index bf28c32..7b5ce93 100644 --- a/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java +++ b/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java @@ -10,15 +10,12 @@ import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Interaction; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -305,26 +302,6 @@ public void onPlayerInteract(PlayerInteractEvent event) { } } - @EventHandler - public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) { - Entity entity = event.getRightClicked(); - if (!(entity instanceof Interaction)) { - return; - } - - Player player = event.getPlayer(); - - // 检查是否是锚点交互实体 - for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) { - if (landmark.getInteractionEntityId() != null - && landmark.getInteractionEntityId().equals(entity.getUniqueId())) { - event.setCancelled(true); - new LandmarkMenu(plugin, player).open(); - break; - } - } - } - @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { UUID playerId = event.getPlayer().getUniqueId(); diff --git a/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java b/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java index f020292..5ed6db5 100644 --- a/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java +++ b/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java @@ -10,17 +10,14 @@ import java.util.Set; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; -import org.bukkit.entity.Interaction; import org.bukkit.entity.Player; import ict.minesunshineone.landmark.LandmarkPlugin; import ict.minesunshineone.landmark.model.Landmark; -import net.kyori.adventure.text.Component; public class LandmarkManager { @@ -55,9 +52,6 @@ public void createLandmark(String name, Location location, String description) { Landmark landmark = new Landmark(name, location, description, menuPosition[0], menuPosition[1]); landmarks.put(name.toLowerCase(), landmark); - // 使用统一的方法创建实体 - createLandmarkEntities(landmark); - plugin.getSLF4JLogger().info("成功创建锚点展示实体: {}", name); saveData(); } catch (IllegalArgumentException | IllegalStateException e) { @@ -107,25 +101,6 @@ public void deleteLandmark(String name) { String lowerName = name.toLowerCase(); Landmark landmark = landmarks.get(lowerName); if (landmark != null) { - // 移除交互实体 - if (landmark.getInteractionEntityId() != null) { - Location loc = landmark.getLocation(); - if (loc != null && loc.getWorld() != null) { - // 移除交互实体 - Entity entity = Bukkit.getEntity(landmark.getInteractionEntityId()); - if (entity != null) { - entity.remove(); - } - - // 移除同位置的所有具有相同名称的交互实体 - loc.getWorld().getNearbyEntities(loc, 2, 2, 2).stream() - .filter(e -> e instanceof Interaction) - .filter(e -> e.customName() != null && e.customName().equals(Component.text("§e[点击打开]"))) - .forEach(Entity::remove); - } - landmark.setInteractionEntityId(null); - } - // 移除锚点数据 landmarks.remove(lowerName); @@ -254,19 +229,7 @@ public final void loadData() { int menuColumn = landmarkSection.getInt("menu_column", 1); Landmark landmark = new Landmark(key, location, description, menuRow, menuColumn); - String interactionId = landmarkSection.getString("interaction_entity_id"); - if (interactionId != null) { - landmark.setInteractionEntityId(UUID.fromString(interactionId)); - } - landmarks.put(key.toLowerCase(), landmark); - - // 延迟创建实体,确保世界加载完成 - plugin.getServer().getRegionScheduler().runDelayed(plugin, location, task -> { - if (location.getWorld() != null && location.getChunk().isLoaded()) { - createLandmarkEntities(landmark); - } - }, 100L); } } catch (IllegalArgumentException | IllegalStateException e) { plugin.getSLF4JLogger().error("加载锚点 {} 时发生错误: {}", key, e.getMessage()); @@ -308,8 +271,6 @@ public void saveData() { Landmark landmark = entry.getValue(); landmarkSection.set("location", landmark.getLocation()); landmarkSection.set("description", landmark.getDescription()); - landmarkSection.set("interaction_entity_id", landmark.getInteractionEntityId() != null - ? landmark.getInteractionEntityId().toString() : null); landmarkSection.set("menu_row", landmark.getMenuRow()); landmarkSection.set("menu_column", landmark.getMenuColumn()); } @@ -428,68 +389,13 @@ public boolean isPlayerNearLandmark(Player player, Location landmarkLoc) { && playerLoc.distance(landmarkLoc) <= plugin.getConfigManager().getUnlockRadius(); } - private void createLandmarkEntities(Landmark landmark) { - try { - Location location = landmark.getLocation(); - if (location.getWorld() == null || !location.getChunk().isLoaded()) { - return; - } - - // 确保位置是方块中心 - Location centerLoc = location.clone(); - centerLoc.setX(location.getBlockX() + 0.5); - centerLoc.setY(location.getBlockY()); - centerLoc.setZ(location.getBlockZ() + 0.5); - - // 创建交互实体 - Location interactLoc = centerLoc.clone().add(0, 0, 0); - Interaction interaction = location.getWorld().spawn(interactLoc, Interaction.class, entity -> { - entity.setInteractionWidth(3.5f); - entity.setInteractionHeight(2.0f); - entity.setPersistent(true); - entity.setInvulnerable(true); - entity.setCustomNameVisible(true); - entity.customName(Component.text("§e[点击打开]")); - entity.setGravity(false); - }); - - landmark.setInteractionEntityId(interaction.getUniqueId()); - saveData(); // 保存实体ID - } catch (IllegalArgumentException | IllegalStateException e) { - plugin.getSLF4JLogger().error("重建锚点实体时发生错误: {}", e.getMessage()); - } - } - public void cleanup() { - // 清理所有实体 - for (Landmark landmark : landmarks.values()) { - removeLandmarkEntities(landmark); - } - // 清理数据结构 landmarks.clear(); unlockedLandmarks.clear(); cooldowns.clear(); } - private void removeLandmarkEntities(Landmark landmark) { - if (landmark.getDisplayEntityId() != null) { - Entity entity = Bukkit.getEntity(landmark.getDisplayEntityId()); - if (entity != null) { - entity.remove(); - } - landmark.setDisplayEntityId(null); - } - - if (landmark.getInteractionEntityId() != null) { - Entity entity = Bukkit.getEntity(landmark.getInteractionEntityId()); - if (entity != null) { - entity.remove(); - } - landmark.setInteractionEntityId(null); - } - } - public void updateMenuPosition(String landmarkName, int newRow, int newColumn) { Landmark landmark = landmarks.get(landmarkName.toLowerCase()); if (landmark != null) { diff --git a/src/main/java/ict/minesunshineone/landmark/model/Landmark.java b/src/main/java/ict/minesunshineone/landmark/model/Landmark.java index 66c198e..82c7ec7 100644 --- a/src/main/java/ict/minesunshineone/landmark/model/Landmark.java +++ b/src/main/java/ict/minesunshineone/landmark/model/Landmark.java @@ -10,7 +10,6 @@ public class Landmark { private Location location; private String description; private UUID displayEntityId; - private UUID interactionEntityId; private int menuRow; // 在菜单中的行位置 private int menuColumn; // 在菜单中的列位置 @@ -62,14 +61,6 @@ public void setDisplayEntityId(UUID displayEntityId) { this.displayEntityId = displayEntityId; } - public UUID getInteractionEntityId() { - return interactionEntityId; - } - - public void setInteractionEntityId(UUID interactionEntityId) { - this.interactionEntityId = interactionEntityId; - } - public int getMenuRow() { return menuRow; } From 405136d3f69ce5718997596c7a6073d3236387a0 Mon Sep 17 00:00:00 2001 From: MineSunshineone Date: Sun, 19 Jan 2025 21:35:42 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=8D=A2=E4=B8=80=E7=A7=8D=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../landmark/listener/PlayerListener.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java b/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java index 7b5ce93..d1233a5 100644 --- a/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java +++ b/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java @@ -8,7 +8,6 @@ import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; -import org.bukkit.block.Block; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -282,22 +281,19 @@ public void cleanup() { @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + // 只监听右键空气 + if (event.getAction() != Action.RIGHT_CLICK_AIR) { return; } - Block block = event.getClickedBlock(); - if (block == null) { - return; - } + Player player = event.getPlayer(); - // 检查是否是锚点中心方块 + // 检查玩家是否在任意锚点范围内 for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) { - Location landmarkLoc = landmark.getLocation(); - if (block.getLocation().equals(landmarkLoc)) { - event.setCancelled(true); - new LandmarkMenu(plugin, event.getPlayer()).open(); - break; + if (plugin.getLandmarkManager().isPlayerNearLandmark(player, landmark.getLocation())) { + // 在锚点范围内,打开菜单 + new LandmarkMenu(plugin, player).open(); + return; } } } From 12f6e58c0b2ac32c9141bfc305f99172ce9e090c Mon Sep 17 00:00:00 2001 From: MineSunshineone Date: Sun, 19 Jan 2025 22:29:16 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=8B?= =?UTF-8?q?=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 不知道为什么右键点击事件没用 --- pom.xml | 2 +- .../landmark/listener/PlayerListener.java | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 90fde81..8c3431e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ict.minesunshineone LandmarkSystem - 1.6 + 1.7 21 diff --git a/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java b/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java index d1233a5..0c68877 100644 --- a/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java +++ b/src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java @@ -279,22 +279,28 @@ public void cleanup() { lastCheckTimes.clear(); } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST) public void onPlayerInteract(PlayerInteractEvent event) { - // 只监听右键空气 - if (event.getAction() != Action.RIGHT_CLICK_AIR) { - return; - } - + Action action = event.getAction(); Player player = event.getPlayer(); - // 检查玩家是否在任意锚点范围内 - for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) { - if (plugin.getLandmarkManager().isPlayerNearLandmark(player, landmark.getLocation())) { - // 在锚点范围内,打开菜单 - new LandmarkMenu(plugin, player).open(); + // 检查是否是左键动作,并且点击的是空气(不要问为什么不右键,因为右键的事件好像有问题) + if (action == Action.LEFT_CLICK_AIR) { + // 检查权限 + if (!player.hasPermission("landmark.menu")) { return; } + + // 检查玩家是否在任意锚点范围内 + for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) { + if (plugin.getLandmarkManager().isPlayerNearLandmark(player, landmark.getLocation())) { + // 在锚点范围内,打开菜单 + plugin.getServer().getRegionScheduler().execute(plugin, player.getLocation(), () -> { + new LandmarkMenu(plugin, player).open(); + }); + return; + } + } } } From 96165290fbc342ac46bfdb035e3dc6bd5b406805 Mon Sep 17 00:00:00 2001 From: MineSunshineone Date: Sun, 19 Jan 2025 22:41:36 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9D=83=E9=99=90?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=92=8C=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../landmark/command/LandmarkCommand.java | 2 + .../command/impl/UnlockAllCommand.java | 38 +++++++++++++++++++ .../landmark/manager/LandmarkManager.java | 17 +++++++++ src/main/resources/config.yml | 7 +--- src/main/resources/plugin.yml | 6 +++ 5 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ict/minesunshineone/landmark/command/impl/UnlockAllCommand.java diff --git a/src/main/java/ict/minesunshineone/landmark/command/LandmarkCommand.java b/src/main/java/ict/minesunshineone/landmark/command/LandmarkCommand.java index 1cf0a67..11e72f7 100644 --- a/src/main/java/ict/minesunshineone/landmark/command/LandmarkCommand.java +++ b/src/main/java/ict/minesunshineone/landmark/command/LandmarkCommand.java @@ -20,6 +20,7 @@ import ict.minesunshineone.landmark.command.impl.ReloadCommand; import ict.minesunshineone.landmark.command.impl.RenameCommand; import ict.minesunshineone.landmark.command.impl.TeleportCommand; +import ict.minesunshineone.landmark.command.impl.UnlockAllCommand; public class LandmarkCommand implements CommandExecutor, TabCompleter { @@ -40,6 +41,7 @@ private void registerSubCommands() { subCommands.put("rename", new RenameCommand(plugin)); subCommands.put("edit", new EditCommand(plugin)); subCommands.put("reload", new ReloadCommand(plugin)); + subCommands.put("unlockall", new UnlockAllCommand(plugin)); } @Override diff --git a/src/main/java/ict/minesunshineone/landmark/command/impl/UnlockAllCommand.java b/src/main/java/ict/minesunshineone/landmark/command/impl/UnlockAllCommand.java new file mode 100644 index 0000000..7ae1dc6 --- /dev/null +++ b/src/main/java/ict/minesunshineone/landmark/command/impl/UnlockAllCommand.java @@ -0,0 +1,38 @@ +package ict.minesunshineone.landmark.command.impl; + +import java.util.Collections; +import java.util.List; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import ict.minesunshineone.landmark.LandmarkPlugin; +import ict.minesunshineone.landmark.command.SubCommand; + +public class UnlockAllCommand extends SubCommand { + + public UnlockAllCommand(LandmarkPlugin plugin) { + super(plugin); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) { + plugin.getConfigManager().sendMessage(sender, "command-player-only", "该命令只能由玩家执行!"); + return; + } + + Player player = (Player) sender; + plugin.getLandmarkManager().unlockAllLandmarks(player); + } + + @Override + public String getPermission() { + return "landmark.unlock.all"; + } + + @Override + public List onTabComplete(CommandSender sender, String[] args) { + return Collections.emptyList(); + } +} diff --git a/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java b/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java index 5ed6db5..e2e939c 100644 --- a/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java +++ b/src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java @@ -131,6 +131,10 @@ public void unlockLandmark(Player player, String landmarkName) { } public boolean canTeleport(Player player) { + // 如果玩家有无视冷却权限,直接返回true + if (player.hasPermission("landmark.bypass.cooldown")) { + return true; + } long lastTeleport = cooldowns.getOrDefault(player.getUniqueId(), 0L); long cooldownTime = plugin.getConfigManager().getCooldownTime() * 1000L; return System.currentTimeMillis() - lastTeleport >= cooldownTime; @@ -407,4 +411,17 @@ public void updateMenuPosition(String landmarkName, int newRow, int newColumn) { } } } + + // 新增一键解锁所有锚点的方法 + public void unlockAllLandmarks(Player player) { + if (!player.hasPermission("landmark.unlock.all")) { + return; + } + Set playerUnlocked = unlockedLandmarks.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>()); + for (String landmarkName : landmarks.keySet()) { + playerUnlocked.add(landmarkName.toLowerCase()); + } + savePlayerData(player.getUniqueId()); + plugin.getConfigManager().sendMessage(player, "unlock-all-success", "✧ 魔法师解开了所有锚点的封印!"); + } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0532c90..9e86db0 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -41,12 +41,7 @@ messages: separator: '✧══════════ 魔法锚点咒语书 ══════════✧' command: '%prefix% %command%' landmark-exists: '✧ 魔法师,这个锚点名称已被占用了!' - create-title: '✧══════════ 魔法锚点 ══════════✧' - create-subtitle: '成功创造新的锚点!' - delete-title: '✧══════════ 魔法锚点 ══════════✧' - delete-subtitle: '锚点已被抹除!' - rename-title: '✧══════════ 魔法锚点 ══════════✧' - rename-subtitle: '锚点重命名成功!' + unlock-all-success: '✧ 魔法师成功解开了所有锚点的封印!' # GUI设置 gui: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index d12f910..074d5d4 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -39,4 +39,10 @@ permissions: default: true landmark.admin: description: 管理员权限 + default: op + landmark.unlock.all: + description: 允许一键解锁所有锚点 + default: op + landmark.bypass.cooldown: + description: 允许无视传送冷却 default: op \ No newline at end of file