From d8d0a4d0b114408781f0680d63a23753e67e1fad Mon Sep 17 00:00:00 2001 From: Boy Date: Sun, 5 May 2024 22:15:46 +0200 Subject: [PATCH] feat: 1.20.5+ support --- .github/workflows/build.yml | 2 +- build.gradle.kts | 43 ++-- core/build.gradle.kts | 1 + .../mineinabyss/emojy/nms/EmojyNMSHandlers.kt | 4 +- gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 4 +- v1_19_R1/build.gradle.kts | 5 +- v1_19_R2/build.gradle.kts | 5 +- v1_19_R3/build.gradle.kts | 5 +- v1_20_R1/build.gradle.kts | 5 +- v1_20_R2/build.gradle.kts | 5 +- .../emojy/nms/v1_20_R2/EmojyNMSHandler.kt | 3 +- v1_20_R3/build.gradle.kts | 5 +- v1_20_R4/build.gradle.kts | 48 +++++ .../emojy/nms/v1_20_R4/EmojyNMSHandler.kt | 197 ++++++++++++++++++ 16 files changed, 298 insertions(+), 40 deletions(-) create mode 100644 v1_20_R4/build.gradle.kts create mode 100644 v1_20_R4/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R4/EmojyNMSHandler.kt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1eaaad1..872e257 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: temurin - java-version: 17 + java-version: 21 cache: gradle - name: Build diff --git a/build.gradle.kts b/build.gradle.kts index 76f4b00..9c001fe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,4 @@ +import io.papermc.paperweight.userdev.ReobfArtifactConfiguration import net.minecrell.pluginyml.paper.PaperPluginDescription plugins { @@ -8,19 +9,19 @@ plugins { id("com.mineinabyss.conventions.autoversion") id("xyz.jpenilla.run-paper") version "2.0.1" // Adds runServer and runMojangMappedServer tasks for testing id("net.minecrell.plugin-yml.paper") version "0.6.0" - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.1" } +paperweight.reobfArtifactConfiguration.set(ReobfArtifactConfiguration.MOJANG_PRODUCTION) + allprojects { apply(plugin = "java") version = rootProject.version - dependencies { - compileOnly(kotlin("stdlib-jdk8")) - } - repositories { + maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") mavenLocal() } } @@ -34,14 +35,15 @@ dependencies { compileOnly(idofrontLibs.minecraft.mccoroutine) // Shaded - paperweight.paperDevBundle("1.20.4-R0.1-SNAPSHOT") //NMS + paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT") //NMS implementation(project(path = ":core")) - implementation(project(path = ":v1_19_R1", configuration = "reobf")) - implementation(project(path = ":v1_19_R2", configuration = "reobf")) - implementation(project(path = ":v1_19_R3", configuration = "reobf")) - implementation(project(path = ":v1_20_R1", configuration = "reobf")) - implementation(project(path = ":v1_20_R2", configuration = "reobf")) - implementation(project(path = ":v1_20_R3", configuration = "reobf")) + //implementation(project(path = ":v1_19_R1", configuration = "reobf")) + //implementation(project(path = ":v1_19_R2", configuration = "reobf")) + //implementation(project(path = ":v1_19_R3", configuration = "reobf")) + //implementation(project(path = ":v1_20_R1", configuration = "reobf")) + //implementation(project(path = ":v1_20_R2", configuration = "reobf")) + //implementation(project(path = ":v1_20_R3", configuration = "reobf")) + implementation(project(path = ":v1_20_R4")) } tasks { @@ -52,7 +54,7 @@ tasks { compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } javadoc { @@ -69,12 +71,13 @@ tasks { } shadowJar { - dependsOn(":v1_19_R1:reobfJar") - dependsOn(":v1_19_R2:reobfJar") - dependsOn(":v1_19_R3:reobfJar") - dependsOn(":v1_20_R1:reobfJar") - dependsOn(":v1_20_R2:reobfJar") - dependsOn(":v1_20_R3:reobfJar") + //dependsOn(":v1_19_R1:reobfJar") + //dependsOn(":v1_19_R2:reobfJar") + //dependsOn(":v1_19_R3:reobfJar") + //dependsOn(":v1_20_R1:reobfJar") + //dependsOn(":v1_20_R2:reobfJar") + //dependsOn(":v1_20_R3:reobfJar") + dependsOn(":v1_20_R4:reobfJar") archiveFileName.set("Emojy.jar") } @@ -88,7 +91,7 @@ paper { val version: String by project this.version = version authors = listOf("boy0000") - apiVersion = "1.19" + apiVersion = "1.20" serverDependencies { register("Idofront") { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 1956639..af2933d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -8,6 +8,7 @@ plugins { repositories { gradlePluginPortal() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.unnamed.team/repository/unnamed-public/") google() diff --git a/core/src/main/kotlin/com/mineinabyss/emojy/nms/EmojyNMSHandlers.kt b/core/src/main/kotlin/com/mineinabyss/emojy/nms/EmojyNMSHandlers.kt index b93c672..2acac7e 100644 --- a/core/src/main/kotlin/com/mineinabyss/emojy/nms/EmojyNMSHandlers.kt +++ b/core/src/main/kotlin/com/mineinabyss/emojy/nms/EmojyNMSHandlers.kt @@ -13,12 +13,12 @@ import org.bukkit.entity.Player object EmojyNMSHandlers { - private val SUPPORTED_VERSION = arrayOf("v1_19_R1", "v1_19_R2", "v1_19_R3", "v1_20_R1", "v1_20_R2", "v1_20_R3") + private val SUPPORTED_VERSION = arrayOf(/*"v1_19_R1", "v1_19_R2", "v1_19_R3", "v1_20_R1", "v1_20_R2", "v1_20_R3", */"v1_20_R4") fun setup(): IEmojyNMSHandler { SUPPORTED_VERSION.forEach { version -> runCatching { - Class.forName("org.bukkit.craftbukkit.$version.entity.CraftPlayer") + //Class.forName("org.bukkit.craftbukkit.entity.CraftPlayer") return Class.forName("com.mineinabyss.emojy.nms.${version}.EmojyNMSHandler").getConstructor() .newInstance() as IEmojyNMSHandler } diff --git a/gradle.properties b/gradle.properties index b8debd1..7906906 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ group=com.mineinabyss -version=0.8 -idofrontVersion=0.23.0 +version=0.9 +idofrontVersion=0.24.0-dev.10 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a595206..48c0a02 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index 2db4462..67f995e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,6 +8,7 @@ pluginManagement { mavenCentral() google() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") mavenLocal() } @@ -23,6 +24,7 @@ dependencyResolutionManagement { repositories { maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") mavenLocal() } @@ -33,4 +35,4 @@ dependencyResolutionManagement { } } -include("core", "v1_19_R1", "v1_19_R2", "v1_19_R3", "v1_20_R1", "v1_20_R2", "v1_20_R3") +include("core", /*"v1_19_R1", "v1_19_R2", "v1_19_R3", "v1_20_R1", "v1_20_R2", */"v1_20_R3", "v1_20_R4") diff --git a/v1_19_R1/build.gradle.kts b/v1_19_R1/build.gradle.kts index 58d0d94..4641baa 100644 --- a/v1_19_R1/build.gradle.kts +++ b/v1_19_R1/build.gradle.kts @@ -1,12 +1,13 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") id("com.mineinabyss.conventions.autoversion") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.1" } repositories { gradlePluginPortal() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") google() } @@ -32,7 +33,7 @@ tasks { compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } javadoc { options.encoding = Charsets.UTF_8.name() diff --git a/v1_19_R2/build.gradle.kts b/v1_19_R2/build.gradle.kts index 0e33bc5..8da5352 100644 --- a/v1_19_R2/build.gradle.kts +++ b/v1_19_R2/build.gradle.kts @@ -1,12 +1,13 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") id("com.mineinabyss.conventions.autoversion") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.1" } repositories { gradlePluginPortal() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") google() } @@ -32,7 +33,7 @@ tasks { compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } javadoc { options.encoding = Charsets.UTF_8.name() diff --git a/v1_19_R3/build.gradle.kts b/v1_19_R3/build.gradle.kts index ccb8d43..634f20e 100644 --- a/v1_19_R3/build.gradle.kts +++ b/v1_19_R3/build.gradle.kts @@ -1,12 +1,13 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") id("com.mineinabyss.conventions.autoversion") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.1" } repositories { gradlePluginPortal() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") google() } @@ -32,7 +33,7 @@ tasks { compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } javadoc { options.encoding = Charsets.UTF_8.name() diff --git a/v1_20_R1/build.gradle.kts b/v1_20_R1/build.gradle.kts index 14eea49..000763d 100644 --- a/v1_20_R1/build.gradle.kts +++ b/v1_20_R1/build.gradle.kts @@ -1,12 +1,13 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") id("com.mineinabyss.conventions.autoversion") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.1" } repositories { gradlePluginPortal() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") google() } @@ -32,7 +33,7 @@ tasks { compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } javadoc { options.encoding = Charsets.UTF_8.name() diff --git a/v1_20_R2/build.gradle.kts b/v1_20_R2/build.gradle.kts index c32e7c5..856d82c 100644 --- a/v1_20_R2/build.gradle.kts +++ b/v1_20_R2/build.gradle.kts @@ -1,12 +1,13 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") id("com.mineinabyss.conventions.autoversion") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.1" } repositories { gradlePluginPortal() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") google() } @@ -32,7 +33,7 @@ tasks { compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } javadoc { options.encoding = Charsets.UTF_8.name() diff --git a/v1_20_R2/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R2/EmojyNMSHandler.kt b/v1_20_R2/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R2/EmojyNMSHandler.kt index 8fb1d39..6c3588b 100644 --- a/v1_20_R2/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R2/EmojyNMSHandler.kt +++ b/v1_20_R2/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R2/EmojyNMSHandler.kt @@ -17,6 +17,7 @@ import io.netty.handler.codec.ByteToMessageDecoder import io.netty.handler.codec.MessageToByteEncoder import io.papermc.paper.adventure.PaperAdventure import net.kyori.adventure.text.Component +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.StringTag @@ -161,7 +162,7 @@ class EmojyNMSHandler : IEmojyNMSHandler { override fun readUtf(maxLength: Int): String { return super.readUtf(maxLength).let { string -> - runCatching { string.miniMsg() }.recover { legacy.deserialize(string) } + runCatching { string.miniMsg() }.recover { LegacyComponentSerializer.legacySection().deserialize(string) } .getOrNull()?.transform(player, true)?.serialize() ?: string } } diff --git a/v1_20_R3/build.gradle.kts b/v1_20_R3/build.gradle.kts index 16fe9bf..0478735 100644 --- a/v1_20_R3/build.gradle.kts +++ b/v1_20_R3/build.gradle.kts @@ -1,12 +1,13 @@ plugins { id("com.mineinabyss.conventions.kotlin.jvm") id("com.mineinabyss.conventions.autoversion") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.1" } repositories { gradlePluginPortal() maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") maven("https://repo.papermc.io/repository/maven-public/") google() } @@ -32,7 +33,7 @@ tasks { compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } javadoc { options.encoding = Charsets.UTF_8.name() diff --git a/v1_20_R4/build.gradle.kts b/v1_20_R4/build.gradle.kts new file mode 100644 index 0000000..11b747f --- /dev/null +++ b/v1_20_R4/build.gradle.kts @@ -0,0 +1,48 @@ +import io.papermc.paperweight.userdev.ReobfArtifactConfiguration + +plugins { + id("com.mineinabyss.conventions.kotlin.jvm") + id("com.mineinabyss.conventions.autoversion") + id("io.papermc.paperweight.userdev") version "1.7.1" +} + +repositories { + gradlePluginPortal() + maven("https://repo.mineinabyss.com/releases") + maven("https://repo.mineinabyss.com/snapshots") + maven("https://repo.papermc.io/repository/maven-public/") + google() +} + +paperweight.reobfArtifactConfiguration.set(ReobfArtifactConfiguration.MOJANG_PRODUCTION) + +dependencies { + // MineInAbyss platform + compileOnly(idofrontLibs.kotlinx.serialization.json) + compileOnly(idofrontLibs.kotlinx.serialization.kaml) + compileOnly(idofrontLibs.kotlinx.coroutines) + compileOnly(idofrontLibs.minecraft.mccoroutine) + + // Shaded + implementation(idofrontLibs.bundles.idofront.core) + implementation(project(":core")) + paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT") //NMS +} + +tasks { + + build { + dependsOn(reobfJar) + } + + compileJava { + options.encoding = Charsets.UTF_8.name() + options.release.set(21) + } + javadoc { + options.encoding = Charsets.UTF_8.name() + } + processResources { + filteringCharset = Charsets.UTF_8.name() + } +} 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 new file mode 100644 index 0000000..181aa9b --- /dev/null +++ b/v1_20_R4/src/main/kotlin/com/mineinabyss/emojy/nms/v1_20_R4/EmojyNMSHandler.kt @@ -0,0 +1,197 @@ +@file:Suppress("unused") + +package com.mineinabyss.emojy.nms.v1_20_R4 + +import com.mineinabyss.emojy.emojy +import com.mineinabyss.emojy.escapeEmoteIDs +import com.mineinabyss.emojy.nms.IEmojyNMSHandler +import com.mineinabyss.emojy.transformEmoteIDs +import io.netty.buffer.ByteBuf +import io.netty.buffer.Unpooled +import io.netty.channel.* +import io.papermc.paper.adventure.PaperAdventure +import net.kyori.adventure.text.Component +import net.minecraft.core.RegistryAccess +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.NbtAccounter +import net.minecraft.nbt.NbtOps +import net.minecraft.nbt.TagTypes +import net.minecraft.network.* +import net.minecraft.network.chat.ComponentSerialization +import net.minecraft.network.protocol.Packet +import org.bukkit.craftbukkit.CraftServer +import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.entity.Player +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.DataInputStream +import java.io.DataOutputStream +import java.util.* +import java.util.function.Function + +class EmojyNMSHandler : IEmojyNMSHandler { + + private var INFO_BY_ENCODER: Function, ProtocolInfo<*>> + private var INFO_BY_DECODER: Function, ProtocolInfo<*>> + + companion object { + private fun Player.connection() = (this as CraftPlayer).handle.connection.connection + private fun Player.channel() = (this as CraftPlayer).handle.connection.connection.channel + private fun registryAccess(): RegistryAccess = + (emojy.plugin.server as CraftServer).handle.server.registryAccess() + } + + init { + val encoder = PacketEncoder::class.java.declaredFields.firstOrNull { + ProtocolInfo::class.java.isAssignableFrom(it.type) + }?.apply { isAccessible = true } ?: throw NullPointerException() + + val decoder = PacketDecoder::class.java.declaredFields.firstOrNull { + ProtocolInfo::class.java.isAssignableFrom(it.type) + }?.apply { isAccessible = true } ?: throw NullPointerException() + + INFO_BY_ENCODER = Function, ProtocolInfo<*>> { e: PacketEncoder<*> -> + return@Function run { encoder.get(e) } as ProtocolInfo<*> + } + INFO_BY_DECODER = Function, ProtocolInfo<*>> { e: PacketDecoder<*> -> + return@Function run { decoder.get(e) } as ProtocolInfo<*> + } + } + + override fun inject(player: Player) { + val channel = player.channel() + val handler = PlayerHandler(player) + channel.eventLoop().submit { + val pipeline = channel.pipeline() + pipeline.forEach { + pipeline.replace( + it.key, it.key, when (it.value) { + is PacketEncoder<*> -> handler.encoder(INFO_BY_ENCODER.apply(it.value as PacketEncoder<*>)) + is PacketDecoder<*> -> handler.decoder(INFO_BY_DECODER.apply(it.value as PacketDecoder<*>)) + else -> return@forEach + } + ) + } + } + } + + override fun uninject(player: Player) { + val channel = player.channel() + val pipeline = channel.pipeline() + pipeline.forEach { + pipeline.replace( + it.key, it.key, when (it.value) { + is PlayerHandler.EmojyEncoder -> PacketEncoder((it.value as PlayerHandler.EmojyEncoder).protocolInfo) + is PlayerHandler.EmojyDecoder -> PacketDecoder((it.value as PlayerHandler.EmojyDecoder).protocolInfo) + else -> return@forEach + } + ) + } + } + + private class EmojyBuffer(val originalBuffer: ByteBuf) : RegistryFriendlyByteBuf(originalBuffer, registryAccess()) { + override fun copy(): EmojyBuffer { + return EmojyBuffer(Unpooled.copiedBuffer(originalBuffer)) + } + } + + @Suppress("UNCHECKED_CAST") + private data class PlayerHandler(val player: Player) { + + private fun hasComponent(clazz: Class<*>): Boolean { + return clazz.declaredFields.any { net.minecraft.network.chat.Component::class.java.isAssignableFrom(it.type) } + || clazz.declaredFields.any { hasComponent(it::class.java) } + } + + fun decoder(protocolInfo: ProtocolInfo<*>) = EmojyDecoder(protocolInfo as ProtocolInfo) + fun encoder(protocolInfo: ProtocolInfo<*>) = EmojyEncoder(protocolInfo as ProtocolInfo) + private fun writeNewNbt(originalBuffer: EmojyBuffer, clientBound: Boolean): EmojyBuffer { + val newBuffer = EmojyBuffer(Unpooled.buffer()) + val id = VarInt.read(originalBuffer) + VarInt.write(newBuffer, id) + + val bytes = byteArrayOf(originalBuffer.readableBytes().toByte()) + originalBuffer.readBytes(bytes) + val list: MutableList = ArrayList(bytes.size) + + var index = 0 + return runCatching { + while (index < bytes.size) { + val aByte = bytes[index++] + list += aByte + + if (TagTypes.getType(aByte.toInt()) === CompoundTag.TYPE) { + val size = bytes.size - index + val nbtByte = ByteArray(size) + System.arraycopy(bytes, index, nbtByte, 0, nbtByte.size) + runCatching { + DataInputStream(ByteArrayInputStream(nbtByte)).use { input -> + val getTag = CompoundTag.TYPE.load( + input, + NbtAccounter.create(FriendlyByteBuf.DEFAULT_NBT_QUOTA.toLong()) + ) + if (getTag.isEmpty) return@use + val oldComponent = PaperAdventure.asAdventure( + ComponentSerialization.CODEC.decode(NbtOps.INSTANCE, getTag).getOrThrow().first + ) + + val newComponent: Component = when (clientBound) { + true -> oldComponent.transformEmoteIDs(player, true, false) + false -> oldComponent.escapeEmoteIDs(player) + } + val newTag = ComponentSerialization.CODEC.encode( + PaperAdventure.asVanilla(newComponent), + NbtOps.INSTANCE, + CompoundTag() + ).getOrThrow() as CompoundTag + val stream = ByteArrayOutputStream() + DataOutputStream(stream).use { output -> + newTag.write(output) + index += nbtByte.size - input.available() + for (b in stream.toByteArray()) list += b + } + } + } + } + } + val newByte = ByteArray(list.size) + var i = 0 + for (b in list) { + newByte[i++] = b + } + newBuffer.writeBytes(newByte) + newBuffer + }.getOrThrow() + } + + inner class EmojyEncoder(val protocolInfo: ProtocolInfo) : + PacketEncoder(protocolInfo) { + + + override fun encode(ctx: ChannelHandlerContext, packet: Packet, byteBuf: ByteBuf) { + if (hasComponent(packet.javaClass)) runCatching { + val newBuffer = EmojyBuffer(Unpooled.buffer()) + protocolInfo.codec().encode(newBuffer, packet) + byteBuf.writeBytes(writeNewNbt(newBuffer, true)) + ProtocolSwapHandler.handleOutboundTerminalPacket(ctx, packet) + } else super.encode(ctx, packet, byteBuf) + } + } + + inner class EmojyDecoder(val protocolInfo: ProtocolInfo) : + PacketDecoder(protocolInfo) { + + override fun decode(ctx: ChannelHandlerContext, byteBuf: ByteBuf, list: MutableList) { + + runCatching { + val packet = protocolInfo.codec().decode(writeNewNbt(EmojyBuffer(byteBuf), false)) + list += packet + ProtocolSwapHandler.handleInboundTerminalPacket(ctx, packet) + }.onFailure { super.decode(ctx, byteBuf, list) } + } + } + } + + + override val supported get() = true +}