diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/JceInput.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/JceInput.kt
index 9ed165582..a2bcd2a0b 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/JceInput.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/JceInput.kt
@@ -3,6 +3,8 @@ package net.mamoe.mirai.qqandroid.io
 import kotlinx.io.charsets.Charset
 import kotlinx.io.core.*
 import kotlinx.io.pool.ObjectPool
+import kotlinx.serialization.DeserializationStrategy
+import net.mamoe.mirai.qqandroid.io.serialization.Jce
 import net.mamoe.mirai.qqandroid.network.protocol.jce.RequestPacket
 import net.mamoe.mirai.utils.io.DebugLogger
 import net.mamoe.mirai.utils.io.readIoBuffer
@@ -18,12 +20,16 @@ inline class JceHead(private val value: Long) {
 
     override fun toString(): String {
         return "JceHead(tag=$tag, type=$type)"
-    }
+    }Z
 }
 
-fun <J : JceStruct> ByteArray.readJceStruct(factory: JceStruct.Factory<J>, tag: Int = 0, charset: Charset = CharsetUTF8): J {
+fun <J : JceStruct> ByteArray.readJceStruct(
+    deserializer: DeserializationStrategy<J>,
+    tag: Int = 0,
+    charset: Charset = CharsetUTF8
+): J {
     this.asJceInput(charset).use {
-        return it.readJceStruct(factory, tag)
+        return Jce.byCharSet(charset).load(deserializer, this.)
     }
 }
 
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/serialization/JceEncoder.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/serialization/JceEncoder.kt
index e74e34355..4f24a0a11 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/serialization/JceEncoder.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/serialization/JceEncoder.kt
@@ -10,6 +10,7 @@ import kotlinx.serialization.*
 import kotlinx.serialization.internal.*
 import kotlinx.serialization.modules.EmptyModule
 import kotlinx.serialization.modules.SerialModule
+import net.mamoe.mirai.qqandroid.io.CharsetUTF8
 import net.mamoe.mirai.qqandroid.io.JceEncodeException
 import net.mamoe.mirai.qqandroid.io.JceOutput
 import net.mamoe.mirai.utils.io.toUHexString
@@ -310,6 +311,14 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo
         val UTF8 = Jce(JceCharset.UTF8)
         val GBK = Jce(JceCharset.GBK)
 
+        public fun byCharSet(c: Charset): Jce {
+            return if (c === CharsetUTF8) {
+                UTF8
+            } else {
+                GBK
+            }
+        }
+
         internal const val BYTE: Int = 0
         internal const val DOUBLE: Int = 5
         internal const val FLOAT: Int = 4