引入TombstoneData

This commit is contained in:
2024-12-21 05:46:28 +08:00
parent fefae68bec
commit 237e7824b0
6 changed files with 187 additions and 55 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
}
/// 检查当前是否还有空余位置显示新的坐标点

View File

@@ -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;
}
}

View File

@@ -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);
}
}