Fix/toolstats (#63)

Fix incompatibility with toolstats
This commit is contained in:
alexcrea 2025-05-13 13:41:20 +02:00 committed by GitHub
commit a74470bd0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 147 additions and 14 deletions

View file

@ -16,7 +16,7 @@ plugins {
}
group = "xyz.alexcrea"
version = "1.11.1"
version = "1.11.2"
repositories {
// EcoEnchants
@ -52,6 +52,9 @@ dependencies {
// HavenBags
compileOnly(files("libs/HavenBags-1.31.0.1760.jar"))
// ToolStats
compileOnly(files("libs/toolstats-1.9.6-stripped.jar"))
// Include nms
implementation(project(":nms:nms-common"))
implementation(project(":nms:v1_17R1", configuration = "reobf"))
@ -67,7 +70,7 @@ dependencies {
implementation(project(":nms:v1_21R1", configuration = "reobf"))
implementation(project(":nms:v1_21R2", configuration = "reobf"))
implementation(project(":nms:v1_21R3", configuration = "reobf"))
implementation(project(":nms:v1_21R4"))//, configuration = "reobf")) // TODO add again when paperweigh 1.21.5 update
implementation(project(":nms:v1_21R4", configuration = "reobf"))
// include kotlin for the offline jar
implementation(kotlin("stdlib"))

Binary file not shown.

View file

@ -5,7 +5,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.dependency.EnchantmentSquaredDependency;
import xyz.alexcrea.cuanvil.dependency.plugins.EnchantmentSquaredDependency;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import java.util.Collections;

View file

@ -14,6 +14,7 @@ import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
import xyz.alexcrea.cuanvil.dependency.gui.GuiTesterSelector
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerSelector
import xyz.alexcrea.cuanvil.dependency.plugins.*
import xyz.alexcrea.cuanvil.dependency.scheduler.BukkitScheduler
import xyz.alexcrea.cuanvil.dependency.scheduler.FoliaScheduler
import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler
@ -34,6 +35,8 @@ object DependencyManager {
var disenchantmentCompatibility: DisenchantmentDependency? = null
var havenBagsCompatibility: HavenBagsDependency? = null
val genericDependencies = ArrayList<GenericPluginDependency>()
fun loadDependency() {
val pluginManager = Bukkit.getPluginManager()
@ -79,6 +82,14 @@ object DependencyManager {
havenBagsCompatibility = HavenBagsDependency()
havenBagsCompatibility!!.redirectListeners()
}
// "Generic" dependencies
if (pluginManager.isPluginEnabled("ToolStats"))
genericDependencies.add(ToolStatsDependency(pluginManager.getPlugin("ToolStats")!!))
for (dependency in genericDependencies)
dependency.redirectListeners()
}
fun handleCompatibilityConfig() {
@ -102,6 +113,7 @@ object DependencyManager {
// Then handle plugin reload
ecoEnchantCompatibility?.handleConfigReload()
}
// Return true if should bypass (either by a dependency or error)
// called before immutability test
fun earlyTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
@ -118,7 +130,10 @@ object DependencyManager {
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
// Finally, warn the player, maybe a lot of time but better warn than do nothing
event.view.player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.")
event.view.player.sendMessage(
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
ChatColor.RED.toString() + "Error while handling the anvil."
)
return true
}
}
@ -147,7 +162,10 @@ object DependencyManager {
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
// Finally, warn the player, maybe a lot of time but better warn than do nothing
event.view.player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.")
event.view.player.sendMessage(
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
ChatColor.RED.toString() + "Error while handling the anvil."
)
return true
}
}
@ -164,6 +182,10 @@ object DependencyManager {
// Test excellent enchantments used prepare anvil
if (!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true
for (genericDependency in genericDependencies) {
if (!bypass && genericDependency.testPrepareAnvil(event)) bypass = true
}
return bypass
}
@ -183,7 +205,10 @@ object DependencyManager {
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
// Finally, warn the player, maybe a lot of time but better warn than do nothing
event.view.player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.")
event.view.player.sendMessage(
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
ChatColor.RED.toString() + "Error while handling the anvil."
)
return true
}
}
@ -207,7 +232,10 @@ object DependencyManager {
event.inventory.setItem(ANVIL_OUTPUT_SLOT, null)
// Finally, warn the player, maybe a lot of time but better warn than do nothing
event.whoClicked.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.")
event.whoClicked.sendMessage(
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
ChatColor.RED.toString() + "Error while handling the anvil."
)
return true
}
}
@ -224,6 +252,10 @@ object DependencyManager {
// Test if disenchantment used event click
if (!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true
for (genericDependency in genericDependencies) {
if (!bypass && genericDependency.testAnvilResult(event)) bypass = true
}
// Test if the inventory is a gui(version specific)
if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.dependency
package xyz.alexcrea.cuanvil.dependency.plugins
import com.jankominek.disenchantment.Disenchantment
import com.jankominek.disenchantment.events.DisenchantClickEvent

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.dependency
package xyz.alexcrea.cuanvil.dependency.plugins
import com.willfp.ecoenchants.enchant.EcoEnchant
import com.willfp.ecoenchants.enchant.EcoEnchants

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.dependency
package xyz.alexcrea.cuanvil.dependency.plugins
import io.delilaheve.CustomAnvil
import me.athlaeos.enchantssquared.enchantments.CustomEnchant

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.dependency
package xyz.alexcrea.cuanvil.dependency.plugins
import io.delilaheve.CustomAnvil
import org.bukkit.Material
@ -146,7 +146,7 @@ class ExcellentEnchantsDependency {
return event.inventory.getItem(2) == null
}
return false;
return false
}
private fun treatInput(item: ItemStack?): ItemStack {

View file

@ -0,0 +1,60 @@
package xyz.alexcrea.cuanvil.dependency.plugins
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener
abstract class GenericPluginDependency(protected val plugin: Plugin) {
protected val preAnvil = ArrayList<RegisteredListener>()
protected val postAnvil = ArrayList<RegisteredListener>()
open fun redirectListeners() {
// get PreAnvil and PostAnvil listeners
for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) {
if (registeredListener.plugin != plugin) continue
preAnvil.add(registeredListener)
}
postAnvil.addAll(postAnvilEvents())
// get required PrepareAnvilEvent listener
for (listener in preAnvil) {
PrepareAnvilEvent.getHandlerList().unregister(listener)
}
for (listener in postAnvil) {
InventoryClickEvent.getHandlerList().unregister(listener)
}
}
protected abstract fun postAnvilEvents(): Collection<RegisteredListener>
open fun testPrepareAnvil(event: PrepareAnvilEvent): Boolean {
val previousResult = event.result
event.result = null
for (registeredListener in preAnvil) {
registeredListener.callEvent(event)
if (event.result != null) return true
}
event.result = previousResult;
return false
}
open fun testAnvilResult(event: InventoryClickEvent): Boolean {
for (registeredListener in postAnvil) {
registeredListener.callEvent(event)
if (event.inventory.getItem(2) == null) return true
}
return false
}
}

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.dependency
package xyz.alexcrea.cuanvil.dependency.plugins
import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.dependency
package xyz.alexcrea.cuanvil.dependency.plugins
import com.willfp.ecoenchants.enchantments.EcoEnchant
import com.willfp.ecoenchants.enchantments.EcoEnchants

View file

@ -0,0 +1,38 @@
package xyz.alexcrea.cuanvil.dependency.plugins
import lol.hyper.toolstats.ToolStats
import lol.hyper.toolstats.tools.ItemChecker
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import java.lang.reflect.Method
class ToolStatsDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
// Sadly, getTokens function is private, so I need to do that
private val getTokenMethod: Method =
ItemChecker::class.java.getDeclaredMethod("getTokens", ItemStack::class.java);
init {
getTokenMethod.trySetAccessible()
}
override fun postAnvilEvents(): Collection<RegisteredListener> {
return listOf()
}
override fun testAnvilResult(event: InventoryClickEvent): Boolean {
// Check if token changes from left with result
val left = event.inventory.getItem(PrepareAnvilListener.ANVIL_INPUT_LEFT)
val result = event.inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
val itemChecker = (plugin as ToolStats).itemChecker
val leftTokens = getTokenMethod.invoke(itemChecker, left) as Array<String>
val resultToken = getTokenMethod.invoke(itemChecker, result) as Array<String>
return !leftTokens.contentDeepEquals(resultToken);
}
}