From 26b5f3de081957cd38fe2c01b10d784310b7c08f Mon Sep 17 00:00:00 2001 From: purofle <3272912942@qq.com> Date: Thu, 20 Aug 2020 12:42:32 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9CHANGELOG.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 把arm改成amr --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f49ee1ea..3d7de24c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ## `1.2.0` 2020/8/19 ### 新特性 -- 初步语音支持: `Group.uploadVoice`, 支持 silk 或 arm 格式. +- 初步语音支持: `Group.uploadVoice`, 支持 silk 或 amr 格式. **注意**: 现阶段语音实现仅为临时方案, 在将来 (`2.0.0`) 一定会变动. 使用时请评估可能带来的不兼容性. - 新增将日志转换为 log4j, JDK Logger, SLF4J 等框架的方法: `LoggerAdapters` (#498 by [@Karlatemp](https://github.com/Karlatemp)) From 8e3fb15556c8afb217c709103ab788d1fbaa214b Mon Sep 17 00:00:00 2001 From: mzdluo123 Date: Fri, 21 Aug 2020 17:57:34 +0800 Subject: [PATCH 2/8] Fix receiving messages repeatedly --- .../network/protocol/data/proto/MsgSvc.kt | 2 +- .../chat/receive/MessageSvc.PbGetMsg.kt | 67 ++++++++++++++----- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt index 0f07c98a5..f357e0af6 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt @@ -19,7 +19,7 @@ internal class MsgSvc : ProtoBuf { @ProtoNumber(1) @JvmField val result: Int = 0, @ProtoNumber(2) @JvmField val errmsg: String = "", @ProtoNumber(3) @JvmField val syncCookie: ByteArray? = EMPTY_BYTE_ARRAY, - @ProtoNumber(4) @JvmField val syncFlag: SyncFlag, + @ProtoNumber(4) @JvmField val syncFlag: SyncFlag = SyncFlag.CONTINUE, @ProtoNumber(5) @JvmField val uinPairMsgs: List? = null, @ProtoNumber(6) @JvmField val bindUin: Long = 0L, @ProtoNumber(7) @JvmField val msgRspType: Int = 0, 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 41ace422f..6eed3e4c6 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 @@ -14,6 +14,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive import kotlinx.atomicfu.loop import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.* +import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact @@ -43,6 +44,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList +import net.mamoe.mirai.qqandroid.utils._miraiContentToString import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf import net.mamoe.mirai.qqandroid.utils.read @@ -56,6 +58,12 @@ import net.mamoe.mirai.utils.warning * 获取好友消息和消息记录 */ internal object MessageSvcPbGetMsg : OutgoingPacketFactory("MessageSvc.PbGetMsg") { + + + private val msgUidQueue = ArrayDeque() + private val msgUidSet = hashSetOf() + private val msgQueueMutex = Mutex() + @Suppress("SpellCheckingInspection") operator fun invoke( client: QQAndroidClient, @@ -114,8 +122,9 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory { + bot.client.c2cMessageSync.syncCookie = resp.syncCookie + bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie + } + 1 -> { + bot.client.c2cMessageSync.syncCookie = resp.syncCookie + } + 2 -> { + bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie + + } + } + +// bot.logger.debug(resp.msgRspType._miraiContentToString()) +// bot.logger.debug(resp.syncCookie._miraiContentToString()) - bot.client.c2cMessageSync.syncCookie = resp.syncCookie - bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie bot.client.c2cMessageSync.msgCtrlBuf = resp.msgCtrlBuf if (resp.uinPairMsgs == null) { @@ -151,10 +174,21 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory msg.msgHead.msgTime > it.lastReadTime.toLong() and 4294967295L } }.also { MessageSvcPbDeleteMsg.delete(bot, it) // 删除消息 - // todo 实现一个锁来防止重复收到消息 } .mapNotNull { msg -> + msgQueueMutex.lock() + val msgUid = msg.msgHead.msgUid + if (msgUidSet.size > 50) { + msgUidSet.remove(msgUidQueue.removeFirst()) + } + if (!msgUidSet.add(msgUid)) { + msgQueueMutex.unlock() + return@mapNotNull null + } + msgQueueMutex.unlock() + msgUidQueue.addLast(msgUid) + suspend fun createGroupForBot(groupUin: Long): Group? { val group = bot.getGroupByUinOrNull(groupUin) if (group != null) { @@ -294,18 +328,15 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory { // friend ptt @@ -387,7 +418,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory() } return @@ -398,7 +429,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory() } return From e56e4ec1db1c673ba057e07cbb7beaeef99c8e95 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Aug 2020 01:28:55 +0800 Subject: [PATCH 3/8] Fix LockFreeLinkedList.isEmpty, also fixes ContactList.isEmpty --- .../kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt | 2 +- .../net/mamoe/mirai/utils/LockFreeLinkedListTest.kt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt index de6182ae5..05d4d479c 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt @@ -844,7 +844,7 @@ internal open class LockFreeLinkedListNode( * [Tail], is not being tested. */ inline fun allMatching(condition: (LockFreeLinkedListNode) -> Boolean): Boolean = - this.childIterateReturnsLastSatisfying({ it.nextNode }, condition) !is Tail + this.childIterateReturnsLastSatisfying({ it.nextNode }, condition) is Tail /** * Stop on and returns the former element of the element that is [equals] to the [element] diff --git a/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt b/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt index bc5c52ac6..a439df16f 100644 --- a/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt +++ b/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt @@ -33,6 +33,14 @@ internal class LockFreeLinkedListTest { list.size shouldBeEqualTo 4 } + @Test + fun isEmpty() { + val list = LockFreeLinkedList() + assertTrue { list.isEmpty() } + list.addLast(1) + assertFalse { list.isEmpty() } + } + @Test fun addAndGetConcurrent() = runBlocking { //withContext(Dispatchers.Default){ From 146768ea103f4590fdd772572b9b3527d852b0c3 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Aug 2020 01:30:38 +0800 Subject: [PATCH 4/8] Fix exception message in PermissionDeniedException --- .../net/mamoe/mirai/qqandroid/contact/MemberImpl.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt index 53e7c17b7..ea8726168 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt @@ -180,7 +180,7 @@ internal class MemberImpl constructor( check(this.id != bot.id) { "A bot can't mute itself." } - checkBotPermissionHigherThanThis() + checkBotPermissionHigherThanThis("mute") bot.network.run { TroopManagement.Mute( client = bot.client, @@ -194,10 +194,10 @@ internal class MemberImpl constructor( net.mamoe.mirai.event.events.MemberMuteEvent(this@MemberImpl, durationSeconds, null).broadcast() } - private fun checkBotPermissionHigherThanThis() { + private fun checkBotPermissionHigherThanThis(operationName: String) { check(group.botPermission > this.permission) { throw PermissionDeniedException( - "`kick` operation requires bot to have a higher permission than the target member, " + + "`$operationName` operation requires bot to have a higher permission than the target member, " + "but bot's is ${group.botPermission}, target's is ${this.permission}" ) } @@ -205,7 +205,7 @@ internal class MemberImpl constructor( @JvmSynthetic override suspend fun unmute() { - checkBotPermissionHigherThanThis() + checkBotPermissionHigherThanThis("unmute") bot.network.run { TroopManagement.Mute( client = bot.client, @@ -222,7 +222,7 @@ internal class MemberImpl constructor( @JvmSynthetic override suspend fun kick(message: String) { - checkBotPermissionHigherThanThis() + checkBotPermissionHigherThanThis("kick") check(group.members.getOrNull(this.id) != null) { "Member ${this.id} had already been kicked from group ${group.id}" } From e7a1ee20e543476c328355c0c4230b51ec805cb0 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 22 Aug 2020 12:15:35 +0800 Subject: [PATCH 5/8] Semantic (#526) --- .../event/internal/InternalEventListeners.kt | 34 +++++++------- .../net.mamoe.mirai/event/subscriber.kt | 4 +- .../event/internal/GlobalEventListeners.kt | 30 +++++++++++++ .../event/internal/MiraiAtomicBoolean.kt | 45 ------------------- 4 files changed, 50 insertions(+), 63 deletions(-) create mode 100644 mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/GlobalEventListeners.kt diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt index 664110225..54d869940 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt @@ -26,7 +26,7 @@ import kotlin.reflect.KClass internal fun , E : Event> KClass.subscribeInternal(listener: L): L { with(GlobalEventListeners[listener.priority]) { @Suppress("UNCHECKED_CAST") - val node = ListenerNode(listener as Listener, this@subscribeInternal) + val node = ListenerRegistry(listener as Listener, this@subscribeInternal) addLast(node) listener.invokeOnCompletion { this.remove(node) @@ -107,13 +107,13 @@ internal class Handler internal constructor( } } -internal class ListenerNode( +internal class ListenerRegistry( val listener: Listener, - val owner: KClass + val type: KClass ) internal expect object GlobalEventListeners { - operator fun get(priority: Listener.EventPriority): LockFreeLinkedList + operator fun get(priority: Listener.EventPriority): LockFreeLinkedList } internal expect class MiraiAtomicBoolean(initial: Boolean) { @@ -135,50 +135,50 @@ internal suspend inline fun AbstractEvent.broadcastInternal() { internal suspend inline fun callAndRemoveIfRequired( event: E ) { - for (p in Listener.EventPriority.valuesExceptMonitor) { - GlobalEventListeners[p].forEachNode { eventNode -> + for (p in Listener.EventPriority.prioritiesExcludedMonitor) { + GlobalEventListeners[p].forEachNode { registeredRegistryNode -> if (event.isIntercepted) { return } - val node = eventNode.nodeValue - if (!node.owner.isInstance(event)) return@forEachNode - val listener = node.listener + val listenerRegistry = registeredRegistryNode.nodeValue + if (!listenerRegistry.type.isInstance(event)) return@forEachNode + val listener = listenerRegistry.listener when (listener.concurrencyKind) { Listener.ConcurrencyKind.LOCKED -> { (listener as Handler).lock!!.withLock { if (listener.onEvent(event) == ListeningStatus.STOPPED) { - removeNode(eventNode) + removeNode(registeredRegistryNode) } } } Listener.ConcurrencyKind.CONCURRENT -> { if (listener.onEvent(event) == ListeningStatus.STOPPED) { - removeNode(eventNode) + removeNode(registeredRegistryNode) } } } } } coroutineScope { - GlobalEventListeners[EventPriority.MONITOR].forEachNode { eventNode -> + GlobalEventListeners[EventPriority.MONITOR].forEachNode { registeredRegistryNode -> if (event.isIntercepted) { return@coroutineScope } - val node = eventNode.nodeValue - if (!node.owner.isInstance(event)) return@forEachNode - val listener = node.listener + val listenerRegistry = registeredRegistryNode.nodeValue + if (!listenerRegistry.type.isInstance(event)) return@forEachNode + val listener = listenerRegistry.listener launch { when (listener.concurrencyKind) { Listener.ConcurrencyKind.LOCKED -> { (listener as Handler).lock!!.withLock { if (listener.onEvent(event) == ListeningStatus.STOPPED) { - removeNode(eventNode) + removeNode(registeredRegistryNode) } } } Listener.ConcurrencyKind.CONCURRENT -> { if (listener.onEvent(event) == ListeningStatus.STOPPED) { - removeNode(eventNode) + removeNode(registeredRegistryNode) } } } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt index fd46a3582..8064800bd 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt @@ -110,7 +110,9 @@ public interface Listener : CompletableJob { internal companion object { @JvmStatic - internal val valuesExceptMonitor: Array = arrayOf(HIGHEST, HIGH, NORMAL, LOW, LOWEST) + internal val prioritiesExcludedMonitor: Array = run { + values().filter { it != MONITOR }.toTypedArray() + } } } diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/GlobalEventListeners.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/GlobalEventListeners.kt new file mode 100644 index 000000000..4b58df483 --- /dev/null +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/GlobalEventListeners.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.event.internal + +import net.mamoe.mirai.event.Listener +import net.mamoe.mirai.utils.LockFreeLinkedList +import java.util.* + + +internal actual object GlobalEventListeners { + private val ALL_LEVEL_REGISTRIES: Map> + + init { + val map = EnumMap>(Listener.EventPriority::class.java) + Listener.EventPriority.values().forEach { + map[it] = LockFreeLinkedList() + } + this.ALL_LEVEL_REGISTRIES = map + } + + actual operator fun get(priority: Listener.EventPriority): LockFreeLinkedList = ALL_LEVEL_REGISTRIES[priority]!! + +} diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt index a5bb1f3fe..0ed43c023 100644 --- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt @@ -9,16 +9,10 @@ package net.mamoe.mirai.event.internal -import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.Listener import net.mamoe.mirai.utils.LockFreeLinkedList -import net.mamoe.mirai.utils.LockFreeLinkedListNode -import net.mamoe.mirai.utils.isRemoved -import net.mamoe.mirai.utils.MiraiInternalAPI import java.util.* import java.util.concurrent.atomic.AtomicBoolean -import kotlin.reflect.KClass - internal actual class MiraiAtomicBoolean actual constructor(initial: Boolean) { private val delegate: AtomicBoolean = AtomicBoolean(initial) @@ -33,42 +27,3 @@ internal actual class MiraiAtomicBoolean actual constructor(initial: Boolean) { delegate.set(value) } } - -internal actual object GlobalEventListeners { - private val map: Map> - - init { - val map = EnumMap>(Listener.EventPriority::class.java) - Listener.EventPriority.values().forEach { - map[it] = LockFreeLinkedList() - } - this.map = map - } - - actual operator fun get(priority: Listener.EventPriority): LockFreeLinkedList = map[priority]!! - -} - -/* -internal actual class EventListeners actual constructor(clazz: KClass) : - LockFreeLinkedList>() { - @Suppress("UNCHECKED_CAST", "UNSUPPORTED", "NO_REFLECTION_IN_CLASS_PATH") - actual val supertypes: Set> by lazy { - val supertypes = mutableSetOf>() - - fun addSupertypes(klass: KClass) { - klass.supertypes.forEach { - val classifier = it.classifier as? KClass - if (classifier != null) { - supertypes.add(classifier) - addSupertypes(classifier) - } - } - } - addSupertypes(clazz) - - supertypes - } - -} - */ \ No newline at end of file From 44d90c703f53f8949e2c6ca9794fcc9c8f411ab1 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Aug 2020 12:56:41 +0800 Subject: [PATCH 6/8] Exclude kotlinx-coroutines-core and kotlin-stdlib from dependencies to avoid clashes (fix #523) --- mirai-core-qqandroid/build.gradle.kts | 38 ++++++++++------ mirai-core/build.gradle.kts | 62 ++++++++++++++------------- 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/mirai-core-qqandroid/build.gradle.kts b/mirai-core-qqandroid/build.gradle.kts index 46a8f1d57..637b3e190 100644 --- a/mirai-core-qqandroid/build.gradle.kts +++ b/mirai-core-qqandroid/build.gradle.kts @@ -60,14 +60,12 @@ kotlin { val commonMain by getting { dependencies { - api(kotlinx("serialization-core", Versions.Kotlin.serialization)) + api1(kotlinx("serialization-core", Versions.Kotlin.serialization)) api(kotlinx("coroutines-core", Versions.Kotlin.coroutines)) - implementation(kotlinx("serialization-protobuf", Versions.Kotlin.serialization)) - api("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}") - api(kotlinx("io", Versions.Kotlin.io)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } - implementation(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo)) + implementation1(kotlinx("serialization-protobuf", Versions.Kotlin.serialization)) + api1("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}") + api1(kotlinx("io", Versions.Kotlin.io)) + implementation1(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo)) } } @@ -97,11 +95,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("io-jvm", Versions.Kotlin.io)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } + api1(kotlinx("io-jvm", Versions.Kotlin.io)) // api(kotlinx("coroutines-debug", Versions.Kotlin.coroutines)) } } @@ -112,14 +107,29 @@ kotlin { implementation(kotlin("test", Versions.Kotlin.compiler)) implementation(kotlin("test-junit", Versions.Kotlin.compiler)) implementation("org.pcap4j:pcap4j-distribution:1.8.2") - - runtimeOnly(files("build/classes/kotlin/jvm/main")) // classpath is not properly set by IDE - runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE } } } } +fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) = + implementation(dependencyNotation) { + exclude("org.jetbrains.kotlin", "kotlin-stdlib") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata") + } + +fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNotation: String) = + api(dependencyNotation) { + exclude("org.jetbrains.kotlin", "kotlin-stdlib") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata") + } + apply(from = rootProject.file("gradle/publish.gradle")) diff --git a/mirai-core/build.gradle.kts b/mirai-core/build.gradle.kts index b0971340e..7efa4d7e7 100644 --- a/mirai-core/build.gradle.kts +++ b/mirai-core/build.gradle.kts @@ -63,21 +63,17 @@ kotlin { api(kotlin("serialization")) api(kotlin("reflect")) - api(kotlinx("serialization-core", Versions.Kotlin.serialization)) - implementation(kotlinx("serialization-protobuf", Versions.Kotlin.serialization)) - api(kotlinx("io", Versions.Kotlin.io)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } - api(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } + api1(kotlinx("serialization-core", Versions.Kotlin.serialization)) + implementation1(kotlinx("serialization-protobuf", Versions.Kotlin.serialization)) + api1(kotlinx("io", Versions.Kotlin.io)) + api1(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo)) api(kotlinx("coroutines-core", Versions.Kotlin.coroutines)) - implementation("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}") + implementation1("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}") - api(ktor("client-cio")) - api(ktor("client-core")) - api(ktor("network")) + api1(ktor("client-cio")) + api1(ktor("client-core")) + api1(ktor("network")) } } @@ -93,14 +89,10 @@ kotlin { dependencies { api(kotlin("reflect")) - api(kotlinx("io-jvm", Versions.Kotlin.io)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } - api(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } + api1(kotlinx("io-jvm", Versions.Kotlin.io)) + api1(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo)) - api(ktor("client-android", Versions.Kotlin.ktor)) + api1(ktor("client-android", Versions.Kotlin.ktor)) } } @@ -116,21 +108,13 @@ kotlin { val jvmMain by getting { dependencies { - //api(kotlin("stdlib-jdk8")) - //api(kotlin("stdlib-jdk7")) api(kotlin("reflect")) compileOnly("org.apache.logging.log4j:log4j-api:" + Versions.Logging.log4j) compileOnly("org.slf4j:slf4j-api:" + Versions.Logging.slf4j) - api(ktor("client-core-jvm", Versions.Kotlin.ktor)) - api(kotlinx("io-jvm", Versions.Kotlin.io)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } - api(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo)) { - exclude("org.jetbrains.kotlin", "kotlin-stdlib") - } - - runtimeOnly(files("build/classes/kotlin/jvm/main")) // classpath is not properly set by IDE + api1(ktor("client-core-jvm", Versions.Kotlin.ktor)) + api1(kotlinx("io-jvm", Versions.Kotlin.io)) + api1(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo)) } } @@ -146,6 +130,24 @@ kotlin { } } +fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) = + implementation(dependencyNotation) { + exclude("org.jetbrains.kotlin", "kotlin-stdlib") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata") + } + +fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNotation: String) = + api(dependencyNotation) { + exclude("org.jetbrains.kotlin", "kotlin-stdlib") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm") + exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata") + } + apply(from = rootProject.file("gradle/publish.gradle")) tasks.withType { From f107048944c1cf420b08878595c628004cb35bee Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Aug 2020 13:06:01 +0800 Subject: [PATCH 7/8] Update CONTRIBUTING.md --- CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abe4ae21f..b92b21c30 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,6 +8,12 @@ mirai 欢迎一切形式的代码贡献。你可以通过以下几种途径向 m **阅读文档**: [docs/mirai.md](docs/mirai.md) +### 构建 +- 要构建项目, 请运行 `gradlew assemble` +- 要运行测试, 请运行 `gradlew test` +- 要构建项目并运行测试, 请运行 `gradlew build` +- 若要添加一个 suspend 函数, 请务必考虑 Java 兼容性, 使用 [kotlin-jvm-blocking-bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge/blob/master/README-chs.md) + ### 能做什么? **请基于 `master` 分支进行文档修改; 基于 `dev` 分支进行其他修改 (否则你的修改可能被关闭或不会立即合并)** From 919c83a4c0dace7eab8fe501015c469867108194 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Aug 2020 14:02:39 +0800 Subject: [PATCH 8/8] 1.2.2 --- CHANGELOG.md | 3 +++ buildSrc/src/main/kotlin/Versions.kt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d7de24c0..4f4ccf6f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Version 1.x +## `1.2.2` 2020/8/22 +- 修复依赖冲突问题 (#523) + ## `1.2.1` 2020/8/19 - 修复在 Java 调用 `group.uploadImage` 时编译出错的问题 (#511) - 为 `group.uploadVoice` 添加 Java 方法 (需要 [kotlin-jvm-blocking-bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge)) (#512) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index f0a7dbb5d..90b01fd16 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -9,7 +9,7 @@ object Versions { object Mirai { - const val version = "1.2.1" + const val version = "1.2.2" } object Kotlin {