From 7c4dbf67271942c647ac0e3e60e4d5443c22e354 Mon Sep 17 00:00:00 2001 From: Fortern Date: Thu, 4 Jun 2026 01:33:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=BA=E5=9D=97=E7=AD=89=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 23 ++++ .../xyz/fortern/forternhelper/Helper.kt | 5 + .../forternhelper/command/HelperCommand.kt | 121 ++++++++++++++++++ .../forternhelper/listener/ForternListener.kt | 4 +- src/main/resources/plugin.yml | 3 +- 5 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt diff --git a/pom.xml b/pom.xml index 0839b01..c0b9ada 100644 --- a/pom.xml +++ b/pom.xml @@ -68,16 +68,39 @@ + org.spigotmc spigot-api 26.1-R0.1-SNAPSHOT provided + org.jetbrains.kotlin kotlin-stdlib ${kotlin.version} + + + org.jetbrains + annotations + 26.1.0 + compile + + + + net.kyori + adventure-api + 4.26.1 + provided + + + + net.kyori + adventure-platform-bukkit + 4.4.1 + provided + diff --git a/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt b/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt index 5cee318..86275f2 100644 --- a/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt +++ b/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt @@ -1,15 +1,20 @@ package xyz.fortern.forternhelper +import net.kyori.adventure.platform.bukkit.BukkitAudiences import org.bukkit.Bukkit import org.bukkit.plugin.java.JavaPlugin +import xyz.fortern.forternhelper.command.HelperCommand import xyz.fortern.forternhelper.listener.ForternListener class Helper : JavaPlugin() { + private lateinit var adventure: BukkitAudiences override fun onEnable() { // Plugin startup logic + this.adventure = BukkitAudiences.create(this) logger.info("Registering listeners...") Bukkit.getPluginManager().registerEvents(ForternListener(this), this) + Bukkit.getPluginCommand("helper")?.setExecutor(HelperCommand(this, adventure)) } override fun onDisable() { diff --git a/src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt b/src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt new file mode 100644 index 0000000..6e1fc97 --- /dev/null +++ b/src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt @@ -0,0 +1,121 @@ +package xyz.fortern.forternhelper.command + +import net.kyori.adventure.platform.bukkit.BukkitAudiences +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import org.bukkit.Bukkit +import org.bukkit.command.Command +import org.bukkit.command.CommandSender +import org.bukkit.command.TabExecutor +import org.bukkit.entity.Player +import org.bukkit.plugin.java.JavaPlugin + +class HelperCommand( + private val plugin: JavaPlugin, + private val adventure: BukkitAudiences, + + ) : TabExecutor { + private val subCommands: List = listOf("loadlevel") + private val helpMessages = listOf( + Component.text("Minehunt v${plugin.description.version}", NamedTextColor.GREEN), + Component.text("/helper help ", NamedTextColor.GOLD) + .append(Component.text("帮助信息", NamedTextColor.WHITE)), + Component.text("/helper loadlevel [world] ", NamedTextColor.GOLD) + .append(Component.text("查看区块的加载等级", NamedTextColor.WHITE)), + ) + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + // onCommand接受到的参数中没有空字符串 + handlerCommand(sender, args.toList(), true) + return true + } + + override fun onTabComplete(sender: CommandSender, command: Command, label: String, args: Array): List? { + return handlerCommand( + sender, + args.filterIndexed { index, s -> s != "" || index == args.size - 1 }, + false + ) + } + + /** + * 执行命令或补全命令 + * + * @param exe true 表示执行命令,false 表示补全命令 + * @param args 命令的参数列表,除最后一条前面的每一条都应当是非空的 + */ + private fun handlerCommand(sender: CommandSender, args: List, exe: Boolean): List? { + if (args.isEmpty()) { + return if (exe) { + sendHelp(sender) + null + } else { + subCommands + } + } + return when (args[0]) { + "help" -> onHelp(sender, exe) + "loadlevel" -> onLoadLevel(sender, args, exe) + else -> { + if (exe) { + adventure.sender(sender).sendMessage(Component.text("错误的子命令")) + null + } else { + // 补全已args[0]开头的子命令 + if (args.size == 1) subCommands.filter { it.startsWith(args[0]) } else null + } + } + } + } + + private fun onHelp(sender: CommandSender, exe: Boolean): List? { + if (exe) sendHelp(sender) + return null + } + + private fun onLoadLevel(sender: CommandSender, args: List, exe: Boolean): List? { + // args[0]: loadlevel args[1]:15 args[2]:15 args[3]:world_the_end + if (args.size < 2) { + if (exe) { + adventure.sender(sender).sendMessage(Component.text("指定正确的区块坐标", NamedTextColor.RED)) + } + return null + } + var x = 0 + var z = 0 + if (exe) { + try { + x = args[1].toInt() + z = args[2].toInt() + } catch (_: NumberFormatException) { + adventure.sender(sender).sendMessage(Component.text("指定正确的区块坐标", NamedTextColor.RED)) + } + val worldInArg = if (args.size == 4 && args[3].isNotBlank()) { + Bukkit.getWorld(args[3]) + } else { + null + } + val world = worldInArg ?: if (sender !is Player) { + adventure.sender(sender).sendMessage(Component.text("世界名称不正确", NamedTextColor.RED)) + return null + } else { + sender.world + } + val chunk = world.getChunkAt(x, z) + val loadLevel = chunk.loadLevel + adventure.sender(sender).sendMessage(Component.text("ChunkPos(${args[1]}, ${args[2]}) loadLevel: $loadLevel")) + return null + } else { + if (args.size == 4) { + val worldName = args[3] + return Bukkit.getWorlds().filter { it.name.startsWith(worldName) }.map { it.name } + } else { + return null + } + } + } + + private fun sendHelp(sender: CommandSender) { + helpMessages.forEach { adventure.sender(sender).sendMessage(it) } + } +} diff --git a/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt b/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt index ceaf049..5562d18 100644 --- a/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt +++ b/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt @@ -4,10 +4,10 @@ import org.bukkit.entity.Villager import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerInteractEntityEvent -import xyz.fortern.forternhelper.Helper +import org.bukkit.plugin.java.JavaPlugin import xyz.fortern.forternhelper.reflection.NMSAdapter -class ForternListener(val helper: Helper) : Listener { +class ForternListener(val plugin: JavaPlugin) : Listener { @EventHandler fun onTrade(event: PlayerInteractEntityEvent) { val entity = event.rightClicked diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 15120d6..a4cc423 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,8 +6,9 @@ main: xyz.fortern.forternhelper.Helper libraries: - org.jetbrains.kotlin:kotlin-stdlib:2.3.21 + - net.kyori:adventure-api:4.26.1 + - net.kyori:adventure-platform-bukkit:4.4.1 commands: helper: description: "游戏主命令" - permission: op