progress on 1.21 transition

This commit is contained in:
alexcrea 2026-06-03 04:25:10 +02:00
parent 007a664db1
commit 7ecfc12b5c
Signed by: alexcrea
GPG key ID: E59DF23EE2A2266C
23 changed files with 62 additions and 1245 deletions

View file

@ -1,6 +1,6 @@
package xyz.alexcrea.cuanvil.enchant;
// because spigot (1.18) do not look like to provide access to enchantment rarity I need to do it myself...
// because spigot (1.21) do not look like to provide access to enchantment rarity I need to do it myself...
public class EnchantmentRarity {
public static final EnchantmentRarity NO_RARITY = new EnchantmentRarity(0, 0);

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.command
import com.github.stefvanschie.inventoryframework.inventoryview.interface_.InventoryViewUtil
import io.delilaheve.CustomAnvil
import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent
@ -16,8 +15,6 @@ import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryType
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable
import org.bukkit.inventory.meta.EnchantmentStorageMeta
@ -263,7 +260,7 @@ class DiagnosticExecutor: CASubCommand() {
}
fun simulateAnvil(player: Player, stb: StringBuilder, left: ItemStack?, right: ItemStack?, result: ItemStack?) {
var invView: InventoryView
var invView: AnvilView
var event: PrepareAnvilEvent
try {
val fakeInv = Bukkit.createInventory(player, InventoryType.ANVIL)
@ -275,42 +272,40 @@ class DiagnosticExecutor: CASubCommand() {
val anvilTypeField = menuTypeClazz.getField("ANVIL")
val anvilType = anvilTypeField.get(null)
val createMethod = anvilType.javaClass.getMethod("create", HumanEntity::class.java)
invView = createMethod.invoke(anvilType, player) as InventoryView
invView = createMethod.invoke(anvilType, player) as AnvilView
player.openInventory(invView)
val anvilViewClass = Class.forName("org.bukkit.inventory.view.AnvilView")
val constructor = PrepareAnvilEvent::class.java.getConstructor(anvilViewClass, ItemStack::class.java)
val constructor = PrepareAnvilEvent::class.java.getConstructor(AnvilView::class.java, ItemStack::class.java)
event = constructor.newInstance(invView, result)
}
val fakeInv = InventoryViewUtil.getInstance().getTopInventory(invView) as AnvilInventory
fakeInv.setItem(0, left)
fakeInv.setItem(1, right)
invView.setItem(0, left)
invView.setItem(1, right)
val xp = fakeInv.repairCost
val maxXp = fakeInv.maximumRepairCost
val mergeResult = fakeInv.getItem(2)
val xp = invView.repairCost
val maxXp = invView.maximumRepairCost
val mergeResult = invView.getItem(2)
stb.append("\n${if(result == mergeResult) "E" else "Une"}xpected Result")
PrepareAnvilListener().anvilCombineCheck(event)
// Now we check if item and xp same
stb.append("\nXP/Max XP: ")
.append(if(fakeInv.repairCost == xp) "Correct" else "Incorrect")
.append(if(invView.repairCost == xp) "Correct" else "Incorrect")
.append("/")
.append(if(fakeInv.maximumRepairCost == maxXp) "Correct" else "Incorrect")
.append(" (${fakeInv.repairCost} $xp|${fakeInv.maximumRepairCost} $maxXp)")
.append(if(invView.maximumRepairCost == maxXp) "Correct" else "Incorrect")
.append(" (${invView.repairCost} $xp|${invView.maximumRepairCost} $maxXp)")
.append("\nMerge result: ")
.append(if(fakeInv.getItem(2) == mergeResult) "Correct" else "Incorrect")
.append(if(invView.getItem(2) == mergeResult) "Correct" else "Incorrect")
PrepareAnvilListener.IS_EMPTY_TEST = true
Bukkit.getPluginManager().callEvent(event)
stb.append("\nNull result test: ")
.append(if(event.result == null) "Correct" else "Incorrect")
fakeInv.setItem(0, null)
fakeInv.setItem(1, null)
fakeInv.setItem(2, null)
invView.setItem(0, null)
invView.setItem(1, null)
invView.setItem(2, null)
player.closeInventory()
}

View file

@ -15,6 +15,7 @@ import org.bukkit.inventory.Inventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.anvil.AnvilCost
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent
@ -164,9 +165,9 @@ object DependencyManager {
)
}
private fun logExceptionAndClear(target: CommandSender, inventory: Inventory, e: Exception) {
private fun logExceptionAndClear(target: CommandSender, view: AnvilView, e: Exception) {
// Just in case to avoid illegal items
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
view.setItem(ANVIL_OUTPUT_SLOT, null)
logException(target, e)
}
@ -177,7 +178,7 @@ object DependencyManager {
try {
return earlyUnsafeTryEventPreAnvilBypass(event, player)
} catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e)
logExceptionAndClear(event.view.player, event.view, e)
return true
}
}
@ -203,7 +204,7 @@ object DependencyManager {
try {
return unsafeTryEventPreAnvilBypass(event, player)
} catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e)
logExceptionAndClear(event.view.player, event.view, e)
return true
}
}
@ -257,16 +258,16 @@ object DependencyManager {
}
// Return true if should bypass (either by a dependency or error)
fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
fun tryClickAnvilResultBypass(event: InventoryClickEvent, view: AnvilView): Boolean {
try {
return unsafeTryClickAnvilResultBypass(event, inventory)
return unsafeTryClickAnvilResultBypass(event, view)
} catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e)
logExceptionAndClear(event.view.player, event.view, e)
return true
}
}
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, view: AnvilView): Boolean {
// Run the event
val bypassEvent = CAClickResultBypassEvent(event)
Bukkit.getPluginManager().callEvent(bypassEvent)
@ -274,10 +275,10 @@ object DependencyManager {
var bypass = bypassEvent.isCancelled
// Test if disenchantment used event click
if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, view) == true)) bypass = true
// Test if haven bag used event click
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, view) == true)) bypass = true
// Test if disenchantment used event click
if (!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true
@ -287,10 +288,10 @@ object DependencyManager {
}
// Test if the inventory is a gui(version specific)
if (!bypass && externGuiTester.testIfGui(event.view)) bypass = true
if (!bypass && externGuiTester.testIfGui(view)) bypass = true
// Test if in an ax player warp rating gui
if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(event.view.player) == true)) bypass = true
if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(view.player) == true)) bypass = true
return bypass
}

