deduplicate lore edit logic

This commit is contained in:
alexcrea 2026-06-02 14:36:09 +02:00
parent e6293be1c6
commit 106bc724a1
Signed by: alexcrea
GPG key ID: E346CD16413450E3
5 changed files with 230 additions and 198 deletions

View file

@ -28,9 +28,10 @@ import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.config.LoreEditType
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
object AnvilMergeUtil {
object AnvilMergeLogic {
open class AnvilResult {
companion object {
@ -64,6 +65,19 @@ object AnvilMergeUtil {
}
}
class LoreEditResult: AnvilResult {
companion object {
val EMPTY = LoreEditResult(null, AnvilCost(), LoreEditType.APPEND_PAPER)
}
val type: LoreEditType
constructor(item: ItemStack?, cost: AnvilCost, type: LoreEditType) : super(item, cost) {
this.type = type
}
}
fun doRenaming(inventory: AnvilInventory,
player: Player, first: ItemStack
): AnvilResult {
@ -258,23 +272,23 @@ object AnvilMergeUtil {
fun testLoreEdit(
player: Player,
first: ItemStack, second: ItemStack
): AnvilResult {
): LoreEditResult {
val type = second.type
var resultItem: ItemStack? = null
val cost = AnvilCost()
if (Material.WRITABLE_BOOK == type) {
resultItem = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second, cost)
} else if (Material.PAPER == type) {
resultItem = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second, cost)
}
val result = if (Material.WRITABLE_BOOK == type)
AnvilLoreEditUtil.tryLoreEditByBook(player, first, second)
else if (Material.PAPER == type)
AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second)
else LoreEditResult.EMPTY
if (resultItem.isAir || first == resultItem) {
if(result.isEmpty()) return result
if (result.item!!.isAir || first == result.item) {
CustomAnvil.log("lore edit, But input is same as output")
return AnvilResult.EMPTY
return LoreEditResult.EMPTY
}
return AnvilResult(resultItem, cost)
return result
}
}

View file

@ -15,8 +15,9 @@ import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BookMeta
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.AnvilResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
@ -112,14 +113,14 @@ class AnvilResultListener : Listener {
}
// For lore edit
if (handleBookLoreEdit(event, inventory, player, leftItem, rightItem, output)) {
return
} else if (handlePaperLoreEdit(event, inventory, player, leftItem, rightItem, output)) {
val loreResult = AnvilMergeLogic.testLoreEdit(player, leftItem, rightItem)
if(!loreResult.isEmpty()) {
if(loreResult.type.isBook)
handleBookLoreEdit(event, inventory, player, leftItem, rightItem, loreResult)
else
handlePaperLoreEdit(event, inventory, player, leftItem, rightItem, loreResult)
return
}
// Else there was no working situation somehow so we deny
event.result = Event.Result.DENY
}
private fun onCustomCraft(
@ -341,7 +342,7 @@ class AnvilResultListener : Listener {
player: Player,
inventory: AnvilInventory
) {
val result = AnvilMergeUtil.testUnitRepair(inventory, player,
val result = AnvilMergeLogic.testUnitRepair(inventory, player,
leftItem.clone(), rightItem,
unitRepairResult)
@ -356,99 +357,90 @@ class AnvilResultListener : Listener {
)
}
private fun getFromLoreEditXpCost(
cost: AnvilCost,
player: Player,
inventory: AnvilInventory,
): AnvilCost {
if (GameMode.CREATIVE == player.gameMode) return AnvilCost(0)
if (ConfigOptions.shouldUseMoney(player)) {
cost.isMonetary = true
if (!EconomyManager.economy!!.has(player, cost.asMonetaryCost()))
cost.valid = false
} else {
val repairCost = cost.asXpCost()
if ((inventory.maximumRepairCost <= repairCost)
|| (player.level < repairCost)
)
cost.valid = false
}
return cost
}
private fun handleBookLoreEdit(
event: InventoryClickEvent,
inventory: AnvilInventory,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
output: ItemStack,
): Boolean {
if (Material.WRITABLE_BOOK != rightItem.type) return false
val bookMeta = rightItem.itemMeta as BookMeta? ?: return false
result: LoreEditResult
) {
if (result.type.isAppend)
handleBookLoreAppend(event, inventory, player, rightItem, result)
else
handleBookLoreRemove(event, inventory, player, leftItem, rightItem, result)
}
val editType = AnvilLoreEditUtil.bookLoreEditIsAppend(leftItem, rightItem) ?: return false
private fun handleBookLoreAppend(
event: InventoryClickEvent,
inventory: AnvilInventory,
player: Player,
rightItem: ItemStack,
result: LoreEditResult
) {
val bookMeta = rightItem.itemMeta as BookMeta? ?: return
val cost = AnvilCost()
if (editType) {
if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta, cost)) return false
// Remove pages to book
val clearedBook: ItemStack?
if (LoreEditType.APPEND_BOOK.doConsume) {
clearedBook = null
} else {
clearedBook = rightItem.clone()
bookMeta.pages = Collections.emptyList()
clearedBook.itemMeta = bookMeta
}
return extractAnvilResult(
event, player, inventory,
null, 0,
clearedBook, 0,
output, getFromLoreEditXpCost(cost, player, inventory)
)
// Remove pages to book
val clearedBook: ItemStack?
if (LoreEditType.APPEND_BOOK.doConsume) {
clearedBook = null
} else {
if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem, cost)) return false
clearedBook = rightItem.clone()
bookMeta.pages = Collections.emptyList()
clearedBook.itemMeta = bookMeta
}
// fill book meta
val lore = DependencyManager.stripLore(leftItem)
if (lore.isEmpty()) return false
extractAnvilResult(
event, player, inventory,
null, 0,
clearedBook, 0,
result
)
}
val rightCopy: ItemStack?
if (LoreEditType.REMOVE_BOOK.doConsume) {
rightCopy = null
} else {
// Uncolor the page
AnvilLoreEditUtil.uncolorLines(player, lore, LoreEditType.REMOVE_BOOK)
private fun handleBookLoreRemove(
event: InventoryClickEvent,
inventory: AnvilInventory,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
result: LoreEditResult
){
val bookMeta = rightItem.itemMeta as BookMeta? ?: return
val bookPage = StringBuilder()
lore.forEach {
if (bookPage.isNotEmpty()) bookPage.append('\n')
if (it == null) return@forEach
// fill book meta
val lore = DependencyManager.stripLore(leftItem)
if (lore.isEmpty()) return
bookPage.append(MiniMessageUtil.plain_text_mm.serialize(it))
}
val rightCopy: ItemStack?
if (LoreEditType.REMOVE_BOOK.doConsume) {
rightCopy = null
} else {
// Uncolor the page
AnvilLoreEditUtil.uncolorLines(player, lore, LoreEditType.REMOVE_BOOK)
val resultPage = bookPage.toString()
//TODO maybe check page size ? bc it may be too big ???
val bookPage = StringBuilder()
lore.forEach {
if (bookPage.isNotEmpty()) bookPage.append('\n')
if (it == null) return@forEach
rightCopy = rightItem.clone()
bookMeta.setPages(resultPage)
rightCopy.itemMeta = bookMeta
bookPage.append(MiniMessageUtil.plain_text_mm.serialize(it))
}
return extractAnvilResult(
event, player, inventory,
null, 0,
rightCopy, 0,
output, getFromLoreEditXpCost(cost, player, inventory)
)
val resultPage = bookPage.toString()
//TODO maybe check page size ? bc it may be too big ???
rightCopy = rightItem.clone()
bookMeta.setPages(resultPage)
rightCopy.itemMeta = bookMeta
}
extractAnvilResult(
event, player, inventory,
null, 0,
rightCopy, 0,
result
)
}
private fun handlePaperLoreEdit(
@ -457,89 +449,101 @@ class AnvilResultListener : Listener {
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
output: ItemStack,
): Boolean {
if (Material.PAPER != rightItem.type) return false
val paperMeta = rightItem.itemMeta ?: return false
result: LoreEditResult
) {
if (result.type.isAppend)
handlePaperLoreAppend(event, inventory, player, rightItem, result)
else
handlePaperLoreRemove(event, inventory, player, leftItem, rightItem, result)
}
val editTypeIsAppend = AnvilLoreEditUtil.paperLoreEditIsAppend(leftItem, rightItem) ?: return false
private fun handlePaperLoreAppend(
event: InventoryClickEvent,
inventory: AnvilInventory,
player: Player,
rightItem: ItemStack,
result: LoreEditResult
) {
val paperMeta = rightItem.itemMeta ?: return
val cost = AnvilCost()
if (editTypeIsAppend) {
if (output != AnvilLoreEditUtil.handleLoreAppendByPaper(player, leftItem, rightItem, cost)) return false
val paperCopy: ItemStack?
if (LoreEditType.APPEND_PAPER.doConsume) {
paperCopy = null
} else {
// Remove custom name to paper
paperCopy = rightItem.clone()
paperCopy.amount = 1
paperMeta.setComponentDisplayName(null)
paperCopy.itemMeta = paperMeta
}
return if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
paperCopy, 0,
rightItem, 1,
output, getFromLoreEditXpCost(cost, player, inventory)
)
} else {
extractAnvilResult(
event, player, inventory,
null, 0,
paperCopy, 0,
output, getFromLoreEditXpCost(cost, player, inventory)
)
}
val paperCopy: ItemStack?
if (LoreEditType.APPEND_PAPER.doConsume) {
paperCopy = null
} else {
if (output != AnvilLoreEditUtil.handleLoreRemoveByPaper(player, leftItem, cost)) return false
val leftMeta = leftItem.itemMeta
if (leftMeta == null || !leftMeta.hasLore()) return false
val lore = DependencyManager.stripLore(leftItem)
if (lore.isEmpty()) return false
// Create result item
val rightClone: ItemStack?
if (LoreEditType.REMOVE_PAPER.doConsume) {
rightClone = null
} else {
val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd
val line = if (removeEnd) lore[lore.size - 1]
else lore[0]
// uncolor the line
val ref = AtomicReference(line)
AnvilLoreEditUtil.uncolorLine(player, ref, LoreEditType.REMOVE_PAPER)
rightClone = rightItem.clone()
rightClone.amount = 1
val resultMeta = rightClone.itemMeta ?: return false
resultMeta.setComponentDisplayName(ref.get())
rightClone.itemMeta = resultMeta
}
return if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
rightClone, 0,
rightItem, 1,
output, getFromLoreEditXpCost(cost, player, inventory)
)
} else {
extractAnvilResult(
event, player, inventory,
null, 0,
rightClone, 0,
output, getFromLoreEditXpCost(cost, player, inventory)
)
}
// Remove custom name to paper
paperCopy = rightItem.clone()
paperCopy.amount = 1
paperMeta.setComponentDisplayName(null)
paperCopy.itemMeta = paperMeta
}
if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
paperCopy, 0,
rightItem, 1,
result
)
} else {
extractAnvilResult(
event, player, inventory,
null, 0,
paperCopy, 0,
result
)
}
}
private fun handlePaperLoreRemove(
event: InventoryClickEvent,
inventory: AnvilInventory,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
result: LoreEditResult
) {
val leftMeta = leftItem.itemMeta
if (leftMeta == null || !leftMeta.hasLore()) return
val lore = DependencyManager.stripLore(leftItem)
if (lore.isEmpty()) return
// Create result item
val rightClone: ItemStack?
if (LoreEditType.REMOVE_PAPER.doConsume) {
rightClone = null
} else {
val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd
val line = if (removeEnd) lore[lore.size - 1]
else lore[0]
// uncolor the line
val ref = AtomicReference(line)
AnvilLoreEditUtil.uncolorLine(player, ref, LoreEditType.REMOVE_PAPER)
rightClone = rightItem.clone()
rightClone.amount = 1
val resultMeta = rightClone.itemMeta ?: return
resultMeta.setComponentDisplayName(ref.get())
rightClone.itemMeta = resultMeta
}
if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
rightClone, 0,
rightItem, 1,
result
)
} else {
extractAnvilResult(
event, player, inventory,
null, 0,
rightClone, 0,
result
)
}
}
/**

View file

@ -13,12 +13,12 @@ import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.bukkit.inventory.meta.ItemMeta
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.AnvilResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.doMerge
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.doRenaming
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.testCustomRecipe
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.testLoreEdit
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.testUnitRepair
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.doMerge
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.doRenaming
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.testCustomRecipe
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.testLoreEdit
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.testUnitRepair
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.util.JustForEasierHotswapUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir

View file

@ -5,10 +5,12 @@ import org.bukkit.entity.HumanEntity
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BookMeta
import org.bukkit.permissions.Permissible
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentLore
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditType
import java.util.*
@ -31,7 +33,7 @@ object AnvilLoreEditUtil {
player: Permissible,
first: ItemStack,
book: BookMeta,
cost: AnvilXpUtil.AnvilCost
cost: AnvilCost
): ItemStack? {
if (!hasLoreEditByBookPermission(player)) return null
@ -60,7 +62,7 @@ object AnvilLoreEditUtil {
return result
}
fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, cost: AnvilXpUtil.AnvilCost): ItemStack? {
fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, cost: AnvilCost): ItemStack? {
if (!hasLoreEditByBookPermission(player)) return null
// remove lore
@ -116,12 +118,17 @@ object AnvilLoreEditUtil {
return null
}
fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack, cost: AnvilXpUtil.AnvilCost): ItemStack? {
val isAppend = bookLoreEditIsAppend(first, second) ?: return null
fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack): LoreEditResult {
val isAppend = bookLoreEditIsAppend(first, second) ?: return LoreEditResult.EMPTY
val type = if(isAppend) LoreEditType.APPEND_BOOK else LoreEditType.REMOVE_BOOK
val meta = second.itemMeta as BookMeta
return if (isAppend) handleLoreAppendByBook(player, first, meta, cost)
val cost = AnvilCost()
val item = if (isAppend)
handleLoreAppendByBook(player, first, meta, cost)
else handleLoreRemoveByBook(player, first, cost)
return LoreEditResult(item, cost, type)
}
// Return true if appended, false if removed, null if neither
@ -147,7 +154,7 @@ object AnvilLoreEditUtil {
player: Permissible,
first: ItemStack,
second: ItemStack,
cost: AnvilXpUtil.AnvilCost
cost: AnvilCost
): ItemStack? {
if (!hasLoreEditByPaperPermission(player)) return null
@ -181,7 +188,7 @@ object AnvilLoreEditUtil {
return result
}
fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack, cost: AnvilXpUtil.AnvilCost): ItemStack? {
fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack, cost: AnvilCost): ItemStack? {
if (!hasLoreEditByPaperPermission(player)) return null
// remove lore line
@ -222,17 +229,21 @@ object AnvilLoreEditUtil {
fun tryLoreEditByPaper(
player: HumanEntity,
first: ItemStack,
second: ItemStack,
cost: AnvilXpUtil.AnvilCost
): ItemStack? {
val isAppend = paperLoreEditIsAppend(first, second) ?: return null
second: ItemStack
): LoreEditResult {
val isAppend = paperLoreEditIsAppend(first, second) ?: return LoreEditResult.EMPTY
val type = if(isAppend) LoreEditType.APPEND_BOOK else LoreEditType.REMOVE_BOOK
return if (isAppend) handleLoreAppendByPaper(player, first, second, cost)
val cost = AnvilCost()
val item = if (isAppend)
handleLoreAppendByPaper(player, first, second, cost)
else handleLoreRemoveByPaper(player, first, cost)
return LoreEditResult(item, cost, type)
}
private fun baseEditLoreXpCost(
cost: AnvilXpUtil.AnvilCost,
cost: AnvilCost,
first: ItemStack,
result: ItemStack,
editType: LoreEditType

View file

@ -18,20 +18,23 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder.DEFAULT_CONFIG as CONFIG
enum class LoreEditType(
val rootPath: String,
val useType: AnvilUseType,
val isBook: Boolean,
val isAppend: Boolean,
val isMultiLine: Boolean,
) {
APPEND_BOOK(AnvilUseType.LORE_EDIT_BOOK_APPEND, true, true),
REMOVE_BOOK(AnvilUseType.LORE_EDIT_BOOK_REMOVE, false, true),
APPEND_PAPER(AnvilUseType.LORE_EDIT_PAPER_APPEND, true, false),
REMOVE_PAPER(AnvilUseType.LORE_EDIT_PAPER_REMOVE, false, false),
APPEND_BOOK(AnvilUseType.LORE_EDIT_BOOK_APPEND, true, true, true),
REMOVE_BOOK(AnvilUseType.LORE_EDIT_BOOK_REMOVE, true, false, true),
APPEND_PAPER(AnvilUseType.LORE_EDIT_PAPER_APPEND, false, true, false),
REMOVE_PAPER(AnvilUseType.LORE_EDIT_PAPER_REMOVE, false, false, false),
;
constructor(
useType: AnvilUseType,
isPaper: Boolean,
isAppend: Boolean,
isMultiLine: Boolean,
) : this(useType.path, useType, isAppend, isMultiLine)
) : this(useType.path, useType,
isPaper, isAppend, isMultiLine)
/**
* If this edit type is enabled