diff --git a/src/main/java/ling/coordinateRecorder/Commands/Help.java b/src/main/java/ling/coordinateRecorder/Commands/Help.java new file mode 100644 index 0000000..61e293c --- /dev/null +++ b/src/main/java/ling/coordinateRecorder/Commands/Help.java @@ -0,0 +1,92 @@ +package ling.coordinateRecorder.Commands; + +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/// 帮助信息 +public class Help { + protected static final String[] HELP_LIST = { + "欢迎使用坐标管理器!你好,%s\n\n本书将向你介绍如何使用指令记录曾探索过的地点,以避免迷路\n\n如果需要再次查看帮助信息,请使用\n/zb help", + """ +添加地标 + +/zb add <地点名称> <固定> + +记录当前地点到数据库中,例如 +/zb add Home +将会记录当前的位置,取名为Home,并固定到屏幕右侧 +如果不想固定到屏幕右侧,可以像这样使用 +/zb add Home false""", + """ +查看已保存地标 + +/zb list + +这将列出已经记录的地标,使用 Page 参数指定页码,例如显示第三页地标内容可以像这样使用: + +/zb list 3 +""", + """ +删除地标 + +/zb remove + +使用remove子命令可以删除一个已经保存的地标,例如 +/zb remove Home +""", + """ +固定和取消固定 + +/zb fixed +/zb unfixed + +如果你想将一个地标固定显示在屏幕右侧,使用 fixed。要取消固定,使用unfixed: + +/zb fixed Home +/zb unfixed Home +""", + """ +重新载入数据 + +/zb reload + +如果你的各项数据不是最新,请使用此命令重新载入。 + +注意!滥用此功能可能被服务器列入不受欢迎名单! +""", + """ +物品保护 + +玩家死亡后,将在原地生成一个上锁的箱子,收纳你的凋落物,我们称之为“墓碑”。 +墓碑将上锁,只有你自己可以解锁(存在例外情况,下文介绍),墓碑解锁后就和普通箱子没有区别了。 +解锁墓碑将增加玩家“沙雕值”,沙雕值过高将无法解锁墓碑。 +""", + """ +你可以付出更多的沙雕值来解锁由你击败的玩家的墓碑! +""", + """ +沙雕值 + +一种具备惩罚性质的数据,沙雕值过高将获得一系列debuff。 +使用此命令检查玩家沙雕值: +/zb sb +""", + """ +PVP惩罚 + +当你击败其他玩家后,将获得沙雕值,另外,你将有机会解锁该玩家本次生成的墓碑。 +如果被其他玩家击败,你可以复仇,复仇不会面临PVP惩罚,而且可以免费解锁该玩家的墓碑。 +""" + }; + + public static List getHelp(Player player) { + List help = Arrays.asList(HELP_LIST); + List list = new ArrayList<>(help); + list.removeFirst(); + list.addFirst(String.format(HELP_LIST[0], player.getName())); + return list; + } +} diff --git a/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java b/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java index 4433baa..eeebdff 100644 --- a/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java +++ b/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java @@ -4,6 +4,7 @@ import ling.coordinateRecorder.CoordinateRecorder; import ling.coordinateRecorder.Listener.PlayerMap; import ling.coordinateRecorder.data.PlayerData; import ling.database.tables.records.LocationnotepadPO; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.Command; @@ -11,6 +12,7 @@ import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; @@ -28,7 +30,7 @@ import static ling.database.tables.LocationnotepadTB.LOCATIONNOTEPAD; public class ZbCommand implements CommandExecutor, TabCompleter { protected final static List TAB_1 = Arrays.asList("add", "remove", "help", "reload", "list", "fixed", - "unfixed", "unlock"); + "unfixed", "unlock", "sb"); public ZbCommand() { @@ -58,8 +60,7 @@ public class ZbCommand implements CommandExecutor, TabCompleter { return; } try { - if (data.addLocation(name, isFixed)) - player.sendMessage("坐标记录完毕!"); + if (data.addLocation(name, isFixed)) player.sendMessage("坐标记录完毕!"); } catch (SQLException e) { CoordinateRecorder.getCurrent().getLogger().severe("记录坐标出错:" + e.getMessage()); player.sendMessage(ChatColor.RED + "服务器内部错误:记录数据失败"); @@ -92,9 +93,8 @@ public class ZbCommand implements CommandExecutor, TabCompleter { //开始查询数据 var ctx = CoordinateRecorder.getDatabase().getDSL(); - Integer count = ctx.select(DSL.count()).from(LOCATIONNOTEPAD) - .where(LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()) - .and(LOCATIONNOTEPAD.ISDELETE.eq(false))) + Integer count = ctx.select(DSL.count()).from(LOCATIONNOTEPAD).where( + LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()).and(LOCATIONNOTEPAD.ISDELETE.eq(false))) .fetchOne(DSL.count()); assert count != null; int pageCount = (count / PAGE_SIZE) + (count % PAGE_SIZE == 0 ? 0 : 1); @@ -104,10 +104,10 @@ public class ZbCommand implements CommandExecutor, TabCompleter { return; } - List result = ctx.select().from(LOCATIONNOTEPAD) - .where(LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()).and(LOCATIONNOTEPAD.ISDELETE.eq(false))) - .orderBy(LOCATIONNOTEPAD.ID.asc()) - .limit(PAGE_SIZE).offset(PAGE_SIZE * (page - 1)).fetch().into(LocationnotepadPO.class); + List result = ctx.select().from(LOCATIONNOTEPAD).where( + LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()).and(LOCATIONNOTEPAD.ISDELETE.eq(false))) + .orderBy(LOCATIONNOTEPAD.ID.asc()).limit(PAGE_SIZE).offset(PAGE_SIZE * (page - 1)).fetch().into( + LocationnotepadPO.class); player.sendMessage("共查询到" + result.size() + "条结果:"); for (LocationnotepadPO po : result) { player.sendMessage(po.getName() + " X " + po.getX() + " Y " + po.getY() + " Z " + po.getZ()); @@ -151,6 +151,40 @@ public class ZbCommand implements CommandExecutor, TabCompleter { } } + /// 查看玩家沙雕值 + protected void sb(Player player, String[] strings) { + if (strings.length < 2) { + player.sendMessage(ChatColor.RED + "需要 [目标]"); + return; + } + if (strings.length > 2) { + player.sendMessage(ChatColor.RED + "命令过长"); + return; + } + try { + List list = Bukkit.selectEntities(player, strings[1]); + if (list.isEmpty()) { + player.sendMessage("没有选中任何玩家"); + return; + } + for (Entity entity : list) { + if (entity instanceof Player target) { + PlayerData data = PlayerMap.getCurrent().getPlayerData(target); + if (data == null) { + player.sendMessage(ChatColor.RED + "玩家 " + target.getName() + " 没有登录,跳过处理"); + continue; + } + player.sendMessage("玩家 " + target.getName() + " 拥有 " + data.getFraction() + " 沙雕值"); + } else { + player.sendMessage( + entity.getCustomName() != null ? entity.getCustomName() : entity.getName() + " 不是玩家"); + } + } + } catch (IllegalArgumentException e) { + player.sendMessage(ChatColor.RED + "无法解析实体"); + } + } + /// 显示帮助 protected void help(Player player, String[] strings) { if (strings.length > 2) { @@ -166,12 +200,9 @@ public class ZbCommand implements CommandExecutor, TabCompleter { BookMeta bookMeta = getHelpBookMeta(player, book); book.setItemMeta(bookMeta); - if (op.equals("open")) - player.openBook(book); - else if (op.equals("give")) - player.getInventory().addItem(book); - else - player.sendMessage(ChatColor.RED + "语法错误:无法解析的参数:" + op); + if (op.equals("open")) player.openBook(book); + else if (op.equals("give")) player.getInventory().addItem(book); + else player.sendMessage(ChatColor.RED + "语法错误:无法解析的参数:" + op); } private static @NotNull BookMeta getHelpBookMeta(Player player, ItemStack book) { @@ -180,10 +211,7 @@ public class ZbCommand implements CommandExecutor, TabCompleter { bookMeta.setGeneration(BookMeta.Generation.COPY_OF_COPY); bookMeta.setTitle("帮助信息"); bookMeta.setAuthor("StarPoles"); - bookMeta.addPage( - "欢迎使用坐标管理器!你好," + player.getName() + "\n\n" + "本书将向你介绍如何使用指令记录曾探索过的地点,以避免迷路\n" + "如果需要再次查看帮助信息,请使用 /zb help\n", - "/zb add <地点名称> <固定到侧边栏> \n" + "记录当前地点到数据库中,例如\n" + "/zb add Home\n" + "将会记录当前的位置,取名为 Home,并固定到屏幕右侧\n", - "如果不想固定到屏幕右侧,可以像这样使用\n" + "/zb add Home false\n" + "然后,你可以使用/zb list来查看已经保存的位置\n" + "使用/zb fixed 来将地点固定到屏幕右侧\n" + "使用/zb unfixed 来取消固定。\n"); + bookMeta.setPages(Help.getHelp(player)); bookMeta.addEnchant(Enchantment.VANISHING_CURSE, 1, true); return bookMeta; } @@ -223,11 +251,9 @@ public class ZbCommand implements CommandExecutor, TabCompleter { return; } var ctx = CoordinateRecorder.getDatabase().getDSL(); - int rows = ctx.update(LOCATIONNOTEPAD).set(LOCATIONNOTEPAD.ISFIXED, true) - .where(LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()) - .and(LOCATIONNOTEPAD.NAME.eq(name)) - .and(LOCATIONNOTEPAD.ISDELETE.eq(false))) - .execute(); + int rows = ctx.update(LOCATIONNOTEPAD).set(LOCATIONNOTEPAD.ISFIXED, true).where(LOCATIONNOTEPAD.UID.eq( + player.getUniqueId().toString()).and(LOCATIONNOTEPAD.NAME.eq(name)).and(LOCATIONNOTEPAD.ISDELETE.eq( + false))).execute(); if (rows == 0) { player.sendMessage(ChatColor.RED + "操作失败:记录不存在"); return; @@ -253,11 +279,9 @@ public class ZbCommand implements CommandExecutor, TabCompleter { return; } var ctx = CoordinateRecorder.getDatabase().getDSL(); - int rows = ctx.update(LOCATIONNOTEPAD).set(LOCATIONNOTEPAD.ISFIXED, false) - .where(LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()) - .and(LOCATIONNOTEPAD.NAME.eq(name)) - .and(LOCATIONNOTEPAD.ISDELETE.eq(false))) - .execute(); + int rows = ctx.update(LOCATIONNOTEPAD).set(LOCATIONNOTEPAD.ISFIXED, false).where(LOCATIONNOTEPAD.UID.eq( + player.getUniqueId().toString()).and(LOCATIONNOTEPAD.NAME.eq(name)).and(LOCATIONNOTEPAD.ISDELETE.eq( + false))).execute(); if (rows == 0) { player.sendMessage(ChatColor.RED + "操作失败:记录不存在"); return; @@ -297,6 +321,12 @@ public class ZbCommand implements CommandExecutor, TabCompleter { case "unlock": unlock(player, strings); break; + case "sb": + sb(player, strings); + break; + default: + player.sendMessage(ChatColor.RED + "未知的选项:" + strings[0]); + break; } } catch (SQLException e) { player.sendMessage(ChatColor.RED + "服务器内部错误,请联系管理员"); @@ -340,6 +370,16 @@ public class ZbCommand implements CommandExecutor, TabCompleter { return List.of(); } + protected List onSbTab(Player player, String latest, String[] strings) { + List list = new ArrayList<>(); + Bukkit.getOnlinePlayers().forEach(player1 -> { + list.add(player1.getName()); + }); + filter(latest, list); + list.addAll(Arrays.asList("@a", "@s", "@p", "@e")); + return list; + } + @Override public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { if (!(commandSender instanceof Player player)) { @@ -364,6 +404,9 @@ public class ZbCommand implements CommandExecutor, TabCompleter { case "help" -> { return filter(latest, new ArrayList<>(Arrays.asList("give", "open"))); } + case "sb" -> { + return onSbTab(player, latest, strings); + } } } if (strings[0].equals("add")) { diff --git a/src/main/java/ling/coordinateRecorder/data/PlayerData.java b/src/main/java/ling/coordinateRecorder/data/PlayerData.java index accf14b..60724c8 100644 --- a/src/main/java/ling/coordinateRecorder/data/PlayerData.java +++ b/src/main/java/ling/coordinateRecorder/data/PlayerData.java @@ -58,6 +58,10 @@ public class PlayerData { this.fractionTime = fractionTime; } + public long getFraction() { + return settings.getFraction(); + } + public void setTombstoneBlock(Block tombstone) { this.tombstoneBlock = tombstone; }