View file

@ -10,32 +10,6 @@ object MinecraftVersionUtil {
if (version.major != 1) return null
return when (version.minor) {
17 -> when (version.patch) {
0, 1 -> "1_17R1"
else -> null
}
18 -> when (version.patch) {
0, 1 -> "1_18R1"
2 -> "1_18R2"
else -> null
}
19 -> when (version.patch) {
0, 1, 2 -> "1_19R1"
3 -> "1_19R2"
4 -> "1_19R3"
else -> null
}
20 -> when (version.patch) {
0, 1 -> "1_20R1"
2 -> "1_20R2"
3, 4 -> "1_20R3"
5, 6 -> "1_20R4"
else -> null
}
21 -> when (version.patch) {
0, 1 -> "1_21R1"
2, 3 -> "1_21R2"
@ -46,6 +20,7 @@ object MinecraftVersionUtil {
11 -> "1_21R7"
else -> null
}
//TODO need to continue updating that for anvil gui test dependency....
else -> null
}

View file

@ -12,8 +12,8 @@ import org.bukkit.entity.Player
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
@ -59,14 +59,14 @@ class DisenchantmentDependency {
DisenchantEvent.onEvent(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil item extract bypass.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
ShatterEvent.onEvent(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil split enchant bypass.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
@ -74,18 +74,18 @@ class DisenchantmentDependency {
return false
}
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
val previousResultSlot = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
fun testAnvilResult(event: InventoryClickEvent, view: AnvilView): Boolean {
val previousResultSlot = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
// Test event if change the result
DisenchantClickEvent.onEvent(event)
if (!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) {
if (!testAnvilChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click item extract bypass.")
return true
}
ShatterClickEvent.onEvent(event)
if (!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) {
if (!testAnvilChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click split enchant bypass.")
return true
}
@ -93,8 +93,8 @@ class DisenchantmentDependency {
return false
}
private fun testAnvilInventoryChange(inventory: AnvilInventory, previous: ItemStack?): Boolean {
val currentResult = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
private fun testAnvilChange(view: AnvilView, previous: ItemStack?): Boolean {
val currentResult = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
return currentResult == previous
}

View file

@ -4,7 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.view.AnvilView
import org.bukkit.plugin.RegisteredListener
import valorless.havenbags.HavenBags
import valorless.havenbags.features.BagSkin
@ -54,14 +54,14 @@ class HavenBagsDependency {
bagSkin.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil skin.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
bagUpgrade.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
@ -69,8 +69,8 @@ class HavenBagsDependency {
return false
}
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
val result = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
fun testAnvilResult(event: InventoryClickEvent, view: AnvilView): Boolean {
val result = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
if (HavenBags.IsBag(result)) {
CustomAnvil.log("Detected anvil click haven bag bypass.")

View file

@ -5,7 +5,7 @@ import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
@ -14,7 +14,7 @@ class AnvilCloseListener(private val packetManager: PacketManager) : Listener {
@EventHandler
fun onAnvilClose(event: InventoryCloseEvent){
val player = event.player
if(event.inventory !is AnvilInventory) return
if(event.view !is AnvilView) return
if(player is Player && GameMode.CREATIVE != player.gameMode){
packetManager.setInstantBuild(player, false)
}

View file

@ -160,10 +160,7 @@ restriction_sweeping_edge:
enchantments: [ minecraft:sweeping, minecraft:sweeping_edge ]
notAffectedGroups: [ enchanted_book, swords ]
# Do not exist in 1.18, that mean useInFuture will be set to true
# useInFuture set to true also mean it will not warn if there is an issue
restriction_swift_sneak:
useInFuture: true
enchantments: [ minecraft:swift_sneak ]
notAffectedGroups: [ enchanted_book, leggings ]

View file

@ -121,7 +121,6 @@ wearable:
- player_head
- creeper_head
- dragon_head
# do not exist in 1.18 but exist in future update
- piglin_head
groups:
- armors

View file

@ -4,7 +4,7 @@ prefix: "Custom Anvil"
version: ${version}
folia-supported: true
description: Allow to customise anvil mechanics
api-version: 1.16
api-version: 1.21
load: POSTWORLD
authors: [ DelilahEve, alexcrea ]
libraries: [${libraries}]