From 6406d3f8d6bd27d7eeff2072ed49c4431181ebaf Mon Sep 17 00:00:00 2001 From: Auxilor Date: Mon, 8 Jul 2024 15:50:04 +0100 Subject: [PATCH] Fixed 1.21 compatibility --- build.gradle.kts | 2 +- eco-core/core-modern/build.gradle.kts | 23 ++++++ .../compat/modern/ModifierHelperImpl.kt | 28 +++++++ eco-core/core-plugin/build.gradle.kts | 6 +- .../ecoitems/compat/ModernCompatibility.kt | 75 +++++++++++++++++++ .../ecoitems/items/ItemAttributeListener.kt | 46 +++++++----- gradle.properties | 4 +- settings.gradle.kts | 1 + 8 files changed, 163 insertions(+), 22 deletions(-) create mode 100644 eco-core/core-modern/build.gradle.kts create mode 100644 eco-core/core-modern/src/main/kotlin/com/willfp/ecoitems/compat/modern/ModifierHelperImpl.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/compat/ModernCompatibility.kt diff --git a/build.gradle.kts b/build.gradle.kts index ba172ec..e002f9d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,7 +44,7 @@ allprojects { java { withSourcesJar() - toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } tasks { diff --git a/eco-core/core-modern/build.gradle.kts b/eco-core/core-modern/build.gradle.kts new file mode 100644 index 0000000..32aefcc --- /dev/null +++ b/eco-core/core-modern/build.gradle.kts @@ -0,0 +1,23 @@ +group = "com.willfp" +version = rootProject.version + +dependencies { + compileOnly(project(":eco-core:core-plugin")) + compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") +} + +tasks { + build { + dependsOn(publishToMavenLocal) + } + + compileJava { + options.release = 21 + } + + compileKotlin { + kotlinOptions { + jvmTarget = "21" + } + } +} diff --git a/eco-core/core-modern/src/main/kotlin/com/willfp/ecoitems/compat/modern/ModifierHelperImpl.kt b/eco-core/core-modern/src/main/kotlin/com/willfp/ecoitems/compat/modern/ModifierHelperImpl.kt new file mode 100644 index 0000000..e95ba02 --- /dev/null +++ b/eco-core/core-modern/src/main/kotlin/com/willfp/ecoitems/compat/modern/ModifierHelperImpl.kt @@ -0,0 +1,28 @@ +package com.willfp.ecoitems.compat.modern + +import com.willfp.eco.core.EcoPlugin +import com.willfp.ecoitems.items.ModifierHelper +import org.bukkit.attribute.AttributeModifier +import org.bukkit.inventory.EquipmentSlotGroup + +class ModifierHelperImpl : ModifierHelper { + override fun createModifier( + plugin: EcoPlugin, + attributeType: String, + amount: Double, + offset: Int + ): AttributeModifier { + @Suppress("UnstableApiUsage") + return AttributeModifier( + plugin.createNamespacedKey("${attributeType.lowercase()}_$offset"), + amount, + AttributeModifier.Operation.ADD_NUMBER, + EquipmentSlotGroup.ANY + ) + } + + override fun isFromEcoItems(modifier: AttributeModifier): Boolean { + return modifier.key.namespace == "ecoitems" && (modifier.key.key.startsWith("damage") + || modifier.key.key.startsWith("speed")) + } +} diff --git a/eco-core/core-plugin/build.gradle.kts b/eco-core/core-plugin/build.gradle.kts index c2b087b..9657ce0 100644 --- a/eco-core/core-plugin/build.gradle.kts +++ b/eco-core/core-plugin/build.gradle.kts @@ -2,7 +2,7 @@ group = "com.willfp" version = rootProject.version dependencies { - compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.20-R0.1-SNAPSHOT") } publishing { @@ -30,6 +30,10 @@ publishing { } } +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) +} + tasks { build { dependsOn(publishToMavenLocal) diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/compat/ModernCompatibility.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/compat/ModernCompatibility.kt new file mode 100644 index 0000000..ad9445a --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/compat/ModernCompatibility.kt @@ -0,0 +1,75 @@ +package com.willfp.ecoitems.compat + +import com.willfp.eco.core.Prerequisite +import com.willfp.libreforge.proxy.InvalidProxyException + +private const val BASE_PACKAGE = "com.willfp.ecoitems.compat.modern" +private val isModern = Prerequisite.HAS_PAPER.isMet && Prerequisite.HAS_1_21.isMet + +internal annotation class ModernCompatibilityProxy( + val location: String +) + +private val cache = mutableMapOf, Any>() + +internal object ModernCompatibilityScope { + inline fun loadProxy(): T { + return loadCompatibilityProxy(T::class.java) + } + + inline fun useProxy(block: T.() -> Unit) { + val proxy = loadProxy() + + with(proxy) { + block() + } + } +} + +internal object PotentiallyModernScope { + fun otherwise(block: () -> Any?) { + if (!isModern) { + block() + } + } +} + +internal fun ifModern( + block: ModernCompatibilityScope.() -> R1 +): PotentiallyModernScope { + if (isModern) { + block(ModernCompatibilityScope) + } + + return PotentiallyModernScope +} + +internal fun loadCompatibilityProxy(clazz: Class): T { + @Suppress("UNCHECKED_CAST") + return cache.getOrPut(clazz) { + loadProxyUncached(clazz) + } as T +} + +private fun loadProxyUncached(clazz: Class<*>): Any { + val proxy = clazz.getAnnotation(ModernCompatibilityProxy::class.java) + val location = proxy?.location ?: throw IllegalArgumentException("Class ${clazz.name} is not a proxy") + val className = "$BASE_PACKAGE.$location" + + try { + val found = Class.forName(className) + + val constructor = found.getConstructor() + val instance = constructor.newInstance() + + if (!clazz.isInstance(instance)) { + throw InvalidProxyException("Modern compatibility proxy class $className does not implement ${clazz.name}") + } + + return instance + } catch (e: ClassNotFoundException) { + throw InvalidProxyException("Could not find modern compatibility proxy class $className") + } catch (e: NoSuchMethodException) { + throw InvalidProxyException("Could not find no-args constructor for modern compatibility proxy class $className") + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/items/ItemAttributeListener.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/items/ItemAttributeListener.kt index a760a4e..8a56082 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/items/ItemAttributeListener.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoitems/items/ItemAttributeListener.kt @@ -1,7 +1,8 @@ package com.willfp.ecoitems.items import com.willfp.eco.core.EcoPlugin -import com.willfp.eco.core.Prerequisite +import com.willfp.ecoitems.compat.ModernCompatibilityProxy +import com.willfp.ecoitems.compat.ifModern import com.willfp.libreforge.toDispatcher import org.bukkit.attribute.Attribute import org.bukkit.attribute.AttributeInstance @@ -10,7 +11,6 @@ import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerItemHeldEvent -import org.bukkit.inventory.EquipmentSlotGroup import java.util.UUID class ItemAttributeListener(private val plugin: EcoPlugin) : Listener { @@ -65,12 +65,15 @@ class ItemAttributeListener(private val plugin: EcoPlugin) : Listener { return true } - if (Prerequisite.HAS_1_21.isMet) { - return this.key.namespace == "ecoitems" && (this.key.key.startsWith("damage") - || this.key.key.startsWith("speed")) + var isFromEcoItems = false + + ifModern { + useProxy { + isFromEcoItems = isFromEcoItems(this@isFromEcoItems) + } } - return false + return isFromEcoItems } private fun AttributeInstance.addCompatibleModifier( @@ -78,19 +81,14 @@ class ItemAttributeListener(private val plugin: EcoPlugin) : Listener { amount: Double, offset: Int ) { - if (Prerequisite.HAS_1_21.isMet) { - this.addModifier( - @Suppress("UnstableApiUsage") - AttributeModifier( - plugin.createNamespacedKey("${attributeType.lowercase()}_$offset"), - amount, - AttributeModifier.Operation.ADD_NUMBER, - EquipmentSlotGroup.ANY + ifModern { + useProxy { + addModifier( + createModifier(plugin, attributeType, amount, offset) ) - ) - } else { - this.addModifier( - @Suppress("DEPRECATION", "REMOVAL") + } + }.otherwise { + addModifier( AttributeModifier( UUID.nameUUIDFromBytes("ecoitems_$offset".toByteArray()), "EcoItems $attributeType $offset", @@ -101,3 +99,15 @@ class ItemAttributeListener(private val plugin: EcoPlugin) : Listener { } } } + +@ModernCompatibilityProxy("ModifierHelperImpl") +interface ModifierHelper { + fun createModifier( + plugin: EcoPlugin, + attributeType: String, + amount: Double, + offset: Int + ): AttributeModifier + + fun isFromEcoItems(modifier: AttributeModifier): Boolean +} diff --git a/gradle.properties b/gradle.properties index a3883c0..11aa29f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ #libreforge-updater -#Fri Jul 05 13:02:23 BST 2024 +#Mon Jul 08 15:31:28 BST 2024 kotlin.code.style=official -libreforge-version=4.64.1 +libreforge-version=4.65.0 version=5.50.1 diff --git a/settings.gradle.kts b/settings.gradle.kts index 90a9bd2..8e0d7c7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,3 +16,4 @@ rootProject.name = "EcoItems" // Core include(":eco-core") include(":eco-core:core-plugin") +include(":eco-core:core-modern")