From f1a5bc05ea245e01937bd7ac5e077b730fe48f8c Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 31 Jan 2020 22:00:38 +0800 Subject: [PATCH 1/5] Add docs --- .../kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt | 2 ++ .../src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt index f1ff2c865..35042adef 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt @@ -49,6 +49,8 @@ abstract class BotNetworkHandler : CoroutineScope { /** * 初始化获取好友列表等值. + * + * 不要使用这个 API. 它会在登录完成后被自动调用. */ @MiraiInternalAPI open suspend fun init() { diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt index 0e37a2827..4796b2278 100644 --- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt @@ -20,7 +20,14 @@ internal val factory: BotFactory = run { No BotFactory found. Please ensure that you've added dependency of protocol modules. Available modules: - net.mamoe:mirai-core-timpc + - net.mamoe:mirai-core-qqandroid (recommended) You should have at lease one protocol module installed. + ------------------------------------------------------- + 找不到 BotFactory. 请确保你依赖了至少一个协议模块. + 可用的协议模块: + - net.mamoe:mirai-core-timpc + - net.mamoe:mirai-core-qqandroid (推荐) + 请添加上述任一模块的依赖(与 mirai-core 版本相同) """.trimIndent() ) From 6ef78118ad60607e444996e7fedf3fcd18341058 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 31 Jan 2020 23:10:31 +0800 Subject: [PATCH 2/5] Fix bugs --- .../network/QQAndroidBotNetworkHandler.kt | 97 ++++++++----------- .../network/protocol/data/jce/FriendList.kt | 2 +- .../protocol/packet/OutgoingPacketAndroid.kt | 1 - .../protocol/packet/login/LoginPacket.kt | 13 ++- .../network/TIMPCBotNetworkHandler.kt | 2 +- .../kotlin/net.mamoe.mirai/BotAccount.kt | 3 +- .../kotlin/net.mamoe.mirai/BotImpl.kt | 12 +-- .../network/BotNetworkHandler.kt | 8 +- 8 files changed, 59 insertions(+), 79 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt index 2b5b577ea..ae2921bb9 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt @@ -3,29 +3,29 @@ package net.mamoe.mirai.qqandroid.network import kotlinx.atomicfu.AtomicRef import kotlinx.atomicfu.atomic import kotlinx.coroutines.* +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.Input import kotlinx.io.core.buildPacket import kotlinx.io.core.use -import net.mamoe.mirai.contact.Contact -import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.data.MultiPacket import net.mamoe.mirai.data.Packet -import net.mamoe.mirai.event.BroadcastControllable -import net.mamoe.mirai.event.Cancellable -import net.mamoe.mirai.event.Subscribable -import net.mamoe.mirai.event.broadcast +import net.mamoe.mirai.event.* import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.QQImpl +import net.mamoe.mirai.qqandroid.event.ForceOfflineEvent import net.mamoe.mirai.qqandroid.event.PacketReceivedEvent import net.mamoe.mirai.qqandroid.network.protocol.packet.* import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc -import net.mamoe.mirai.utils.* -import net.mamoe.mirai.utils.cryptor.contentToString +import net.mamoe.mirai.utils.LockFreeLinkedList +import net.mamoe.mirai.utils.MiraiInternalAPI +import net.mamoe.mirai.utils.getValue import net.mamoe.mirai.utils.io.* +import net.mamoe.mirai.utils.unsafeWeakRef import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext @@ -41,14 +41,13 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler private lateinit var channel: PlatformSocket - override suspend fun login() { if (::channel.isInitialized) { channel.close() } channel = PlatformSocket() channel.connect("113.96.13.208", 8080) - launch(CoroutineName("Incoming Packet Receiver")) { processReceive() } + this.launch(CoroutineName("Incoming Packet Receiver")) { processReceive() } // bot.logger.info("Trying login") var response: LoginPacket.LoginPacketResponse = LoginPacket.SubCommand9(bot.client).sendAndExpect() @@ -104,27 +103,18 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler } override suspend fun init() { - //start updating friend/group list - bot.logger.info("Start updating friend/group list") - - /* - val data = FriendList.GetFriendGroupList( - bot.client, - 0, - 20, - 0, - 0 - ).sendAndExpect() - - - println(data.contentToString()) - */ + bot.logger.info("开始加载好友信息") + this@QQAndroidBotNetworkHandler.subscribeAlways { + if (this@QQAndroidBotNetworkHandler.bot == this.bot) { + close() + } + } /* * 开始加载Contact表 * */ var currentFriendCount = 0 - var totalFriendCount: Short = 0 + var totalFriendCount: Short while (true) { val data = FriendList.GetFriendGroupList( bot.client, @@ -134,14 +124,13 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler 0 ).sendAndExpect() totalFriendCount = data.totalFriendCount - bot.qqs.delegate.addAll( - data.friendList.map { - QQImpl(this@QQAndroidBotNetworkHandler.bot, EmptyCoroutineContext, it.friendUin!!).also { - currentFriendCount++ - } - } - ) - bot.logger.info("正在加载好友信息 ${currentFriendCount}/${totalFriendCount}") + data.friendList.forEach { + // atomic add + bot.qqs.delegate.addLast(QQImpl(bot, EmptyCoroutineContext, it.friendUin).also { + currentFriendCount++ + }) + } + bot.logger.verbose("正在加载好友信息 ${currentFriendCount}/${totalFriendCount}") if (currentFriendCount >= totalFriendCount) { break } @@ -155,22 +144,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler ).sendAndExpect(100000) println(data.contentToString()) */ - } - - /** - * 单线程处理包的接收, 分割和连接. - */ - @Suppress("PrivatePropertyName") - private val PacketReceiveDispatcher = newCoroutineDispatcher(1) - - /** - * 单线程处理包的解析 (协程挂起效率够) - */ - @Suppress("PrivatePropertyName") - private val PacketProcessDispatcher = newCoroutineDispatcher(1) - /** * 缓存超时处理的 [Job]. 超时后将清空缓存, 以免阻碍后续包的处理 */ @@ -185,12 +160,12 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler private var expectingRemainingLength: Long = 0 /** - * 在 [PacketProcessDispatcher] 调度器中解析包内容. + * 解析包内容. * * @param input 一个完整的包的内容, 去掉开头的 int 包长度 */ fun parsePacketAsync(input: Input): Job { - return this.launch(PacketProcessDispatcher) { + return this.launch { input.use { parsePacket(it) } } } @@ -337,28 +312,32 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler val rawInput = try { channel.read() } catch (e: ClosedChannelException) { - dispose() + close() bot.tryReinitializeNetworkHandler(e) return } catch (e: ReadPacketInternalException) { bot.logger.error("Socket channel read failed: ${e.message}") - dispose() + close() bot.tryReinitializeNetworkHandler(e) return } catch (e: CancellationException) { return } catch (e: Throwable) { bot.logger.error("Caught unexpected exceptions", e) - dispose() + close() bot.tryReinitializeNetworkHandler(e) return } - launch(context = PacketReceiveDispatcher + CoroutineName("Incoming Packet handler"), start = CoroutineStart.ATOMIC) { - processPacket(rawInput) + launch(CoroutineName("Incoming Packet handler"), start = CoroutineStart.ATOMIC) { + packetReceiveLock.withLock { + processPacket(rawInput) + } } } } + private val packetReceiveLock: Mutex = Mutex() + /** * 发送一个包, 并挂起直到接收到指定的返回包或超时(3000ms) */ @@ -381,7 +360,9 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler } private suspend inline fun OutgoingPacket.doSendAndReceive(timeoutMillis: Long = 3000, handler: PacketListener): E { - channel.send(delegate) + withContext(this@QQAndroidBotNetworkHandler.coroutineContext + CoroutineName("Packet sender")) { + channel.send(delegate) + } bot.logger.info("Send: ${this.commandName}") return withTimeoutOrNull(timeoutMillis) { @Suppress("UNCHECKED_CAST") @@ -403,11 +384,11 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler fun filter(commandName: String, sequenceId: Int) = this.commandName == commandName && this.sequenceId == sequenceId } - override fun dispose(cause: Throwable?) { + override fun close(cause: Throwable?) { if (::channel.isInitialized) { channel.close() } - super.dispose(cause) + super.close(cause) } override suspend fun awaitDisconnection() = supervisor.join() diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/FriendList.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/FriendList.kt index 1f979fc26..0e3529024 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/FriendList.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/FriendList.kt @@ -67,7 +67,7 @@ internal class FriendListSubSrvRspCode( @Serializable internal class FriendInfo( - @SerialId(0) val friendUin: Long? = 0, + @SerialId(0) val friendUin: Long, @SerialId(1) val groupId: Byte, @SerialId(2) val faceId: Short, @SerialId(3) val remark: String = "", diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/OutgoingPacketAndroid.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/OutgoingPacketAndroid.kt index f1b05fd0a..7eb5d35c1 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/OutgoingPacketAndroid.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/OutgoingPacketAndroid.kt @@ -16,7 +16,6 @@ import net.mamoe.mirai.utils.io.writeQQ * 待发送给服务器的数据包. 它代表着一个 [ByteReadPacket]. * 只有最终的包才会被包装为 [OutgoingPacket]. */ -@UseExperimental(ExperimentalUnsignedTypes::class) internal class OutgoingPacket constructor( name: String?, val commandName: String, diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt index 0ec5f14f2..7b031ecdd 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt @@ -12,7 +12,6 @@ import net.mamoe.mirai.qqandroid.utils.GuidSource import net.mamoe.mirai.qqandroid.utils.MacOrAndroidIdChangeFlag import net.mamoe.mirai.qqandroid.utils.guidFlag import net.mamoe.mirai.utils.* -import net.mamoe.mirai.utils.cryptor.contentToString import net.mamoe.mirai.utils.cryptor.decryptBy import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.discardExact @@ -317,13 +316,13 @@ internal object LoginPacket : PacketFactory("wt val subCommand = readUShort().toInt() - println("subCommand=$subCommand") + // println("subCommand=$subCommand") val type = readUByte() - println("type=$type") + // println("type=$type") discardExact(2) val tlvMap: TlvMap = this.readTLVMap() - tlvMap.printTLVMap() + // tlvMap.printTLVMap() return when (type.toInt()) { 0 -> onLoginSuccess(tlvMap, bot) 1, 15 -> onErrorMessage(tlvMap) @@ -340,7 +339,7 @@ internal object LoginPacket : PacketFactory("wt bot: QQAndroidBot ): LoginPacketResponse.DeviceLockLogin { bot.client.t104 = tlvMap.getOrFail(0x104) - println("403: " + tlvMap[0x403]?.toUHexString()) + // println("403: " + tlvMap[0x403]?.toUHexString()) return LoginPacketResponse.DeviceLockLogin(tlvMap[0x402]!!, tlvMap.getOrFail(0x403)) } @@ -392,10 +391,10 @@ internal object LoginPacket : PacketFactory("wt @UseExperimental(MiraiDebugAPI::class) private fun onLoginSuccess(tlvMap: TlvMap, bot: QQAndroidBot): LoginPacketResponse.Success { val client = bot.client - println("TLV KEYS: " + tlvMap.keys.joinToString { it.contentToString() }) + //println("TLV KEYS: " + tlvMap.keys.joinToString { it.contentToString() }) tlvMap[0x150]?.let { client.analysisTlv150(it) } - tlvMap[0x305]?.let { println("TLV 0x305=${it.toUHexString()}") } + // tlvMap[0x305]?.let { println("TLV 0x305=${it.toUHexString()}") } tlvMap[0x161]?.let { client.analysisTlv161(it) } tlvMap[0x119]?.let { t119Data -> t119Data.decryptBy(client.tgtgtKey).toReadPacket().debugPrint("0x119data").apply { diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt index b3140ee04..c4ec231f1 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt @@ -92,7 +92,7 @@ internal class TIMPCBotNetworkHandler internal constructor(coroutineContext: Cor } override fun dispose(cause: Throwable?) { - super.dispose(cause) + super.close(cause) this.heartbeatJob?.cancel(CancellationException("handler closed")) this.heartbeatJob = null diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt index 63cd58025..8b425a220 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt @@ -22,7 +22,8 @@ data class BotAccount( /** * 标记直接访问 [BotAccount.id], 而不是访问 [Bot.uin]. 这可能会不兼容未来的 API 修改. */ +@MiraiInternalAPI @Retention(AnnotationRetention.SOURCE) @Target(CLASS, TYPEALIAS, FUNCTION, PROPERTY, FIELD, CONSTRUCTOR) @Experimental(level = Experimental.Level.WARNING) -internal annotation class RawAccountIdUse \ No newline at end of file +annotation class RawAccountIdUse \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt index 6a6293f31..52973abbe 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt @@ -92,20 +92,20 @@ abstract class BotImpl constructor( try { if (::_network.isInitialized) { BotOfflineEvent(this).broadcast() - _network.dispose(cause) + _network.close(cause) } } catch (e: Exception) { logger.error("Cannot close network handler", e) } - _network = createNetworkHandler(this.coroutineContext) loginLoop@ while (true) { + _network = createNetworkHandler(this.coroutineContext) try { _network.login() break@loginLoop } catch (e: Exception) { e.logStacktrace() - _network.dispose(e) + _network.close(e) } logger.warning("Login failed. Retrying in 3s...") delay(3000) @@ -116,7 +116,7 @@ abstract class BotImpl constructor( return _network.init() } catch (e: Exception) { e.logStacktrace() - _network.dispose(e) + _network.close(e) } logger.warning("Init failed. Retrying in 3s...") delay(3000) @@ -130,12 +130,12 @@ abstract class BotImpl constructor( @UseExperimental(MiraiInternalAPI::class) override fun dispose(throwable: Throwable?) { if (throwable == null) { - network.dispose() + network.close() this.botJob.complete() groups.delegate.clear() qqs.delegate.clear() } else { - network.dispose(throwable) + network.close(throwable) this.botJob.completeExceptionally(throwable) groups.delegate.clear() qqs.delegate.clear() diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt index 35042adef..ee8d11a5a 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt @@ -24,7 +24,7 @@ import net.mamoe.mirai.utils.io.PlatformDatagramChannel * - Key 刷新 * - 所有数据包处理和发送 * - * [BotNetworkHandler.dispose] 时将会 [取消][Job.cancel] 所有此作用域下的协程 + * [BotNetworkHandler.close] 时将会 [取消][Job.cancel] 所有此作用域下的协程 */ @Suppress("PropertyName") abstract class BotNetworkHandler : CoroutineScope { @@ -64,12 +64,12 @@ abstract class BotNetworkHandler : CoroutineScope { /** * 关闭网络接口, 停止所有有关协程和任务 */ - open fun dispose(cause: Throwable? = null) { + open fun close(cause: Throwable? = null) { if (supervisor.isActive) { if (cause != null) { - supervisor.cancel(CancellationException("handler closed", cause)) + supervisor.cancel(CancellationException("NetworkHandler closed", cause)) } else { - supervisor.cancel() + supervisor.cancel(CancellationException("NetworkHandler closed")) } } } From 4c1b25d4bbbf09a4c6f26f17450469e7be86430e Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 31 Jan 2020 23:14:46 +0800 Subject: [PATCH 3/5] Remove print --- .../qqandroid/network/protocol/packet/login/LoginPacket.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt index 7b031ecdd..4f8cd20a5 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt @@ -306,7 +306,7 @@ internal object LoginPacket : PacketFactory("wt @InternalAPI @UseExperimental(MiraiDebugAPI::class) - override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): LoginPacketResponse = this.debugPrint("login解析").run { + override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): LoginPacketResponse { // 00 09 sub cmd // 00 type // 00 02 @@ -381,8 +381,7 @@ internal object LoginPacket : PacketFactory("wt data = imageData.readRemainingBytes().toIoBuffer(), sign = sign ) - } - else error("UNKNOWN CAPTCHA QUESTION: $question") + } else error("UNKNOWN CAPTCHA QUESTION: $question") } error("UNKNOWN CAPTCHA") @@ -397,7 +396,7 @@ internal object LoginPacket : PacketFactory("wt // tlvMap[0x305]?.let { println("TLV 0x305=${it.toUHexString()}") } tlvMap[0x161]?.let { client.analysisTlv161(it) } tlvMap[0x119]?.let { t119Data -> - t119Data.decryptBy(client.tgtgtKey).toReadPacket().debugPrint("0x119data").apply { + t119Data.decryptBy(client.tgtgtKey).read { discardExact(2) // always discarded. 00 1C // 00 1C // 01 08 00 10 A1 73 76 98 64 E0 38 C6 C8 18 73 FA D3 85 DA D6 01 6A 00 30 1D 99 4A 28 7E B3 B8 AC 74 B9 C4 BB 6D BB 41 72 F7 5C 9F 0F 79 8A 82 4F 1F 69 34 6D 10 D6 BB E8 A3 4A 2B 5D F1 C7 05 3C F8 72 EF CF 67 E4 3C 94 01 06 00 78 B4 ED 9F 44 ED 10 18 A8 85 0A 8A 85 79 45 47 7F 25 AA EE 2C 53 83 80 0A B3 B0 47 3E 95 51 A4 AE 3E CA A0 1D B4 91 F7 BB 2E 94 76 A8 C8 97 02 C4 5B 15 02 B7 03 9A FC C2 58 6D 17 92 46 AE EB 2F 6F 65 B8 69 6C D6 9D AC 18 6F 07 53 AC FE FA BC BD CE 57 13 10 2D 5A C6 50 AA C2 AE 18 D4 FD CD F2 E0 D1 25 29 56 21 35 8F 01 9D D6 69 44 8F 06 D0 23 26 D3 0E E6 E6 B7 01 0C 00 10 73 32 61 4E 2C 72 35 58 68 28 47 3E 2B 6E 52 62 01 0A 00 48 A4 DA 48 FB B4 8D DA 7B 86 D7 A7 FE 01 1B 70 6F 54 F8 55 38 B0 AD 1B 0C 0B B9 F6 94 24 F8 9E 30 32 22 99 0C 22 CD 44 B8 B0 8A A8 65 E1 B8 F0 49 EF E1 23 D7 0D A3 F1 BB 52 B7 4B AF BD 50 EA BF 15 02 78 2B 8B 10 FB 15 01 0D 00 10 29 75 38 72 21 5D 3F 24 37 46 67 79 2B 65 6D 34 01 14 00 60 00 01 5E 19 65 8C 00 58 93 DD 4D 2C 2D 01 44 99 62 B8 7A EF 04 C5 71 0B F1 BE 4C F4 21 F2 97 B0 14 67 0E 14 9F D8 A2 0B 93 40 90 80 F3 59 7A 69 45 D7 D4 53 4C 08 3A 56 1D C9 95 36 2C 7C 5E EE 36 47 5F AE 26 72 76 FD FD 69 E6 0C 2D 3A E8 CF D4 8D 76 C9 17 C3 E3 CD 21 AB 04 6B 70 C5 EC EC 01 0E 00 10 56 48 3E 29 3A 5A 21 74 55 6A 2C 72 58 73 79 71 01 03 00 30 9B A6 5D 85 5C 40 7C 28 E7 05 A9 25 CA F5 FC C0 51 40 85 F3 2F D2 37 F9 09 A6 E6 56 7F 7A 2E 7D 9F B9 1C 00 65 55 D2 A9 60 03 77 AB 6A F5 3F CE 01 33 00 30 F4 3A A7 08 E2 04 FA C8 9D 54 49 DE 63 EA F0 A5 1C C4 03 57 51 B6 AE 0B 55 41 F8 AB 22 F1 DC A3 B0 73 08 55 14 02 BF FF 55 87 42 4C 23 70 91 6A 01 34 00 10 61 C7 02 3F 1D BE A6 27 2F 24 D4 92 95 68 71 EF 05 28 00 1A 7B 22 51 49 4D 5F 69 6E 76 69 74 61 74 69 6F 6E 5F 62 69 74 22 3A 22 31 22 7D 03 22 00 10 CE 1E 2E DC 69 24 4F 9B FF 2F 52 D8 8F 69 DD 40 01 1D 00 76 5F 5E 10 E2 34 36 79 27 23 53 4D 65 6B 6A 33 6D 7D 4E 3C 5F 00 60 00 01 5E 19 65 8C 00 58 67 00 9C 02 E4 BC DB A3 93 98 A1 ED 4C 91 08 6F 0C 06 E0 12 6A DC 14 5B 4D 20 7C 82 83 AE 94 53 A2 4A A0 35 FF 59 9D F3 EF 82 42 61 67 2A 31 E7 87 7E 74 E7 A3 E7 5C A8 3C 87 CF 40 6A 9F E5 F7 20 4E 56 C6 4F 1C 98 3A 8B A9 4F 1D 10 35 C2 3B A1 08 7A 89 0B 25 0C 63 01 1F 00 0A 00 01 51 80 00 00 03 84 00 00 01 38 00 0E 00 00 00 01 01 0A 00 27 8D 00 00 00 00 00 01 1A 00 13 02 5B 06 01 0E 73 74 65 61 6D 63 68 69 6E 61 2E 66 75 6E 05 22 00 14 00 00 00 00 76 E4 B8 DD AB 53 02 9F 5E 19 65 8C 20 02 ED BD 05 37 00 17 01 01 00 00 00 00 76 E4 B8 DD 04 AB 53 02 9F 5E 19 65 8C 20 02 ED BD 01 20 00 0A 4D 39 50 57 50 6E 4C 31 65 4F 01 6D 00 2C 31 7A 50 7A 63 72 70 4D 30 43 6E 31 37 4C 32 32 6E 77 2D 36 7A 4E 71 48 48 59 41 35 48 71 77 41 37 6D 76 4F 63 2D 4A 56 77 47 51 5F 05 12 03 5D 00 0E 00 0A 74 65 6E 70 61 79 2E 63 6F 6D 00 2C 6E 4A 72 55 55 74 63 2A 34 7A 32 76 31 66 6A 75 77 6F 6A 65 73 72 76 4F 68 70 66 45 76 4A 75 55 4B 6D 34 43 2D 76 74 38 4D 77 38 5F 00 00 00 11 6F 70 65 6E 6D 6F 62 69 6C 65 2E 71 71 2E 63 6F 6D 00 2C 78 59 35 65 62 4D 74 48 44 6D 30 53 6F 68 56 71 68 33 43 79 79 34 6F 63 65 4A 46 6A 51 58 65 68 30 44 61 75 55 30 6C 78 65 52 6B 5F 00 00 00 0B 64 6F 63 73 2E 71 71 2E 63 6F 6D 00 2C 64 6A 62 79 47 57 45 4F 34 58 34 6A 36 4A 73 48 45 65 6B 73 69 74 72 78 79 62 57 69 77 49 68 46 45 70 72 4A 59 4F 2D 6B 36 47 6F 5F 00 00 00 0E 63 6F 6E 6E 65 63 74 2E 71 71 2E 63 6F 6D 00 2C 64 4C 31 41 79 32 41 31 74 33 58 36 58 58 2A 74 33 64 4E 70 2A 31 61 2D 50 7A 65 57 67 48 70 2D 65 47 78 6B 59 74 71 62 69 6C 55 5F 00 00 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 2C 75 6A 55 5A 4F 6A 4F 48 52 61 75 6B 32 55 50 38 77 33 34 68 36 69 46 38 2A 77 4E 50 35 2D 66 54 75 37 67 39 56 67 44 57 2A 6B 6F 5F 00 00 00 0A 76 69 70 2E 71 71 2E 63 6F 6D 00 2C 37 47 31 44 6F 54 2D 4D 57 50 63 2D 62 43 46 68 63 62 32 56 38 6E 77 4A 75 41 51 63 54 39 77 45 49 62 57 43 4A 4B 44 4D 6C 6D 34 5F 00 00 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 2C 7A 73 70 5A 56 43 59 45 7A 35 2A 4F 6B 4E 68 6E 74 79 61 69 6E 6F 68 4D 32 6B 41 6C 2A 74 31 63 7A 48 57 77 30 41 6A 4B 50 4B 6B 5F 00 00 00 0B 67 61 6D 65 2E 71 71 2E 63 6F 6D 00 2C 32 6F 2D 51 53 36 65 43 70 37 6A 43 4E 34 6A 74 6E 47 4F 4B 33 67 73 32 63 4A 6F 56 71 58 65 44 48 61 55 39 65 34 2D 32 34 64 30 5F 00 00 00 0C 71 71 77 65 62 2E 71 71 2E 63 6F 6D 00 2C 63 54 4D 79 64 51 43 35 50 74 43 45 51 72 6F 33 53 54 41 66 7A 56 2D 44 76 46 56 35 58 6D 56 6B 49 31 68 4C 55 48 4E 65 76 56 38 5F 00 00 00 0D 6F 66 66 69 63 65 2E 71 71 2E 63 6F 6D 00 2C 6F 73 72 54 36 32 69 37 66 76 6D 49 50 64 6F 58 4B 48 74 38 58 52 59 56 77 72 7A 6E 69 31 58 7A 57 4C 77 2A 71 36 33 44 74 73 6F 5F 00 00 00 09 74 69 2E 71 71 2E 63 6F 6D 00 2C 41 61 77 4D 78 4D 32 79 58 51 47 75 72 75 55 6C 66 53 58 79 5A 57 48 53 78 52 57 58 50 74 6B 6B 4F 78 6F 66 4A 59 47 6C 71 68 34 5F 00 00 00 0B 6D 61 69 6C 2E 71 71 2E 63 6F 6D 00 2C 67 72 57 68 58 77 34 4C 6E 4B 49 4F 67 63 78 45 71 70 33 61 45 67 37 38 46 7A 77 4E 6D 4B 48 56 6E 6F 50 4C 4F 32 6D 57 6D 6E 38 5F 00 00 00 09 71 7A 6F 6E 65 2E 63 6F 6D 00 2C 72 61 47 79 51 35 54 72 4D 55 7A 6E 74 31 4E 52 44 2D 50 72 74 72 41 55 43 35 6A 61 2D 49 47 2D 73 77 4C 6D 49 51 51 41 44 4C 41 5F 00 00 00 0A 6D 6D 61 2E 71 71 2E 63 6F 6D 00 2C 39 73 2D 4F 51 30 67 76 39 42 6A 37 58 71 52 49 4E 30 35 46 32 64 4D 47 67 47 43 58 57 4A 62 68 63 30 38 63 7A 4B 52 76 6B 78 6B 5F 00 00 03 05 00 10 77 75 6E 54 5F 7E 66 7A 72 40 3C 6E 35 50 53 46 01 43 00 40 3A AE 30 87 81 3D EE BA 31 9C EA 9D 0D D4 73 B1 81 12 E0 94 71 73 7A B0 47 3D 09 47 E5 1B E1 E2 06 1A CB A4 E3 71 9E A6 EA 2A 73 5C C8 D3 B1 2A B1 C7 DA 04 A6 6D 12 26 DF 6B 8B EC C7 12 F8 E1 01 18 00 05 00 00 00 01 00 01 63 00 10 67 6B 60 23 24 6A 55 39 4E 58 24 5E 39 2B 7A 69 01 38 00 5E 00 00 00 09 01 06 00 27 8D 00 00 00 00 00 01 0A 00 24 EA 00 00 00 00 00 01 1C 00 1A 5E 00 00 00 00 00 01 02 00 01 51 80 00 00 00 00 01 03 00 00 1C 20 00 00 00 00 01 20 00 01 51 80 00 00 00 00 01 36 00 1B AF 80 00 00 00 00 01 43 00 1B AF 80 00 00 00 00 01 64 00 1B AF 80 00 00 00 00 01 30 00 0E 00 00 5E 19 65 8C 9F 02 53 AB 00 00 00 00 From aa0bf81af10da1fd1d653b58d32ce5612bff286a Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 31 Jan 2020 23:33:03 +0800 Subject: [PATCH 4/5] Add init retry --- .../network/QQAndroidBotNetworkHandler.kt | 3 --- .../packet/chat/receive/MessageSvc.kt | 6 +++-- .../kotlin/net.mamoe.mirai/BotImpl.kt | 25 +++++++++++-------- .../network/BotNetworkHandler.kt | 5 ++++ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt index ae2921bb9..86c6048f3 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt @@ -312,19 +312,16 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler val rawInput = try { channel.read() } catch (e: ClosedChannelException) { - close() bot.tryReinitializeNetworkHandler(e) return } catch (e: ReadPacketInternalException) { bot.logger.error("Socket channel read failed: ${e.message}") - close() bot.tryReinitializeNetworkHandler(e) return } catch (e: CancellationException) { return } catch (e: Throwable) { bot.logger.error("Caught unexpected exceptions", e) - close() bot.tryReinitializeNetworkHandler(e) return } diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt index 875858b11..b34eaf445 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt @@ -25,6 +25,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket import net.mamoe.mirai.qqandroid.utils.toMessageChain import net.mamoe.mirai.qqandroid.utils.toRichTextElems import net.mamoe.mirai.utils.cryptor.contentToString +import net.mamoe.mirai.utils.currentTimeSeconds import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.toReadPacket import kotlin.math.absoluteValue @@ -162,8 +163,9 @@ internal class MessageSvc { ) ), msgSeq = client.atomicNextMessageSequenceId(), - msgRand = Random.nextInt().absoluteValue - // syncCookie = client.c2cMessageSync.syncCookie.takeIf { it.isNotEmpty() } ?: "08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00".hexToBytes(), + msgRand = Random.nextInt().absoluteValue, + syncCookie = client.c2cMessageSync.syncCookie?.takeIf { it.isNotEmpty() } + ?: SyncCookie(currentTimeSeconds).toByteArray(SyncCookie.serializer()) // msgVia = 1 ) ) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt index 52973abbe..b05997de8 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.* import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.events.BotOfflineEvent import net.mamoe.mirai.network.BotNetworkHandler +import net.mamoe.mirai.network.closeAndJoin import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.io.logStacktrace import kotlin.coroutines.CoroutineContext @@ -92,7 +93,7 @@ abstract class BotImpl constructor( try { if (::_network.isInitialized) { BotOfflineEvent(this).broadcast() - _network.close(cause) + _network.closeAndJoin(cause) } } catch (e: Exception) { logger.error("Cannot close network handler", e) @@ -105,22 +106,26 @@ abstract class BotImpl constructor( break@loginLoop } catch (e: Exception) { e.logStacktrace() - _network.close(e) + _network.closeAndJoin(e) } logger.warning("Login failed. Retrying in 3s...") delay(3000) } - while (true) { - try { - return _network.init() - } catch (e: Exception) { - e.logStacktrace() - _network.close(e) + repeat(1) block@{ + repeat(2) { + try { + _network.init() + return@block + } catch (e: Exception) { + e.logStacktrace() + } + logger.warning("Init failed. Retrying in 3s...") + delay(3000) } - logger.warning("Init failed. Retrying in 3s...") - delay(3000) + logger.error("cannot init. some features may be affected") } + } protected abstract fun createNetworkHandler(coroutineContext: CoroutineContext): N diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt index ee8d11a5a..5ba71e7b5 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt @@ -73,4 +73,9 @@ abstract class BotNetworkHandler : CoroutineScope { } } } +} + +suspend fun BotNetworkHandler.closeAndJoin(cause: Throwable? = null){ + this.close(cause) + this.supervisor.join() } \ No newline at end of file From df56c86fca1dc006fa7ac5937d818d1cc2fdfabe Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 1 Feb 2020 00:58:23 +0800 Subject: [PATCH 5/5] Fix build --- .../mirai/qqandroid/utils/SystemDeviceInfo.kt | 1 + .../network/protocol/data/proto/SyncCookie.kt | 2 +- .../packet/chat/receive/MessageSvc.kt | 5 ++-- .../kotlin/net.mamoe.mirai.timpc/TIMPC.kt | 8 ++++++- .../network/TIMPCBotNetworkHandler.kt | 3 ++- .../kotlin/net/mamoe/mirai/BotFactoryJvm.kt | 16 ++++++++++++- .../java/demo/subscribe/SubscribeSamples.kt | 8 +++---- .../net/mamoe/mirai/demo/MiraiService.kt | 1 + .../src/main/kotlin/demo/gentleman/Main.kt | 23 ++++--------------- 9 files changed, 37 insertions(+), 30 deletions(-) diff --git a/mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/utils/SystemDeviceInfo.kt b/mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/utils/SystemDeviceInfo.kt index c9936f510..fd14c7c7c 100644 --- a/mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/utils/SystemDeviceInfo.kt +++ b/mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/utils/SystemDeviceInfo.kt @@ -5,6 +5,7 @@ import android.net.wifi.WifiManager import android.os.Build import android.telephony.TelephonyManager import kotlinx.io.core.toByteArray +import net.mamoe.mirai.utils.Context import net.mamoe.mirai.utils.localIpAddress import net.mamoe.mirai.utils.md5 import java.io.File diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/SyncCookie.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/SyncCookie.kt index 149e1bf62..77017e058 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/SyncCookie.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/SyncCookie.kt @@ -11,6 +11,6 @@ class SyncCookie( @SerialId(4) val unknown2: Long = 3497826378, @SerialId(5) val const1: Long = 1680172298, @SerialId(6) val const2: Long = 2424173273, - @SerialId(7) val unknown3: Long = 83, + @SerialId(7) val unknown3: Long = 0, @SerialId(8) val unknown4: Long = 0 ) : ProtoBuf \ No newline at end of file diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt index b34eaf445..5a9906d45 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt @@ -27,7 +27,6 @@ import net.mamoe.mirai.qqandroid.utils.toRichTextElems import net.mamoe.mirai.utils.cryptor.contentToString import net.mamoe.mirai.utils.currentTimeSeconds import net.mamoe.mirai.utils.io.hexToBytes -import net.mamoe.mirai.utils.io.toReadPacket import kotlin.math.absoluteValue import kotlin.random.Random @@ -61,8 +60,8 @@ internal class MessageSvc { client: QQAndroidClient, msgTime: Long //PbPushMsg.msg.msgHead.msgTime ): OutgoingPacket = buildOutgoingUniPacket( - client, - extraData = EXTRA_DATA.toReadPacket() + client//, + // extraData = EXTRA_DATA.toReadPacket() ) { writeProtoBuf( MsgSvc.PbGetMsgReq.serializer(), diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPC.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPC.kt index b8060c3ff..c24a4d49f 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPC.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPC.kt @@ -24,4 +24,10 @@ object TIMPC : BotFactory { * 使用指定的 [配置][configuration] 构造 [Bot] 实例 */ fun Bot(qq: Long, password: String, configuration: BotConfiguration = BotConfiguration.Default): Bot = TIMPCBot(BotAccount(qq, password), configuration) -} \ No newline at end of file +} + +/** + * 使用指定的 [配置][configuration] 构造 [Bot] 实例 + */ +inline fun TIMPC.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-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt index c4ec231f1..933e96dd1 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMPCBotNetworkHandler.kt @@ -91,7 +91,7 @@ internal class TIMPCBotNetworkHandler internal constructor(coroutineContext: Cor heartbeatJob?.join() } - override fun dispose(cause: Throwable?) { + override fun close(cause: Throwable?) { super.close(cause) this.heartbeatJob?.cancel(CancellationException("handler closed")) @@ -312,6 +312,7 @@ internal class TIMPCBotNetworkHandler internal constructor(coroutineContext: Cor else -> error("No decrypter is found") } as? D ?: error("Internal error: could not cast decrypter which is found for factory to class Decrypter") + @UseExperimental(MiraiInternalAPI::class) suspend fun onPacketReceived(packet: Any) {//complex function, but it doesn't matter when (packet) { is TouchPacket.TouchResponse.OK -> { diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt index 4796b2278..588ee8ea1 100644 --- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotFactoryJvm.kt @@ -4,6 +4,7 @@ package net.mamoe.mirai import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.Context +import net.mamoe.mirai.utils.ContextImpl // Do not use ServiceLoader. Probably not working on MPP @PublishedApi @@ -41,4 +42,17 @@ fun Bot(context: Context, qq: Long, password: String, configuration: BotConfigur * 加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例 */ inline fun Bot(context: Context, qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot = - factory.Bot(context, qq, password, configuration) \ No newline at end of file + factory.Bot(context, qq, password, configuration) + + +/** + * 加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例 + */ +fun Bot(qq: Long, password: String, configuration: BotConfiguration = BotConfiguration.Default): Bot = + factory.Bot(ContextImpl(), qq, password, configuration) + +/** + * 加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例 + */ +inline fun Bot(qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot = + factory.Bot(ContextImpl(), qq, password, configuration) \ No newline at end of file diff --git a/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt b/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt index e1f898ce4..c86a43c3e 100644 --- a/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt +++ b/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt @@ -17,6 +17,7 @@ import net.mamoe.mirai.message.data.ImageId import net.mamoe.mirai.message.data.PlainText import net.mamoe.mirai.message.data.firstOrNull import net.mamoe.mirai.message.sendAsImageTo +import net.mamoe.mirai.timpc.Bot import net.mamoe.mirai.timpc.TIMPC import net.mamoe.mirai.utils.suspendToExternalImage import java.io.File @@ -39,10 +40,8 @@ private fun readTestAccount(): BotAccount? { @Suppress("UNUSED_VARIABLE") suspend fun main() { val bot = TIMPC.Bot( // JVM 下也可以不写 `TIMPC.` 引用顶层函数 - readTestAccount() ?: BotAccount(//填写你的账号 - id = 1994701121, - passwordPlainText = "123456" - ) + 1994701121, + "123456" ) { // 覆盖默认的配置 randomDeviceName = false @@ -134,6 +133,7 @@ fun Bot.messageDSL() { reply(message) } + listener.complete() // 停止监听 // 自定义的 filter, filter 中 it 为转为 String 的消息. // 也可以用任何能在处理时使用的变量, 如 subject, sender, message diff --git a/mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt b/mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt index 1492693fe..1297be2f9 100644 --- a/mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt +++ b/mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt @@ -14,6 +14,7 @@ import kotlinx.io.core.IoBuffer import kotlinx.io.core.readBytes import net.mamoe.mirai.Bot import net.mamoe.mirai.event.subscribeMessages +import net.mamoe.mirai.timpc.Bot import net.mamoe.mirai.timpc.TIMPC import net.mamoe.mirai.utils.LoginFailedException import net.mamoe.mirai.utils.LoginSolver diff --git a/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt b/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt index 98cf4a85a..06455d10f 100644 --- a/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt +++ b/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt @@ -8,7 +8,6 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import net.mamoe.mirai.Bot -import net.mamoe.mirai.BotAccount import net.mamoe.mirai.alsoLogin import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.event.Subscribable @@ -23,32 +22,18 @@ import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.buildXMLMessage import net.mamoe.mirai.message.data.getValue import net.mamoe.mirai.message.sendAsImageTo +import net.mamoe.mirai.utils.ContextImpl import java.io.File import java.util.* import javax.swing.filechooser.FileSystemView import kotlin.random.Random -private fun readTestAccount(): BotAccount? { - val file = File("testAccount.txt") - if (!file.exists() || !file.canRead()) { - return null - } - - val lines = file.readLines() - return try { - BotAccount(lines[0].toLong(), lines[1]) - } catch (e: Throwable) { - null - } -} - @Suppress("UNUSED_VARIABLE") suspend fun main() { val bot = Bot( - readTestAccount() ?: BotAccount( - id = 913366033, - passwordPlainText = "a18260132383" - ) + ContextImpl(), + 913366033, + "a18260132383" ) { // override config here. }.alsoLogin()