Added 1.21.4 support

This commit is contained in:
Will FP 2024-12-08 16:10:54 +00:00
parent c7f07cffef
commit 114b7b12ca
15 changed files with 391 additions and 12 deletions

4
.gitignore vendored
View File

@ -20,4 +20,6 @@ bin/
gradle-app.setting
# Mac OSX
.DS_Store
.DS_Store
.kotlin

View File

@ -1,8 +1,10 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
java
`java-library`
`maven-publish`
kotlin("jvm") version "1.9.20"
kotlin("jvm") version "2.1.0"
id("com.gradleup.shadow") version "8.3.5"
id("com.willfp.libreforge-gradle-plugin") version "1.0.0"
}
@ -28,6 +30,7 @@ dependencies {
implementation(project(":eco-core:core-nms:v1_20_R3", configuration = "reobf"))
implementation(project(":eco-core:core-nms:v1_21", configuration = "reobf"))
implementation(project(":eco-core:core-nms:v1_21_3", configuration = "reobf"))
implementation(project(":eco-core:core-nms:v1_21_4", configuration = "reobf"))
}
allprojects {
@ -54,7 +57,7 @@ allprojects {
dependencies {
compileOnly("com.willfp:eco:6.74.3")
compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.1.0")
compileOnly("com.github.ben-manes.caffeine:caffeine:3.1.5")
}
@ -64,8 +67,8 @@ allprojects {
}
compileKotlin {
kotlinOptions {
jvmTarget = "17"
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}

View File

@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("io.papermc.paperweight.userdev")
}
@ -19,8 +21,8 @@ tasks {
}
compileKotlin {
kotlinOptions {
jvmTarget = "21"
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
}

View File

@ -63,7 +63,7 @@ class ModernEnchantmentRegisterer : ModernEnchantmentRegistererProxy {
override fun replaceRegistry() {
val newRegistryMTB =
BiFunction<NamespacedKey, net.minecraft.world.item.enchantment.Enchantment, Enchantment> { key, registry ->
BiFunction<NamespacedKey, net.minecraft.world.item.enchantment.Enchantment, Enchantment?> { key, registry ->
val eco = EcoEnchants.getByID(key.key)
val registered = enchantmentRegistry.containsKey(CraftNamespacedKey.toMinecraft(key))

View File

@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("io.papermc.paperweight.userdev")
}
@ -19,8 +21,8 @@ tasks {
}
compileKotlin {
kotlinOptions {
jvmTarget = "21"
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
}

View File

@ -60,7 +60,7 @@ class ModernEnchantmentRegisterer : ModernEnchantmentRegistererProxy {
override fun replaceRegistry() {
val newRegistryMTB =
BiFunction<NamespacedKey, net.minecraft.world.item.enchantment.Enchantment, Enchantment> { key, registry ->
BiFunction<NamespacedKey, net.minecraft.world.item.enchantment.Enchantment, Enchantment?> { key, registry ->
val eco = EcoEnchants.getByID(key.key)
val registered = enchantmentRegistry.containsKey(CraftNamespacedKey.toMinecraft(key))

View File

@ -0,0 +1,28 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("io.papermc.paperweight.userdev")
}
group = "com.willfp"
version = rootProject.version
dependencies {
paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT")
}
tasks {
build {
dependsOn(reobfJar)
}
compileJava {
options.release = 21
}
compileKotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
}

View File

@ -0,0 +1,33 @@
package com.willfp.ecoenchants.proxy.v1_21_4
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.ecoenchants.display.HideStoredEnchantsProxy
import org.bukkit.inventory.ItemFlag
import javax.print.attribute.PrintRequestAttribute
class HideStoredEnchants: HideStoredEnchantsProxy {
override fun hideStoredEnchants(fis: FastItemStack) {
if (Prerequisite.HAS_PAPER.isMet) {
fis.addItemFlags(ItemFlag.HIDE_STORED_ENCHANTS)
} else {
fis.addItemFlags(ItemFlag.HIDE_ADDITIONAL_TOOLTIP)
}
}
override fun areStoredEnchantsHidden(fis: FastItemStack): Boolean {
return if (Prerequisite.HAS_PAPER.isMet) {
fis.hasItemFlag(ItemFlag.HIDE_STORED_ENCHANTS)
} else {
fis.hasItemFlag(ItemFlag.HIDE_ADDITIONAL_TOOLTIP)
}
}
override fun showStoredEnchants(fis: FastItemStack) {
if (Prerequisite.HAS_PAPER.isMet) {
fis.removeItemFlags(ItemFlag.HIDE_STORED_ENCHANTS)
} else {
fis.removeItemFlags(ItemFlag.HIDE_ADDITIONAL_TOOLTIP)
}
}
}

View File

@ -0,0 +1,142 @@
package com.willfp.ecoenchants.proxy.v1_21_4
import com.willfp.ecoenchants.enchant.EcoEnchant
import com.willfp.ecoenchants.enchant.EcoEnchants
import com.willfp.ecoenchants.enchant.impl.EcoEnchantBase
import com.willfp.ecoenchants.enchant.registration.modern.ModernEnchantmentRegistererProxy
import com.willfp.ecoenchants.proxy.v1_21_4.registration.EcoEnchantsCraftEnchantment
import com.willfp.ecoenchants.proxy.v1_21_4.registration.ModifiedVanillaCraftEnchantment
import com.willfp.ecoenchants.proxy.v1_21_4.registration.vanillaEcoEnchantsEnchantment
import net.minecraft.core.Holder
import net.minecraft.core.MappedRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceLocation
import org.bukkit.Bukkit
import org.bukkit.NamespacedKey
import org.bukkit.craftbukkit.CraftRegistry
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.util.CraftNamespacedKey
import org.bukkit.enchantments.Enchantment
import java.lang.reflect.Modifier
import java.util.IdentityHashMap
import java.util.function.BiFunction
private val enchantmentRegistry =
(Bukkit.getServer() as CraftServer).server.registryAccess().lookupOrThrow(Registries.ENCHANTMENT)
@Suppress("DEPRECATION")
private val bukkitRegistry =
org.bukkit.Registry.ENCHANTMENT
class ModernEnchantmentRegisterer : ModernEnchantmentRegistererProxy {
private val frozenField = MappedRegistry::class.java
.declaredFields
.filter { it.type.isPrimitive }[0]
.apply { isAccessible = true }
private val allTags = MappedRegistry::class.java
.declaredFields
.filter { it.type.name.contains("TagSet") }[0]
.apply { isAccessible = true }
private val unregisteredIntrusiveHoldersField = MappedRegistry::class.java
.declaredFields
.last { it.type == Map::class.java }
.apply { isAccessible = true }
private val minecraftToBukkit = bukkitRegistry::class.java
.getDeclaredField("minecraftToBukkit")
.apply { isAccessible = true }
// Paper has two minecraftToBukkit fields, one in CraftRegistry and one in WritableCraftRegistry
private val minecraftToBukkitAlt = CraftRegistry::class.java
.getDeclaredField("minecraftToBukkit")
.apply { isAccessible = true }
private val cache = CraftRegistry::class.java
.getDeclaredField("cache")
.apply { isAccessible = true }
override fun replaceRegistry() {
val newRegistryMTB =
BiFunction<NamespacedKey, net.minecraft.world.item.enchantment.Enchantment, Enchantment?> { key, registry ->
val eco = EcoEnchants.getByID(key.key)
val registered = enchantmentRegistry.containsKey(CraftNamespacedKey.toMinecraft(key))
if (eco != null) {
eco as Enchantment
} else if (registered) {
ModifiedVanillaCraftEnchantment(key, registry)
} else {
null
}
}
// Update bukkit registry
minecraftToBukkit.set(bukkitRegistry, newRegistryMTB)
minecraftToBukkitAlt.set(bukkitRegistry, newRegistryMTB)
// Clear the enchantment cache
cache.set(bukkitRegistry, mutableMapOf<NamespacedKey, Enchantment>())
// Unfreeze NMS registry
frozenField.set(enchantmentRegistry, false)
unregisteredIntrusiveHoldersField.set(
enchantmentRegistry,
IdentityHashMap<net.minecraft.world.item.enchantment.Enchantment,
Holder.Reference<net.minecraft.world.item.enchantment.Enchantment>>()
)
/*
Creating an unbound tag set requires using reflection because the inner class is
package-private, so we just find the method manually.
*/
val unboundTagSet = MappedRegistry::class.java
.declaredClasses[0]
.declaredMethods
.filter { Modifier.isStatic(it.modifiers) }
.filter { it.parameterCount == 0 }[0]
.apply { isAccessible = true }
.invoke(null)
allTags.set(enchantmentRegistry, unboundTagSet)
}
override fun register(enchant: EcoEnchantBase): Enchantment {
// Clear the enchantment cache
cache.set(bukkitRegistry, mutableMapOf<NamespacedKey, Enchantment>())
if (enchantmentRegistry.containsKey(CraftNamespacedKey.toMinecraft(enchant.enchantmentKey))) {
val nms = enchantmentRegistry[CraftNamespacedKey.toMinecraft(enchant.enchantmentKey)]
if (nms.isPresent) {
return EcoEnchantsCraftEnchantment(enchant, nms.get().value())
} else {
throw IllegalStateException("Enchantment ${enchant.id} wasn't registered")
}
}
val vanillaEnchantment = vanillaEcoEnchantsEnchantment(enchant)
enchantmentRegistry.createIntrusiveHolder(vanillaEnchantment)
Registry.register(
enchantmentRegistry,
ResourceLocation.withDefaultNamespace(enchant.id),
vanillaEnchantment
)
return register(enchant)
}
override fun unregister(enchant: EcoEnchant) {
/*
You can't unregister from a minecraft registry, so we simply leave the stale reference there.
This shouldn't cause many issues in production as the bukkit registry is replaced on each reload.
*/
}
}

View File

@ -0,0 +1,11 @@
package com.willfp.ecoenchants.proxy.v1_21_4
import com.willfp.ecoenchants.mechanics.OpenInventoryProxy
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
class OpenInventory : OpenInventoryProxy {
override fun getOpenInventory(player: Player): Any {
return (player as CraftPlayer).handle.containerMenu
}
}

View File

@ -0,0 +1,109 @@
package com.willfp.ecoenchants.proxy.v1_21_4.registration
import com.willfp.eco.util.toComponent
import com.willfp.ecoenchants.display.getFormattedName
import com.willfp.ecoenchants.enchant.EcoEnchant
import com.willfp.ecoenchants.enchant.impl.EcoEnchantBase
import net.kyori.adventure.text.Component
import net.minecraft.world.item.enchantment.Enchantment
import org.bukkit.craftbukkit.enchantments.CraftEnchantment
import org.bukkit.enchantments.EnchantmentTarget
import org.bukkit.inventory.ItemStack
class EcoEnchantsCraftEnchantment(
private val enchant: EcoEnchantBase,
nmsEnchantment: Enchantment
) : CraftEnchantment(enchant.enchantmentKey, nmsEnchantment), EcoEnchant by enchant {
init {
enchant.enchantment = this
}
override fun onRegister() {
// Fix for hardcoded enchantments
if (plugin.isLoaded) {
enchant.onRegister()
}
}
override fun onRemove() {
enchant.onRemove()
}
override fun canEnchantItem(item: ItemStack): Boolean {
return enchant.canEnchantItem(item)
}
override fun conflictsWith(other: org.bukkit.enchantments.Enchantment): Boolean {
return enchant.conflictsWith(other)
}
@Deprecated(
message = "EcoEnchants enchantments are not translatable",
replaceWith = ReplaceWith("this.displayName(level)")
)
override fun translationKey(): String {
return "ecoenchants:enchantment.$id"
}
@Deprecated(
message = "getName is a legacy Spigot API",
replaceWith = ReplaceWith("this.displayName(level)")
)
override fun getName(): String = this.id.uppercase()
override fun getMaxLevel(): Int = enchant.maximumLevel
override fun getStartLevel(): Int = 1
@Deprecated(
message = "getItemTargets is an incompatible Spigot API",
replaceWith = ReplaceWith("this.targets")
)
@Suppress("DEPRECATION")
override fun getItemTarget(): EnchantmentTarget = EnchantmentTarget.ALL
@Deprecated(
message = "Treasure enchantments do not exist in EcoEnchants",
replaceWith = ReplaceWith("this.isEnchantable")
)
override fun isTreasure(): Boolean = !enchant.isObtainableThroughEnchanting
@Deprecated(
message = "Use EnchantmentType instead",
replaceWith = ReplaceWith("type.id")
)
override fun isCursed(): Boolean {
return false
}
override fun displayName(level: Int): Component {
return enchant.getFormattedName(level).toComponent()
}
override fun isTradeable(): Boolean {
return enchant.isObtainableThroughTrading
}
override fun isDiscoverable(): Boolean {
return enchant.isObtainableThroughDiscovery
}
override fun getMinModifiedCost(level: Int): Int {
return Int.MAX_VALUE
}
override fun getMaxModifiedCost(level: Int): Int {
return Int.MAX_VALUE
}
override fun equals(other: Any?): Boolean {
return other is EcoEnchant && this.enchantmentKey == other.enchantmentKey
}
override fun hashCode(): Int {
return this.enchantmentKey.hashCode()
}
override fun toString(): String {
return "EcoEnchantsCraftEnchantment(key=$key)"
}
}

View File

@ -0,0 +1,23 @@
package com.willfp.ecoenchants.proxy.v1_21_4.registration
import com.willfp.ecoenchants.enchant.vanillaEnchantmentData
import net.minecraft.world.item.enchantment.Enchantment
import org.bukkit.NamespacedKey
import org.bukkit.craftbukkit.enchantments.CraftEnchantment
class ModifiedVanillaCraftEnchantment(
key: NamespacedKey,
target: Enchantment
) : CraftEnchantment(key, target) {
override fun getMaxLevel(): Int = this.vanillaEnchantmentData?.maxLevel ?: super.getMaxLevel()
override fun conflictsWith(other: org.bukkit.enchantments.Enchantment): Boolean {
val otherConflicts = when (other) {
is ModifiedVanillaCraftEnchantment -> other.vanillaEnchantmentData?.conflicts?.contains(this.key) == true
else -> other.conflictsWith(this)
}
return this.vanillaEnchantmentData?.conflicts?.contains(other.key) ?: super.conflictsWith(other)
|| otherConflicts
}
}

View File

@ -0,0 +1,21 @@
package com.willfp.ecoenchants.proxy.v1_21_4.registration
import com.willfp.ecoenchants.enchant.EcoEnchant
import net.minecraft.core.HolderSet
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.enchantment.Enchantment
fun vanillaEcoEnchantsEnchantment(enchant: EcoEnchant): Enchantment {
val enchantment = Enchantment.enchantment(
Enchantment.definition(
HolderSet.empty(),
1, // 1.21 hardcodes a minimum weight of 1
enchant.maximumLevel,
Enchantment.constantCost(1),
Enchantment.constantCost(1),
0
)
)
return enchantment.build(ResourceLocation.withDefaultNamespace(enchant.id))
}

View File

@ -1,5 +1,7 @@
#libreforge-updater
#Wed Nov 06 18:33:45 GMT 2024
kotlin.code.style=official
libreforge-version=4.72.2
version=12.19.3
org.gradle.parallel=true
kotlin.daemon.jvmargs=-Xmx2g -XX:+UseG1GC -XX:MaxMetaspaceSize=512m
kotlin.code.style=official

View File

@ -28,3 +28,4 @@ include(":eco-core:core-nms:v1_20_R2")
include(":eco-core:core-nms:v1_20_R3")
include(":eco-core:core-nms:v1_21")
include(":eco-core:core-nms:v1_21_3")
include(":eco-core:core-nms:v1_21_4")