diff --git a/pom.xml b/pom.xml
index 51a623d..a77388a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
cn.lunadeer
EssentialsD
- 2.0.3
+ 2.1.0
jar
EssentialsD
diff --git a/src/main/java/cn/lunadeer/essentialsd/commands/warp/DelWarp.java b/src/main/java/cn/lunadeer/essentialsd/commands/warp/DelWarp.java
index 6a792ac..ba39c04 100644
--- a/src/main/java/cn/lunadeer/essentialsd/commands/warp/DelWarp.java
+++ b/src/main/java/cn/lunadeer/essentialsd/commands/warp/DelWarp.java
@@ -1,14 +1,35 @@
package cn.lunadeer.essentialsd.commands.warp;
+import cn.lunadeer.essentialsd.dtos.WarpPoint;
+import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-public class DelWarp implements CommandExecutor {
+import java.util.List;
+
+public class DelWarp implements TabExecutor {
+
+ /**
+ * /delwarp
+ */
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
- // todo
- return false;
+ WarpPoint point = WarpPoint.selectByName(strings[0]);
+ if (point == null) {
+ Notification.error(commandSender, "传送点 %s 不存在", strings[0]);
+ return true;
+ }
+ WarpPoint.delete(point);
+ Notification.info(commandSender, "传送点 %s 已删除", strings[0]);
+ return true;
+ }
+
+ @Override
+ public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
+ return WarpPoint.selectAllNames();
}
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/commands/warp/SetWarp.java b/src/main/java/cn/lunadeer/essentialsd/commands/warp/SetWarp.java
index 4aca849..b17aa9b 100644
--- a/src/main/java/cn/lunadeer/essentialsd/commands/warp/SetWarp.java
+++ b/src/main/java/cn/lunadeer/essentialsd/commands/warp/SetWarp.java
@@ -1,14 +1,86 @@
package cn.lunadeer.essentialsd.commands.warp;
+import cn.lunadeer.essentialsd.EssentialsD;
+import cn.lunadeer.essentialsd.dtos.WarpPoint;
+import cn.lunadeer.minecraftpluginutils.Notification;
+import org.bukkit.Location;
+import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-public class SetWarp implements CommandExecutor {
+import java.util.ArrayList;
+import java.util.List;
+
+public class SetWarp implements TabExecutor {
+ /**
+ * /setwarp
+ * /setwarp
+ */
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
- // todo
- return false;
+ if (strings.length != 1 && strings.length != 5) {
+ Notification.error(commandSender, "用法: /setwarp 或 /setwarp ");
+ return true;
+ }
+ String name = strings[0];
+ Location location;
+ if (strings.length == 1) {
+ if (commandSender instanceof Player) {
+ location = ((Player) commandSender).getLocation();
+ } else {
+ Notification.error(commandSender, "请指定坐标 /setwarp ");
+ return true;
+ }
+ } else {
+ try {
+ double x = Double.parseDouble(strings[1]);
+ double y = Double.parseDouble(strings[2]);
+ double z = Double.parseDouble(strings[3]);
+ World world = EssentialsD.instance.getServer().getWorld(strings[0]);
+ if (world == null) {
+ Notification.error(commandSender, "世界 %s 不存在", strings[0]);
+ return true;
+ }
+ location = new Location(world, x, y, z);
+ } catch (NumberFormatException e) {
+ Notification.error(commandSender, "坐标必须是数字");
+ return true;
+ }
+ }
+ WarpPoint existing = WarpPoint.selectByName(name);
+ if (existing != null) {
+ Notification.error(commandSender, "传送点 %s 已存在", name);
+ return true;
+ }
+ WarpPoint point = new WarpPoint(name, location);
+ WarpPoint.insert(point);
+ Notification.info(commandSender, "传送点 %s 已设置", name);
+ return true;
+ }
+
+ @Override
+ public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
+ List res = new ArrayList<>();
+ if (args.length == 1) {
+ res.add("传送点名称");
+ }
+ if (args.length == 2) {
+ res.add("世界名称");
+ }
+ if (args.length == 3) {
+ res.add("x");
+ }
+ if (args.length == 4) {
+ res.add("y");
+ }
+ if (args.length == 5) {
+ res.add("z");
+ }
+ return res;
}
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warp.java b/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warp.java
index 1dd8fe1..4fc3a5a 100644
--- a/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warp.java
+++ b/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warp.java
@@ -1,14 +1,50 @@
package cn.lunadeer.essentialsd.commands.warp;
+import cn.lunadeer.essentialsd.EssentialsD;
+import cn.lunadeer.essentialsd.dtos.WarpPoint;
+import cn.lunadeer.essentialsd.managers.TeleportManager;
+import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-public class Warp implements CommandExecutor {
+import java.util.List;
+
+public class Warp implements TabExecutor {
+
+ /**
+ * /warp
+ */
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
- // todo
- return false;
+ if (!(commandSender instanceof Player)) {
+ Notification.warn(commandSender, "只有玩家可以使用此命令");
+ return true;
+ }
+ Player player = (Player) commandSender;
+ WarpPoint point = WarpPoint.selectByName(strings[0]);
+ if (point == null) {
+ Notification.error(commandSender, "传送点 %s 不存在", strings[0]);
+ return true;
+ }
+ try {
+ EssentialsD.tpManager.doTeleportDelayed(player, point.getLocation(), EssentialsD.config.getTpDelay(), () -> {
+ Notification.info(player, "正在传送到 %s", strings[0]);
+ }, () -> {
+ Notification.info(player, "已传送到 %s", strings[0]);
+ });
+ } catch (RuntimeException e) {
+ Notification.error(player, e.getMessage());
+ }
+ return true;
+ }
+
+ @Override
+ public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
+ return WarpPoint.selectAllNames();
}
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warps.java b/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warps.java
index 969b6bd..2739f45 100644
--- a/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warps.java
+++ b/src/main/java/cn/lunadeer/essentialsd/commands/warp/Warps.java
@@ -1,5 +1,6 @@
package cn.lunadeer.essentialsd.commands.warp;
+import cn.lunadeer.essentialsd.tuis.WarpList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -8,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
public class Warps implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
- // todo
- return false;
+ WarpList.show(commandSender, strings);
+ return true;
}
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/dtos/WarpPoint.java b/src/main/java/cn/lunadeer/essentialsd/dtos/WarpPoint.java
new file mode 100644
index 0000000..8336484
--- /dev/null
+++ b/src/main/java/cn/lunadeer/essentialsd/dtos/WarpPoint.java
@@ -0,0 +1,100 @@
+package cn.lunadeer.essentialsd.dtos;
+
+import cn.lunadeer.essentialsd.EssentialsD;
+import cn.lunadeer.essentialsd.utils.LocUtil;
+import org.bukkit.Location;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WarpPoint {
+ private Integer id;
+ private final String name;
+ private final Location location;
+
+ public WarpPoint(Integer id, String name, Location location) {
+ this.id = id;
+ this.name = name;
+ this.location = location;
+ }
+
+ public WarpPoint(String name, Location location) {
+ this.name = name;
+ this.location = location;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public static void insert(WarpPoint point) {
+ String sql = "INSERT INTO warp_point (warp_name, location) VALUES (?, ?);";
+ try (ResultSet rs = EssentialsD.database.query(sql, point.getName(), LocUtil.toString(point.getLocation()))) {
+ if (rs == null) return;
+ } catch (Exception e) {
+ EssentialsD.database.handleDatabaseError("插入传送点失败", e, sql);
+ }
+ }
+
+ public static void delete(WarpPoint point) {
+ String sql = "DELETE FROM warp_point WHERE warp_name = ?;";
+ try (ResultSet rs = EssentialsD.database.query(sql, point.getName())) {
+ if (rs == null) return;
+ } catch (Exception e) {
+ EssentialsD.database.handleDatabaseError("删除传送点失败", e, sql);
+ }
+ }
+
+ public static WarpPoint selectByName(String name) {
+ String sql = "SELECT * FROM warp_point WHERE warp_name = ?;";
+ try (ResultSet rs = EssentialsD.database.query(sql, name)) {
+ if (rs == null) return null;
+ if (rs.next()) {
+ return new WarpPoint(rs.getInt("id"), rs.getString("warp_name"), LocUtil.fromString(rs.getString("location")));
+ }
+ } catch (Exception e) {
+ EssentialsD.database.handleDatabaseError("查询传送点失败", e, sql);
+ return null;
+ }
+ return null;
+ }
+
+ public static List selectAllNames() {
+ List names = new ArrayList<>();
+ String sql = "SELECT DISTINCT warp_name FROM warp_point;";
+ try (ResultSet rs = EssentialsD.database.query(sql)) {
+ if (rs == null) return names;
+ while (rs.next()) {
+ names.add(rs.getString("warp_name"));
+ }
+ } catch (Exception e) {
+ EssentialsD.database.handleDatabaseError("查询传送点名字失败", e, sql);
+ return names;
+ }
+ return names;
+ }
+
+ public static List selectAll() {
+ List points = new ArrayList<>();
+ String sql = "SELECT * FROM warp_point;";
+ try (ResultSet rs = EssentialsD.database.query(sql)) {
+ if (rs == null) return points;
+ while (rs.next()) {
+ points.add(new WarpPoint(rs.getInt("id"), rs.getString("warp_name"), LocUtil.fromString(rs.getString("location"))));
+ }
+ } catch (Exception e) {
+ EssentialsD.database.handleDatabaseError("查询传送点失败", e, sql);
+ return points;
+ }
+ return points;
+ }
+}
diff --git a/src/main/java/cn/lunadeer/essentialsd/managers/DatabaseTables.java b/src/main/java/cn/lunadeer/essentialsd/managers/DatabaseTables.java
index 5b4f290..4454092 100644
--- a/src/main/java/cn/lunadeer/essentialsd/managers/DatabaseTables.java
+++ b/src/main/java/cn/lunadeer/essentialsd/managers/DatabaseTables.java
@@ -84,5 +84,13 @@ public class DatabaseTables {
" FOREIGN KEY (uuid) REFERENCES player_name(uuid) ON DELETE CASCADE" +
");";
EssentialsD.database.query(sql);
+
+ // warp info
+ sql = "CREATE TABLE IF NOT EXISTS warp_point (" +
+ " id SERIAL PRIMARY KEY," +
+ " warp_name TEXT NOT NULL," +
+ " location TEXT NOT NULL" +
+ ");";
+ EssentialsD.database.query(sql);
}
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/tuis/HomeList.java b/src/main/java/cn/lunadeer/essentialsd/tuis/HomeList.java
index 2e93d74..17840fc 100644
--- a/src/main/java/cn/lunadeer/essentialsd/tuis/HomeList.java
+++ b/src/main/java/cn/lunadeer/essentialsd/tuis/HomeList.java
@@ -19,7 +19,7 @@ public class HomeList {
}
Player player = (Player) sender;
List homes = HomeInfo.getHomesOf(((Player) sender).getUniqueId());
- if (homes.size() == 0) {
+ if (homes.isEmpty()) {
Notification.warn(player, "你还没有设置家");
return;
}
diff --git a/src/main/java/cn/lunadeer/essentialsd/tuis/WarpList.java b/src/main/java/cn/lunadeer/essentialsd/tuis/WarpList.java
new file mode 100644
index 0000000..7539a8b
--- /dev/null
+++ b/src/main/java/cn/lunadeer/essentialsd/tuis/WarpList.java
@@ -0,0 +1,45 @@
+package cn.lunadeer.essentialsd.tuis;
+
+import cn.lunadeer.essentialsd.dtos.HomeInfo;
+import cn.lunadeer.essentialsd.dtos.WarpPoint;
+import cn.lunadeer.essentialsd.utils.LocUtil;
+import cn.lunadeer.minecraftpluginutils.Notification;
+import cn.lunadeer.minecraftpluginutils.stui.ListView;
+import cn.lunadeer.minecraftpluginutils.stui.components.Button;
+import cn.lunadeer.minecraftpluginutils.stui.components.Line;
+import net.kyori.adventure.text.Component;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.List;
+
+public class WarpList {
+ public static void show(CommandSender sender, String[] args) {
+ if (!(sender instanceof Player)) {
+ Notification.warn(sender, "只有玩家可以使用此命令");
+ return;
+ }
+ Player player = (Player) sender;
+ List points = WarpPoint.selectAll();
+ if (points.isEmpty()) {
+ Notification.warn(player, "没有传送点");
+ return;
+ }
+ int page = 1;
+ if (args.length == 1) {
+ try {
+ page = Integer.parseInt(args[0]);
+ } catch (Exception ignored) {
+ }
+ }
+ ListView view = ListView.create(5, "/warps");
+ view.title("Warp 列表");
+ for (WarpPoint point : points) {
+ Line line = Line.create()
+ .append(Component.text(point.getName()).hoverEvent(Component.text(LocUtil.toString(point.getLocation()))))
+ .append(Button.create("传送").setExecuteCommand("/warp " + point.getName()).build());
+ view.add(line);
+ }
+ view.showOn(player, page);
+ }
+}
diff --git a/src/main/java/cn/lunadeer/essentialsd/utils/LocUtil.java b/src/main/java/cn/lunadeer/essentialsd/utils/LocUtil.java
new file mode 100644
index 0000000..d100ae5
--- /dev/null
+++ b/src/main/java/cn/lunadeer/essentialsd/utils/LocUtil.java
@@ -0,0 +1,23 @@
+package cn.lunadeer.essentialsd.utils;
+
+import org.bukkit.Location;
+
+public class LocUtil {
+
+ public static String toString(Location loc) {
+ return String.format("[%s, %.2f, %.2f, %.2f, %.2f, %.2f]", loc.getWorld().getName(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
+ }
+
+ public static Location fromString(String str) {
+ String[] parts = str.substring(1, str.length() - 1).split(", ");
+ return new Location(
+ org.bukkit.Bukkit.getWorld(parts[0]),
+ Double.parseDouble(parts[1]),
+ Double.parseDouble(parts[2]),
+ Double.parseDouble(parts[3]),
+ Float.parseFloat(parts[4]),
+ Float.parseFloat(parts[5])
+ );
+ }
+
+}