Got ModernEnchantmentRegisterer working

This commit is contained in:
Will FP 2023-12-09 15:48:06 +00:00
parent cd8dd2de57
commit f3af2a0a75
4 changed files with 45 additions and 20 deletions

View File

@ -6,6 +6,7 @@ import com.willfp.ecoenchants.enchant.registration.modern.ModernEnchantmentRegis
import com.willfp.ecoenchants.proxy.v1_20_R3.registration.EcoEnchantsCraftEnchantment
import com.willfp.ecoenchants.proxy.v1_20_R3.registration.ModifiedVanillaCraftEnchantment
import com.willfp.ecoenchants.proxy.v1_20_R3.registration.VanillaEcoEnchantsEnchantment
import com.willfp.ecoenchants.setStaticFinal
import net.minecraft.core.Holder
import net.minecraft.core.MappedRegistry
import net.minecraft.core.Registry
@ -49,7 +50,7 @@ class ModernEnchantmentRegisterer : ModernEnchantmentRegistererProxy {
val server = Bukkit.getServer() as CraftServer
@Suppress("UNCHECKED_CAST")
registries[Enchantment::class.java] = CraftRegistry(
val registry = CraftRegistry(
Enchantment::class.java as Class<in Enchantment?>,
server.handle.server.registryAccess().registryOrThrow(Registries.ENCHANTMENT)
) { key, registry ->
@ -64,33 +65,42 @@ class ModernEnchantmentRegisterer : ModernEnchantmentRegistererProxy {
null
}
}
// Register to server
registries[Enchantment::class.java] = registry
// Register to API
org.bukkit.Registry::class.java
.getDeclaredField("ENCHANTMENT")
.setStaticFinal(registry)
// Unfreeze NMS registry
frozenField.set(BuiltInRegistries.ENCHANTMENT, false)
unregisteredIntrusiveHoldersField.set(BuiltInRegistries.ENCHANTMENT, IdentityHashMap<Enchantment, Holder.Reference<Enchantment>>())
}
override fun register(enchant: EcoEnchant): Enchantment {
if (BuiltInRegistries.ENCHANTMENT.containsKey(CraftNamespacedKey.toMinecraft(enchant.enchantmentKey))) {
return org.bukkit.Registry.ENCHANTMENT.get(enchant.enchantmentKey)!!
val nms = BuiltInRegistries.ENCHANTMENT[CraftNamespacedKey.toMinecraft(enchant.enchantmentKey)]
if (nms != null) {
return EcoEnchantsCraftEnchantment(enchant, nms)
} else {
throw IllegalStateException("Enchantment ${enchant.id} wasn't registered")
}
}
// Unfreeze registry
unfreeze(BuiltInRegistries.ENCHANTMENT)
Registry.register(BuiltInRegistries.ENCHANTMENT, enchant.id, VanillaEcoEnchantsEnchantment(enchant.id))
val nms = VanillaEcoEnchantsEnchantment(enchant.id)
Registry.register(BuiltInRegistries.ENCHANTMENT, enchant.id, nms)
return EcoEnchantsCraftEnchantment(enchant, nms)
return register(enchant)
}
private fun <T> unfreeze(registry: Registry<T>) {
frozenField.set(registry, false)
unregisteredIntrusiveHoldersField.set(registry, IdentityHashMap<T, Holder.Reference<T>>())
}
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 because unregistered enchantments can't be accessed.
This shouldn't cause many issues in production as the bukkit registry is replaced on each reload.
*/
}

View File

@ -64,7 +64,7 @@ class EcoEnchantsPlugin : LibreforgePlugin() {
plugin = this
if (Prerequisite.HAS_1_20_3.isMet) {
this.getProxy(ModernEnchantmentRegistererProxy::class.java).replaceRegistry()
plugin.getProxy(ModernEnchantmentRegistererProxy::class.java).replaceRegistry()
}
}
@ -106,11 +106,6 @@ class EcoEnchantsPlugin : LibreforgePlugin() {
legacyRegisterVanillaEnchantmentData(this)
}
// Replace registry on reload to manage some enchantment removal logic
if (Prerequisite.HAS_1_20_3.isMet) {
this.getProxy(ModernEnchantmentRegistererProxy::class.java).replaceRegistry()
}
DisplayCache.reload()
EnchantSorter.reload(this)
ExtraItemSupport.reload(this)

View File

@ -0,0 +1,13 @@
package com.willfp.ecoenchants
import sun.misc.Unsafe
import java.lang.reflect.Field
private val unsafe = Unsafe::class.java.getDeclaredField("theUnsafe")
.apply { isAccessible = true }
.get(null) as Unsafe
fun Field.setStaticFinal(value: Any) {
val offset = unsafe.staticFieldOffset(this)
unsafe.putObject(unsafe.staticFieldBase(this), offset, value)
}

View File

@ -1,6 +1,7 @@
package com.willfp.ecoenchants.enchant
import com.google.common.collect.HashBiMap
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.config.interfaces.Config
import com.willfp.ecoenchants.EcoEnchantsPlugin
import com.willfp.ecoenchants.display.getFormattedName
@ -9,6 +10,7 @@ import com.willfp.ecoenchants.enchant.impl.hardcoded.EnchantmentPermanenceCurse
import com.willfp.ecoenchants.enchant.impl.hardcoded.EnchantmentRepairing
import com.willfp.ecoenchants.enchant.impl.hardcoded.EnchantmentReplenish
import com.willfp.ecoenchants.enchant.impl.hardcoded.EnchantmentSoulbound
import com.willfp.ecoenchants.enchant.registration.modern.ModernEnchantmentRegistererProxy
import com.willfp.ecoenchants.integrations.EnchantRegistrations
import com.willfp.ecoenchants.rarity.EnchantmentRarities
import com.willfp.ecoenchants.target.EnchantmentTargets
@ -34,6 +36,11 @@ object EcoEnchants : RegistrableCategory<EcoEnchant>("enchant", "enchants") {
}
override fun beforeReload(plugin: LibreforgePlugin) {
// Replace registry on reload to manage some enchantment removal logic
if (Prerequisite.HAS_1_20_3.isMet) {
plugin.getProxy(ModernEnchantmentRegistererProxy::class.java).replaceRegistry()
}
plugin as EcoEnchantsPlugin
EnchantmentRarities.update(plugin)