diff --git a/pom.xml b/pom.xml
index 83926d4..13f7b38 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
cn.lunadeer
EssentialsD
- 1.18.0
+ 1.18.11
jar
EssentialsD
diff --git a/src/main/java/cn/lunadeer/essentialsd/Events.java b/src/main/java/cn/lunadeer/essentialsd/Events.java
index 3542fc6..4120bd1 100644
--- a/src/main/java/cn/lunadeer/essentialsd/Events.java
+++ b/src/main/java/cn/lunadeer/essentialsd/Events.java
@@ -5,6 +5,8 @@ import cn.lunadeer.essentialsd.recipes.Crowbar;
import cn.lunadeer.essentialsd.recipes.InvisibleGlowItemFrame;
import cn.lunadeer.essentialsd.recipes.InvisibleItemFrame;
import cn.lunadeer.essentialsd.utils.Notification;
+import cn.lunadeer.essentialsd.utils.XLogger;
+import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
@@ -16,11 +18,13 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ExpBottleEvent;
+import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
@@ -192,4 +196,11 @@ public class Events implements Listener {
}
event.setExperience((int) (exp * EssentialsD.config.getExpBottleRatio()));
}
+
+ // on player death update tpManager
+ @EventHandler(priority = EventPriority.HIGHEST)
+ public void onPlayerDeath(PlayerDeathEvent event) {
+ Player player = event.getEntity();
+ EssentialsD.tpManager.updateLastTpLocation(player);
+ }
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/TeleportManager.java b/src/main/java/cn/lunadeer/essentialsd/TeleportManager.java
index 550ef4d..1c38557 100644
--- a/src/main/java/cn/lunadeer/essentialsd/TeleportManager.java
+++ b/src/main/java/cn/lunadeer/essentialsd/TeleportManager.java
@@ -2,21 +2,26 @@ package cn.lunadeer.essentialsd;
import cn.lunadeer.essentialsd.utils.Notification;
import cn.lunadeer.essentialsd.utils.STUI.Button;
+import cn.lunadeer.essentialsd.utils.XLogger;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.Location;
+import org.bukkit.World;
import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerTeleportEvent;
import java.time.LocalDateTime;
-import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
public class TeleportManager {
private static final TextColor main_color = TextColor.color(0, 233, 255);
- private final Map _tasks = new java.util.HashMap<>();
- private final Map _next_time_allow_tp = new java.util.HashMap<>();
+ private final ConcurrentHashMap _tasks = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap _next_time_allow_tp = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap _last_tp_location = new ConcurrentHashMap<>();
private static class TpTask {
public Player initiator;
@@ -102,21 +107,64 @@ public class TeleportManager {
return;
}
Notification.info(task.target, "已接受 " + task.initiator.getName() + " 的传送请求");
- Notification.info(task.initiator, "玩家 " + task.target.getName() + " 已接受你的传送请求,传送将在 " + EssentialsD.config.getTpDelay() + " 秒后进行");
+ if (EssentialsD.config.getTpDelay() > 0) {
+ Notification.info(task.initiator, "玩家 " + task.target.getName() + " 已接受你的传送请求,传送将在 " + EssentialsD.config.getTpDelay() + " 秒后进行");
+ }
EssentialsD.scheduler.global.runDelayed(EssentialsD.instance, (instance) -> {
if (task.initiator.isOnline() && task.target.isOnline()) {
- task.initiator.teleportAsync(task.target.getLocation());
+ doTeleportSafely(task.initiator, task.target.getLocation());
Notification.info(task.initiator, "已传送到 " + task.target.getName() + " 的位置");
Notification.info(task.target, "玩家 " + task.initiator.getName() + " 已传送到你的位置");
}
- }, EssentialsD.config.getTpDelay() == 0 ? 1 : 20L * EssentialsD.config.getTpDelay());
+ }, EssentialsD.config.getTpDelay() <= 0 ? 1 : 20L * EssentialsD.config.getTpDelay());
}
public void back(Player player) {
- // todo: implement back teleport
+ if (!_last_tp_location.containsKey(player.getUniqueId())) {
+ Notification.error(player, "没有找到可返回的位置");
+ return;
+ }
+ if (EssentialsD.config.getTpDelay() > 0) {
+ Notification.info(player, "将在 " + EssentialsD.config.getTpDelay() + " 秒后返回上次传送的位置");
+ }
+ EssentialsD.scheduler.global.runDelayed(EssentialsD.instance, (instance) -> {
+ doTeleportSafely(player, _last_tp_location.get(player.getUniqueId()));
+ Notification.info(player, "已返回上次传送的位置");
+ }, EssentialsD.config.getTpDelay() <= 0 ? 1 : 20L * EssentialsD.config.getTpDelay());
}
public void rtp(Player player) {
- // todo: implement rtp teleport
+ int radius = EssentialsD.config.getTpRtpRadius();
+ World world = player.getWorld();
+ int x = (int) (Math.random() * radius * 2) - radius;
+ int z = (int) (Math.random() * radius * 2) - radius;
+ XLogger.debug("RTP: " + x + " " + z);
+ Location location = new Location(world, x, player.getY(), z);
+ if (EssentialsD.config.getTpDelay() > 0) {
+ Notification.info(player, "将在 " + EssentialsD.config.getTpDelay() + " 秒后传送到随机位置");
+ }
+ EssentialsD.scheduler.global.runDelayed(EssentialsD.instance, (instance) -> {
+ doTeleportSafely(player, location);
+ Notification.info(player, "已传送到随机位置");
+ }, EssentialsD.config.getTpDelay() <= 0 ? 1 : 20L * EssentialsD.config.getTpDelay());
+ }
+
+ /**
+ * 把玩家传送到指定位置 并更新上次传送的位置
+ * 需要使用 schedule 传送
+ *
+ * @param player 玩家
+ * @param location 位置
+ */
+ private void doTeleportSafely(Player player, Location location) {
+ location.getWorld().getChunkAtAsyncUrgently(location).thenAccept((chunk) -> {
+ location.setY(chunk.getWorld().getHighestBlockYAt(location) + 1);
+ player.teleportAsync(location, PlayerTeleportEvent.TeleportCause.PLUGIN);
+ _last_tp_location.put(player.getUniqueId(), location);
+ });
+ }
+
+ public void updateLastTpLocation(Player player) {
+ _last_tp_location.put(player.getUniqueId(), player.getLocation());
}
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/commands/Back.java b/src/main/java/cn/lunadeer/essentialsd/commands/Back.java
index 5174147..a0bbe76 100644
--- a/src/main/java/cn/lunadeer/essentialsd/commands/Back.java
+++ b/src/main/java/cn/lunadeer/essentialsd/commands/Back.java
@@ -1,6 +1,7 @@
package cn.lunadeer.essentialsd.commands;
import cn.lunadeer.essentialsd.EssentialsD;
+import cn.lunadeer.essentialsd.TeleportManager;
import cn.lunadeer.essentialsd.utils.Notification;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -23,8 +24,7 @@ public class Back implements TabExecutor {
return false;
}
Player player = (Player) sender;
- // todo: implement this command
- Notification.error(player, "这个命令还没有实现");
+ EssentialsD.tpManager.back(player);
return true;
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/commands/Rtp.java b/src/main/java/cn/lunadeer/essentialsd/commands/Rtp.java
index 86765ad..3a11476 100644
--- a/src/main/java/cn/lunadeer/essentialsd/commands/Rtp.java
+++ b/src/main/java/cn/lunadeer/essentialsd/commands/Rtp.java
@@ -23,8 +23,7 @@ public class Rtp implements TabExecutor {
return false;
}
Player player = (Player) sender;
- // todo: implement this command
- Notification.error(player, "这个命令还没有实现");
+ EssentialsD.tpManager.rtp(player);
return true;
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 23671b0..357002d 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -2,7 +2,7 @@
ExpBottleRatio: 1.0
# 强加载区块列表
-ForceLoadChunks:
+ForceLoadChunks: []
# - world:0:0
# - world_the_end:-12:12
@@ -11,14 +11,14 @@ ForceLoadChunks:
# -1 为禁用强加载区块操作
ChunkOperateDelay: 10
-# 特殊合成表
+# 扩展合成表
Recipes:
CrowBar: true # 撬棍
InvisibleItemFrame: true # 隐形(发光)物品展示框
LightBlock: true # 光源方块
StackedEnchantBook: true # 附魔书堆叠
-# 特殊指令
+# 扩展指令
Commands:
EnderChest: true # 快速末影箱
Suicide: true # 自杀
@@ -36,6 +36,7 @@ Teleport:
TpaExpire: 30 # 传送请求有效期 秒
RtpRadius: 1000 # 随机传送最大半径
+# 把楼梯当作椅子使用
Chair:
Enable: true
MaxWidth: 4