diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 122a2a67..9264fc00 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,6 +17,7 @@ zstd-jni = "1.5.6-9" luckperms-api = "5.4" reactive-streams = "1.0.4" ehcache = "3.10.8" +kotlin-byte-buf-serializer = "1.0.0" [libraries] @@ -65,6 +66,7 @@ spring-aspects = { module = "org.springframework:spring-aspects" } flyway-core = { module = "org.flywaydb:flyway-core" } flyway-mysql = { module = "org.flywaydb:flyway-mysql" } spring-instrument = { module = "org.springframework:spring-instrument" } +kotlin-byte-buf-serializer = { module = "dev.slne.surf:kotlin-byte-buf-serializer", version.ref = "kotlin-byte-buf-serializer" } [plugins] diff --git a/surf-cloud-api/surf-cloud-api-common/api/surf-cloud-api-common.api b/surf-cloud-api/surf-cloud-api-common/api/surf-cloud-api-common.api index 559c4125..19ea1656 100644 --- a/surf-cloud-api/surf-cloud-api-common/api/surf-cloud-api-common.api +++ b/surf-cloud-api/surf-cloud-api-common/api/surf-cloud-api-common.api @@ -19,6 +19,47 @@ public final class dev/slne/surf/cloud/api/common/CloudInstanceKt { public abstract interface annotation class dev/slne/surf/cloud/api/common/SurfCloudApplication : java/lang/annotation/Annotation { } +public final class dev/slne/surf/cloud/api/common/TestPacket : dev/slne/surf/cloud/api/common/netty/packet/NettyPacket { + public static final field Companion Ldev/slne/surf/cloud/api/common/TestPacket$Companion; + public fun (Ljava/lang/String;IZLjava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()I + public final fun component3 ()Z + public final fun component4 ()Ljava/util/List; + public final fun component5 ()Ljava/util/Map; + public final fun component6 ()Ljava/lang/String; + public final fun component7 ()Ljava/util/List; + public final fun component8 ()Ljava/util/Map; + public final fun copy (Ljava/lang/String;IZLjava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)Ldev/slne/surf/cloud/api/common/TestPacket; + public static synthetic fun copy$default (Ldev/slne/surf/cloud/api/common/TestPacket;Ljava/lang/String;IZLjava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;ILjava/lang/Object;)Ldev/slne/surf/cloud/api/common/TestPacket; + public fun equals (Ljava/lang/Object;)Z + public final fun getBoolean ()Z + public final fun getData ()Ljava/lang/String; + public final fun getList ()Ljava/util/List; + public final fun getMap ()Ljava/util/Map; + public final fun getNullable ()Ljava/lang/String; + public final fun getNullableList ()Ljava/util/List; + public final fun getNullableMap ()Ljava/util/Map; + public final fun getNumber ()I + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public synthetic class dev/slne/surf/cloud/api/common/TestPacket$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Ldev/slne/surf/cloud/api/common/TestPacket$$serializer; + public final fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/slne/surf/cloud/api/common/TestPacket; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Ldev/slne/surf/cloud/api/common/TestPacket;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class dev/slne/surf/cloud/api/common/TestPacket$Companion { + public final fun random ()Ldev/slne/surf/cloud/api/common/TestPacket; + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public class dev/slne/surf/cloud/api/common/config/auto/AdventureAutoConfiguration { public fun ()V public fun miniMessage ()Lnet/kyori/adventure/text/minimessage/MiniMessage; diff --git a/surf-cloud-api/surf-cloud-api-common/build.gradle.kts b/surf-cloud-api/surf-cloud-api-common/build.gradle.kts index 112f4f8d..3f71cc87 100644 --- a/surf-cloud-api/surf-cloud-api-common/build.gradle.kts +++ b/surf-cloud-api/surf-cloud-api-common/build.gradle.kts @@ -10,6 +10,10 @@ dependencies { api(libs.aide.reflection) api(libs.netty.all) + api(libs.kotlin.byte.buf.serializer) { + exclude(group = "io.netty") + } + api(libs.nbt) api(libs.datafixerupper) { isTransitive = false diff --git a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/TestPacket.kt b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/TestPacket.kt new file mode 100644 index 00000000..57291899 --- /dev/null +++ b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/TestPacket.kt @@ -0,0 +1,32 @@ +package dev.slne.surf.cloud.api.common + +import dev.slne.surf.cloud.api.common.meta.SurfNettyPacket +import dev.slne.surf.cloud.api.common.netty.network.protocol.PacketFlow +import dev.slne.surf.cloud.api.common.netty.packet.NettyPacket +import kotlinx.serialization.Serializable + +@Serializable +@SurfNettyPacket("cloud:serverbound:test", PacketFlow.SERVERBOUND) +data class TestPacket( + val data: String, + val number: Int, + val boolean: Boolean, + val list: List, + val map: Map, + val nullable: String?, + val nullableList: List?, + val nullableMap: Map?, +) : NettyPacket() { + companion object { + fun random() = TestPacket( + data = "test", + number = 42, + boolean = true, + list = listOf("one", "two", "three"), + map = mapOf("key1" to "value1", "key2" to "value2"), + nullable = null, + nullableList = null, + nullableMap = null + ) + } +} \ No newline at end of file diff --git a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/packet-extension.kt b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/packet-extension.kt index c20890cf..2528084d 100644 --- a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/packet-extension.kt +++ b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/packet-extension.kt @@ -1,5 +1,6 @@ package dev.slne.surf.cloud.api.common.netty.packet +import dev.slne.surf.bytebufserializer.Buf import dev.slne.surf.cloud.api.common.meta.PacketCodec import dev.slne.surf.cloud.api.common.meta.SurfNettyPacket import dev.slne.surf.cloud.api.common.netty.network.codec.StreamCodec @@ -7,6 +8,9 @@ import dev.slne.surf.cloud.api.common.netty.network.codec.StreamDecoder import dev.slne.surf.cloud.api.common.netty.network.codec.StreamMemberEncoder import dev.slne.surf.cloud.api.common.util.mutableObject2ObjectMapOf import io.netty.buffer.ByteBuf +import kotlinx.serialization.InternalSerializationApi +import kotlinx.serialization.KSerializer +import kotlinx.serialization.serializerOrNull import kotlin.reflect.KClass import kotlin.reflect.full.companionObject import kotlin.reflect.full.companionObjectInstance @@ -69,10 +73,24 @@ private val codecCache = mutableObject2ObjectMapOf, Stre * * @return The [StreamCodec] for the packet type, or `null` if not found. */ +@OptIn(InternalSerializationApi::class) @Suppress("UNCHECKED_CAST") -fun KClass.findPacketCodec(): StreamCodec? { +fun KClass.findPacketCodec(): StreamCodec? { codecCache[this]?.let { return it as? StreamCodec } + val serializer = serializerOrNull() + if (serializer != null) { + return object : StreamCodec { + override fun decode(buf: B): V { + return Buf.decodeFromBuf(buf, serializer) + } + + override fun encode(buf: B, value: V) { + Buf.encodeToBuf(buf, serializer as KSerializer, value) + } + } + } + val properties = declaredMemberProperties + (companionObject?.declaredMemberProperties ?: emptyList()) @@ -92,4 +110,4 @@ fun KClass.findPacketCodec(): StreamCodec + TestPacket.random().fireAndForget() + sender.sendPlainMessage("Test packet sent") + } + } } @OptIn(ExperimentalContracts::class) diff --git a/surf-cloud-standalone/src/main/kotlin/dev/slne/surf/cloud/standalone/test/TestPacketListener.kt b/surf-cloud-standalone/src/main/kotlin/dev/slne/surf/cloud/standalone/test/TestPacketListener.kt index 4a915fd0..7f37020f 100644 --- a/surf-cloud-standalone/src/main/kotlin/dev/slne/surf/cloud/standalone/test/TestPacketListener.kt +++ b/surf-cloud-standalone/src/main/kotlin/dev/slne/surf/cloud/standalone/test/TestPacketListener.kt @@ -1,5 +1,7 @@ package dev.slne.surf.cloud.standalone.test +import dev.slne.surf.cloud.api.common.TestPacket +import dev.slne.surf.cloud.api.common.meta.SurfNettyPacketHandler import dev.slne.surf.surfapi.core.api.util.logger import org.springframework.stereotype.Component @@ -7,4 +9,10 @@ import org.springframework.stereotype.Component @Component class TestPacketListener { private val log = logger() + + @SurfNettyPacketHandler + fun onTestPacket(packet: TestPacket) { + log.atInfo() + .log("Received TestPacket: $packet") + } }