mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
Do not continue anvil process if Disenchantment done something.
This commit is contained in:
parent
3c8810ed72
commit
804c11a7f4
5 changed files with 231 additions and 59 deletions
|
|
@ -27,10 +27,12 @@ import org.bukkit.inventory.InventoryView.Property.REPAIR_COST
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import org.bukkit.inventory.meta.Repairable
|
import org.bukkit.inventory.meta.Repairable
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||||
|
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
||||||
import xyz.alexcrea.cuanvil.group.ConflictType
|
import xyz.alexcrea.cuanvil.group.ConflictType
|
||||||
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
|
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
|
||||||
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
||||||
|
import xyz.alexcrea.cuanvil.util.XpSetterUtil.setAnvilInvXp
|
||||||
import java.util.regex.Matcher
|
import java.util.regex.Matcher
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
@ -43,9 +45,9 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// Anvil's output slot
|
// Anvil's output slot
|
||||||
private const val ANVIL_INPUT_LEFT = 0
|
const val ANVIL_INPUT_LEFT = 0
|
||||||
private const val ANVIL_INPUT_RIGHT = 1
|
const val ANVIL_INPUT_RIGHT = 1
|
||||||
private const val ANVIL_OUTPUT_SLOT = 2
|
const val ANVIL_OUTPUT_SLOT = 2
|
||||||
|
|
||||||
// static slot container
|
// static slot container
|
||||||
private val NO_SLOT = SlotContainer(SlotType.NO_SLOT, 0)
|
private val NO_SLOT = SlotContainer(SlotType.NO_SLOT, 0)
|
||||||
|
|
@ -57,6 +59,9 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = HIGHEST)
|
@EventHandler(priority = HIGHEST)
|
||||||
fun anvilCombineCheck(event: PrepareAnvilEvent) {
|
fun anvilCombineCheck(event: PrepareAnvilEvent) {
|
||||||
|
// Test if the event should bypass custom anvil.
|
||||||
|
if(DependencyManager.tryEventPreAnvilBypass(event)) return
|
||||||
|
|
||||||
val inventory = event.inventory
|
val inventory = event.inventory
|
||||||
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
||||||
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
|
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
|
||||||
|
|
@ -75,7 +80,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
resultItem.amount *= amount
|
resultItem.amount *= amount
|
||||||
|
|
||||||
event.result = resultItem
|
event.result = resultItem
|
||||||
handleAnvilXp(inventory, event, recipe.xpCostPerCraft * amount, true)
|
setAnvilInvXp(inventory, event.view, recipe.xpCostPerCraft * amount, true)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +101,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
|
|
||||||
anvilCost += calculatePenalty(first, null, resultItem)
|
anvilCost += calculatePenalty(first, null, resultItem)
|
||||||
|
|
||||||
handleAnvilXp(inventory, event, anvilCost)
|
setAnvilInvXp(inventory, event.view, anvilCost)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +135,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
// Finally, we set result
|
// Finally, we set result
|
||||||
event.result = resultItem
|
event.result = resultItem
|
||||||
|
|
||||||
handleAnvilXp(inventory, event, anvilCost)
|
setAnvilInvXp(inventory, event.view, anvilCost)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +160,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
}
|
}
|
||||||
event.result = resultItem
|
event.result = resultItem
|
||||||
|
|
||||||
handleAnvilXp(inventory, event, anvilCost)
|
setAnvilInvXp(inventory, event.view, anvilCost)
|
||||||
} else {
|
} else {
|
||||||
CustomAnvil.log("no anvil fuse type found")
|
CustomAnvil.log("no anvil fuse type found")
|
||||||
event.result = null
|
event.result = null
|
||||||
|
|
@ -282,9 +287,13 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
val player = event.whoClicked as? Player ?: return
|
val player = event.whoClicked as? Player ?: return
|
||||||
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
||||||
val inventory = event.inventory as? AnvilInventory ?: return
|
val inventory = event.inventory as? AnvilInventory ?: return
|
||||||
|
|
||||||
if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
|
if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Test if the event should bypass custom anvil.
|
||||||
|
if(DependencyManager.tryClickAnvilResultBypass(event, inventory)) return
|
||||||
|
|
||||||
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
|
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
|
||||||
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
||||||
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
|
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
|
||||||
|
|
@ -638,58 +647,6 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display xp needed for the work on the anvil inventory
|
|
||||||
*/
|
|
||||||
private fun handleAnvilXp(
|
|
||||||
inventory: AnvilInventory,
|
|
||||||
event: PrepareAnvilEvent,
|
|
||||||
anvilCost: Int,
|
|
||||||
ignoreRules: Boolean = false
|
|
||||||
) {
|
|
||||||
// Test repair cost limit
|
|
||||||
val finalAnvilCost = if (
|
|
||||||
!ignoreRules &&
|
|
||||||
!ConfigOptions.doRemoveCostLimit &&
|
|
||||||
ConfigOptions.doCapCost) {
|
|
||||||
min(anvilCost, ConfigOptions.maxAnvilCost)
|
|
||||||
} else {
|
|
||||||
anvilCost
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Because Minecraft likes to have the final say in the repair cost displayed
|
|
||||||
* we need to wait for the event to end before overriding it, this ensures that
|
|
||||||
* we have the final say in the process. */
|
|
||||||
CustomAnvil.instance
|
|
||||||
.server
|
|
||||||
.scheduler
|
|
||||||
.runTask(CustomAnvil.instance, Runnable {
|
|
||||||
inventory.maximumRepairCost =
|
|
||||||
if (ConfigOptions.doRemoveCostLimit || ignoreRules)
|
|
||||||
{ Int.MAX_VALUE }
|
|
||||||
else
|
|
||||||
{ ConfigOptions.maxAnvilCost + 1 }
|
|
||||||
|
|
||||||
val player = event.view.player
|
|
||||||
|
|
||||||
inventory.repairCost = finalAnvilCost
|
|
||||||
event.view.setProperty(REPAIR_COST, finalAnvilCost)
|
|
||||||
player.openInventory.setProperty(REPAIR_COST, finalAnvilCost)
|
|
||||||
|
|
||||||
if(player is Player){
|
|
||||||
if(player.gameMode != GameMode.CREATIVE ){
|
|
||||||
val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) &&
|
|
||||||
(finalAnvilCost >= 40) &&
|
|
||||||
finalAnvilCost < inventory.maximumRepairCost
|
|
||||||
|
|
||||||
packetManager.setInstantBuild(player, bypassToExpensive)
|
|
||||||
}
|
|
||||||
|
|
||||||
player.updateInventory()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun onAnvilClose(event: InventoryCloseEvent){
|
fun onAnvilClose(event: InventoryCloseEvent){
|
||||||
val player = event.player
|
val player = event.player
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency
|
package xyz.alexcrea.cuanvil.dependency
|
||||||
|
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||||
|
import org.bukkit.inventory.AnvilInventory
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
||||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerSelector
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerSelector
|
||||||
|
|
@ -10,6 +13,7 @@ object DependencyManager {
|
||||||
lateinit var packetManager: PacketManager
|
lateinit var packetManager: PacketManager
|
||||||
var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null
|
var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null
|
||||||
var ecoEnchantCompatibility: EcoEnchantDependency? = null
|
var ecoEnchantCompatibility: EcoEnchantDependency? = null
|
||||||
|
var disenchantmentCompatibility: DisenchantmentDependency? = null
|
||||||
|
|
||||||
fun loadDependency(){
|
fun loadDependency(){
|
||||||
val pluginManager = Bukkit.getPluginManager()
|
val pluginManager = Bukkit.getPluginManager()
|
||||||
|
|
@ -30,6 +34,12 @@ object DependencyManager {
|
||||||
ecoEnchantCompatibility!!.disableAnvilListener()
|
ecoEnchantCompatibility!!.disableAnvilListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disenchantment dependency
|
||||||
|
if(pluginManager.isPluginEnabled("Disenchantment")){
|
||||||
|
disenchantmentCompatibility = DisenchantmentDependency()
|
||||||
|
disenchantmentCompatibility!!.redirectListeners()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleCompatibilityConfig() {
|
fun handleCompatibilityConfig() {
|
||||||
|
|
@ -52,4 +62,20 @@ object DependencyManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent): Boolean {
|
||||||
|
var bypass = false
|
||||||
|
|
||||||
|
if(disenchantmentCompatibility?.testPrepareAnvil(event) == true) bypass = true
|
||||||
|
|
||||||
|
return bypass
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
|
||||||
|
var bypass = false
|
||||||
|
|
||||||
|
if(disenchantmentCompatibility?.testAnvilResult(event, inventory) == true) bypass = true
|
||||||
|
|
||||||
|
return bypass
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
package xyz.alexcrea.cuanvil.dependency
|
||||||
|
|
||||||
|
import cz.kominekjan.disenchantment.events.ItemClickEvent
|
||||||
|
import cz.kominekjan.disenchantment.events.ItemEvent
|
||||||
|
import cz.kominekjan.disenchantment.events.SplitBookClickEvent
|
||||||
|
import cz.kominekjan.disenchantment.events.SplitBookEvent
|
||||||
|
import io.delilaheve.AnvilEventListener
|
||||||
|
import io.delilaheve.CustomAnvil
|
||||||
|
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.plugin.RegisteredListener
|
||||||
|
import xyz.alexcrea.cuanvil.util.XpSetterUtil
|
||||||
|
|
||||||
|
class DisenchantmentDependency {
|
||||||
|
|
||||||
|
init {
|
||||||
|
CustomAnvil.instance.logger.info("Disenchantment Detected !")
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var splitEvent: SplitBookEvent
|
||||||
|
private lateinit var itemEvent: ItemEvent
|
||||||
|
|
||||||
|
private lateinit var splitBookClickEvent: SplitBookClickEvent
|
||||||
|
private lateinit var itemClickEvent: ItemClickEvent
|
||||||
|
|
||||||
|
fun redirectListeners() {
|
||||||
|
|
||||||
|
val toUnregister = ArrayList<RegisteredListener>()
|
||||||
|
// get required PrepareAnvilEvent listener
|
||||||
|
for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) {
|
||||||
|
val listener = registeredListener.listener
|
||||||
|
|
||||||
|
if(listener is SplitBookEvent){
|
||||||
|
this.splitEvent = listener
|
||||||
|
toUnregister.add(registeredListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listener is ItemEvent){
|
||||||
|
itemEvent = listener
|
||||||
|
toUnregister.add(registeredListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (listener in toUnregister) {
|
||||||
|
PrepareAnvilEvent.getHandlerList().unregister(listener)
|
||||||
|
}
|
||||||
|
toUnregister.clear()
|
||||||
|
|
||||||
|
// get required InventoryClickEvent listener
|
||||||
|
for (registeredListener in InventoryClickEvent.getHandlerList().registeredListeners) {
|
||||||
|
val listener = registeredListener.listener
|
||||||
|
|
||||||
|
if(listener is SplitBookClickEvent){
|
||||||
|
splitBookClickEvent = listener
|
||||||
|
toUnregister.add(registeredListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listener is ItemClickEvent){
|
||||||
|
itemClickEvent = listener
|
||||||
|
toUnregister.add(registeredListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (listener in toUnregister) {
|
||||||
|
InventoryClickEvent.getHandlerList().unregister(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPrepareAnvil(event: PrepareAnvilEvent): Boolean {
|
||||||
|
val previousResult = event.result
|
||||||
|
event.result = null
|
||||||
|
|
||||||
|
// Test if event change the result
|
||||||
|
itemEvent.onDisenchantmentEvent(event)
|
||||||
|
|
||||||
|
if(event.result != null) {
|
||||||
|
CustomAnvil.log("Detected pre anvil item extract bypass.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
splitEvent.onDisenchantmentEvent(event)
|
||||||
|
if(event.result != null) {
|
||||||
|
CustomAnvil.log("Detected pre anvil split enchant bypass.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
event.result = previousResult
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
|
||||||
|
val previousResultSlot = inventory.getItem(AnvilEventListener.ANVIL_OUTPUT_SLOT)?.clone()
|
||||||
|
|
||||||
|
// Test event if change the result
|
||||||
|
itemClickEvent.onDisenchantmentClickEvent(event)
|
||||||
|
if(!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) {
|
||||||
|
CustomAnvil.log("Detected anvil click item extract bypass.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
splitBookClickEvent.onDisenchantmentClickEvent(event)
|
||||||
|
if(!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) {
|
||||||
|
CustomAnvil.log("Detected anvil click split enchant bypass.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testAnvilInventoryChange(inventory: AnvilInventory, previous: ItemStack?): Boolean {
|
||||||
|
val currentResult = inventory.getItem(AnvilEventListener.ANVIL_OUTPUT_SLOT)
|
||||||
|
|
||||||
|
return currentResult == previous
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
67
src/main/kotlin/xyz/alexcrea/cuanvil/util/XpSetterUtil.kt
Normal file
67
src/main/kotlin/xyz/alexcrea/cuanvil/util/XpSetterUtil.kt
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
package xyz.alexcrea.cuanvil.util
|
||||||
|
|
||||||
|
import io.delilaheve.CustomAnvil
|
||||||
|
import io.delilaheve.util.ConfigOptions
|
||||||
|
import org.bukkit.GameMode
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.AnvilInventory
|
||||||
|
import org.bukkit.inventory.InventoryView
|
||||||
|
import org.bukkit.inventory.InventoryView.Property.REPAIR_COST
|
||||||
|
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
object XpSetterUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display xp needed for the work on the anvil inventory
|
||||||
|
*/
|
||||||
|
fun setAnvilInvXp(
|
||||||
|
inventory: AnvilInventory,
|
||||||
|
view: InventoryView,
|
||||||
|
anvilCost: Int,
|
||||||
|
ignoreRules: Boolean = false
|
||||||
|
) {
|
||||||
|
// Test repair cost limit
|
||||||
|
val finalAnvilCost = if (
|
||||||
|
!ignoreRules &&
|
||||||
|
!ConfigOptions.doRemoveCostLimit &&
|
||||||
|
ConfigOptions.doCapCost) {
|
||||||
|
min(anvilCost, ConfigOptions.maxAnvilCost)
|
||||||
|
} else {
|
||||||
|
anvilCost
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Because Minecraft likes to have the final say in the repair cost displayed
|
||||||
|
* we need to wait for the event to end before overriding it, this ensures that
|
||||||
|
* we have the final say in the process. */
|
||||||
|
CustomAnvil.instance
|
||||||
|
.server
|
||||||
|
.scheduler
|
||||||
|
.runTask(CustomAnvil.instance, Runnable {
|
||||||
|
inventory.maximumRepairCost =
|
||||||
|
if (ConfigOptions.doRemoveCostLimit || ignoreRules)
|
||||||
|
{ Int.MAX_VALUE }
|
||||||
|
else
|
||||||
|
{ ConfigOptions.maxAnvilCost + 1 }
|
||||||
|
|
||||||
|
val player = view.player
|
||||||
|
|
||||||
|
inventory.repairCost = finalAnvilCost
|
||||||
|
view.setProperty(REPAIR_COST, finalAnvilCost)
|
||||||
|
player.openInventory.setProperty(REPAIR_COST, finalAnvilCost)
|
||||||
|
|
||||||
|
if(player is Player){
|
||||||
|
if(player.gameMode != GameMode.CREATIVE ){
|
||||||
|
val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) &&
|
||||||
|
(finalAnvilCost >= 40) &&
|
||||||
|
finalAnvilCost < inventory.maximumRepairCost
|
||||||
|
|
||||||
|
DependencyManager.packetManager.setInstantBuild(player, bypassToExpensive)
|
||||||
|
}
|
||||||
|
|
||||||
|
player.updateInventory()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -53,6 +53,7 @@ permissions:
|
||||||
softdepend:
|
softdepend:
|
||||||
- UnsafeEnchantsPlus
|
- UnsafeEnchantsPlus
|
||||||
- ProtocolLib
|
- ProtocolLib
|
||||||
|
- Disenchantment
|
||||||
- EnchantsSquared
|
- EnchantsSquared
|
||||||
- EcoEnchants
|
- EcoEnchants
|
||||||
- eco
|
- eco
|
||||||
Loading…
Add table
Add a link
Reference in a new issue