Skip to content

Commit

Permalink
fix: properly unescape escaped emoteids
Browse files Browse the repository at this point in the history
  • Loading branch information
Boy0000 committed May 29, 2024
1 parent 717fdf2 commit 1c820a3
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 41 deletions.
2 changes: 1 addition & 1 deletion core/src/main/kotlin/com/mineinabyss/emojy/EmojyHelpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fun Component.transform(player: Player?, insert: Boolean, unescape: Boolean = tr

val legacy = LegacyComponentSerializer.legacySection()
val spaceRegex: Regex = "(?<!\\\\):space_(-?\\d+):".toRegex()
private val escapedSpaceRegex: Regex = "\\\\(:space_(-?\\d+):)".toRegex()
val escapedSpaceRegex: Regex = "\\\\(:space_(-?\\d+):)".toRegex()
val colorableRegex: Regex = "\\|(c|colorable)".toRegex()
val bitmapIndexRegex: Regex = "\\|([0-9]+)".toRegex()
//TODO Tags like rainbow and gradient, which split the text into multiple children, will break replacement below
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler {
val codecs = (PaperAdventure::class.java.getDeclaredField("LOCALIZED_CODECS").apply { isAccessible = true }
.get(null) as MutableMap<Locale, Codec<Component>>)

for (locale in Locale.getAvailableLocales()) {
/*for (locale in Locale.getAvailableLocales()) {
codecs[locale] = AdventureCodecs.COMPONENT_CODEC.xmap(
{ component -> component }, // decode
{ component -> GlobalTranslator.render(component, locale) } // encode
)
}
}*/

val key = NamespacedKey.fromString("packet_listener", emojy)
ChannelInitializeListenerHolder.addListener(key!!) { channel: Channel ->
Expand All @@ -59,8 +59,8 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler {
override fun write(ctx: ChannelHandlerContext, packet: Any, promise: ChannelPromise) {
ctx.write(
when (packet) {
is ClientboundDisguisedChatPacket -> ClientboundDisguisedChatPacket(packet.message.transformEmotes(connection.locale()), packet.chatType)
is ClientboundSystemChatPacket -> ClientboundSystemChatPacket(packet.content.transformEmotes(connection.locale()), packet.overlay)
is ClientboundDisguisedChatPacket -> ClientboundDisguisedChatPacket(packet.message.transformEmotes(connection.locale()).unescapeEmoteIds(), packet.chatType)
is ClientboundSystemChatPacket -> ClientboundSystemChatPacket(packet.content.transformEmotes(connection.locale()).unescapeEmoteIds(), packet.overlay)
is ClientboundSetTitleTextPacket -> ClientboundSetTitleTextPacket(packet.text.transformEmotes(connection.locale()))
is ClientboundSetSubtitleTextPacket -> ClientboundSetSubtitleTextPacket(packet.text.transformEmotes(connection.locale()))
is ClientboundSetActionBarTextPacket -> ClientboundSetActionBarTextPacket(packet.text.transformEmotes(connection.locale()))
Expand Down Expand Up @@ -105,6 +105,60 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler {
val ORIGINAL_SIGN_BACK_LINES = NamespacedKey.fromString("emojy:original_back_lines")!!
val ORIGINAL_ITEM_RENAME_TEXT = NamespacedKey.fromString("emojy:original_item_rename")!!

fun String.transformEmotes(locale: Locale? = null): String {
return miniMsg().transformEmotes(locale).serialize()
}

fun net.minecraft.network.chat.Component.transformEmotes(locale: Locale? = null): net.minecraft.network.chat.Component {
return PaperAdventure.asVanilla(PaperAdventure.asAdventure(this).transformEmotes(locale))
}

fun Component.transformEmotes(locale: Locale? = null): Component {
var component = GlobalTranslator.render(this, locale ?: Locale.US)
val serialized = this.serialize()

for (emote in emojy.emotes) emote.baseRegex.findAll(serialized).forEach { match ->

val colorable = colorableRegex in match.value
val bitmapIndex = bitmapIndexRegex.find(match.value)?.groupValues?.get(1)?.toIntOrNull() ?: -1

component = component.replaceText(
TextReplacementConfig.builder()
.match(emote.baseRegex.pattern).once()
.replacement(
emote.formattedUnicode(
insert = false,
colorable = colorable,
bitmapIndex = bitmapIndex
)
)
.build()
)
}

for (gif in emojy.gifs) gif.baseRegex.findAll(serialized).forEach { _ ->
component = component.replaceText(
TextReplacementConfig.builder()
.match(gif.baseRegex.pattern).once()
.replacement(gif.formattedUnicode(insert = false))
.build()
)
}

spaceRegex.findAll(serialized).forEach { match ->
val space = match.groupValues[1].toIntOrNull() ?: return@forEach
val spaceRegex = "(?<!\\\\):space_(-?$space+):".toRegex()
component = component.replaceText(
TextReplacementConfig.builder()
.match(spaceRegex.pattern).once()
.replacement(spaceComponent(space))
.build()
)
}

return component
}

fun String.escapeEmoteIDs(player: Player?): String {
return miniMsg().escapeEmoteIDs(player).serialize()
}
Expand All @@ -114,14 +168,14 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler {
}

fun Component.escapeEmoteIDs(player: Player?): Component {
var msg = this
val serialized = msg.serialize()
var component = this
val serialized = component.serialize()

// Replace all unicodes found in default font with a random one
// This is to prevent use of unicodes from the font the chat is in
val (defaultKey, randomKey) = Key.key("default") to Key.key("random")
for (emote in emojy.emotes.filter { it.font == defaultKey && !it.checkPermission(player) }) emote.unicodes.forEach {
msg = msg.replaceText(
component = component.replaceText(
TextReplacementConfig.builder()
.matchLiteral(it)
.replacement(it.miniMsg().font(randomKey))
Expand All @@ -132,7 +186,7 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler {
for (emote in emojy.emotes) emote.baseRegex.findAll(serialized).forEach { match ->
if (emote.checkPermission(player)) return@forEach

msg = msg.replaceText(
component = component.replaceText(
TextReplacementConfig.builder()
.matchLiteral(match.value).once()
.replacement("\\${match.value}".miniMsg())
Expand All @@ -142,7 +196,7 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler {

for (gif in emojy.gifs) gif.baseRegex.findAll(serialized).forEach { match ->
if (gif.checkPermission(player)) return@forEach
msg = msg.replaceText(
component = component.replaceText(
TextReplacementConfig.builder()
.matchLiteral(match.value).once()
.replacement("\\${match.value}".miniMsg())
Expand All @@ -154,64 +208,48 @@ class EmojyNMSHandler(emojy: EmojyPlugin) : IEmojyNMSHandler {
if (player?.hasPermission(SPACE_PERMISSION) != false) return@forEach
val space = match.groupValues[1].toIntOrNull() ?: return@forEach

msg = msg.replaceText(
component = component.replaceText(
TextReplacementConfig.builder()
.matchLiteral(match.value).once()
.replacement("\\:space_$space:".miniMsg())
.build()
)
}

return msg
}

fun String.transformEmotes(locale: Locale? = null): String {
return miniMsg().transformEmotes(locale).serialize()
return component
}

fun net.minecraft.network.chat.Component.transformEmotes(locale: Locale? = null): net.minecraft.network.chat.Component {
return PaperAdventure.asVanilla(PaperAdventure.asAdventure(this).transformEmotes(locale))
fun net.minecraft.network.chat.Component.unescapeEmoteIds(): net.minecraft.network.chat.Component {
return PaperAdventure.asVanilla(PaperAdventure.asAdventure(this).unescapeEmoteIds())
}

fun Component.transformEmotes(locale: Locale? = null): Component {
var component = GlobalTranslator.render(this, locale ?: Locale.US)
fun Component.unescapeEmoteIds(): Component {
var component = this
val serialized = this.serialize()

for (emote in emojy.emotes) emote.baseRegex.findAll(serialized).forEach { match ->

val colorable = colorableRegex in match.value
val bitmapIndex = bitmapIndexRegex.find(match.value)?.groupValues?.get(1)?.toIntOrNull() ?: -1

for (emote in emojy.emotes) emote.escapedRegex.findAll(serialized).forEach { match ->
component = component.replaceText(
TextReplacementConfig.builder()
.match(emote.baseRegex.pattern).once()
.replacement(
emote.formattedUnicode(
insert = false,
colorable = colorable,
bitmapIndex = bitmapIndex
)
)
.match(emote.escapedRegex.pattern).once()
.replacement(match.value.removePrefix("\\"))
.build()
)
}

for (gif in emojy.gifs) gif.baseRegex.findAll(serialized).forEach { _ ->
for (gif in emojy.gifs) gif.escapedRegex.findAll(serialized).forEach { match ->
component = component.replaceText(
TextReplacementConfig.builder()
.match(gif.baseRegex.pattern).once()
.replacement(gif.formattedUnicode(insert = false))
.match(gif.escapedRegex.pattern).once()
.replacement(match.value.removePrefix("\\"))
.build()
)
}

spaceRegex.findAll(serialized).forEach { match ->
val space = match.groupValues[1].toIntOrNull() ?: return@forEach
val spaceRegex = "(?<!\\\\):space_(-?$space+):".toRegex()
escapedSpaceRegex.findAll(serialized).forEach { match ->
component = component.replaceText(
TextReplacementConfig.builder()
.match(spaceRegex.pattern).once()
.replacement(spaceComponent(space))
.match(match.value).once()
.replacement(match.value.removePrefix("\\"))
.build()
)
}
Expand Down

0 comments on commit 1c820a3

Please sign in to comment.