From 237e7824b08f05b980b52653bfad4879697ab683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=BB=E9=AD=82=E5=9C=A3=E4=BD=BF?= Date: Sat, 21 Dec 2024 05:46:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=95=E5=85=A5TombstoneData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CoordinateRecorder.java | 19 --- .../Listener/PlayerEventListener.java | 42 ++++--- .../data/PersistentData.java | 14 +++ .../coordinateRecorder/data/PlayerData.java | 28 ++--- .../data/PlayerDeathData.java | 27 +++++ .../data/TombstoneData.java | 112 ++++++++++++++++++ 6 files changed, 187 insertions(+), 55 deletions(-) create mode 100644 src/main/java/ling/coordinateRecorder/data/PersistentData.java create mode 100644 src/main/java/ling/coordinateRecorder/data/PlayerDeathData.java create mode 100644 src/main/java/ling/coordinateRecorder/data/TombstoneData.java diff --git a/src/main/java/ling/coordinateRecorder/CoordinateRecorder.java b/src/main/java/ling/coordinateRecorder/CoordinateRecorder.java index 3938878..12c5076 100644 --- a/src/main/java/ling/coordinateRecorder/CoordinateRecorder.java +++ b/src/main/java/ling/coordinateRecorder/CoordinateRecorder.java @@ -17,10 +17,6 @@ public final class CoordinateRecorder extends JavaPlugin { private static CoordinateRecorder current; private static Database database; private static Plugin authMePlugin; - private static NamespacedKey tombstoneOwner; - private static NamespacedKey tombstoneOwnerName; - //墓碑配套盔甲架的名称 - private static NamespacedKey tombstoneOwnerTitle; private static void start() throws SQLException { database.installPlugin(); @@ -41,9 +37,6 @@ public final class CoordinateRecorder extends JavaPlugin { public void onEnable() { // Plugin startup logic current = this; - tombstoneOwner = new NamespacedKey(this, "tombstoneOwner"); - tombstoneOwnerName = new NamespacedKey(this, "tombstoneOwnerName"); - tombstoneOwnerTitle = new NamespacedKey(this, "tombstoneOwnerTitle"); authMePlugin = Bukkit.getPluginManager().getPlugin("AuthMe"); try { database = new Database(this); @@ -60,18 +53,6 @@ public final class CoordinateRecorder extends JavaPlugin { } } - public static NamespacedKey getTombstoneOwner() { - return tombstoneOwner; - } - - public static NamespacedKey getTombstoneOwnerName() { - return tombstoneOwnerName; - } - - public static NamespacedKey getTombstoneOwnerTitle() { - return tombstoneOwnerTitle; - } - @Override public void onDisable() { // Plugin shutdown logic diff --git a/src/main/java/ling/coordinateRecorder/Listener/PlayerEventListener.java b/src/main/java/ling/coordinateRecorder/Listener/PlayerEventListener.java index 9da19ca..dd592bc 100644 --- a/src/main/java/ling/coordinateRecorder/Listener/PlayerEventListener.java +++ b/src/main/java/ling/coordinateRecorder/Listener/PlayerEventListener.java @@ -2,6 +2,8 @@ package ling.coordinateRecorder.Listener; import ling.coordinateRecorder.CoordinateRecorder; import ling.coordinateRecorder.data.PlayerData; +import ling.coordinateRecorder.data.PlayerDeathData; +import ling.coordinateRecorder.data.TombstoneData; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.Chest; @@ -23,7 +25,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.MapMeta; import org.bukkit.map.*; import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; import java.time.LocalDateTime; @@ -102,14 +103,13 @@ public class PlayerEventListener implements Listener { } Chest chest = (Chest) block.getState(); PersistentDataContainer persistent = chest.getPersistentDataContainer(); - if (!persistent.has(CoordinateRecorder.getTombstoneOwner())) { + TombstoneData tombstoneData = TombstoneData.getInstance(persistent); + if (tombstoneData == null) { //没有存储元数据的箱子一定不是墓碑 return; } - String uuid = persistent.get(CoordinateRecorder.getTombstoneOwner(), PersistentDataType.STRING); - String name = persistent.get(CoordinateRecorder.getTombstoneOwnerName(), PersistentDataType.STRING); - if (!player.getUniqueId().toString().equals(uuid)) { - player.sendMessage(ChatColor.RED + "这是 " + name + " 的墓碑,你无权访问!"); + if (!player.getUniqueId().toString().equals(tombstoneData.getOwnerUuid())) { + player.sendMessage(ChatColor.RED + "这是 " + tombstoneData.getOwnerName() + " 的墓碑,你无权访问!"); event.setCancelled(true); } else { int count = 0; @@ -153,7 +153,7 @@ public class PlayerEventListener implements Listener { if (block.getType() != Material.CHEST) return; Chest chest = (Chest) block.getState(); PersistentDataContainer persistent = chest.getPersistentDataContainer(); - if (persistent.has(CoordinateRecorder.getTombstoneOwner())) { + if (TombstoneData.isTombstone(persistent)) { //有元数据的箱子一定是墓碑 System.out.println("阻止点燃"); event.setCancelled(true); @@ -169,24 +169,25 @@ public class PlayerEventListener implements Listener { player.sendMessage("玩家没有注册,跳过提供地图"); return; } - Location death = data.getDeathLocation(); + PlayerDeathData death = data.getDeathLocation(); if (death == null) return; data.setDeathLocation(null); - World deathWorld = death.getWorld(); + World deathWorld = death.getLocation().getWorld(); if (deathWorld == null) return; //计算距离,如果重生点距离死亡位置很近,则不提供地图 - if (PlayerData.isSameWorld(death, player.getLocation()) && death.distance(player.getLocation()) < 128) { + if (PlayerData.isSameWorld(death.getLocation(), player.getLocation()) && death.getLocation().distance( + player.getLocation()) < 128) { player.sendMessage("你的死亡位置距离重生点太近,本次重生不提供导向地图。"); return; } //创建地图,并设置中心为死亡位置 MapView map = Bukkit.createMap(deathWorld); - map.setCenterX(death.getBlockX()); - map.setCenterZ(death.getBlockZ()); + map.setCenterX(death.getLocation().getBlockX()); + map.setCenterZ(death.getLocation().getBlockZ()); //给予一级缩放的地图,避免找不到箱子 map.setScale(MapView.Scale.CLOSEST); map.setTrackingPosition(true); @@ -203,8 +204,8 @@ public class PlayerEventListener implements Listener { isAdd = true; // 添加目标位置标记 int scale = 1 << map.getScale().ordinal(); // 当前地图缩放比例 - int x = (death.getBlockX() - map.getCenterX()) / scale; - int z = (death.getBlockZ() - map.getCenterZ()) / scale; + int x = (death.getLocation().getBlockX() - map.getCenterX()) / scale; + int z = (death.getLocation().getBlockZ() - map.getCenterZ()) / scale; // 限制标记范围(避免标记在地图外无法显示) x = Math.max(-128, Math.min(127, x)); @@ -240,23 +241,20 @@ public class PlayerEventListener implements Listener { CoordinateRecorder.getCurrent().getLogger().info("没有找到玩家的登录信息,不生成墓碑"); return; } - data.setDeathLocation(location); + data.setDeathLocation(new PlayerDeathData(location, null)); //寻找可以生成墓碑的位置 Location save = getGraveLocation(location); Block block = save.getBlock(); - String text = ChatColor.YELLOW + "这里长眠着 " + player.getName(); - //生成一个箱子 block.setType(Material.CHEST); Chest chest = (Chest) block.getState(); //为墓碑附加元数据 PersistentDataContainer persistent = chest.getPersistentDataContainer(); - persistent.set(CoordinateRecorder.getTombstoneOwner(), PersistentDataType.STRING, - player.getUniqueId().toString()); - persistent.set(CoordinateRecorder.getTombstoneOwnerName(), PersistentDataType.STRING, player.getName()); - persistent.set(CoordinateRecorder.getTombstoneOwnerTitle(), PersistentDataType.STRING, text); + + TombstoneData tombstoneData = new TombstoneData(player, null); + tombstoneData.save(persistent); chest.setCustomName(player.getName() + " 的墓碑"); chest.update(); @@ -274,7 +272,7 @@ public class PlayerEventListener implements Listener { ArmorStand armorStand = (ArmorStand) world.spawnEntity(textLocation, EntityType.ARMOR_STAND); armorStand.setVisible(false); armorStand.setGravity(false); - armorStand.setCustomName(text); + armorStand.setCustomName(tombstoneData.getOwnerTitle()); armorStand.setCustomNameVisible(true); armorStand.setMarker(true); diff --git a/src/main/java/ling/coordinateRecorder/data/PersistentData.java b/src/main/java/ling/coordinateRecorder/data/PersistentData.java new file mode 100644 index 0000000..9da58e5 --- /dev/null +++ b/src/main/java/ling/coordinateRecorder/data/PersistentData.java @@ -0,0 +1,14 @@ +package ling.coordinateRecorder.data; + +import org.bukkit.persistence.PersistentDataContainer; + +import java.io.IOException; + +public interface PersistentData { + + void save(PersistentDataContainer data); + + void load(PersistentDataContainer data) throws IOException; + + void remove(PersistentDataContainer data); +} diff --git a/src/main/java/ling/coordinateRecorder/data/PlayerData.java b/src/main/java/ling/coordinateRecorder/data/PlayerData.java index 60724c8..6d0759e 100644 --- a/src/main/java/ling/coordinateRecorder/data/PlayerData.java +++ b/src/main/java/ling/coordinateRecorder/data/PlayerData.java @@ -10,7 +10,6 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; import org.jooq.Record; import org.jooq.Result; import org.jooq.impl.DSL; @@ -35,8 +34,8 @@ public class PlayerData { protected ScoreboardUI ui; //正在交互的墓碑 protected Block tombstoneBlock; - //上次死亡位置 - protected Location deathLocation; + //上次死亡信息 + protected PlayerDeathData death; //上次计分时间 protected long fractionTime; @@ -92,26 +91,27 @@ public class PlayerData { } Chest chest = (Chest) tombstoneBlock.getState(); PersistentDataContainer persistent = chest.getPersistentDataContainer(); - if (!persistent.has(CoordinateRecorder.getTombstoneOwnerTitle())) { + TombstoneData data = TombstoneData.getInstance(persistent); + if (data == null) { player.sendMessage(ChatColor.RED + "目标不是一个墓碑!"); return; } - String name = persistent.get(CoordinateRecorder.getTombstoneOwnerTitle(), PersistentDataType.STRING); - assert name != null; + if (!data.getOwnerUuid().equals(player.getUniqueId().toString())) { + player.sendMessage(ChatColor.RED + "不是你的墓碑,无法解锁!"); + return; + } Location location = tombstoneBlock.getLocation(); World world = location.getWorld(); assert world != null; //先清理盔甲架 for (Entity entity : world.getNearbyEntities(location, 3, 3, 3)) { - if (entity.getType() == EntityType.ARMOR_STAND && name.equals(entity.getCustomName())) { + if (entity.getType() == EntityType.ARMOR_STAND && data.getOwnerTitle().equals(entity.getCustomName())) { entity.remove(); } } //然后解除箱子的锁 - persistent.remove(CoordinateRecorder.getTombstoneOwnerTitle()); - persistent.remove(CoordinateRecorder.getTombstoneOwner()); - persistent.remove(CoordinateRecorder.getTombstoneOwnerName()); + data.remove(persistent); chest.update(); //绘制六芒星 playMagic(location); @@ -293,13 +293,13 @@ public class PlayerData { } /// 上次死亡地点 - public Location getDeathLocation() { - return deathLocation; + public PlayerDeathData getDeathLocation() { + return death; } /// 设置死亡地点 - public void setDeathLocation(Location deathLocation) { - this.deathLocation = deathLocation; + public void setDeathLocation(PlayerDeathData death) { + this.death = death; } /// 检查当前是否还有空余位置显示新的坐标点 diff --git a/src/main/java/ling/coordinateRecorder/data/PlayerDeathData.java b/src/main/java/ling/coordinateRecorder/data/PlayerDeathData.java new file mode 100644 index 0000000..040e98d --- /dev/null +++ b/src/main/java/ling/coordinateRecorder/data/PlayerDeathData.java @@ -0,0 +1,27 @@ +package ling.coordinateRecorder.data; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/// 玩家死亡信息 +public class PlayerDeathData { + /// 死亡地点 + protected Location location; + /// 击败玩家 + protected Player player; + + public PlayerDeathData(@NotNull Location location, @Nullable Player player) { + this.location = location; + this.player = player; + } + + public Location getLocation() { + return location; + } + + public Player getPlayer() { + return player; + } +} diff --git a/src/main/java/ling/coordinateRecorder/data/TombstoneData.java b/src/main/java/ling/coordinateRecorder/data/TombstoneData.java new file mode 100644 index 0000000..edffb75 --- /dev/null +++ b/src/main/java/ling/coordinateRecorder/data/TombstoneData.java @@ -0,0 +1,112 @@ +package ling.coordinateRecorder.data; + +import ling.coordinateRecorder.CoordinateRecorder; +import org.bukkit.ChatColor; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; + +/// 墓碑数据 +public class TombstoneData implements PersistentData { + private static final CoordinateRecorder current = CoordinateRecorder.getCurrent(); + /// 主人名称 + private static final NamespacedKey OWNER_NAME = new NamespacedKey(current, "tombstoneOwner"); + /// 主人uid + private static final NamespacedKey OWNER_UUID = new NamespacedKey(current, "tombstoneOwnerName"); + /// 附带盔甲架的标题 + private static final NamespacedKey OWNER_TITLE = new NamespacedKey(current, "tombstoneOwnerTitle"); + /// 击败者uid + private static final NamespacedKey OWNER_DEFEATER = new NamespacedKey(current, "tombstoneOwnerDefeater"); + + protected String ownerName; + protected String ownerUuid; + protected String ownerTitle; + protected String ownerDefeater; + + public TombstoneData(@NotNull Player owner, @Nullable Player defeater) { + ownerName = owner.getName(); + ownerUuid = owner.getUniqueId().toString(); + ownerTitle = ChatColor.YELLOW + "这里长眠着 " + owner.getName(); + ownerDefeater = defeater != null ? defeater.getUniqueId().toString() : ""; + } + + protected TombstoneData() { + } + + public static TombstoneData getInstance(PersistentDataContainer data) { + TombstoneData curr = new TombstoneData(); + try { + curr.load(data); + return curr; + } catch (IOException e) { + return null; + } + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public void setOwnerUuid(String ownerUuid) { + this.ownerUuid = ownerUuid; + } + + public void setOwnerTitle(String ownerTitle) { + this.ownerTitle = ownerTitle; + } + + public void setOwnerDefeater(String ownerDefeater) { + this.ownerDefeater = ownerDefeater; + } + + public String getOwnerName() { + return ownerName; + } + + public String getOwnerUuid() { + return ownerUuid; + } + + public String getOwnerTitle() { + return ownerTitle; + } + + public String getOwnerDefeater() { + return ownerDefeater; + } + + public static boolean isTombstone(PersistentDataContainer data) { + return data.has(OWNER_NAME) && data.has(OWNER_UUID) && data.has(OWNER_TITLE) && data.has(OWNER_DEFEATER); + } + + @Override + public void save(PersistentDataContainer data) { + data.set(OWNER_NAME, PersistentDataType.STRING, ownerName); + data.set(OWNER_UUID, PersistentDataType.STRING, ownerUuid); + data.set(OWNER_TITLE, PersistentDataType.STRING, ownerTitle); + data.set(OWNER_DEFEATER, PersistentDataType.STRING, ownerDefeater); + } + + @Override + public void load(PersistentDataContainer data) throws IOException { + if (!isTombstone(data)) + throw new IOException("没有有效数据!"); + this.ownerName = data.get(OWNER_NAME, PersistentDataType.STRING); + this.ownerUuid = data.get(OWNER_UUID, PersistentDataType.STRING); + this.ownerTitle = data.get(OWNER_TITLE, PersistentDataType.STRING); + this.ownerDefeater = data.get(OWNER_DEFEATER, PersistentDataType.STRING); + } + + @Override + public void remove(PersistentDataContainer data) { + data.remove(OWNER_NAME); + data.remove(OWNER_UUID); + data.remove(OWNER_TITLE); + data.remove(OWNER_DEFEATER); + } +}