mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
lore edit color should work
This commit is contained in:
parent
2c9b2ef9fa
commit
762e7d4e0b
5 changed files with 259 additions and 45 deletions
|
|
@ -30,6 +30,7 @@ import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil
|
|||
import xyz.alexcrea.cuanvil.util.config.LoreEditType
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.min
|
||||
|
||||
class AnvilResultListener : Listener {
|
||||
|
|
@ -348,13 +349,15 @@ class AnvilResultListener : Listener {
|
|||
// fill book meta
|
||||
val meta = leftItem.itemMeta
|
||||
if (meta == null || !meta.hasLore()) return false
|
||||
val lore = meta.lore!!
|
||||
val lore = ArrayList<String>(meta.lore!!)
|
||||
if (lore.isEmpty()) return false
|
||||
|
||||
// Uncolor the page
|
||||
AnvilLoreEditUtil.uncolorLines(player, lore, LoreEditType.REMOVE_BOOK)
|
||||
|
||||
val bookPage = StringBuilder()
|
||||
lore.forEach {
|
||||
if (bookPage.isNotEmpty()) bookPage.append('\n')
|
||||
//TODO check & do color
|
||||
bookPage.append(it)
|
||||
}
|
||||
|
||||
|
|
@ -426,10 +429,15 @@ class AnvilResultListener : Listener {
|
|||
if (lore.isEmpty()) return false
|
||||
|
||||
val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd
|
||||
//TODO check & do color
|
||||
val line = if (removeEnd) lore[lore.size - 1]
|
||||
var line = if (removeEnd) lore[lore.size - 1]
|
||||
else lore[0]
|
||||
|
||||
// Overkill but uncolor the line
|
||||
val tempList = ArrayList<String>(1)
|
||||
tempList.add(line)
|
||||
AnvilLoreEditUtil.uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER)
|
||||
line = tempList[0]
|
||||
|
||||
// Create result item
|
||||
val rightClone = rightItem.clone()
|
||||
rightClone.amount = 1
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class PrepareAnvilListener : Listener {
|
|||
|
||||
}
|
||||
|
||||
// return true if a custom recipe exist with these ingredient
|
||||
// return true if a custom recipe exist with these ingredients
|
||||
private fun testCustomRecipe(event: PrepareAnvilEvent, inventory: AnvilInventory,
|
||||
player: HumanEntity,
|
||||
first: ItemStack, second: ItemStack?): Boolean {
|
||||
|
|
@ -134,7 +134,10 @@ class PrepareAnvilListener : Listener {
|
|||
if(ConfigOptions.renameColorPossible && inventoryName != null){
|
||||
val resultString = StringBuilder(inventoryName)
|
||||
|
||||
useColor = AnvilColorUtil.handleRenamingColor(resultString, player)
|
||||
useColor = AnvilColorUtil.handleColor(resultString, player,
|
||||
ConfigOptions.permissionNeededForColor,
|
||||
ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor,
|
||||
AnvilColorUtil.ColorUseType.RENAME)
|
||||
|
||||
if(useColor) {
|
||||
inventoryName = resultString.toString()
|
||||
|
|
|
|||
|
|
@ -1,17 +1,35 @@
|
|||
package xyz.alexcrea.cuanvil.util
|
||||
|
||||
import io.delilaheve.util.ConfigOptions
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.permissions.Permissible
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
|
||||
object AnvilColorUtil {
|
||||
private val HEX_PATTERN: Pattern = Pattern.compile("#[A-Fa-f0-9]{6}") // pattern to find hexadecimal string
|
||||
private val TRANSFORMED_HEX_PATTERN = Pattern.compile("§x(§[0-9a-fA-F]){6}") // pattern to find minecraft hex string
|
||||
|
||||
fun handleRenamingColor(textToColor: StringBuilder, player: HumanEntity): Boolean {
|
||||
val usePermission = ConfigOptions.permissionNeededForColor
|
||||
val canUseColorCode = ConfigOptions.allowColorCode && (!usePermission || player.hasPermission("ca.color.code"))
|
||||
val canUseHexColor = ConfigOptions.allowHexadecimalColor && (!usePermission || player.hasPermission("ca.color.hex"))
|
||||
/**
|
||||
* Color a stringbuilder object depending on allowed color type and player permissions on color use type
|
||||
* @return if the stringbuilder was changed and color applied
|
||||
*/
|
||||
fun handleColor(
|
||||
textToColor: StringBuilder,
|
||||
player: Permissible,
|
||||
usePermission: Boolean,
|
||||
allowColorCode: Boolean,
|
||||
allowHexadecimalColor: Boolean,
|
||||
useType: ColorUseType
|
||||
): Boolean {
|
||||
if (!allowColorCode && !allowHexadecimalColor) return false
|
||||
|
||||
val canUseColorCode =
|
||||
allowColorCode && (!usePermission || useType.colorCodePerm == null || player.hasPermission(
|
||||
useType.colorCodePerm
|
||||
))
|
||||
val canUseHexColor =
|
||||
allowHexadecimalColor && (!usePermission || useType.hexColorPerm == null || player.hasPermission(
|
||||
useType.hexColorPerm
|
||||
))
|
||||
|
||||
if ((!canUseColorCode) && (!canUseHexColor)) return false
|
||||
|
||||
|
|
@ -33,6 +51,49 @@ object AnvilColorUtil {
|
|||
return useColor
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert a stringbuilder to a state where applying handleColor with the same options would give the same result
|
||||
* @return if the stringbuilder was changed and color unapplied
|
||||
*/
|
||||
fun revertColor(
|
||||
colorToText: StringBuilder,
|
||||
player: Permissible,
|
||||
usePermission: Boolean,
|
||||
allowColorCode: Boolean,
|
||||
allowHexadecimalColor: Boolean,
|
||||
useType: ColorUseType
|
||||
): Boolean {
|
||||
if (!allowColorCode && !allowHexadecimalColor) return false
|
||||
|
||||
val canUseColorCode =
|
||||
allowColorCode && (!usePermission || useType.colorCodePerm == null || player.hasPermission(
|
||||
useType.colorCodePerm
|
||||
))
|
||||
val canUseHexColor =
|
||||
allowHexadecimalColor && (!usePermission || useType.hexColorPerm == null || player.hasPermission(
|
||||
useType.hexColorPerm
|
||||
))
|
||||
|
||||
if ((!canUseColorCode) && (!canUseHexColor)) return false
|
||||
var hasReversed = false
|
||||
|
||||
// Reverse hex pattern
|
||||
if (canUseHexColor) {
|
||||
val nbReplacement = replaceHexToColor(colorToText, 14)
|
||||
|
||||
if (nbReplacement > 0) hasReversed = true
|
||||
}
|
||||
|
||||
if (canUseColorCode) {
|
||||
replaceAll(colorToText, "&", "&&", 1)
|
||||
val nbReplacement = replaceAll(colorToText, "§", "&", 2)
|
||||
|
||||
if (nbReplacement > 0) hasReversed = true
|
||||
}
|
||||
|
||||
return hasReversed
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace every instance of "from" to "to".
|
||||
* @param builder The builder to replace the string from.
|
||||
|
|
@ -70,7 +131,7 @@ object AnvilColorUtil {
|
|||
|
||||
while (matcher.find(startIndex)) {
|
||||
startIndex = matcher.start()
|
||||
if(startIndex >= builder.length - endOffset) break
|
||||
if (startIndex >= builder.length - endOffset) break //HOW AND WHERE WOULD THIS HAPPEN ?????
|
||||
|
||||
builder.replace(startIndex, startIndex + 1, "§x")
|
||||
startIndex += 2
|
||||
|
|
@ -85,4 +146,41 @@ object AnvilColorUtil {
|
|||
return numberOfChanges
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace every hex color from the minecraft format to a format like #000000
|
||||
* @param builder The builder to replace the minecraft hex color from.
|
||||
* @param endOffset Amount of character that should be ignored at the end.
|
||||
* @return The number of replacement was that was done.
|
||||
*/
|
||||
private fun replaceColorToHex(builder: StringBuilder, endOffset: Int): Int {
|
||||
val matcher: Matcher = TRANSFORMED_HEX_PATTERN.matcher(builder)
|
||||
|
||||
var numberOfChanges = 0
|
||||
var startIndex = 0
|
||||
|
||||
while (matcher.find(startIndex)) {
|
||||
startIndex = matcher.start()
|
||||
if (startIndex >= builder.length - endOffset) break //HOW AND WHERE WOULD THIS HAPPEN ?????
|
||||
|
||||
builder.replace(startIndex, startIndex + 2, "#")
|
||||
startIndex += 1
|
||||
for (i in 0..5) {
|
||||
builder.deleteCharAt(startIndex)
|
||||
startIndex += 1
|
||||
}
|
||||
|
||||
numberOfChanges += 1
|
||||
}
|
||||
|
||||
return numberOfChanges
|
||||
}
|
||||
|
||||
enum class ColorUseType(
|
||||
val colorCodePerm: String?,
|
||||
val hexColorPerm: String?
|
||||
) {
|
||||
RENAME("ca.color.code", "ca.color.hex"),
|
||||
LORE_EDIT(null, null)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -35,16 +35,21 @@ object AnvilLoreEditUtil {
|
|||
ArrayList<String>(meta.lore!!)
|
||||
} else ArrayList()
|
||||
|
||||
//TODO check color if color if enabled
|
||||
val lines = book.pages[0].split("\n")
|
||||
val page = book.pages[0]
|
||||
val lines = ArrayList<String>(page.split("\n"))
|
||||
val colorCost = colorLines(player, lines, LoreEditType.APPEND_BOOK)
|
||||
|
||||
lore.addAll(lines)
|
||||
|
||||
meta.lore = lore
|
||||
result.itemMeta = meta
|
||||
|
||||
// Handle other xp
|
||||
xpCost.addAndGet(lines.size * LoreEditType.APPEND_BOOK.perLineCost)
|
||||
xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_BOOK))
|
||||
if (result == first) return null
|
||||
|
||||
// Handle xp
|
||||
xpCost.addAndGet(colorCost) // Cost of using color
|
||||
xpCost.addAndGet(lines.size * LoreEditType.APPEND_BOOK.perLineCost) // per line cost
|
||||
xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_BOOK)) // Fixed cost and work penalty
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
@ -55,19 +60,24 @@ object AnvilLoreEditUtil {
|
|||
// remove lore
|
||||
val result = first.clone()
|
||||
val leftMeta = result.itemMeta ?: return null
|
||||
val currentLore = leftMeta.lore?: return null
|
||||
val currentLore = ArrayList<String>(leftMeta.lore ?: return null)
|
||||
|
||||
val uncolorCost = uncolorLines(player, currentLore, LoreEditType.REMOVE_BOOK)
|
||||
|
||||
leftMeta.lore = null
|
||||
result.itemMeta = leftMeta
|
||||
|
||||
// Handle other xp
|
||||
if (result == first) return null
|
||||
|
||||
// Handle xp
|
||||
xpCost.addAndGet(uncolorCost)
|
||||
xpCost.addAndGet(currentLore.size * LoreEditType.REMOVE_BOOK.perLineCost)
|
||||
xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_BOOK))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Return true if append, false if remove, null if neither
|
||||
// Return true if appended, false if removed, null if neither
|
||||
fun bookLoreEditIsAppend(first: ItemStack, second: ItemStack): Boolean? {
|
||||
// Test if the book & quil contain content
|
||||
val meta = second.itemMeta as BookMeta? ?: return false
|
||||
|
|
@ -106,7 +116,7 @@ object AnvilLoreEditUtil {
|
|||
else handleLoreRemoveByBook(player, first, xpCost)
|
||||
}
|
||||
|
||||
// Return true if append, false if remove, null if neither
|
||||
// Return true if appended, false if removed, null if neither
|
||||
fun paperLoreEditIsAppend(first: ItemStack, second: ItemStack): Boolean? {
|
||||
// Test if the paper contain a display name
|
||||
val meta = second.itemMeta ?: return false
|
||||
|
|
@ -134,24 +144,31 @@ object AnvilLoreEditUtil {
|
|||
if (!hasLoreEditByPaperPermission(player)) return null
|
||||
|
||||
val result = first.clone()
|
||||
val meta = result.itemMeta
|
||||
val lore = if (meta?.hasLore() == true) {
|
||||
val meta = result.itemMeta?: return null
|
||||
val lore = if (meta.hasLore()) {
|
||||
ArrayList<String>(meta.lore!!)
|
||||
} else ArrayList()
|
||||
|
||||
val appendEnd = LoreEditConfigUtil.paperLoreOrderIsEnd
|
||||
|
||||
//TODO check color if color if enabled
|
||||
val line = second.itemMeta!!.displayName
|
||||
// A bit overdone to color 1 line but hey
|
||||
val tempList = ArrayList<String>(1)
|
||||
tempList.add(second.itemMeta!!.displayName)
|
||||
val colorCost = colorLines(player, tempList, LoreEditType.APPEND_PAPER)
|
||||
|
||||
val line = tempList[0]
|
||||
if (appendEnd)
|
||||
lore.add(line)
|
||||
else
|
||||
lore.add(0, line)
|
||||
|
||||
meta?.lore = lore
|
||||
meta.lore = lore
|
||||
result.itemMeta = meta
|
||||
|
||||
// Handle other xp
|
||||
if (result == first) return null
|
||||
|
||||
// Handle xp
|
||||
xpCost.addAndGet(colorCost)
|
||||
xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_PAPER))
|
||||
|
||||
return result
|
||||
|
|
@ -167,13 +184,21 @@ object AnvilLoreEditUtil {
|
|||
val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd
|
||||
val lore: ArrayList<String> = ArrayList(meta.lore!!)
|
||||
|
||||
if (removeEnd) lore.removeAt(lore.size - 1)
|
||||
val line = if (removeEnd) lore.removeAt(lore.size - 1)
|
||||
else lore.removeAt(0)
|
||||
|
||||
meta.lore = if (lore.isEmpty()) null else lore
|
||||
result.itemMeta = meta
|
||||
|
||||
// Get color cost to uncolor this line
|
||||
val tempList = ArrayList<String>(1)
|
||||
tempList.add(line)
|
||||
val uncolorCost = uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER)
|
||||
|
||||
if (result == first) return null
|
||||
|
||||
// Handle other xp
|
||||
xpCost.addAndGet(uncolorCost)
|
||||
xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_PAPER))
|
||||
|
||||
return result
|
||||
|
|
@ -202,4 +227,86 @@ object AnvilLoreEditUtil {
|
|||
return xpCost
|
||||
}
|
||||
|
||||
private fun colorLines(player: Permissible, lines: ArrayList<String>, useType: LoreEditType): Int {
|
||||
val canUseHex: Boolean
|
||||
val canUseColorCode: Boolean
|
||||
val colorCost: Int
|
||||
// If is book
|
||||
if (useType == LoreEditType.REMOVE_BOOK || useType == LoreEditType.APPEND_BOOK) {
|
||||
canUseHex = LoreEditConfigUtil.bookAllowHexColor
|
||||
canUseColorCode = LoreEditConfigUtil.bookAllowColorCode
|
||||
colorCost = LoreEditConfigUtil.bookUseColorCost
|
||||
} // Else if is paper
|
||||
else {
|
||||
canUseHex = LoreEditConfigUtil.paperAllowHexColor
|
||||
canUseColorCode = LoreEditConfigUtil.paperAllowColorCode
|
||||
colorCost = LoreEditConfigUtil.paperUseColorCost
|
||||
}
|
||||
|
||||
// Now handle color of each lines
|
||||
var hasUsedColor = false
|
||||
for ((index, line) in lines.withIndex()) {
|
||||
val coloredLine = StringBuilder(line)
|
||||
|
||||
val lineUsedColor = AnvilColorUtil.handleColor(
|
||||
coloredLine,
|
||||
player,
|
||||
false, canUseColorCode, canUseHex,
|
||||
AnvilColorUtil.ColorUseType.LORE_EDIT
|
||||
)
|
||||
|
||||
if (lineUsedColor) {
|
||||
hasUsedColor = true
|
||||
lines[index] = coloredLine.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return if (hasUsedColor) {
|
||||
colorCost
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fun uncolorLines(player: Permissible, lines: ArrayList<String>, useType: LoreEditType): Int {
|
||||
val canUseHex: Boolean
|
||||
val canUseColorCode: Boolean
|
||||
val colorCost: Int
|
||||
// If is book
|
||||
if (useType == LoreEditType.REMOVE_BOOK || useType == LoreEditType.APPEND_BOOK) {
|
||||
canUseHex = LoreEditConfigUtil.bookAllowHexColor
|
||||
canUseColorCode = LoreEditConfigUtil.bookAllowColorCode
|
||||
colorCost = LoreEditConfigUtil.bookUseColorCost
|
||||
} // Else if is paper
|
||||
else {
|
||||
canUseHex = LoreEditConfigUtil.paperAllowHexColor
|
||||
canUseColorCode = LoreEditConfigUtil.paperAllowColorCode
|
||||
colorCost = LoreEditConfigUtil.paperUseColorCost
|
||||
}
|
||||
|
||||
// Now handle color of each lines
|
||||
var hasUndidColor = false
|
||||
for ((index, line) in lines.withIndex()) {
|
||||
val uncoloredLine = StringBuilder(line)
|
||||
|
||||
val lineUndidColor = AnvilColorUtil.revertColor(
|
||||
uncoloredLine,
|
||||
player,
|
||||
false, canUseColorCode, canUseHex,
|
||||
AnvilColorUtil.ColorUseType.LORE_EDIT
|
||||
)
|
||||
|
||||
if (lineUndidColor) {
|
||||
hasUndidColor = true
|
||||
lines[index] = uncoloredLine.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return if (hasUndidColor) {
|
||||
colorCost
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,8 +8,6 @@ object LoreEditConfigUtil {
|
|||
const val IS_ENABLED = "enabled"
|
||||
const val FIXED_COST = "fixed_cost"
|
||||
const val PER_LINE_COST = "per_line_cost"
|
||||
const val USE_COST_PENALTY = "use_cost_penalty"
|
||||
const val INCREASE_COST_PENALTY = "increase_cost_penalty"
|
||||
const val DO_CONSUME = "do_consume"
|
||||
|
||||
// Permission configs path
|
||||
|
|
@ -61,8 +59,8 @@ object LoreEditConfigUtil {
|
|||
val FIXED_COST_RANGE = 0..1000
|
||||
val PER_LINE_COST_RANGE = 0..1000
|
||||
|
||||
val COLOR_BOOK_COST_RANGE = 0..1000
|
||||
val COLOR_PAPER_COST_RANGE = 0..1000
|
||||
private val COLOR_BOOK_COST_RANGE = 0..1000
|
||||
private val COLOR_PAPER_COST_RANGE = 0..1000
|
||||
|
||||
// -------------------
|
||||
// Generic Get methods
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue