From d850455b98072a8cfbef05c2d0637917d0a70561 Mon Sep 17 00:00:00 2001 From: Fortern Date: Sun, 7 Jun 2026 19:32:48 +0800 Subject: [PATCH] nbt tools --- .../xyz/fortern/forternhelper/Helper.kt | 5 + .../forternhelper/command/HelperCommand.kt | 122 ++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt b/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt index 1948589..d52430b 100644 --- a/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt +++ b/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt @@ -21,6 +21,11 @@ class Helper : JavaPlugin() { // Plugin startup logic this.adventure = BukkitAudiences.create(this) + // init data-folders + logger.info("Initializing data-folders...") + File(this.dataFolder, "block-nbt").mkdirs() + File(this.dataFolder, "item-nbt").mkdirs() + // register asyncManager logger.info("Registering asyncManager...") asyncManager = AsyncManager(this) diff --git a/src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt b/src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt index f39c893..fba98e2 100644 --- a/src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt +++ b/src/main/kotlin/xyz/fortern/forternhelper/command/HelperCommand.kt @@ -1,5 +1,7 @@ package xyz.fortern.forternhelper.command +import de.tr7zw.nbtapi.NBT +import de.tr7zw.nbtapi.iface.ReadWriteNBT import net.kyori.adventure.platform.bukkit.BukkitAudiences import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.NamedTextColor @@ -10,6 +12,9 @@ import org.bukkit.command.TabExecutor import org.bukkit.entity.Player import org.bukkit.plugin.java.JavaPlugin import xyz.fortern.forternhelper.async.AsyncManager +import java.io.File +import java.io.FileReader +import java.util.logging.Level class HelperCommand( private val plugin: JavaPlugin, @@ -63,6 +68,16 @@ class HelperCommand( onLoadLevel(sender, args, exe) } + "setblock" -> { + setBlockFromNbt(sender, args, exe) + null + } + + "getitem" -> { + getItemFromNbt(sender, args, exe) + null + } + else -> { if (exe) { adventure.sender(sender).sendMessage(Component.text("错误的子命令")) @@ -75,6 +90,113 @@ class HelperCommand( } } + private fun getItemFromNbt(sender: CommandSender, args: List, exe: Boolean) { + // args[0]:getitem | args[1]:0 | args[2]:txt + if (!exe) return + if (sender !is Player) return + if (!sender.isOp) return + if (args.size < 2) return + val i = args[1] + val isNbt = if (args.size > 2) args[2] == "nbt" else false + val itemNbtDir = File(plugin.dataFolder, "item-nbt") + + var readWriteNBT: ReadWriteNBT? = null + var fileExists = true + var parse = true + + asyncManager.execInMainAfterAsync("read item nbt in helper command", 20, run@{ + if (isNbt) { + val file = File(itemNbtDir, "${i}.nbt") + if (!file.exists()) { + fileExists = false + return@run + } + try { + readWriteNBT = NBT.readFile(file) + } catch (ex: Exception) { + plugin.logger.log(Level.WARNING, "Error reading nbt", ex) + parse = false + } + } else { + val file = File(itemNbtDir, "${i}.txt") + if (!file.exists()) { + fileExists = false + return@run + } + try { + readWriteNBT = NBT.parseNBT(FileReader(file).readAllAsString()) + } catch (ex: Exception) { + plugin.logger.log(Level.WARNING, "Error reading nbt", ex) + parse = false + } + } + }) { + if (!fileExists) { + adventure.sender(sender).sendMessage(Component.text("文件不存在")) + } else if (!parse) { + adventure.sender(sender).sendMessage(Component.text("文件解析错误")) + } else { + if (readWriteNBT != null) { + sender.inventory.addItem(NBT.itemStackFromNBT(readWriteNBT)) + } + } + } + return + } + + private fun setBlockFromNbt(sender: CommandSender, args: List, exe: Boolean) { + // args[0]:setblock | args[1]:0 | args[2]:txt + if (!exe) return + if (sender !is Player) return + if (!sender.isOp) return + if (args.size < 2) return + val i = args[1] + val isNbt = if (args.size > 2) args[2] == "nbt" else false + val world = sender.world + val blockState = world.getBlockState(0, 128, 0) + val blockNbtDir = File(plugin.dataFolder, "block-nbt") + + var readWriteNBT: ReadWriteNBT? = null + var fileExists = true + var parse = true + + asyncManager.execInMainAfterAsync("read block nbt in helper command", 20, run@{ + if (isNbt) { + val file = File(blockNbtDir, "${i}.nbt") + if (!file.exists()) { + fileExists = false + return@run + } + try { + readWriteNBT = NBT.readFile(file) + } catch (ex: Exception) { + plugin.logger.log(Level.WARNING, "Error reading nbt", ex) + parse = false + } + } else { + val file = File(blockNbtDir, "${i}.txt") + if (!file.exists()) { + fileExists = false + return@run + } + readWriteNBT = NBT.parseNBT(FileReader(file).readAllAsString()) + } + }) { + if (!fileExists) { + adventure.sender(sender).sendMessage(Component.text("文件不存在")) + } else if (!parse) { + adventure.sender(sender).sendMessage(Component.text("文件解析错误")) + } else { + if (readWriteNBT != null) { + NBT.modify(blockState) { nbt: ReadWriteNBT -> + nbt.mergeCompound(readWriteNBT) + } + } + } + } + return + } + private fun onHelp(sender: CommandSender, exe: Boolean): List? { if (exe) sendHelp(sender) return null