diff --git a/core/src/main/kotlin/com/mineinabyss/emojy/EmojyHelpers.kt b/core/src/main/kotlin/com/mineinabyss/emojy/EmojyHelpers.kt index 6f18b85..540aaa3 100644 --- a/core/src/main/kotlin/com/mineinabyss/emojy/EmojyHelpers.kt +++ b/core/src/main/kotlin/com/mineinabyss/emojy/EmojyHelpers.kt @@ -18,10 +18,14 @@ val escapedSpaceRegex: Regex = "\\\\(:space_(-?\\d+):)".toRegex() val colorableRegex: Regex = "\\|(c|colorable)".toRegex() val bitmapIndexRegex: Regex = "\\|([0-9]+)".toRegex() +private val defaultKey = Key.key("default") +private val randomKey = Key.key("random") + val ORIGINAL_SIGN_FRONT_LINES = NamespacedKey.fromString("emojy:original_front_lines")!! val ORIGINAL_SIGN_BACK_LINES = NamespacedKey.fromString("emojy:original_back_lines")!! val ORIGINAL_ITEM_RENAME_TEXT = NamespacedKey.fromString("emojy:original_item_rename")!! +fun spaceString(space: Int) = "${Space.of(space)}" fun spaceComponent(space: Int) = Component.textOfChildren(Component.text(Space.of(space)).font(emojyConfig.spaceFont)) private fun Component.asFlatTextContent(): String { @@ -36,6 +40,37 @@ private fun Component.asFlatTextContent(): String { } } +fun String.transformEmotes(insert: Boolean = false): String { + var content = this + + for (emote in emojy.emotes) emote.baseRegex.findAll(this).forEach { match -> + + val colorable = colorableRegex in match.value + val bitmapIndex = bitmapIndexRegex.find(match.value)?.groupValues?.get(1)?.toIntOrNull() ?: -1 + + content = content.replaceFirst( + emote.baseRegex, emote.formattedUnicode( + insert = insert, + colorable = colorable, + bitmapIndex = bitmapIndex + ).serialize() + ) + } + + for (gif in emojy.gifs) gif.baseRegex.findAll(this).forEach { _ -> + content = content.replaceFirst(gif.baseRegex, gif.formattedUnicode(insert = insert).serialize()) + } + + spaceRegex.findAll(this).forEach { match -> + val space = match.groupValues[1].toIntOrNull() ?: return@forEach + val spaceRegex = "(?$it") + } + + for (emote in emojy.emotes) emote.baseRegex.findAll(this).forEach { match -> + if (emote.checkPermission(player)) return@forEach + + content = content.replaceFirst("(? + if (gif.checkPermission(player)) return@forEach + content = content.replaceFirst("(? + if (player?.hasPermission(SPACE_PERMISSION) != false) return@forEach + val space = match.groupValues[1].toIntOrNull() ?: return@forEach + + content = content.replaceFirst("(? + content = content.replaceFirst(emote.escapedRegex, match.value.removePrefix("\\")) + } + + for (gif in emojy.gifs) gif.escapedRegex.findAll(this).forEach { match -> + content = content.replaceFirst(gif.escapedRegex, match.value.removePrefix("\\")) + } + + escapedSpaceRegex.findAll(this).forEach { match -> + content = content.replaceFirst(match.value, match.value.removePrefix("\\")) + } + + return content +} + fun Component.unescapeEmoteIds(): Component { var component = this val serialized = component.asFlatTextContent() diff --git a/core/src/main/kotlin/com/mineinabyss/emojy/config/EmojyConfig.kt b/core/src/main/kotlin/com/mineinabyss/emojy/config/EmojyConfig.kt index 73c7a35..38e46ee 100644 --- a/core/src/main/kotlin/com/mineinabyss/emojy/config/EmojyConfig.kt +++ b/core/src/main/kotlin/com/mineinabyss/emojy/config/EmojyConfig.kt @@ -3,10 +3,7 @@ package com.mineinabyss.emojy.config import co.touchlab.kermit.Severity -import com.mineinabyss.emojy.emojy -import com.mineinabyss.emojy.emojyConfig -import com.mineinabyss.emojy.spaceComponent -import com.mineinabyss.emojy.templates +import com.mineinabyss.emojy.* import com.mineinabyss.idofront.serialization.KeySerializer import com.mineinabyss.idofront.textcomponents.miniMsg import com.mineinabyss.idofront.textcomponents.serialize diff --git a/v1_20_R4/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R4/EmojyNMSHandler.kt b/v1_20_R4/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R4/EmojyNMSHandler.kt index 353b3b0..b568d45 100644 --- a/v1_20_R4/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R4/EmojyNMSHandler.kt +++ b/v1_20_R4/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R4/EmojyNMSHandler.kt @@ -20,8 +20,6 @@ import net.minecraft.core.NonNullList import net.minecraft.network.Connection import net.minecraft.network.chat.ChatType import net.minecraft.network.chat.Component -import net.minecraft.network.chat.MessageSignature -import net.minecraft.network.chat.SignedMessageBody import net.minecraft.network.protocol.game.* import net.minecraft.network.syncher.EntityDataSerializer import net.minecraft.network.syncher.SynchedEntityData @@ -88,28 +86,20 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler { when (operation::class.java.simpleName) { "AddOperation" -> { val nameField = operation::class.java.getDeclaredField("name").apply { isAccessible = true } - // Get the component, serialize it and replace "\\<" as it might be escaped if not an AdventureBossbar - val name = PaperAdventure.asAdventure(nameField.get(operation) as Component).serialize().replace("\\<", "<").miniMsg() - nameField.set(operation, PaperAdventure.asVanilla(name.transformEmotes(connection.locale()))) + nameField.set(operation, (nameField.get(operation) as Component).transformEmotes(connection.locale())) } "UpdateNameOperation" -> { val accessorMethod = operation::class.java.methods.find { it.name == "name" } accessorMethod?.isAccessible = true if (accessorMethod != null) { - val name = PaperAdventure.asAdventure(accessorMethod.invoke(operation) as Component) - .serialize().replace("\\<", "<") - .miniMsg().transformEmotes(connection.locale()) - val updateNameOperationClass = operation::class.java.enclosingClass.declaredClasses.find { it.simpleName == "UpdateNameOperation" } ?: throw IllegalStateException("UpdateNameOperation class not found") val constructor = updateNameOperationClass.getDeclaredConstructor(Component::class.java).apply { isAccessible = true } - // Create a new instance of UpdateNameOperation with the modified name - - val updatedOperation = constructor.newInstance(PaperAdventure.asVanilla(name)) + val name = (accessorMethod.invoke(operation) as Component).transformEmotes(connection.locale()) + val updatedOperation = constructor.newInstance(name) - // Set the updated operation in the packet operationField.set(packet, updatedOperation) } } @@ -143,7 +133,7 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler { itemName(if (hasItemName()) itemName().transformEmotes(locale) else null) lore(lore()?.map { l -> l.transformEmotes(locale) }) persistentDataContainer.get(ORIGINAL_ITEM_RENAME_TEXT, DataType.STRING)?.let { - displayName(it.miniMsg().escapeEmoteIDs(player).transformEmotes(locale).unescapeEmoteIds()) + displayName(it.escapeEmoteIDs(player).transformEmotes().unescapeEmoteIds().miniMsg()) } }) } @@ -154,18 +144,10 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler { companion object { - fun String.transformEmotes(locale: Locale? = null, insert: Boolean = false): String { - return miniMsg().transformEmotes(locale, insert).serialize() - } - fun Component.transformEmotes(locale: Locale? = null, insert: Boolean = false): Component { return PaperAdventure.asVanilla(PaperAdventure.asAdventure(this).transformEmotes(locale, insert)) } - fun String.escapeEmoteIDs(player: Player?): String { - return miniMsg().escapeEmoteIDs(player).serialize() - } - fun Component.escapeEmoteIDs(player: Player?): Component { return PaperAdventure.asVanilla((PaperAdventure.asAdventure(this)).escapeEmoteIDs(player)) } diff --git a/v1_21_R1/src/main/kotlin/com/mineinabyss/emojy/nms/v1_21_R1/EmojyNMSHandler.kt b/v1_21_R1/src/main/kotlin/com/mineinabyss/emojy/nms/v1_21_R1/EmojyNMSHandler.kt index 18df81a..3aa6e64 100644 --- a/v1_21_R1/src/main/kotlin/com/mineinabyss/emojy/nms/v1_21_R1/EmojyNMSHandler.kt +++ b/v1_21_R1/src/main/kotlin/com/mineinabyss/emojy/nms/v1_21_R1/EmojyNMSHandler.kt @@ -92,28 +92,20 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler { when (operation::class.java.simpleName) { "AddOperation" -> { val nameField = operation::class.java.getDeclaredField("name").apply { isAccessible = true } - // Get the component, serialize it and replace "\\<" as it might be escaped if not an AdventureBossbar - val name = PaperAdventure.asAdventure(nameField.get(operation) as Component).serialize().replace("\\<", "<").miniMsg() - nameField.set(operation, PaperAdventure.asVanilla(name.transformEmotes(connection.locale()))) + nameField.set(operation, (nameField.get(operation) as Component).transformEmotes(connection.locale())) } "UpdateNameOperation" -> { val accessorMethod = operation::class.java.methods.find { it.name == "name" } accessorMethod?.isAccessible = true if (accessorMethod != null) { - val name = PaperAdventure.asAdventure(accessorMethod.invoke(operation) as Component) - .serialize().replace("\\<", "<") - .miniMsg().transformEmotes(connection.locale()) - val updateNameOperationClass = operation::class.java.enclosingClass.declaredClasses.find { it.simpleName == "UpdateNameOperation" } ?: throw IllegalStateException("UpdateNameOperation class not found") val constructor = updateNameOperationClass.getDeclaredConstructor(Component::class.java).apply { isAccessible = true } - // Create a new instance of UpdateNameOperation with the modified name - - val updatedOperation = constructor.newInstance(PaperAdventure.asVanilla(name)) + val name = (accessorMethod.invoke(operation) as Component).transformEmotes(connection.locale()) + val updatedOperation = constructor.newInstance(name) - // Set the updated operation in the packet operationField.set(packet, updatedOperation) } } @@ -147,7 +139,7 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler { itemName(if (hasItemName()) itemName().transformEmotes(locale) else null) lore(lore()?.map { l -> l.transformEmotes(locale) }) persistentDataContainer.get(ORIGINAL_ITEM_RENAME_TEXT, DataType.STRING)?.let { - displayName(it.miniMsg().escapeEmoteIDs(player).transformEmotes(locale).unescapeEmoteIds()) + displayName(it.escapeEmoteIDs(player).transformEmotes().unescapeEmoteIds().miniMsg()) } }) } @@ -158,18 +150,10 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler { companion object { - fun String.transformEmotes(locale: Locale? = null, insert: Boolean = false): String { - return miniMsg().transformEmotes(locale, insert).serialize() - } - fun Component.transformEmotes(locale: Locale? = null, insert: Boolean = false): Component { return PaperAdventure.asVanilla(PaperAdventure.asAdventure(this).transformEmotes(locale, insert)) } - fun String.escapeEmoteIDs(player: Player?): String { - return miniMsg().escapeEmoteIDs(player).serialize() - } - fun Component.escapeEmoteIDs(player: Player?): Component { return PaperAdventure.asVanilla((PaperAdventure.asAdventure(this)).escapeEmoteIDs(player)) }