From 87e76d48902c7e94f6da335968151b9346f1c15d Mon Sep 17 00:00:00 2001
From: Him188 <Him188@mamoe.net>
Date: Fri, 31 Jul 2020 16:29:25 +0800
Subject: [PATCH] Update Kotlin version to 1.4 and relevant libraries

---
 build.gradle.kts                              |  4 ++
 buildSrc/src/main/kotlin/Versions.kt          | 12 +++---
 mirai-core-qqandroid/build.gradle.kts         | 21 ++++------
 .../net/mamoe/mirai/qqandroid/BotFactory.kt   |  1 +
 .../mirai/qqandroid/QQAndroidBot.common.kt    | 29 ++++++++-----
 .../qqandroid/network/protocol/LoginType.kt   |  3 +-
 .../network/protocol/data/proto/Cmd0x857.kt   |  2 +-
 .../protocol/data/proto/MsgRevokeUserDef.kt   |  6 +--
 .../network/protocol/data/proto/Oidb0x769.kt  | 40 +++++++++---------
 .../protocol/data/proto/StatSvcGetOnline.kt   |  8 ++--
 .../protocol/packet/chat/image/ImgStore.kt    |  2 +-
 .../chat/receive/MessageSvc.PbGetMsg.kt       | 15 +++----
 .../chat/receive/MessageSvc.PushNotify.kt     |  2 -
 .../network/protocol/packet/login/StatSvc.kt  |  2 +-
 .../mirai/qqandroid/utils/PlatformSocket.kt   |  9 ++--
 .../mirai/qqandroid/utils/cryptor/ECDH.kt     |  4 +-
 .../ProtoBufWithNullableSupport.kt            | 42 ++++++++++++-------
 .../qqandroid/utils/io/serialization/utils.kt | 10 ++---
 .../mamoe/mirai/qqandroid/utils/tryNTimes.kt  |  1 +
 .../net/mamoe/mirai/qqandroid/QQAndroid.kt    | 12 +++---
 .../mirai/qqandroid/utils/PlatformSocket.kt   |  9 ++--
 .../mirai/qqandroid/utils/cryptor/ECDHJvm.kt  |  6 ++-
 mirai-core/build.gradle.kts                   | 28 +++++--------
 .../utils/BotConfiguration.common.kt          |  1 +
 .../kotlin/net.mamoe.mirai/utils/Channels.kt  |  3 +-
 .../net.mamoe.mirai/utils/DeviceInfo.kt       |  2 +-
 .../net.mamoe.mirai/utils/ExternalImage.kt    | 19 ++++-----
 .../net.mamoe.mirai/utils/LoginSolver.kt      | 30 -------------
 .../utils/internal/retryCatching.common.kt    |  4 +-
 mirai-serialization/build.gradle.kts          |  4 --
 settings.gradle                               |  2 +
 31 files changed, 151 insertions(+), 182 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index e62ecba83..7ccf23c51 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -9,8 +9,10 @@ buildscript {
         mavenLocal()
         // maven(url = "https://mirrors.huaweicloud.com/repository/maven")
         maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
+        maven(url = "https://kotlin.bintray.com/kotlinx")
         jcenter()
         google()
+        mavenCentral()
     }
 
     dependencies {
@@ -60,8 +62,10 @@ allprojects {
         mavenLocal()
         // maven(url = "https://mirrors.huaweicloud.com/repository/maven")
         maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
+        maven(url = "https://kotlin.bintray.com/kotlinx")
         jcenter()
         google()
+        mavenCentral()
     }
 }
 
diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt
index fd7229764..88dfdc943 100644
--- a/buildSrc/src/main/kotlin/Versions.kt
+++ b/buildSrc/src/main/kotlin/Versions.kt
@@ -14,11 +14,11 @@ object Versions {
 
     object Kotlin {
         const val compiler = "1.4.0-rc"
-        const val stdlib = "1.3.72"
-        const val coroutines = "1.3.8"
-        const val atomicFU = "0.14.2"
-        const val serialization = "0.20.0"
-        const val ktor = "1.3.2"
+        const val stdlib = "1.4.0-rc"
+        const val coroutines = "1.3.8-1.4.0-rc"
+        const val atomicFU = "0.14.3-1.4.0-rc"
+        const val serialization = "1.0-M1-1.4.0-rc"
+        const val ktor = "1.3.2-1.4.0-rc"
         const val binaryValidator = "0.2.3"
 
         const val io = "0.1.16"
@@ -26,7 +26,7 @@ object Versions {
         const val dokka = "0.10.1"
     }
 
-    const val jcekt = "1.0.0"
+    const val jcekt = "2.0.0-1.4.0-rc-4"
 
     object Android {
         const val androidGradlePlugin = "3.5.3"
diff --git a/mirai-core-qqandroid/build.gradle.kts b/mirai-core-qqandroid/build.gradle.kts
index 8f3d20b24..2ca01df42 100644
--- a/mirai-core-qqandroid/build.gradle.kts
+++ b/mirai-core-qqandroid/build.gradle.kts
@@ -48,9 +48,6 @@ kotlin {
             languageSettings.useExperimentalAnnotation("kotlin.time.ExperimentalTime")
             languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
 
-            languageSettings.languageVersion = "1.3"
-            languageSettings.apiVersion = "1.3"
-
             languageSettings.progressiveMode = true
 
             dependencies {
@@ -60,13 +57,13 @@ kotlin {
 
         val commonMain by getting {
             dependencies {
-                api(kotlin("stdlib", Versions.Kotlin.stdlib))
-                api(kotlinx("serialization-runtime-common", Versions.Kotlin.serialization))
-                api(kotlinx("serialization-protobuf-common", Versions.Kotlin.serialization))
-                api("moe.him188:jcekt-common:${Versions.jcekt}")
+                api(kotlinx("serialization-runtime", Versions.Kotlin.serialization))
+                implementation(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
                 api("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}")
-                api(kotlinx("io", Versions.Kotlin.io))
-                api(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
+                implementation(kotlinx("io", Versions.Kotlin.io))
+                implementation(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
+                //implementation("moe.him188:jcekt:${Versions.jcekt}")
+                implementation("moe.him188:jcekt:${Versions.jcekt}")
             }
         }
 
@@ -81,7 +78,6 @@ kotlin {
         if (isAndroidSDKAvailable) {
             val androidMain by getting {
                 dependencies {
-                    api(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
                 }
             }
 
@@ -98,11 +94,8 @@ kotlin {
         val jvmMain by getting {
             dependencies {
                 runtimeOnly(files("build/classes/kotlin/jvm/main")) // classpath is not properly set by IDE
+                implementation("org.bouncycastle:bcprov-jdk15on:1.64")
                 //    api(kotlinx("coroutines-debug", Versions.Kotlin.coroutines))
-                api("moe.him188:jcekt:${Versions.jcekt}")
-                api(kotlinx("serialization-runtime", Versions.Kotlin.serialization))
-                //api(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
-
             }
         }
 
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/BotFactory.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/BotFactory.kt
index 94cbc5639..6b560433c 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/BotFactory.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/BotFactory.kt
@@ -6,6 +6,7 @@
  *
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
+
 @file:Suppress(
     "FunctionName", "INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith",
     "OverridingDeprecatedMember"
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
index 0f9715139..612877dbf 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
@@ -18,6 +18,8 @@ import kotlinx.coroutines.async
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.withContext
 import kotlinx.serialization.json.int
+import kotlinx.serialization.json.jsonObject
+import kotlinx.serialization.json.jsonPrimitive
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.LowLevelAPI
 import net.mamoe.mirai.contact.*
@@ -297,7 +299,7 @@ internal abstract class QQAndroidBotBase constructor(
     }
 
     fun getGroupByUinOrNull(uin: Long): Group? {
-        return groups.asSequence().firstOrNull { it.checkIsGroupImpl(); it.uin == uin }
+        return groups.firstOrNull { it.checkIsGroupImpl(); it.uin == uin }
     }
 
     @OptIn(LowLevelAPI::class)
@@ -487,7 +489,7 @@ internal abstract class QQAndroidBotBase constructor(
 
         val rep = data.await()
 //        bot.network.logger.error(rep)
-        return json.parse(GroupAnnouncementList.serializer(), rep)
+        return json.decodeFromString(GroupAnnouncementList.serializer(), rep)
     }
 
     @LowLevelAPI
@@ -503,7 +505,7 @@ internal abstract class QQAndroidBotBase constructor(
                     append("pinned", announcement.pinned)
                     append(
                         "settings",
-                        json.stringify(
+                        json.encodeToString(
                             GroupAnnouncementSettings.serializer(),
                             announcement.settings ?: GroupAnnouncementSettings()
                         )
@@ -521,8 +523,8 @@ internal abstract class QQAndroidBotBase constructor(
                 }
             }
         }
-        val jsonObj = json.parseJson(rep)
-        return jsonObj.jsonObject["new_fid"]?.primitive?.content
+        val jsonObj = json.parseToJsonElement(rep)
+        return jsonObj.jsonObject["new_fid"]?.jsonPrimitive?.content
             ?: throw throw IllegalStateException("Send Announcement fail group:$groupId msg:${jsonObj.jsonObject["em"]} content:${announcement.msg.text}")
     }
 
@@ -549,8 +551,8 @@ internal abstract class QQAndroidBotBase constructor(
                 }
             }
         }
-        val jsonObj = json.parseJson(data)
-        if (jsonObj.jsonObject["ec"]?.int ?: 1 != 0) {
+        val jsonObj = json.parseToJsonElement(data)
+        if (jsonObj.jsonObject["ec"]?.jsonPrimitive?.int ?: 1 != 0) {
             throw throw IllegalStateException("delete Announcement fail group:$groupId msg:${jsonObj.jsonObject["em"]} fid:$fid")
         }
     }
@@ -578,7 +580,7 @@ internal abstract class QQAndroidBotBase constructor(
 
         val rep = data.await()
 //        bot.network.logger.error(rep)
-        return json.parse(GroupAnnouncement.serializer(), rep)
+        return json.decodeFromString(GroupAnnouncement.serializer(), rep)
 
     }
 
@@ -602,7 +604,7 @@ internal abstract class QQAndroidBotBase constructor(
             }
         }
         val rep = data.await()
-        return json.parse(GroupActiveData.serializer(), rep)
+        return json.decodeFromString(GroupActiveData.serializer(), rep)
     }
 
     @JvmSynthetic
@@ -798,13 +800,18 @@ internal abstract class QQAndroidBotBase constructor(
         groupId: Long,
         dstUin: Long
     ): String {
-          network.run {
+        network.run {
             val response: PttStore.GroupPttDown.Response.DownLoadInfo =
-                PttStore.GroupPttDown(client, groupId, dstUin,md5).sendAndExpect()
+                PttStore.GroupPttDown(client, groupId, dstUin, md5).sendAndExpect()
             return "http://${response.strDomain}${response.downPara.encodeToString()}"
         }
     }
 
+    @LowLevelAPI
+    override suspend fun _lowLevelUploadVoice(md5: ByteArray, groupId: Long) {
+
+    }
+
     @Suppress("DEPRECATION", "OverridingDeprecatedMember")
     override suspend fun queryImageUrl(image: Image): String = when (image) {
         is ConstOriginUrlAware -> image.originUrl
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/LoginType.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/LoginType.kt
index 86b3f57a6..c079373bb 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/LoginType.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/LoginType.kt
@@ -9,7 +9,7 @@
 
 package net.mamoe.mirai.qqandroid.network.protocol
 
-inline class LoginType(
+internal inline class LoginType(
     val value: Int
 ) {
     companion object {
@@ -17,6 +17,7 @@ inline class LoginType(
          * 短信验证登录
          */
         val SMS = LoginType(3)
+
         /**
          * 密码登录
          */
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x857.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x857.kt
index 38f2fca82..db490b7a4 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x857.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x857.kt
@@ -19,7 +19,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
 import net.mamoe.mirai.qqandroid.utils.io.ProtoBuf
 import kotlin.jvm.JvmField
 
-class GroupOpenSysMsg : ProtoBuf {
+internal class GroupOpenSysMsg : ProtoBuf {
     @Serializable
     internal class LightApp(
         @ProtoId(1) @JvmField val app: String = "",
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgRevokeUserDef.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgRevokeUserDef.kt
index 92a6f9e8a..54caa51f5 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgRevokeUserDef.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgRevokeUserDef.kt
@@ -14,15 +14,15 @@ import kotlinx.serialization.protobuf.ProtoId
 import net.mamoe.mirai.qqandroid.utils.io.ProtoBuf
 import kotlin.jvm.JvmField
 
-class MsgRevokeUserDef : ProtoBuf {
+internal class MsgRevokeUserDef : ProtoBuf {
     @Serializable
-internal class MsgInfoUserDef(
+    internal class MsgInfoUserDef(
         @ProtoId(1) @JvmField val longMessageFlag: Int = 0,
         @ProtoId(2) @JvmField val longMsgInfo: List<MsgInfoDef>? = null,
         @ProtoId(3) @JvmField val fileUuid: List<String> = listOf()
     ) : ProtoBuf {
         @Serializable
-internal class MsgInfoDef(
+        internal class MsgInfoDef(
             @ProtoId(1) @JvmField val msgSeq: Int = 0,
             @ProtoId(2) @JvmField val longMsgId: Int = 0,
             @ProtoId(3) @JvmField val longMsgNum: Int = 0,
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Oidb0x769.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Oidb0x769.kt
index 932c6cfde..fae4e6ec2 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Oidb0x769.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Oidb0x769.kt
@@ -14,9 +14,9 @@ import kotlinx.serialization.protobuf.ProtoId
 import net.mamoe.mirai.qqandroid.utils.io.ProtoBuf
 import kotlin.jvm.JvmField
 
-class Oidb0x769 {
+internal class Oidb0x769 {
     @Serializable
-internal class RequestBody(
+    internal class RequestBody(
         @ProtoId(1) @JvmField val rpt_config_list: List<ConfigSeq>
         // @SerialId(2) @JvmField val msg_device_info: DeviceInfo,
         // @SerialId(3) @JvmField val str_info: String = "",
@@ -27,19 +27,19 @@ internal class RequestBody(
     ) : ProtoBuf
 
     @Serializable
-internal class QueryUinPackageUsageReq(
+    internal class QueryUinPackageUsageReq(
         @ProtoId(1) @JvmField val type: Int,
         @ProtoId(2) @JvmField val uinFileSize: Long = 0
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class ConfigSeq(
+    internal class ConfigSeq(
         @ProtoId(1) @JvmField val type: Int, // uint
         @ProtoId(2) @JvmField val version: Int // uint
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class DeviceInfo(
+    internal class DeviceInfo(
         @ProtoId(1) @JvmField val brand: String,
         @ProtoId(2) @JvmField val model: String
         //@SerialId(3) @JvmField val os: OS,
@@ -48,49 +48,49 @@ internal class DeviceInfo(
         //@SerialId(6) @JvmField val storage: Storage,
         //@SerialId(7) @JvmField val screen: Screen,
         //@SerialId(8) @JvmField val camera: Camera
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class OS(
+    internal class OS(
         @ProtoId(1) @JvmField val type: Int = 1,
         @ProtoId(2) @JvmField val version: String,
         @ProtoId(3) @JvmField val sdk: String,
         @ProtoId(4) @JvmField val kernel: String,
         @ProtoId(5) @JvmField val rom: String
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class Camera(
+    internal class Camera(
         @ProtoId(1) @JvmField val primary: Long,
         @ProtoId(2) @JvmField val secondary: Long,
         @ProtoId(3) @JvmField val flag: Boolean
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class CPU(
+    internal class CPU(
         @ProtoId(1) @JvmField val model: String,
         @ProtoId(2) @JvmField val frequency: Int,
         @ProtoId(3) @JvmField val cores: Int
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class Memory(
+    internal class Memory(
         @ProtoId(1) @JvmField val total: Int,
         @ProtoId(2) @JvmField val process: Int
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class Screen(
+    internal class Screen(
         @ProtoId(1) @JvmField val model: String,
         @ProtoId(2) @JvmField val width: Int,
         @ProtoId(3) @JvmField val height: Int,
         @ProtoId(4) @JvmField val dpi: Int,
         @ProtoId(5) @JvmField val multiTouch: Boolean
-    ): ProtoBuf
+    ) : ProtoBuf
 
     @Serializable
-internal class Storage(
+    internal class Storage(
         @ProtoId(1) @JvmField val builtin: Int,
         @ProtoId(2) @JvmField val external: Int
-    ): ProtoBuf
+    ) : ProtoBuf
 }
\ No newline at end of file
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/StatSvcGetOnline.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/StatSvcGetOnline.kt
index b9138e59b..600c862f5 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/StatSvcGetOnline.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/StatSvcGetOnline.kt
@@ -14,21 +14,21 @@ import kotlinx.serialization.protobuf.ProtoId
 import net.mamoe.mirai.qqandroid.utils.io.ProtoBuf
 import kotlin.jvm.JvmField
 
-class StatSvcGetOnline {
+internal class StatSvcGetOnline {
     @Serializable
-internal class Instance(
+    internal class Instance(
         @ProtoId(1) @JvmField val instanceId: Int = 0,
         @ProtoId(2) @JvmField val clientType: Int = 0
     ) : ProtoBuf
 
     @Serializable
-internal class ReqBody(
+    internal class ReqBody(
         @ProtoId(1) @JvmField val uin: Long = 0L,
         @ProtoId(2) @JvmField val appid: Int = 0
     ) : ProtoBuf
 
     @Serializable
-internal class RspBody(
+    internal class RspBody(
         @ProtoId(1) @JvmField val errorCode: Int = 0,
         @ProtoId(2) @JvmField val errorMsg: String = "",
         @ProtoId(3) @JvmField val uin: Long = 0L,
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt
index 81ca1a4b5..afd586c15 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt
@@ -29,7 +29,7 @@ internal fun getRandomString(length: Int): String =
 private val defaultRanges: Array<CharRange> = arrayOf('a'..'z', 'A'..'Z', '0'..'9')
 
 internal fun getRandomString(length: Int, vararg charRanges: CharRange): String =
-    String(CharArray(length) { charRanges[Random.Default.nextInt(0..charRanges.lastIndex)].random() })
+    CharArray(length) { charRanges[Random.Default.nextInt(0..charRanges.lastIndex)].random() }.concatToString()
 
 internal class ImgStore {
     object GroupPicUp : OutgoingPacketFactory<GroupPicUp.Response>("ImgStore.GroupPicUp") {
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt
index dcb4cd326..ca9a85f80 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt
@@ -48,7 +48,6 @@ import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
 import net.mamoe.mirai.qqandroid.utils.read
 import net.mamoe.mirai.qqandroid.utils.toInt
 import net.mamoe.mirai.qqandroid.utils.toUHexString
-import net.mamoe.mirai.utils.currentTimeSeconds
 import net.mamoe.mirai.utils.debug
 import net.mamoe.mirai.utils.warning
 
@@ -57,20 +56,18 @@ import net.mamoe.mirai.utils.warning
  * 获取好友消息和消息记录
  */
 internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Response>("MessageSvc.PbGetMsg") {
-    private var firstSyncPackets = 0  // 启动时候仅将所有好友信息设为已读的包
     @Suppress("SpellCheckingInspection")
     operator fun invoke(
         client: QQAndroidClient,
         syncFlag: MsgSvc.SyncFlag = MsgSvc.SyncFlag.START,
-        msgTime: Long, //PbPushMsg.msg.msgHead.msgTime
-        syncCookie: ByteArray?,
+        syncCookie: ByteArray?, //PbPushMsg.msg.msgHead.msgTime
         firstSync: Boolean = false
     ): OutgoingPacket = buildOutgoingUniPacket(
         client
     ) {
         //println("syncCookie=${client.c2cMessageSync.syncCookie?.toUHexString()}")
         if (firstSync) {
-            firstSyncPackets++
+            client.firstSyncPackets.getAndAdd(1)
         }
         writeProtoBuf(
             MsgSvc.PbGetMsgReq.serializer(),
@@ -279,7 +276,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                     */
 
                     166 -> {
-                        if (firstSyncPackets != 0) {
+                        if (bot.client.firstSyncPackets.value != 0) {
                             return@mapNotNull null
                         }
                         if (msg.msgHead.fromUin == bot.id) {
@@ -384,8 +381,8 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
     override suspend fun QQAndroidBot.handle(packet: Response) {
         when (packet.syncFlagFromServer) {
             MsgSvc.SyncFlag.STOP -> {
-                if (firstSyncPackets != 0) {
-                    firstSyncPackets--
+                if (client.firstSyncPackets.value != 0) {
+                    client.firstSyncPackets.getAndDecrement()
                 }
             }
 
@@ -394,7 +391,6 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                     MessageSvcPbGetMsg(
                         client,
                         MsgSvc.SyncFlag.CONTINUE,
-                        currentTimeSeconds,
                         packet.syncCookie
                     ).sendAndExpect<Packet>()
                 }
@@ -406,7 +402,6 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                     MessageSvcPbGetMsg(
                         client,
                         MsgSvc.SyncFlag.CONTINUE,
-                        currentTimeSeconds,
                         packet.syncCookie
                     ).sendAndExpect<Packet>()
                 }
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt
index cbe623d57..3afc081ac 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt
@@ -18,7 +18,6 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
 import net.mamoe.mirai.qqandroid.network.protocol.packet.IncomingPacketFactory
 import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
 import net.mamoe.mirai.qqandroid.utils.io.serialization.readUniPacket
-import net.mamoe.mirai.utils.currentTimeSeconds
 
 
 /**
@@ -37,7 +36,6 @@ internal object MessageSvcPushNotify : IncomingPacketFactory<RequestPushNotify>(
                 return MessageSvcPbGetMsg(
                     client,
                     MsgSvc.SyncFlag.START,
-                    packet.stMsgInfo?.uMsgTime ?: currentTimeSeconds,
                     if (firstNotify) {
                         if (!client.c2cMessageSync.firstNotify.compareAndSet(firstNotify, false)) {
                             return@loop
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt
index c0834831a..76761ec18 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt
@@ -148,7 +148,7 @@ internal class StatSvc {
                                 var44.strVendorName = ROMUtil.getRomName();
                                 var44.strVendorOSName = ROMUtil.getRomVersion(20);
                                 */
-                                bytes_0x769_reqbody = ProtoBuf.dump(
+                                bytes_0x769_reqbody = ProtoBuf.encodeToByteArray(
                                     Oidb0x769.RequestBody.serializer(), Oidb0x769.RequestBody(
                                         rpt_config_list = listOf(
                                             Oidb0x769.ConfigSeq(
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt
index 2f19e3ea9..d8fa35889 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt
@@ -12,14 +12,13 @@ package net.mamoe.mirai.qqandroid.utils
 import kotlinx.io.core.ByteReadPacket
 import kotlinx.io.core.Closeable
 import kotlinx.io.errors.IOException
-import net.mamoe.mirai.utils.Throws
 import kotlin.coroutines.CoroutineContext
 
 /**
  * 多平台适配的 TCP Socket.
  */
 internal expect class PlatformSocket() : Closeable {
-    @Throws(SocketException::class)
+    @kotlin.Throws(SocketException::class)
     suspend fun connect(coroutineContext: CoroutineContext, serverHost: String, serverPort: Int)
 
     /**
@@ -42,6 +41,6 @@ internal expect class PlatformSocket() : Closeable {
     override fun close()
 }
 
-expect open class SocketException : IOException
-expect class NoRouteToHostException : SocketException
-expect class UnknownHostException : IOException
\ No newline at end of file
+internal expect open class SocketException : IOException
+internal expect class NoRouteToHostException : SocketException
+internal expect class UnknownHostException : IOException
\ No newline at end of file
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDH.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDH.kt
index 7ebda47fb..b16b86552 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDH.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDH.kt
@@ -11,11 +11,11 @@ package net.mamoe.mirai.qqandroid.utils.cryptor
 
 import net.mamoe.mirai.qqandroid.utils.chunkedHexToBytes
 
-expect interface ECDHPrivateKey {
+internal expect interface ECDHPrivateKey {
     fun getEncoded(): ByteArray
 }
 
-expect interface ECDHPublicKey {
+internal expect interface ECDHPublicKey {
     fun getEncoded(): ByteArray
 }
 
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/ProtoBufWithNullableSupport.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/ProtoBufWithNullableSupport.kt
index 565030251..7c8a83a62 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/ProtoBufWithNullableSupport.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/ProtoBufWithNullableSupport.kt
@@ -9,22 +9,26 @@
 
 package net.mamoe.mirai.qqandroid.utils.io.serialization
 
-import kotlinx.io.ByteArrayOutputStream
-import kotlinx.io.ByteBuffer
-import kotlinx.io.ByteOrder
 import kotlinx.serialization.*
 import kotlinx.serialization.builtins.ByteArraySerializer
 import kotlinx.serialization.builtins.MapEntrySerializer
 import kotlinx.serialization.builtins.SetSerializer
+import kotlinx.serialization.descriptors.PolymorphicKind
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.descriptors.StructureKind
+import kotlinx.serialization.encoding.CompositeEncoder
 import kotlinx.serialization.internal.MapLikeSerializer
 import kotlinx.serialization.internal.TaggedEncoder
-import kotlinx.serialization.modules.EmptyModule
-import kotlinx.serialization.modules.SerialModule
+import kotlinx.serialization.modules.EmptySerializersModule
+import kotlinx.serialization.modules.SerializersModule
 import kotlinx.serialization.protobuf.ProtoBuf
 import kotlinx.serialization.protobuf.ProtoNumberType
 import kotlinx.serialization.protobuf.ProtoType
 import moe.him188.jcekt.JceId
 import net.mamoe.mirai.qqandroid.utils.io.serialization.ProtoBufWithNullableSupport.Varint.encodeVarint
+import java.io.ByteArrayOutputStream
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
 
 internal typealias ProtoDesc = Pair<Int, ProtoNumberType>
 
@@ -45,11 +49,12 @@ internal fun extractParameters(desc: SerialDescriptor, index: Int, zeroBasedDefa
  * 代码复制自 kotlinx.serialization. 修改部分已进行标注 (详见 "MIRAI MODIFY START")
  */
 @OptIn(InternalSerializationApi::class)
-internal class ProtoBufWithNullableSupport(override val context: SerialModule = EmptyModule) : SerialFormat, BinaryFormat {
+internal class ProtoBufWithNullableSupport(override val serializersModule: SerializersModule = EmptySerializersModule) :
+    SerialFormat, BinaryFormat {
 
     internal open inner class ProtobufWriter(private val encoder: ProtobufEncoder) : TaggedEncoder<ProtoDesc>() {
-        override val context
-            get() = this@ProtoBufWithNullableSupport.context
+        override val serializersModule
+            get() = this@ProtoBufWithNullableSupport.serializersModule
 
         override fun beginStructure(
             descriptor: SerialDescriptor,
@@ -241,7 +246,8 @@ internal class ProtoBufWithNullableSupport(override val context: SerialModule =
     }
 
     companion object : BinaryFormat {
-        override val context: SerialModule get() = plain.context
+        override val serializersModule: SerializersModule
+            get() = plain.serializersModule
 
         private fun SerialDescriptor.getProtoDesc(index: Int): ProtoDesc {
             return extractParameters(this, index)
@@ -254,20 +260,24 @@ internal class ProtoBufWithNullableSupport(override val context: SerialModule =
 
         private val plain = ProtoBufWithNullableSupport()
 
-        override fun <T> dump(serializer: SerializationStrategy<T>, value: T): ByteArray = plain.dump(serializer, value)
-        override fun <T> load(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T =
-            plain.load(deserializer, bytes)
+        override fun <T> encodeToByteArray(serializer: SerializationStrategy<T>, value: T): ByteArray {
+            return plain.encodeToByteArray(serializer, value)
+        }
+
+        override fun <T> decodeFromByteArray(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T {
+            return plain.decodeFromByteArray(deserializer, bytes)
+        }
     }
 
-    override fun <T> dump(serializer: SerializationStrategy<T>, value: T): ByteArray {
+    override fun <T> encodeToByteArray(serializer: SerializationStrategy<T>, value: T): ByteArray {
         val encoder = ByteArrayOutputStream()
         val dumper = ProtobufWriter(ProtobufEncoder(encoder))
-        dumper.encode(serializer, value)
+        dumper.encodeSerializableValue(serializer, value)
         return encoder.toByteArray()
     }
 
-    override fun <T> load(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T {
-        return ProtoBuf.load(deserializer, bytes)
+    override fun <T> decodeFromByteArray(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T {
+        return ProtoBuf.decodeFromByteArray(deserializer, bytes)
     }
 
 }
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/utils.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/utils.kt
index 5ea7bf77c..302864f3b 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/utils.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/serialization/utils.kt
@@ -14,8 +14,8 @@ package net.mamoe.mirai.qqandroid.utils.io.serialization
 
 import kotlinx.io.core.*
 import kotlinx.serialization.DeserializationStrategy
-import kotlinx.serialization.SerialDescriptor
 import kotlinx.serialization.SerializationStrategy
+import kotlinx.serialization.descriptors.SerialDescriptor
 import moe.him188.jcekt.Jce
 import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion2
 import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion3
@@ -99,7 +99,7 @@ private fun <R> ByteReadPacket.decodeUniRequestPacketAndDeserialize(name: String
 
 internal fun <T : JceStruct> T.toByteArray(
     serializer: SerializationStrategy<T>
-): ByteArray = Jce.UTF_8.dump(serializer, this)
+): ByteArray = Jce.UTF_8.encodeToByteArray(serializer, this)
 
 internal fun <T : ProtoBuf> BytePacketBuilder.writeProtoBuf(serializer: SerializationStrategy<T>, v: T) {
     this.writeFully(v.toByteArray(serializer))
@@ -109,14 +109,14 @@ internal fun <T : ProtoBuf> BytePacketBuilder.writeProtoBuf(serializer: Serializ
  * dump
  */
 internal fun <T : ProtoBuf> T.toByteArray(serializer: SerializationStrategy<T>): ByteArray {
-    return ProtoBufWithNullableSupport.dump(serializer, this)
+    return ProtoBufWithNullableSupport.encodeToByteArray(serializer, this)
 }
 
 /**
  * load
  */
 internal fun <T : ProtoBuf> ByteArray.loadAs(deserializer: DeserializationStrategy<T>): T {
-    return ProtoBufWithNullableSupport.load(deserializer, this)
+    return ProtoBufWithNullableSupport.decodeFromByteArray(deserializer, this)
 }
 
 /**
@@ -125,7 +125,7 @@ internal fun <T : ProtoBuf> ByteArray.loadAs(deserializer: DeserializationStrate
 internal fun <T : ProtoBuf> ByteReadPacket.readProtoBuf(
     serializer: DeserializationStrategy<T>,
     length: Int = this.remaining.toInt()
-): T = ProtoBufWithNullableSupport.load(serializer, this.readBytes(length))
+): T = ProtoBufWithNullableSupport.decodeFromByteArray(serializer, this.readBytes(length))
 
 /**
  * 构造 [RequestPacket] 的 [RequestPacket.sBuffer]
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/tryNTimes.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/tryNTimes.kt
index 6bed29889..1c1028687 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/tryNTimes.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/tryNTimes.kt
@@ -6,6 +6,7 @@
  *
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
+
 @file:Suppress("DuplicatedCode")
 
 @file:JvmMultifileClass
diff --git a/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroid.kt b/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroid.kt
index 2e8c6f731..435d934c9 100644
--- a/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroid.kt
+++ b/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroid.kt
@@ -21,13 +21,13 @@ import net.mamoe.mirai.utils.Context
  * QQ for Android
  */
 @Suppress("INAPPLICABLE_JVM_NAME")
-actual object QQAndroid : BotFactory {
+public actual object QQAndroid : BotFactory {
 
     /**
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
     @JvmName("newBot")
-    actual override fun Bot(context: Context, qq: Long, password: String, configuration: BotConfiguration): Bot {
+    public actual override fun Bot(context: Context, qq: Long, password: String, configuration: BotConfiguration): Bot {
         return QQAndroidBot(context, BotAccount(qq, password), configuration)
     }
 
@@ -35,14 +35,14 @@ actual object QQAndroid : BotFactory {
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
     @JvmName("newBot")
-    fun Bot(qq: Long, password: String, configuration: BotConfiguration = BotConfiguration.Default): Bot =
+    public fun Bot(qq: Long, password: String, configuration: BotConfiguration = BotConfiguration.Default): Bot =
         QQAndroidBot(BotAccount(qq, password), configuration)
 
     /**
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
     @JvmName("newBot")
-    actual override fun Bot(
+    public actual override fun Bot(
         context: Context,
         qq: Long,
         passwordMd5: ByteArray,
@@ -53,7 +53,7 @@ actual object QQAndroid : BotFactory {
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
     @JvmName("newBot")
-    fun Bot(
+    public fun Bot(
         qq: Long,
         passwordMd5: ByteArray,
         configuration: BotConfiguration
@@ -63,5 +63,5 @@ actual object QQAndroid : BotFactory {
 /**
  * 使用指定的 [配置][configuration] 构造 [Bot] 实例
  */
-inline fun QQAndroid.Bot(qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot =
+public inline fun QQAndroid.Bot(qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot =
     this.Bot(qq, password, BotConfiguration().apply(configuration))
\ No newline at end of file
diff --git a/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt b/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt
index a7f4a39c1..e05f85dd7 100644
--- a/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt
+++ b/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/PlatformSocket.kt
@@ -90,9 +90,11 @@ internal actual class PlatformSocket : Closeable {
     }
 }
 
-actual typealias NoRouteToHostException = java.net.NoRouteToHostException
+@Suppress("ACTUAL_WITHOUT_EXPECT")
+internal actual typealias NoRouteToHostException = java.net.NoRouteToHostException
 
-actual typealias SocketException = SocketException
+@Suppress("ACTUAL_WITHOUT_EXPECT")
+internal actual typealias SocketException = SocketException
 
 // ktor aSocket
 
@@ -202,4 +204,5 @@ actual typealias NoRouteToHostException = java.net.NoRouteToHostException
 
 actual typealias SocketException = SocketException
  */
-actual typealias UnknownHostException = java.net.UnknownHostException
\ No newline at end of file
+@Suppress("ACTUAL_WITHOUT_EXPECT")
+internal actual typealias UnknownHostException = java.net.UnknownHostException
\ No newline at end of file
diff --git a/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHJvm.kt b/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHJvm.kt
index 8b0d5cd2a..cd30c75ea 100644
--- a/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHJvm.kt
+++ b/mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHJvm.kt
@@ -17,8 +17,10 @@ import java.security.spec.X509EncodedKeySpec
 import javax.crypto.KeyAgreement
 
 
-actual typealias ECDHPrivateKey = PrivateKey
-actual typealias ECDHPublicKey = PublicKey
+@Suppress("ACTUAL_WITHOUT_EXPECT")
+internal actual typealias ECDHPrivateKey = PrivateKey
+@Suppress("ACTUAL_WITHOUT_EXPECT")
+internal actual typealias ECDHPublicKey = PublicKey
 
 internal actual class ECDHKeyPairImpl(
     private val delegate: KeyPair
diff --git a/mirai-core/build.gradle.kts b/mirai-core/build.gradle.kts
index bb2b04a8a..a25c55564 100644
--- a/mirai-core/build.gradle.kts
+++ b/mirai-core/build.gradle.kts
@@ -57,17 +57,16 @@ kotlin {
 
         val commonMain by getting {
             dependencies {
-                api(kotlin("stdlib", Versions.Kotlin.stdlib))
                 api(kotlin("serialization"))
                 api(kotlin("reflect"))
 
-                api(kotlinx("serialization-runtime-common", Versions.Kotlin.serialization))
-                api(kotlinx("serialization-protobuf-common", Versions.Kotlin.serialization))
-                api(kotlinx("io", Versions.Kotlin.io))
-                api(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
-                api(kotlinx("coroutines-core-common", Versions.Kotlin.coroutines))
+                api(kotlinx("serialization-runtime", Versions.Kotlin.serialization))
+                implementation(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
+                implementation(kotlinx("io", Versions.Kotlin.io))
+                implementation(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
+                api(kotlinx("coroutines-core", Versions.Kotlin.coroutines))
 
-                api("org.jetbrains.kotlinx:atomicfu-common:${Versions.Kotlin.atomicFU}")
+                implementation("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}")
 
                 api(ktor("client-cio"))
                 api(ktor("client-core"))
@@ -87,11 +86,8 @@ kotlin {
                 dependencies {
                     api(kotlin("reflect"))
 
-                    api(kotlinx("io-jvm", Versions.Kotlin.io))
-                    api(kotlinx("serialization-runtime", Versions.Kotlin.serialization))
-                    api(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
-                    api(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo))
-                    api(kotlinx("coroutines-core", Versions.Kotlin.coroutines))
+                    implementation(kotlinx("io-jvm", Versions.Kotlin.io))
+                    implementation(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo))
 
                     api(ktor("client-android", Versions.Kotlin.ktor))
                 }
@@ -114,13 +110,9 @@ kotlin {
                 api(kotlin("reflect"))
 
                 api(ktor("client-core-jvm", Versions.Kotlin.ktor))
-                api(kotlinx("io-jvm", Versions.Kotlin.io))
-                api(kotlinx("serialization-runtime", Versions.Kotlin.serialization))
-                api(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
-                api(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo))
-                api(kotlinx("coroutines-core", Versions.Kotlin.coroutines))
+                implementation(kotlinx("io-jvm", Versions.Kotlin.io))
+                implementation(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo))
 
-                api("org.bouncycastle:bcprov-jdk15on:1.64")
                 runtimeOnly(files("build/classes/kotlin/jvm/main")) // classpath is not properly set by IDE
             }
         }
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.common.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.common.kt
index 2cdf642e1..80d86699e 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.common.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.common.kt
@@ -6,6 +6,7 @@
  *
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
+
 @file:Suppress("unused", "DEPRECATION_ERROR", "EXPOSED_SUPER_CLASS")
 
 package net.mamoe.mirai.utils
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Channels.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Channels.kt
index a85590ade..4b45197a6 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Channels.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Channels.kt
@@ -7,7 +7,6 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-
 @file:JvmName("Utils")
 @file:JvmMultifileClass
 
@@ -17,9 +16,9 @@ package net.mamoe.mirai.utils
 import kotlinx.coroutines.io.ByteReadChannel
 import kotlinx.coroutines.io.ByteWriteChannel
 import kotlinx.coroutines.io.readAvailable
-import kotlinx.io.OutputStream
 import kotlinx.io.core.Output
 import kotlinx.serialization.InternalSerializationApi
+import java.io.OutputStream
 import kotlin.jvm.JvmMultifileClass
 import kotlin.jvm.JvmName
 
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/DeviceInfo.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/DeviceInfo.kt
index 45ab5995b..0412868f6 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/DeviceInfo.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/DeviceInfo.kt
@@ -69,7 +69,7 @@ public abstract class DeviceInfo {
             @ProtoId(9) val innerVersion: ByteArray
         )
 
-        return ProtoBuf.dump(
+        return ProtoBuf.encodeToByteArray(
             DevInfo.serializer(), DevInfo(
                 bootloader,
                 procVersion,
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
index 163837ae8..ab7fe3f9b 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
@@ -11,18 +11,14 @@
 
 package net.mamoe.mirai.utils
 
-import kotlinx.io.core.readBytes
-import kotlinx.io.core.use
 import net.mamoe.mirai.contact.Contact
 import net.mamoe.mirai.contact.Group
 import net.mamoe.mirai.contact.User
 import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.Image
 import net.mamoe.mirai.message.data.sendTo
-import net.mamoe.mirai.message.data.toUHexString
 import net.mamoe.mirai.utils.internal.DeferredReusableInput
 import net.mamoe.mirai.utils.internal.ReusableInput
-import kotlin.jvm.JvmField
 import kotlin.jvm.JvmSynthetic
 
 /**
@@ -34,15 +30,16 @@ import kotlin.jvm.JvmSynthetic
  * @See ExternalImage.upload 上传图片并得到 [Image] 消息
  */
 public class ExternalImage internal constructor(
-    @JvmField
-    internal val input: ReusableInput
-) {
-    internal val md5: ByteArray get() = this.input.md5
-    public val formatName: String by lazy {
+    override val input: ReusableInput
+) : ExternalFile {
+    public override val formatName: String by lazy {
+        TODO()
+        /*
         val hex = input.asInput().use {
-            it.readBytes(8).toUHexString("")
+            //it.asInput().readBytes(8).toUHexString("")
+            TODO()
         }
-        return@lazy hex.detectFormatName()
+        return@lazy hex.detectFormatName() as String*/
     }
 
     init {
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LoginSolver.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LoginSolver.kt
index d422c7b8c..ec0265803 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LoginSolver.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LoginSolver.kt
@@ -11,36 +11,6 @@ package net.mamoe.mirai.utils
 
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.network.LoginFailedException
-import kotlin.reflect.KClass
-
-/**
- * This annotation indicates what exceptions should be declared by a function when compiled to a JVM method.
- *
- * Example:
- *
- * ```
- * @Throws(IOException::class)
- * fun readFile(name: String): String {...}
- * ```
- *
- * will be translated to
- *
- * ```
- * String readFile(String name) throws IOException {...}
- * ```
- *
- * @property exceptionClasses the list of checked exception classes that may be thrown by the function.
- */
-@Target(
-    AnnotationTarget.FUNCTION,
-    AnnotationTarget.PROPERTY_GETTER,
-    AnnotationTarget.PROPERTY_SETTER,
-    AnnotationTarget.CONSTRUCTOR
-)
-@Retention(AnnotationRetention.SOURCE)
-@OptIn(ExperimentalMultiplatform::class)
-@OptionalExpectation
-internal expect annotation class Throws(vararg val exceptionClasses: KClass<out Throwable>)
 
 /**
  * 验证码, 设备锁解决器
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/retryCatching.common.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/retryCatching.common.kt
index e1f294a3d..cefdb70d0 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/retryCatching.common.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/retryCatching.common.kt
@@ -11,8 +11,6 @@ package net.mamoe.mirai.utils.internal
 
 import kotlin.reflect.KClass
 
-internal expect fun Throwable.addSuppressedMirai(e: Throwable)
-
 
 // Currently we can't share internal code between modules.
 @Suppress("DuplicatedCode", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
@@ -33,7 +31,7 @@ internal inline fun <R> retryCatching(
             if (except?.isInstance(e) == true) {
                 return Result.failure(e)
             }
-            exception?.addSuppressedMirai(e)
+            exception?.addSuppressed(e)
             exception = e
         }
     }
diff --git a/mirai-serialization/build.gradle.kts b/mirai-serialization/build.gradle.kts
index 005ee5477..753965ff0 100644
--- a/mirai-serialization/build.gradle.kts
+++ b/mirai-serialization/build.gradle.kts
@@ -50,15 +50,11 @@ kotlin {
             languageSettings.useExperimentalAnnotation("kotlin.time.ExperimentalTime")
             languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
 
-            languageSettings.languageVersion = "1.3"
-            languageSettings.apiVersion = "1.3"
-
             languageSettings.progressiveMode = true
         }
 
         val commonMain by getting {
             dependencies {
-                api(kotlin("stdlib", Versions.Kotlin.stdlib))
                 api(project(":mirai-core"))
             }
         }
diff --git a/settings.gradle b/settings.gradle
index 6beed1398..2d0f24415 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -11,11 +11,13 @@ pluginManagement {
 
     repositories {
         mavenLocal()
+        gradlePluginPortal()
         jcenter()
         google()
         mavenCentral()
         maven { url "https://plugins.gradle.org/m2/" }
         maven { url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" }
+        maven { url "https://kotlin.bintray.com/kotlinx" }
     }
 }