From 5f1dcb024bfe73faa958d0ca282abd1fcf65ce3f Mon Sep 17 00:00:00 2001 From: Fortern Date: Sun, 31 May 2026 02:58:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9D=91=E6=B0=91=E6=97=A0=E9=99=90=E8=A1=A5?= =?UTF-8?q?=E8=B4=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xyz/fortern/forternhelper/Helper.kt | 3 +- .../forternhelper/listener/ForternListener.kt | 23 +++------- .../nms/v26_R1/NMSHandlerImpl.kt | 36 +++++++++++++++ .../forternhelper/reflection/NMSAdapter.kt | 44 +++++++++++++++++++ .../forternhelper/reflection/NMSHandler.kt | 7 +++ 5 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 src/main/kotlin/xyz/fortern/forternhelper/nms/v26_R1/NMSHandlerImpl.kt create mode 100644 src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSAdapter.kt create mode 100644 src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSHandler.kt diff --git a/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt b/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt index 09b2e05..5cee318 100644 --- a/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt +++ b/src/main/kotlin/xyz/fortern/forternhelper/Helper.kt @@ -8,8 +8,7 @@ class Helper : JavaPlugin() { override fun onEnable() { // Plugin startup logic - logger.info("Registering events...") - logger.info("监听末影人生成...") + logger.info("Registering listeners...") Bukkit.getPluginManager().registerEvents(ForternListener(this), this) } diff --git a/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt b/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt index 3d984c6..ceaf049 100644 --- a/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt +++ b/src/main/kotlin/xyz/fortern/forternhelper/listener/ForternListener.kt @@ -1,31 +1,20 @@ package xyz.fortern.forternhelper.listener -import org.bukkit.entity.Enderman -import org.bukkit.entity.Player import org.bukkit.entity.Villager import org.bukkit.event.EventHandler import org.bukkit.event.Listener -import org.bukkit.event.entity.CreatureSpawnEvent -import org.bukkit.event.entity.VillagerReplenishTradeEvent -import org.bukkit.event.inventory.TradeSelectEvent -import org.bukkit.event.player.PlayerInteractAtEntityEvent +import org.bukkit.event.player.PlayerInteractEntityEvent import xyz.fortern.forternhelper.Helper +import xyz.fortern.forternhelper.reflection.NMSAdapter class ForternListener(val helper: Helper) : Listener { @EventHandler - fun onCreatureSpawn(event: CreatureSpawnEvent) { - val entity = event.entity - if (entity !is Enderman) { + fun onTrade(event: PlayerInteractEntityEvent) { + val entity = event.rightClicked + if (entity !is Villager) { return } - val location = event.location - val x = location.x - val y = location.y - val z = location.z - // x: -900 - if (x > -1028 && x < -770 && y > 0 && y < 186 && z > -777 && z < -521) { - helper.logger.info("Enderman spawned at ${entity.location}") - } + NMSAdapter.NMS.setVillagerRestock(entity, 0) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/fortern/forternhelper/nms/v26_R1/NMSHandlerImpl.kt b/src/main/kotlin/xyz/fortern/forternhelper/nms/v26_R1/NMSHandlerImpl.kt new file mode 100644 index 0000000..48d17f3 --- /dev/null +++ b/src/main/kotlin/xyz/fortern/forternhelper/nms/v26_R1/NMSHandlerImpl.kt @@ -0,0 +1,36 @@ +package xyz.fortern.forternhelper.nms.v26_R1 + +import org.bukkit.entity.Villager +import xyz.fortern.forternhelper.reflection.NMSAdapter.PKG_NAME +import xyz.fortern.forternhelper.reflection.NMSHandler +import java.lang.reflect.Field +import java.lang.reflect.Method + +// 26.1.x +class NMSHandlerImpl : NMSHandler { + + override fun setVillagerRestock(villager: Villager, restockToday: Int) { + val mcVillager = villagerGetHandlerMethod.invoke(villager) + villagerRestockTodayField.isAccessible = true + villagerRestockTodayField.set(mcVillager, restockToday) + } + + companion object { + private val craftVillagerClass: Class<*> + private val villagerGetHandlerMethod: Method + private val mcVillagerClass: Class<*> + private val villagerRestockTodayField: Field + + + init { + try { + craftVillagerClass = Class.forName("$PKG_NAME.entity.CraftVillager") + villagerGetHandlerMethod = craftVillagerClass.getMethod("getHandle") + mcVillagerClass = Class.forName("net.minecraft.world.entity.npc.villager.Villager") + villagerRestockTodayField = mcVillagerClass.getField("numberOfRestocksToday") + } catch (e: ReflectiveOperationException) { + throw RuntimeException(e) + } + } + } +} diff --git a/src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSAdapter.kt b/src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSAdapter.kt new file mode 100644 index 0000000..99b7989 --- /dev/null +++ b/src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSAdapter.kt @@ -0,0 +1,44 @@ +package xyz.fortern.forternhelper.reflection + +import org.bukkit.Bukkit + +object NMSAdapter { + val NMS: NMSHandler + + val REFLECT_VERSION: String + + val PKG_NAME: String + + init { + try { + // "org.bukkit.craftbukkit" or "org.bukkit.craftbukkit.vX_RY" + PKG_NAME = Bukkit.getServer().javaClass.getPackage().name + if (PKG_NAME.contains("R")) { + // e.g. org.bukkit.craftbukkit.v1_21_R5 + REFLECT_VERSION = PKG_NAME.substring(PKG_NAME.lastIndexOf('.') + 1) + } else { + // Paper 自 1.20.5 开始不再重定位 CraftBukkit 包。 + // Spigot 自 26.1 开始不再重定位 CraftBukkit 包。 + val bukkitVersion = Bukkit.getBukkitVersion() + val mcVersion = bukkitVersion.split("-".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] + REFLECT_VERSION = when (mcVersion) { + "1.20.5", "1.20.6" -> "v1_20_R4" + "1.21", "1.21.1" -> "v1_21_R1" + "1.21.2", "1.21.3" -> "v1_21_R2" + "1.21.4" -> "v1_21_R3" + "1.21.5" -> "v1_21_R4" + "1.21.6", "1.21.7", "1.21.8" -> "v1_21_R5" + "1.21.9", "1.21.10" -> "v1_21_R6" + "1.21.11" -> "v1_21_R7" + "26.1", "26.1.1", "26.1.2" -> "v26_R1" + else -> throw Exception("Unknown NMS version") + } + } + NMS = Class.forName("xyz.fortern.forternhelper.nms.$REFLECT_VERSION.NMSHandlerImpl").getConstructor() + .newInstance() as NMSHandler + } catch (e: Exception) { + throw RuntimeException("init NMSAdapter fail. NMS", e) + } + } + +} diff --git a/src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSHandler.kt b/src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSHandler.kt new file mode 100644 index 0000000..4de6ebd --- /dev/null +++ b/src/main/kotlin/xyz/fortern/forternhelper/reflection/NMSHandler.kt @@ -0,0 +1,7 @@ +package xyz.fortern.forternhelper.reflection + +import org.bukkit.entity.Villager + +interface NMSHandler { + fun setVillagerRestock(villager: Villager, restockToday: Int) +}