Implement multiplatform modules

This commit is contained in:
Him188 2022-05-18 20:54:47 +01:00
parent ce87400998
commit ff2a8acb0c
555 changed files with 10181 additions and 3918 deletions

View File

@ -16,15 +16,10 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPI
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
/* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
* Copyright 2019-2022 Mamoe Technologies and contributors. import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
* import java.io.File
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
private val miraiPlatform = Attribute.of( private val miraiPlatform = Attribute.of(
"net.mamoe.mirai.platform", "net.mamoe.mirai.platform",
@ -35,6 +30,9 @@ private val miraiPlatform = Attribute.of(
fun Project.configureHMPPJvm() { fun Project.configureHMPPJvm() {
extensions.getByType(KotlinMultiplatformExtension::class.java).apply { extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
jvm("jvmBase") { jvm("jvmBase") {
compilations.all {
this.compileKotlinTask.enabled = false // IDE complain
}
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) // avoid resolving by others attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) // avoid resolving by others
// attributes.attribute(miraiPlatform, "jvmBase") // attributes.attribute(miraiPlatform, "jvmBase")
} }
@ -57,16 +55,18 @@ fun Project.configureHMPPJvm() {
val nativeMainSets = mutableListOf<KotlinSourceSet>() val nativeMainSets = mutableListOf<KotlinSourceSet>()
val nativeTestSets = mutableListOf<KotlinSourceSet>() val nativeTestSets = mutableListOf<KotlinSourceSet>()
val nativeTargets = mutableListOf<KotlinNativeTarget>()
if (ideaActive) { if (ideaActive) {
when { val target = when {
Os.isFamily(Os.FAMILY_MAC) -> if (Os.isArch("aarch64")) macosArm64("native") else macosX64("native") Os.isFamily(Os.FAMILY_MAC) -> if (Os.isArch("aarch64")) macosArm64("native") else macosX64("native")
Os.isFamily(Os.FAMILY_WINDOWS) -> mingwX64("native") Os.isFamily(Os.FAMILY_WINDOWS) -> mingwX64("native")
else -> linuxX64("native") else -> linuxX64("native")
} }
nativeTargets.add(target)
} else { } else {
// 1.6.0 // 1.6.0
val nativeTargets: List<String> = arrayOf( val nativeTargetNames: List<String> = arrayOf(
// serialization doesn't support those commented targets // serialization doesn't support those commented targets
// "androidNativeArm32, androidNativeArm64, androidNativeX86, androidNativeX64", // "androidNativeArm32, androidNativeArm64, androidNativeX86, androidNativeX64",
"iosArm32, iosArm64, iosX64, iosSimulatorArm64", "iosArm32, iosArm64, iosX64, iosSimulatorArm64",
@ -77,11 +77,12 @@ fun Project.configureHMPPJvm() {
"mingwX64", "mingwX64",
// "wasm32" // linuxArm32Hfp, mingwX86 // "wasm32" // linuxArm32Hfp, mingwX86
).flatMap { it.split(",") }.map { it.trim() } ).flatMap { it.split(",") }.map { it.trim() }
presets.filter { it.name in nativeTargets } presets.filter { it.name in nativeTargetNames }
.forEach { preset -> .forEach { preset ->
val target = targetFromPreset(preset, preset.name) val target = targetFromPreset(preset, preset.name) as KotlinNativeTarget
nativeMainSets.add(target.compilations[MAIN_COMPILATION_NAME].kotlinSourceSets.first()) nativeMainSets.add(target.compilations[MAIN_COMPILATION_NAME].kotlinSourceSets.first())
nativeTestSets.add(target.compilations[TEST_COMPILATION_NAME].kotlinSourceSets.first()) nativeTestSets.add(target.compilations[TEST_COMPILATION_NAME].kotlinSourceSets.first())
nativeTargets.add(target)
} }
if (!ideaActive) { if (!ideaActive) {
@ -95,31 +96,8 @@ fun Project.configureHMPPJvm() {
} }
} }
// nativeTarget.apply { configureNativeInterop("main", projectDir.resolve("src/nativeMainInterop"), nativeTargets)
// val myrust by compilations.getByName("main").cinterops.creating { configureNativeInterop("test", projectDir.resolve("src/nativeTestInterop"), nativeTargets)
// headers(project.projectDir.resolve("untitled/myrust.h"))
// }
//
// binaries {
// sharedLib {
// linkerOpts("-v")
// linkerOpts("-L${project.projectDir.resolve("untitled/target/debug/").absolutePath}")
//// linkerOpts("-lmyrust")
// linkerOpts("-Wl,-undefined,dynamic_lookup") // resolve symbols in runtime
// baseName = "mykotlin"
// }
//
// executable {
//
// linkerOpts("-v")
// linkerOpts("-L${project.projectDir.resolve("untitled/target/debug/").absolutePath}")
//// linkerOpts("-lmyrust")
// linkerOpts("-Wl,-undefined,dynamic_lookup") // resolve symbols in runtime
// baseName = "KotlinExecutable"
// entryPoint = "main.main"
// }
// }
// }
val sourceSets = kotlinSourceSets.orEmpty() val sourceSets = kotlinSourceSets.orEmpty()
@ -143,9 +121,181 @@ fun Project.configureHMPPJvm() {
androidMain.dependsOn(jvmBaseMain) androidMain.dependsOn(jvmBaseMain)
jvmTest.dependsOn(jvmBaseTest) jvmTest.dependsOn(jvmBaseTest)
androidTest.dependsOn(commonTest) androidTest.dependsOn(jvmBaseTest)
nativeMain.dependsOn(commonMain) nativeMain.dependsOn(commonMain)
nativeTest.dependsOn(commonTest) nativeTest.dependsOn(commonTest)
} }
}
private fun Project.linkerDirs(): List<String> {
return listOf(
":mirai-core",
":mirai-core-api",
":mirai-core-utils",
).map {
rootProject.project(it).projectDir.resolve("src/nativeMainInterop/target/debug/").absolutePath
}
}
private fun Project.includeDirs(): List<String> {
return listOf(
":mirai-core",
":mirai-core-api",
":mirai-core-utils",
).map {
rootProject.project(it).projectDir.resolve("src/nativeMainInterop/").absolutePath
}
}
private fun Project.configureNativeInterop(
compilationName: String,
nativeInteropDir: File,
nativeTargets: MutableList<KotlinNativeTarget>
) {
val crateName = project.name.replace("-", "_") + "_i"
configure(nativeTargets) {
binaries {
for (buildType in NativeBuildType.values()) {
findTest(buildType)?.apply {
linkerOpts("-v")
linkerOpts(*linkerDirs().map { "-L$it" }.toTypedArray())
linkerOpts("-undefined", "dynamic_lookup") // resolve symbol in runtime
}
}
}
}
if (nativeInteropDir.exists() && nativeInteropDir.isDirectory && nativeInteropDir.resolve("build.rs").exists()) {
val kotlinDylibName = project.name.replace("-", "_") + "_i"
val kotlinDylibName = project.name.replace("-", "_")
val headerName = "$crateName.h"
val rustLibDir = nativeInteropDir.resolve("target/debug/")
var interopTaskName = ""
configure(nativeTargets) {
interopTaskName = compilations.getByName(compilationName).cinterops.create(compilationName) {
defFile(nativeInteropDir.resolve("interop.def"))
val headerFile = nativeInteropDir.resolve(headerName)
if (headerFile.exists()) headers(headerFile)
}.interopProcessingTaskName
binaries {
sharedLib {
linkerOpts("-v")
linkerOpts("-L${rustLibDir.absolutePath.replace("\\", "/")}")
// linkerOpts("-lmirai_core_utils_i")
linkerOpts("-undefined", "dynamic_lookup")
baseName = project.name
}
getTest(NativeBuildType.DEBUG).apply {
linkerOpts("-v")
linkerOpts("-L${rustLibDir.absolutePath.replace("\\", "/")}")
linkerOpts("-lmirai_core_utils_i")
// linkerOpts("-undefined", "dynamic_lookup")
}
}
}
val cbindgen = tasks.register("cbindgen${compilationName.titlecase()}") {
group = "mirai"
description = "Generate C Headers from Rust"
inputs.files(
project.objects.fileTree().from(nativeInteropDir.resolve("src"))
.filterNot { it.name == "bindings.rs" }
)
outputs.file(nativeInteropDir.resolve(headerName))
doLast {
exec {
workingDir(nativeInteropDir)
commandLine(
"cbindgen",
"--config", "cbindgen.toml",
"--crate", crateName,
"--output", headerName
)
}
}
}
val generateRustBindings = tasks.register("generateRustBindings${compilationName.titlecase()}") {
group = "mirai"
description = "Generates Rust bindings for Kotlin"
dependsOn(cbindgen)
}
afterEvaluate {
val cinteropTask = tasks.getByName(interopTaskName)
cinteropTask.mustRunAfter(cbindgen)
generateRustBindings.get().dependsOn(cinteropTask)
}
val bindgen = tasks.register("bindgen${compilationName.titlecase()}") {
group = "mirai"
val bindingsPath = nativeInteropDir.resolve("src/bindings.rs")
val headerFile = buildDir.resolve("bin/native/debugShared/lib${kotlinDylibName}_api.h")
inputs.files(headerFile)
outputs.file(bindingsPath)
mustRunAfter(tasks.findByName("linkDebugSharedNative"))
doLast {
exec {
workingDir(nativeInteropDir)
// bindgen input.h -o bindings.rs
commandLine(
"bindgen",
headerFile,
"-o", bindingsPath,
)
}
}
}
val generateKotlinBindings = tasks.register("generateKotlinBindings${compilationName.titlecase()}") {
group = "mirai"
description = "Generates Kotlin bindings for Rust"
dependsOn(bindgen)
dependsOn(tasks.findByName("linkDebugSharedNative"))
}
var targetCompilation: KotlinNativeCompilation? = null
configure(nativeTargets) {
val compilations = compilations.filter { nativeInteropDir.name.contains(it.name, ignoreCase = true) }
check(compilations.isNotEmpty()) { "Should be at lease one corresponding native compilation, but found 0" }
targetCompilation = compilations.single()
// targetCompilation!!.compileKotlinTask.dependsOn(cbindgen)
// tasks.getByName("cinteropNative$name").dependsOn(cbindgen)
}
targetCompilation!!
val compileRust = tasks.register("compileRust${compilationName.titlecase()}") {
group = "mirai"
inputs.files(nativeInteropDir.resolve("src"))
outputs.file(rustLibDir.resolve("lib$crateName.dylib"))
// dependsOn(targetCompilation!!.compileKotlinTask)
dependsOn(bindgen)
dependsOn(tasks.findByName("linkDebugSharedNative")) // dylib to link
doLast {
exec {
workingDir(nativeInteropDir)
commandLine(
"cargo",
"build",
"--color", "always",
"--all",
// "--", "--color", "always", "2>&1"
)
}
}
}
tasks.getByName("assemble").dependsOn(compileRust)
}
}
fun String.titlecase(): String {
if (this.isEmpty()) return this
val c = get(0)
return replaceFirst(c, Character.toTitleCase(c))
} }

View File

@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
fun Project.useIr() { fun Project.useIr() {
@ -41,7 +42,6 @@ fun Project.preConfigureJvmTarget() {
val defaultVer = jvmVersion() val defaultVer = jvmVersion()
tasks.withType(KotlinJvmCompile::class.java) { tasks.withType(KotlinJvmCompile::class.java) {
kotlinOptions.languageVersion = "1.6"
kotlinOptions.jvmTarget = defaultVer.toString() kotlinOptions.jvmTarget = defaultVer.toString()
kotlinOptions.freeCompilerArgs += "-Xjvm-default=all" kotlinOptions.freeCompilerArgs += "-Xjvm-default=all"
@ -61,8 +61,8 @@ fun Project.preConfigureJvmTarget() {
fun Project.configureJvmTarget() { fun Project.configureJvmTarget() {
val defaultVer = jvmVersion() val defaultVer = jvmVersion()
tasks.withType(KotlinJvmCompile::class) tasks.withType(KotlinCompile::class)
.filter { it.name.startsWith("compileTestKotlin") } .filter { it.name.contains("test", ignoreCase = true) }
.forEach { task -> .forEach { task ->
task.kotlinOptions.freeCompilerArgs += "-Xopt-in=net.mamoe.mirai.utils.TestOnly" task.kotlinOptions.freeCompilerArgs += "-Xopt-in=net.mamoe.mirai.utils.TestOnly"
} }

View File

@ -22,11 +22,11 @@ object Versions {
val consoleIntellij = "221-$project-162-1" // idea-mirai-kotlin-patch val consoleIntellij = "221-$project-162-1" // idea-mirai-kotlin-patch
val consoleTerminal = project val consoleTerminal = project
const val kotlinCompiler = "1.6.21" const val kotlinCompiler = "1.7.0-RC"
const val kotlinStdlib = kotlinCompiler const val kotlinStdlib = kotlinCompiler
const val dokka = "1.6.20" const val dokka = "1.6.21"
const val kotlinCompilerForIdeaPlugin = "1.6.20" const val kotlinCompilerForIdeaPlugin = "1.7.0-RC"
const val coroutines = "1.6.1" const val coroutines = "1.6.1"
const val atomicFU = "0.17.2" const val atomicFU = "0.17.2"
@ -38,8 +38,8 @@ object Versions {
const val io = "0.1.16" const val io = "0.1.16"
const val coroutinesIo = "0.1.16" const val coroutinesIo = "0.1.16"
const val blockingBridge = "2.1.0-162.1" const val blockingBridge = "2.1.0-170.1"
const val dynamicDelegation = "0.3.0-162.4" const val dynamicDelegation = "0.3.0-170.1"
const val androidGradlePlugin = "4.1.1" const val androidGradlePlugin = "4.1.1"
const val android = "4.1.1.4" const val android = "4.1.1.4"
@ -106,13 +106,13 @@ val `kotlinx-coroutines-io` = kotlinx("coroutines-io", Versions.coroutinesIo)
val `ktor-serialization` = ktor("serialization", Versions.ktor) val `ktor-serialization` = ktor("serialization", Versions.ktor)
val `ktor-client-core` = ktor("client-core-jvm", Versions.ktor) val `ktor-client-core` = ktor("client-core", Versions.ktor)
val `ktor-client-cio` = ktor("client-cio-jvm", Versions.ktor) val `ktor-client-cio` = ktor("client-cio", Versions.ktor)
val `ktor-client-okhttp` = ktor("client-okhttp", Versions.ktor) val `ktor-client-okhttp` = ktor("client-okhttp", Versions.ktor)
val `ktor-client-android` = ktor("client-android", Versions.ktor) val `ktor-client-android` = ktor("client-android", Versions.ktor)
val `ktor-client-logging` = ktor("client-logging-jvm", Versions.ktor) val `ktor-client-logging` = ktor("client-logging", Versions.ktor)
val `ktor-network` = ktor("network-jvm", Versions.ktor) val `ktor-network` = ktor("network-jvm", Versions.ktor)
val `ktor-client-serialization` = ktor("client-serialization-jvm", Versions.ktor) val `ktor-client-serialization` = ktor("client-serialization", Versions.ktor)
const val `logback-classic` = "ch.qos.logback:logback-classic:" + Versions.logback const val `logback-classic` = "ch.qos.logback:logback-classic:" + Versions.logback

View File

@ -13,6 +13,7 @@ org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 --illegal-access=permit -Dkot
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.vfs.watch=true org.gradle.vfs.watch=true
kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.binary.memoryModel=experimental
kotlin.native.enableDependencyPropagation=false kotlin.native.enableDependencyPropagation=false
#kotlin.mpp.enableCompatibilityMetadataVariant=true #kotlin.mpp.enableCompatibilityMetadataVariant=true
#kotlin.mpp.enableGranularSourceSetsMetadata=true #kotlin.mpp.enableGranularSourceSetsMetadata=true
@ -21,4 +22,5 @@ gnsp.disableApplyOnlyOnRootProjectEnforcement=true
# We may target 15 with Kotlin 1.5 IR # We may target 15 with Kotlin 1.5 IR
mirai.android.target.api.level=24 mirai.android.target.api.level=24
# Enable if you want to use mavenLocal for both Gradle plugin and project dependencies resolutions. # Enable if you want to use mavenLocal for both Gradle plugin and project dependencies resolutions.
systemProp.use.maven.local=false systemProp.use.maven.local=false
org.gradle.caching=true

11
install.sh Normal file
View File

@ -0,0 +1,11 @@
#
# Copyright 2019-2022 Mamoe Technologies and contributors.
#
# 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
# Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
#
# https://github.com/mamoe/mirai/blob/dev/LICENSE
#
cargo install --force cbindgen
cargo install bindgen

View File

@ -10,7 +10,6 @@
package net.mamoe.console.integrationtest package net.mamoe.console.integrationtest
import net.mamoe.console.integrationtest.testpoints.MCITBSelfAssertions import net.mamoe.console.integrationtest.testpoints.MCITBSelfAssertions
import org.junit.jupiter.api.Test
import org.objectweb.asm.ClassReader import org.objectweb.asm.ClassReader
import java.io.File import java.io.File
import java.lang.management.ManagementFactory import java.lang.management.ManagementFactory
@ -22,6 +21,7 @@ import kotlin.io.path.inputStream
import kotlin.io.path.isDirectory import kotlin.io.path.isDirectory
import kotlin.io.path.name import kotlin.io.path.name
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.test.Test
import kotlin.test.assertTrue import kotlin.test.assertTrue

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -17,7 +17,6 @@ import net.mamoe.mirai.console.data.value
import net.mamoe.mirai.console.extension.PluginComponentStorage import net.mamoe.mirai.console.extension.PluginComponentStorage
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.utils.touch
import java.io.File import java.io.File
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -40,13 +39,14 @@ internal object PluginDataRenameToIdTest : AbstractTestPointAsPlugin() {
} }
override fun beforeConsoleStartup() { override fun beforeConsoleStartup() {
File("config/PluginDataRenameToIdTest/test.txt").touch() File("config/PluginDataRenameToIdTest").mkdirs()
File("config/PluginDataRenameToIdTest/test.txt").createNewFile()
File("config/PluginDataRenameToIdTest/testconf.yml").writeText( File("config/PluginDataRenameToIdTest/testconf.yml").writeText(
""" """
test: a test: a
""".trimIndent() """.trimIndent()
) )
File("data/PluginDataRenameToIdTest/test.txt").touch() File("data/PluginDataRenameToIdTest/test.txt").createNewFile()
File("data/PluginDataRenameToIdTest/testdata.yml").writeText( File("data/PluginDataRenameToIdTest/testdata.yml").writeText(
""" """
test: a test: a

View File

@ -28,9 +28,6 @@ import net.mamoe.mirai.console.internal.command.flattenCommandComponents
import net.mamoe.mirai.console.permission.PermissionService.Companion.permit import net.mamoe.mirai.console.permission.PermissionService.Companion.permit
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import java.time.* import java.time.*
import java.time.temporal.TemporalAccessor import java.time.temporal.TemporalAccessor
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -158,7 +155,6 @@ class TestTemporalArgCommand : CompositeCommand(owner, "testtemporal") {
private val sender get() = ConsoleCommandSender private val sender get() = ConsoleCommandSender
private val owner get() = ConsoleCommandOwner private val owner get() = ConsoleCommandOwner
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
@OptIn(ExperimentalCommandDescriptors::class) @OptIn(ExperimentalCommandDescriptors::class)
internal class InstanceTestCommand : AbstractConsoleInstanceTest() { internal class InstanceTestCommand : AbstractConsoleInstanceTest() {
private val manager by lazy { MiraiConsoleImplementation.getBridge().commandManager as CommandManagerImpl } private val manager by lazy { MiraiConsoleImplementation.getBridge().commandManager as CommandManagerImpl }
@ -167,7 +163,7 @@ internal class InstanceTestCommand : AbstractConsoleInstanceTest() {
private val rawCommand by lazy { TestRawCommand() } private val rawCommand by lazy { TestRawCommand() }
private val compositeCommand by lazy { TestCompositeCommand() } private val compositeCommand by lazy { TestCompositeCommand() }
@BeforeEach @BeforeTest
fun grantPermission() { fun grantPermission() {
ConsoleCommandSender.permit(simpleCommand.permission) ConsoleCommandSender.permit(simpleCommand.permission)
ConsoleCommandSender.permit(compositeCommand.permission) ConsoleCommandSender.permit(compositeCommand.permission)

View File

@ -12,6 +12,7 @@
package net.mamoe.mirai.console.command package net.mamoe.mirai.console.command
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.runBlocking
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
@ -23,7 +24,7 @@ import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.Pa
import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.utils.md5 import net.mamoe.mirai.utils.md5
import net.mamoe.mirai.utils.toUHexString import net.mamoe.mirai.utils.toUHexString
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertContentEquals import kotlin.test.assertContentEquals
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -32,7 +33,7 @@ import kotlin.test.assertEquals
internal class LoginCommandTest : AbstractCommandTest() { internal class LoginCommandTest : AbstractCommandTest() {
@Test @Test
suspend fun `login with provided password`() { fun `login with provided password`() = runBlocking {
val myId = 123L val myId = 123L
val myPwd = "password001" val myPwd = "password001"
@ -52,7 +53,7 @@ internal class LoginCommandTest : AbstractCommandTest() {
} }
@Test @Test
suspend fun `login with saved plain password`() { fun `login with saved plain password`() = runBlocking {
val myId = 123L val myId = 123L
val myPwd = "password001" val myPwd = "password001"
@ -81,7 +82,7 @@ internal class LoginCommandTest : AbstractCommandTest() {
} }
@Test @Test
suspend fun `login with saved md5 password`() { fun `login with saved md5 password`() = runBlocking {
val myId = 123L val myId = 123L
val myPwd = "password001" val myPwd = "password001"

View File

@ -17,7 +17,7 @@ import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.event.globalEventChannel import net.mamoe.mirai.event.globalEventChannel
import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.BotConfiguration
import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class AutoLoginTest : AbstractConsoleInstanceTest() { class AutoLoginTest : AbstractConsoleInstanceTest() {

View File

@ -13,7 +13,7 @@ import net.mamoe.mirai.console.data.java.JavaAutoSavePluginData
import net.mamoe.mirai.console.plugin.jvm.reloadPluginData import net.mamoe.mirai.console.plugin.jvm.reloadPluginData
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
import net.mamoe.mirai.console.util.JavaFriendlyApi import net.mamoe.mirai.console.util.JavaFriendlyApi
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@ -19,9 +19,9 @@ import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.message.data.SingleMessage import net.mamoe.mirai.message.data.SingleMessage
import net.mamoe.mirai.message.data.messageChainOf import net.mamoe.mirai.message.data.messageChainOf
import net.mamoe.mirai.utils.mapPrimitive import net.mamoe.mirai.utils.mapPrimitive
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path import java.nio.file.Path
import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertSame import kotlin.test.assertSame

View File

@ -18,7 +18,7 @@ import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.console.plugin.name import net.mamoe.mirai.console.plugin.name
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
import org.junit.jupiter.api.Test import kotlin.test.Test
class PluginMovingTests : AbstractConsoleInstanceTest() { class PluginMovingTests : AbstractConsoleInstanceTest() {
private val mockPluginWithName = object : KotlinPlugin(JvmPluginDescription("org.test1.test1", "1.0.0", "test1")) {} private val mockPluginWithName = object : KotlinPlugin(JvmPluginDescription("org.test1.test1", "1.0.0", "test1")) {}

View File

@ -12,7 +12,7 @@ package net.mamoe.mirai.console.extension
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorageImpl import net.mamoe.mirai.console.internal.extension.GlobalComponentStorageImpl
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
internal class GlobalComponentStorageTest : AbstractConsoleInstanceTest() { internal class GlobalComponentStorageTest : AbstractConsoleInstanceTest() {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -9,7 +9,7 @@
package net.mamoe.mirai.console.logging package net.mamoe.mirai.console.logging
import org.junit.jupiter.api.Test import kotlin.test.Test
@Suppress("ClassName") @Suppress("ClassName")
internal class TestALC_PathBased { internal class TestALC_PathBased {

View File

@ -11,7 +11,6 @@ package net.mamoe.mirai.console.permission
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
import net.mamoe.mirai.console.internal.permission.PermissionImpl import net.mamoe.mirai.console.internal.permission.PermissionImpl
import org.junit.jupiter.api.Test
import kotlin.test.* import kotlin.test.*
internal class PermissionServiceTest { internal class PermissionServiceTest {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -9,7 +9,7 @@
package net.mamoe.mirai.console.permission package net.mamoe.mirai.console.permission
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertFails import kotlin.test.assertFails
internal class PermissionsBasicsTest { internal class PermissionsBasicsTest {

View File

@ -19,14 +19,14 @@ import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach import kotlin.test.BeforeTest
abstract class AbstractConsoleInstanceTest { abstract class AbstractConsoleInstanceTest {
val mockPlugin by lazy { mockKotlinPlugin() } val mockPlugin by lazy { mockKotlinPlugin() }
private lateinit var implementation: MiraiConsoleImplementation private lateinit var implementation: MiraiConsoleImplementation
val consoleImplementation: MiraiConsoleImplementation by ::implementation val consoleImplementation: MiraiConsoleImplementation by ::implementation
@BeforeEach @BeforeTest
protected open fun initializeConsole() { protected open fun initializeConsole() {
this.implementation = MockConsoleImplementation().apply { start() } this.implementation = MockConsoleImplementation().apply { start() }
CommandManager CommandManager

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -9,9 +9,9 @@
package net.mamoe.mirai.console.testFramework.test package net.mamoe.mirai.console.testFramework.test
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
import net.mamoe.mirai.console.plugin.PluginManager import net.mamoe.mirai.console.plugin.PluginManager
import org.junit.jupiter.api.Test import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class FrameworkInstanceTest : AbstractConsoleInstanceTest() { class FrameworkInstanceTest : AbstractConsoleInstanceTest() {

View File

@ -1,17 +1,17 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
package net.mamoe.mirai.console.util package net.mamoe.mirai.console.util
//import kotlinx.coroutines.* //import kotlinx.coroutines.*
//import org.junit.jupiter.api.Test //import kotlin.test.Test
//import java.util.concurrent.atomic.AtomicInteger //import java.util.concurrent.atomic.AtomicInteger
//import kotlin.coroutines.resume //import kotlin.coroutines.resume
//import kotlin.test.assertEquals //import kotlin.test.assertEquals

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -14,7 +14,7 @@
package net.mamoe.mirai.console.util package net.mamoe.mirai.console.util
import net.mamoe.mirai.console.util.SemVersion.Companion.test import net.mamoe.mirai.console.util.SemVersion.Companion.test
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertFails import kotlin.test.assertFails
internal class TestSemVersion { internal class TestSemVersion {

View File

@ -20,7 +20,7 @@ description = "Mirai Console compiler annotations"
kotlin { kotlin {
explicitApi() explicitApi()
configureHMPPJvm() configureHMPP()
} }
configureMppPublishing() configureMppPublishing()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -58,10 +58,12 @@ abstract class AbstractTest {
File(tempDir, "gradle.properties").apply { File(tempDir, "gradle.properties").apply {
delete() delete()
writeText(""" writeText(
"""
org.gradle.daemon=false org.gradle.daemon=false
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
""".trimIndent()) """.trimIndent()
)
} }
buildFile = File(tempDir, "build.gradle") buildFile = File(tempDir, "build.gradle")

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -11,11 +11,11 @@ package net.mamoe.mirai.console.gradle
import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.GradleRunner
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir import org.junit.jupiter.api.io.TempDir
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.io.PrintWriter import java.io.PrintWriter
import kotlin.test.Test
class KotlinTransitiveDependenciesIntegrationTest { class KotlinTransitiveDependenciesIntegrationTest {
@Test @Test

View File

@ -12,9 +12,9 @@
package net.mamoe.mirai.console.gradle package net.mamoe.mirai.console.gradle
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import java.io.File import java.io.File
import java.util.zip.ZipFile import java.util.zip.ZipFile
import kotlin.test.Test
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
import kotlin.test.assertNull import kotlin.test.assertNull

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -9,7 +9,7 @@
package net.mamoe.mirai.console.gradle package net.mamoe.mirai.console.gradle
import org.junit.jupiter.api.Test import kotlin.test.Test
class TestPluginApply : AbstractTest() { class TestPluginApply : AbstractTest() {

View File

@ -45,8 +45,10 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
try { try {
languageSettings.optIn("kotlin.RequiresOptIn") languageSettings.optIn("kotlin.RequiresOptIn")
} catch (e: NoSuchMethodError) { } catch (e: NoSuchMethodError) {
@Suppress("DEPRECATION") // User is using < 1.6
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn") target.compilations.forEach { compilation ->
compilation.kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
} }
dependencies { configureDependencies(project, this@configureSourceSet, target) } dependencies { configureDependencies(project, this@configureSourceSet, target) }
} }

View File

@ -9,7 +9,7 @@
package creator package creator
import net.mamoe.mirai.console.intellij.wizard.sortVersionsDescending import net.mamoe.mirai.console.intellij.wizard.sortVersionsDescending
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class MiraiVersionKindTest { class MiraiVersionKindTest {

View File

@ -13,7 +13,7 @@ import net.mamoe.mirai.console.intellij.diagnostics.adjustToClassName
import net.mamoe.mirai.console.intellij.diagnostics.isValidPackageName import net.mamoe.mirai.console.intellij.diagnostics.isValidPackageName
import net.mamoe.mirai.console.intellij.diagnostics.isValidQualifiedClassName import net.mamoe.mirai.console.intellij.diagnostics.isValidQualifiedClassName
import net.mamoe.mirai.console.intellij.diagnostics.isValidSimpleClassName import net.mamoe.mirai.console.intellij.diagnostics.isValidSimpleClassName
import org.junit.jupiter.api.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue

View File

@ -26,7 +26,7 @@ description = "Mirai API module"
kotlin { kotlin {
explicitApi() explicitApi()
configureHMPPJvm() configureHMPP()
sourceSets { sourceSets {
@ -36,6 +36,7 @@ kotlin {
api(`kotlinx-serialization-core`) api(`kotlinx-serialization-core`)
api(`kotlinx-serialization-json`) api(`kotlinx-serialization-json`)
api(`kotlinx-coroutines-core`) // don't remove it, otherwise IDE will complain api(`kotlinx-coroutines-core`) // don't remove it, otherwise IDE will complain
implementation(`ktor-client-core`)
implementation(project(":mirai-core-utils")) implementation(project(":mirai-core-utils"))
implementation(project(":mirai-console-compiler-annotations")) implementation(project(":mirai-console-compiler-annotations"))

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress("unused", "NOTHING_TO_INLINE") @file:Suppress("unused", "NOTHING_TO_INLINE")
@ -12,6 +12,7 @@
package net.mamoe.mirai package net.mamoe.mirai
import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.BotConfiguration
import kotlin.jvm.JvmSynthetic
/** /**
* 构造 [Bot] 的工厂. 这是 [Bot] 唯一的构造方式. * 构造 [Bot] 的工厂. 这是 [Bot] 唯一的构造方式.

View File

@ -15,7 +15,6 @@
package net.mamoe.mirai package net.mamoe.mirai
import io.ktor.client.* import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.UserProfile import net.mamoe.mirai.data.UserProfile
@ -30,8 +29,9 @@ import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.Image.Key.queryUrl import net.mamoe.mirai.message.data.Image.Key.queryUrl
import net.mamoe.mirai.message.data.MessageSource.Key.recall import net.mamoe.mirai.message.data.MessageSource.Key.recall
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import java.util.ServiceLoader import kotlin.jvm.JvmName
import kotlin.reflect.full.companionObjectInstance import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* [IMirai] 实例. * [IMirai] 实例.
@ -336,11 +336,10 @@ public suspend inline fun IMirai.recallMessage(bot: Bot, message: MessageChain):
@PublishedApi // for tests and potential public uses. @PublishedApi // for tests and potential public uses.
@Suppress("ClassName") @Suppress("ClassName")
internal object _MiraiInstance { internal object _MiraiInstance {
private var instance: IMirai? = null
@JvmStatic @JvmStatic
fun set(instance: IMirai) { fun set(instance: IMirai) {
this.instance = instance miraiInstance = instance
} }
/** /**
@ -348,15 +347,14 @@ internal object _MiraiInstance {
*/ */
@JvmStatic @JvmStatic
fun get(): IMirai { fun get(): IMirai {
return instance ?: findMiraiInstance().also { instance = it } return miraiInstance ?: findMiraiInstance().also { miraiInstance = it }
} }
} }
// to overcome native gc issue
private var miraiInstance: IMirai? = null
@JvmSynthetic @JvmSynthetic
internal fun findMiraiInstance(): IMirai { internal fun findMiraiInstance(): IMirai {
ServiceLoader.load(IMirai::class.java).firstOrNull()?.let { return it } return loadService(IMirai::class, "net.mamoe.mirai.internal.MiraiImpl")
val implClass = Class.forName("net.mamoe.mirai.internal.MiraiImpl")
(implClass.kotlin.companionObjectInstance as? IMirai)?.let { return it }
return implClass.asSubclass(IMirai::class.java).getConstructor().newInstance()
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -17,7 +17,6 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.* import net.mamoe.mirai.data.*
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import net.mamoe.mirai.utils.WeakRef
import kotlin.annotation.AnnotationTarget.* import kotlin.annotation.AnnotationTarget.*
/** /**
@ -52,7 +51,7 @@ public interface LowLevelApiAccessor {
public suspend fun refreshKeys(bot: Bot) public suspend fun refreshKeys(bot: Bot)
/** /**
* 构造一个 [Friend] 对象. 它持有对 [Bot] 的弱引用([WeakRef]). * 构造一个 [Friend] 对象.
* *
* [Bot] 无法管理这个对象, 但这个对象会以 [Bot] [Job] 作为父 Job. * [Bot] 无法管理这个对象, 但这个对象会以 [Bot] [Job] 作为父 Job.
* 因此, [Bot] 被关闭后, 这个对象也会被关闭. * 因此, [Bot] 被关闭后, 这个对象也会被关闭.
@ -61,7 +60,7 @@ public interface LowLevelApiAccessor {
public fun newFriend(bot: Bot, friendInfo: FriendInfo): Friend public fun newFriend(bot: Bot, friendInfo: FriendInfo): Friend
/** /**
* 构造一个 [Stranger] 对象. 它持有对 [Bot] 的弱引用([WeakRef]). * 构造一个 [Stranger] 对象.
* *
* [Bot] 无法管理这个对象, 但这个对象会以 [Bot] [Job] 作为父 Job. * [Bot] 无法管理这个对象, 但这个对象会以 [Bot] [Job] 作为父 Job.
* 因此, [Bot] 被关闭后, 这个对象也会被关闭. * 因此, [Bot] 被关闭后, 这个对象也会被关闭.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -23,16 +23,16 @@ import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.recallMessage import net.mamoe.mirai.recallMessage
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.ExternalResource.Companion.sendAsImageTo
import net.mamoe.mirai.utils.ExternalResource.Companion.uploadAsImage import net.mamoe.mirai.utils.ExternalResource.Companion.uploadAsImage
import java.io.File import kotlin.coroutines.cancellation.CancellationException
import java.io.InputStream import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* 联系对象, 即可以与 [Bot] 互动的对象. 包含 [用户][User], [][Group]. * 联系对象, 即可以与 [Bot] 互动的对象. 包含 [用户][User], [][Group].
*/ */
@NotStableForInheritance @NotStableForInheritance
public interface Contact : ContactOrBot, CoroutineScope { public expect interface Contact : ContactOrBot, CoroutineScope {
/** /**
* 这个联系对象所属 [Bot]. * 这个联系对象所属 [Bot].
*/ */
@ -67,7 +67,7 @@ public interface Contact : ContactOrBot, CoroutineScope {
* 发送纯文本消息 * 发送纯文本消息
* @see sendMessage * @see sendMessage
*/ */
public suspend fun sendMessage(message: String): MessageReceipt<Contact> = this.sendMessage(message.toPlainText()) public open suspend fun sendMessage(message: String): MessageReceipt<Contact>
/** /**
* 上传一个 [资源][ExternalResource] 作为图片以备发送. * 上传一个 [资源][ExternalResource] 作为图片以备发送.
@ -90,81 +90,23 @@ public interface Contact : ContactOrBot, CoroutineScope {
@JvmBlockingBridge @JvmBlockingBridge
public companion object { public companion object {
/**
* 读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
*
* 注意此函数不会关闭 [imageStream]
*
* @param formatName 查看 [ExternalResource.formatName]
* @throws OverFileSizeMaxException
* @see FileCacheStrategy
*/
@JvmStatic
@JvmOverloads
public suspend fun <C : Contact> C.sendImage(
imageStream: InputStream,
formatName: String? = null
): MessageReceipt<C> = imageStream.sendAsImageTo(this, formatName)
/**
* 将文件作为图片发送到指定联系人
* @param formatName 查看 [ExternalResource.formatName]
* @throws OverFileSizeMaxException
* @see FileCacheStrategy
*/
@JvmStatic
@JvmOverloads
public suspend fun <C : Contact> C.sendImage(
file: File,
formatName: String? = null
): MessageReceipt<C> = file.sendAsImageTo(this, formatName)
/** /**
* 将资源作为单独的图片消息发送给 [this] * 将资源作为单独的图片消息发送给 [this]
* *
* @see Contact.sendMessage 最终调用, 发送消息. * @see Contact.sendMessage 最终调用, 发送消息.
*/ */
@JvmStatic @JvmStatic
public suspend fun <C : Contact> C.sendImage(resource: ExternalResource): MessageReceipt<C> = public suspend fun <C : Contact> C.sendImage(resource: ExternalResource): MessageReceipt<C>
resource.sendAsImageTo(this)
/**
* 读取 [InputStream] 到临时文件并将其作为图片上传, 但不发送
*
* 注意本函数不会关闭流
*
* @param formatName 查看 [ExternalResource.formatName]
* @throws OverFileSizeMaxException
*/
@JvmStatic
@JvmOverloads
public suspend fun Contact.uploadImage(
imageStream: InputStream,
formatName: String? = null
): Image = imageStream.uploadAsImage(this@uploadImage, formatName)
/**
* 将文件作为图片上传, 但不发送
* @param formatName 查看 [ExternalResource.formatName]
* @throws OverFileSizeMaxException
*/
@JvmStatic
@JvmOverloads
public suspend fun Contact.uploadImage(
file: File,
formatName: String? = null
): Image = file.uploadAsImage(this, formatName)
/** /**
* 将文件作为图片上传, 但不发送 * 将文件作为图片上传, 但不发送
* @throws OverFileSizeMaxException * @throws OverFileSizeMaxException
*/ */
@Throws(OverFileSizeMaxException::class) @Throws(OverFileSizeMaxException::class, CancellationException::class)
@JvmStatic @JvmStatic
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXTENSION_SHADOWED_BY_MEMBER") @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXTENSION_SHADOWED_BY_MEMBER")
@kotlin.internal.LowPriorityInOverloadResolution // for better Java API @kotlin.internal.LowPriorityInOverloadResolution // for better Java API
public suspend fun Contact.uploadImage(resource: ExternalResource): Image = this.uploadImage(resource) public suspend fun Contact.uploadImage(resource: ExternalResource): Image
} }
} }

View File

@ -1,18 +1,19 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress("EXPERIMENTAL_API_USAGE", "unused") @file:Suppress("EXPERIMENTAL_API_USAGE", "unused")
package net.mamoe.mirai.contact package net.mamoe.mirai.contact
import net.mamoe.mirai.utils.ConcurrentLinkedDeque
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import java.util.concurrent.ConcurrentLinkedQueue import kotlin.jvm.JvmField
/** /**
@ -26,7 +27,7 @@ public class ContactList<out C : Contact>
Collection<C> by delegate { Collection<C> by delegate {
@MiraiInternalApi @MiraiInternalApi
public constructor() : this(ConcurrentLinkedQueue()) public constructor() : this(ConcurrentLinkedDeque())
/** /**
* 获取一个 [Contact.id] [id] 的元素. 在不存在时返回 `null`. * 获取一个 [Contact.id] [id] 的元素. 在不存在时返回 `null`.

View File

@ -12,6 +12,7 @@ package net.mamoe.mirai.contact
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import kotlin.jvm.JvmName
/** /**
* 拥有 [id] 的对象. * 拥有 [id] 的对象.

View File

@ -23,6 +23,8 @@ import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.ExternalResource import net.mamoe.mirai.utils.ExternalResource
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* . * .

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -20,8 +20,8 @@ import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.isContentEmpty import net.mamoe.mirai.message.data.isContentEmpty
import net.mamoe.mirai.message.data.toPlainText import net.mamoe.mirai.message.data.toPlainText
import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import kotlin.jvm.JvmName
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.DurationUnit import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -16,6 +16,9 @@ import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.PermissionDeniedException import net.mamoe.mirai.contact.PermissionDeniedException
import net.mamoe.mirai.contact.announcement.Announcement.Companion.publishAnnouncement import net.mamoe.mirai.contact.announcement.Announcement.Companion.publishAnnouncement
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -11,6 +11,8 @@ package net.mamoe.mirai.contact.announcement
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.utils.isSameClass
import kotlin.jvm.JvmStatic
/** /**
@ -47,9 +49,7 @@ public class AnnouncementImage private constructor(
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (other !is AnnouncementImage || !isSameClass(this, other)) return false
other as AnnouncementImage
if (id != other.id) return false if (id != other.id) return false
if (height != other.height) return false if (height != other.height) return false

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -12,6 +12,9 @@ package net.mamoe.mirai.contact.announcement
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.contact.announcement.AnnouncementParameters.Companion.DEFAULT import net.mamoe.mirai.contact.announcement.AnnouncementParameters.Companion.DEFAULT
import net.mamoe.mirai.utils.isSameClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
/** /**
* 群公告的附加参数. * 群公告的附加参数.
@ -65,9 +68,7 @@ public class AnnouncementParameters internal constructor(
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (other !is AnnouncementParameters || !isSameClass(this, other)) return false
other as AnnouncementParameters
if (image != other.image) return false if (image != other.image) return false
if (sendToNewMember != other.sendToNewMember) return false if (sendToNewMember != other.sendToNewMember) return false

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -13,6 +13,9 @@ package net.mamoe.mirai.contact.announcement
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmSynthetic
/** /**

View File

@ -21,6 +21,9 @@ import net.mamoe.mirai.utils.map
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* 表示在本地构建的 [Announcement]. * 表示在本地构建的 [Announcement].

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -18,7 +18,6 @@ import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.NormalMember import net.mamoe.mirai.contact.NormalMember
import net.mamoe.mirai.contact.PermissionDeniedException import net.mamoe.mirai.contact.PermissionDeniedException
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import java.time.Instant
/** /**
@ -65,7 +64,7 @@ public interface OnlineAnnouncement : Announcement {
/** /**
* 公告发出的时间 EpochSecond ( 1970-01-01T000000Z 的秒数) * 公告发出的时间 EpochSecond ( 1970-01-01T000000Z 的秒数)
* *
* @see Instant.ofEpochSecond * @see java.time.Instant.ofEpochSecond
*/ */
public val publicationTime: Long public val publicationTime: Long

View File

@ -17,7 +17,7 @@ import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.contact.FileSupported import net.mamoe.mirai.contact.FileSupported
import net.mamoe.mirai.contact.PermissionDeniedException import net.mamoe.mirai.contact.PermissionDeniedException
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import java.io.File import kotlin.jvm.JvmStatic
/** /**
* 绝对文件或目录标识. 精确表示一个远程文件. 不会受同名文件或目录的影响. * 绝对文件或目录标识. 精确表示一个远程文件. 不会受同名文件或目录的影响.
@ -174,7 +174,7 @@ public sealed interface AbsoluteFileFolder {
* *
* 不会包含 `:*?"<>|/\` 任一字符. * 不会包含 `:*?"<>|/\` 任一字符.
* *
* @see File.extension * @see java.io.File.extension
*/ */
@get:JvmStatic @get:JvmStatic
public val AbsoluteFileFolder.extension: String public val AbsoluteFileFolder.extension: String

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -16,10 +16,9 @@ import kotlinx.coroutines.flow.Flow
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.contact.PermissionDeniedException import net.mamoe.mirai.contact.PermissionDeniedException
import net.mamoe.mirai.utils.ExternalResource import net.mamoe.mirai.utils.ExternalResource
import net.mamoe.mirai.utils.JavaFriendlyAPI
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import net.mamoe.mirai.utils.ProgressionCallback import net.mamoe.mirai.utils.ProgressionCallback
import java.util.stream.Stream import kotlin.jvm.JvmOverloads
/** /**
* 绝对目录标识. 精确表示一个远程目录. 不会受同名文件或目录的影响. * 绝对目录标识. 精确表示一个远程目录. 不会受同名文件或目录的影响.
@ -30,7 +29,7 @@ import java.util.stream.Stream
* @see AbsoluteFileFolder * @see AbsoluteFileFolder
*/ */
@NotStableForInheritance @NotStableForInheritance
public interface AbsoluteFolder : AbsoluteFileFolder { public expect interface AbsoluteFolder : AbsoluteFileFolder {
/** /**
* 当前快照中文件数量, 当有文件更新时(上传/删除文件) 该属性不会更新. * 当前快照中文件数量, 当有文件更新时(上传/删除文件) 该属性不会更新.
* *
@ -43,7 +42,7 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
/** /**
* 当该目录为空时返回 `true`. * 当该目录为空时返回 `true`.
*/ */
public fun isEmpty(): Boolean = contentsCount == 0 public open fun isEmpty(): Boolean
/** /**
* 返回更新了文件或目录信息 ([lastModifiedTime] ) , 指向相同文件的 [AbsoluteFileFolder]. * 返回更新了文件或目录信息 ([lastModifiedTime] ) , 指向相同文件的 [AbsoluteFileFolder].
@ -64,42 +63,18 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
*/ */
public suspend fun folders(): Flow<AbsoluteFolder> public suspend fun folders(): Flow<AbsoluteFolder>
/**
* 获取该目录下所有子目录列表.
*
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [folders], 因此不建议在 Kotlin 使用. Kotlin 请使用 [folders].
*/
@JavaFriendlyAPI
public suspend fun foldersStream(): Stream<AbsoluteFolder>
/** /**
* 获取该目录下所有文件列表. * 获取该目录下所有文件列表.
*/ */
public suspend fun files(): Flow<AbsoluteFile> public suspend fun files(): Flow<AbsoluteFile>
/**
* 获取该目录下所有文件列表.
*
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [files], 因此不建议在 Kotlin 使用. Kotlin 请使用 [files].
*/
@JavaFriendlyAPI
public suspend fun filesStream(): Stream<AbsoluteFile>
/** /**
* 获取该目录下所有文件和子目录列表. * 获取该目录下所有文件和子目录列表.
*/ */
public suspend fun children(): Flow<AbsoluteFileFolder> public suspend fun children(): Flow<AbsoluteFileFolder>
/**
* 获取该目录下所有文件和子目录列表.
*
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [children], 因此不建议在 Kotlin 使用. Kotlin 请使用 [children].
*/
@JavaFriendlyAPI
public suspend fun childrenStream(): Stream<AbsoluteFileFolder>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// resolve and upload // resolve and upload
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -144,16 +119,6 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
path: String path: String
): Flow<AbsoluteFile> ): Flow<AbsoluteFile>
/**
* 根据路径获取指向的所有路径为 [path] 的文件列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件.
*
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [resolveFiles], 因此不建议在 Kotlin 使用. Kotlin 请使用 [resolveFiles].
*/
@JavaFriendlyAPI
public suspend fun resolveFilesStream(
path: String
): Stream<AbsoluteFile>
/** /**
* 根据路径获取指向的所有路径为 [path] 的文件和目录列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件和目录. * 根据路径获取指向的所有路径为 [path] 的文件和目录列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件和目录.
*/ */
@ -161,16 +126,6 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
path: String path: String
): Flow<AbsoluteFileFolder> ): Flow<AbsoluteFileFolder>
/**
* 根据路径获取指向的所有路径为 [path] 的文件和目录列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件和目录.
*
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [resolveAll], 因此不建议在 Kotlin 使用. Kotlin 请使用 [resolveAll].
*/
@JavaFriendlyAPI
public suspend fun resolveAllStream(
path: String
): Stream<AbsoluteFileFolder>
/** /**
* 上传一个文件到该目录, 返回上传成功的文件标识. * 上传一个文件到该目录, 返回上传成功的文件标识.
* *
@ -200,6 +155,7 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
* 根目录 folder ID. * 根目录 folder ID.
* @see id * @see id
*/ */
public const val ROOT_FOLDER_ID: String = "/" @Suppress("CONST_VAL_WITHOUT_INITIALIZER") // compiler bug
public const val ROOT_FOLDER_ID: String
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -19,8 +19,7 @@ import net.mamoe.mirai.contact.PermissionDeniedException
import net.mamoe.mirai.utils.ExternalResource import net.mamoe.mirai.utils.ExternalResource
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import net.mamoe.mirai.utils.ProgressionCallback import net.mamoe.mirai.utils.ProgressionCallback
import java.io.File import kotlin.jvm.JvmOverloads
import java.util.stream.Stream
/** /**
* 表示远程文件列表 (管理器). * 表示远程文件列表 (管理器).
@ -46,7 +45,7 @@ import java.util.stream.Stream
* *
* # 绝对路径与相对路径 * # 绝对路径与相对路径
* *
* mirai 文件系统的绝对路径与相对路径与 Java [File] 实现的相同. * mirai 文件系统的绝对路径与相对路径与 Java [java.io.File] 实现的相同.
* *
* `/` 起始的路径表示绝对路径, 基于根目录 [root] 处理. 其他路径均表示相对路径. * `/` 起始的路径表示绝对路径, 基于根目录 [root] 处理. 其他路径均表示相对路径.
* *
@ -64,11 +63,11 @@ import java.util.stream.Stream
* *
* 一个目录 ([AbsoluteFolder]) 可以包含多个子文件, 根目录还可以包含多个子目录 (详见下文 '目录结构限制'). * 一个目录 ([AbsoluteFolder]) 可以包含多个子文件, 根目录还可以包含多个子目录 (详见下文 '目录结构限制').
* *
* 使用 [AbsoluteFolder.children] 可以获得其内子目录和文件列表 [Flow]. [AbsoluteFolder.childrenStream] 提供适合 Java [Stream] 实现. * 使用 [AbsoluteFolder.children] 可以获得其内子目录和文件列表 [Flow]. [AbsoluteFolder.childrenStream] 提供适合 Java [java.util.stream.Stream] 实现.
* 使用 [AbsoluteFolder.folders] [AbsoluteFolder.files] 可以特定地只获取子目录或文件列表. 这些函数也有其 `*Stream` 实现. * 使用 [AbsoluteFolder.folders] [AbsoluteFolder.files] 可以特定地只获取子目录或文件列表. 这些函数也有其 `*Stream` 实现.
* *
* 若要根据确定的文件或目录名称获取其 [AbsoluteFileFolder] 实例, 可使用 [AbsoluteFolder.resolveFiles] [AbsoluteFolder.resolveFiles]. * 若要根据确定的文件或目录名称获取其 [AbsoluteFileFolder] 实例, 可使用 [AbsoluteFolder.resolveFiles] [AbsoluteFolder.resolveFiles].
* 注意 [AbsoluteFolder.resolveFiles] 返回 [Flow] ( Stream 版返回 [Stream]), 因为服务器允许多个文件有相同名称. (详见下文 '允许重名'). * 注意 [AbsoluteFolder.resolveFiles] 返回 [Flow] ( Stream 版返回 [java.util.stream.Stream]), 因为服务器允许多个文件有相同名称. (详见下文 '允许重名').
* *
* 若已知文件 [AbsoluteFile.id], 可通过 [AbsoluteFolder.resolveFileById] 获得该文件. * 若已知文件 [AbsoluteFile.id], 可通过 [AbsoluteFolder.resolveFileById] 获得该文件.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -12,6 +12,7 @@ package net.mamoe.mirai.contact.roaming
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import kotlin.jvm.JvmField
/** /**
* @since 2.8 * @since 2.8

View File

@ -16,8 +16,6 @@ import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.contact.Friend import net.mamoe.mirai.contact.Friend
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.utils.JavaFriendlyAPI
import java.util.stream.Stream
/** /**
* 漫游消息记录管理器. 可通过 [RoamingSupported.roamingMessages] 获得. 目前仅 [Friend] 实现 [RoamingSupported]. * 漫游消息记录管理器. 可通过 [RoamingSupported.roamingMessages] 获得. 目前仅 [Friend] 实现 [RoamingSupported].
@ -25,13 +23,13 @@ import java.util.stream.Stream
* @since 2.8 * @since 2.8
* @see RoamingSupported * @see RoamingSupported
*/ */
public interface RoamingMessages { public expect interface RoamingMessages {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Get list // Get list
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/** /**
* 查询指定时间段内的漫游消息记录. Java Stream 方法查看 [getMessagesStream]. * 查询指定时间段内的漫游消息记录.
* *
* 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息. * 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
* 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回. * 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
@ -55,7 +53,7 @@ public interface RoamingMessages {
): Flow<MessageChain> ): Flow<MessageChain>
/** /**
* 查询所有漫游消息记录. Java Stream 方法查看 [getAllMessagesStream]. * 查询所有漫游消息记录.
* *
* 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息. * 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
* 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回. * 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
@ -70,57 +68,7 @@ public interface RoamingMessages {
* *
* @param filter 过滤器. * @param filter 过滤器.
*/ */
public suspend fun getAllMessages( public open suspend fun getAllMessages(
filter: RoamingMessageFilter? = null filter: RoamingMessageFilter? = null
): Flow<MessageChain> = getMessagesIn(0, Long.MAX_VALUE, filter) ): Flow<MessageChain>
/**
* 查询指定时间段内的漫游消息记录. Kotlin Flow 版本查看 [getMessagesIn].
*
* 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
* 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
*
* 注意, 返回的消息记录既包含机器人发送给目标用户的消息, 也包含目标用户发送给机器人的消息.
* 可通过 [MessageChain] 获取 [MessageSource] (用法为 `messageChain.get(MessageSource.Key)`), 判断 [MessageSource.fromId] (发送人).
* 消息的其他*元数据*信息也要通过 [MessageSource] 获取 ( [MessageSource.time] 获取时间).
*
* 若只需要获取单向消息 (机器人发送给目标用户的消息或反之), 可使用 [RoamingMessageFilter.SENT] [RoamingMessageFilter.RECEIVED] 作为 [filter] 参数传递.
*
* 性能提示: 请在 [filter] 执行筛选, [filter] 返回 `false` 则不会解析消息链, 这对本函数的处理速度有决定性影响.
*
* @param timeStart 起始时间, UTC+8 时间戳, 单位为秒. 可以为 `0`, 即表示从可以获取的最早的消息起. 负数将会被看是 `0`.
* @param timeEnd 结束时间, UTC+8 时间戳, 单位为秒. 可以为 [Long.MAX_VALUE], 即表示到可以获取的最晚的消息为止. 低于 [timeStart] 的值将会被看作是 [timeStart] 的值.
* @param filter 过滤器.
*/
@Suppress("OVERLOADS_INTERFACE")
@JvmOverloads
@JavaFriendlyAPI
public suspend fun getMessagesStream(
timeStart: Long,
timeEnd: Long,
filter: RoamingMessageFilter? = null
): Stream<MessageChain>
/**
* 查询所有漫游消息记录. Kotlin Flow 版本查看 [getAllMessages].
*
* 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
* 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
*
* 注意, 返回的消息记录既包含机器人发送给目标用户的消息, 也包含目标用户发送给机器人的消息.
* 可通过 [MessageChain] 获取 [MessageSource] (用法为 `messageChain.get(MessageSource.Key)`), 判断 [MessageSource.fromId] (发送人).
* 消息的其他*元数据*信息也要通过 [MessageSource] 获取 ( [MessageSource.time] 获取时间).
*
* 若只需要获取单向消息 (机器人发送给目标用户的消息或反之), 可使用 [RoamingMessageFilter.SENT] [RoamingMessageFilter.RECEIVED] 作为 [filter] 参数传递.
*
* 性能提示: 请在 [filter] 执行筛选, [filter] 返回 `false` 则不会解析消息链, 这对本函数的处理速度有决定性影响.
*
* @param filter 过滤器.
*/
@Suppress("OVERLOADS_INTERFACE")
@JvmOverloads
@JavaFriendlyAPI
public suspend fun getAllMessagesStream(
filter: RoamingMessageFilter? = null
): Stream<MessageChain> = getMessagesStream(0, Long.MAX_VALUE, filter)
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -19,6 +19,7 @@ import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import kotlin.jvm.JvmStatic
/** /**
* 群荣誉信息 * 群荣誉信息

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -20,6 +20,9 @@ import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import net.mamoe.mirai.event.events.MemberJoinRequestEvent import net.mamoe.mirai.event.events.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmStatic
@Serializable @Serializable
@SerialName("RequestEventData") @SerialName("RequestEventData")

View File

@ -18,6 +18,8 @@ import net.mamoe.mirai.Mirai
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmField
import kotlin.jvm.Volatile
/** /**
* 表示一个事件. * 表示一个事件.
@ -152,6 +154,7 @@ public interface CancellableEvent : Event {
* [EventChannel.filter] [Listener.onEvent] 时产生的异常只会由监听方处理. * [EventChannel.filter] [Listener.onEvent] 时产生的异常只会由监听方处理.
*/ */
@JvmBlockingBridge @JvmBlockingBridge
@Suppress("TOP_LEVEL_FUNCTIONS_NOT_SUPPORTED") // compiler bug
public suspend fun <E : Event> E.broadcast(): E { public suspend fun <E : Event> E.broadcast(): E {
Mirai.broadcastEvent(this) Mirai.broadcastEvent(this)
return this return this

View File

@ -25,12 +25,14 @@ import net.mamoe.mirai.IMirai
import net.mamoe.mirai.event.ConcurrencyKind.CONCURRENT import net.mamoe.mirai.event.ConcurrencyKind.CONCURRENT
import net.mamoe.mirai.event.ConcurrencyKind.LOCKED import net.mamoe.mirai.event.ConcurrencyKind.LOCKED
import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.internal.event.registerEventHandler import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.NotStableForInheritance
import org.jetbrains.annotations.Contract import net.mamoe.mirai.utils.context
import java.util.function.Consumer
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**
@ -54,7 +56,7 @@ import kotlin.reflect.KClass
* *
* ### 对通道的操作 * ### 对通道的操作
* - 过滤通道: 通过 [EventChannel.filter]. 例如 `filter { it is BotEvent }` 得到一个只能监听到 [BotEvent] 的事件通道. * - 过滤通道: 通过 [EventChannel.filter]. 例如 `filter { it is BotEvent }` 得到一个只能监听到 [BotEvent] 的事件通道.
* - 转换为 Kotlin 协程 [Channel]: [EventChannel.asChannel] * - 转换为 Kotlin 协程 [Channel]: [EventChannel.forwardToChannel]
* - 添加 [CoroutineContext]: [context], [parentJob], [parentScope], [exceptionHandler] * - 添加 [CoroutineContext]: [context], [parentJob], [parentScope], [exceptionHandler]
* *
* ### 创建事件监听 * ### 创建事件监听
@ -80,38 +82,17 @@ import kotlin.reflect.KClass
* 使用 [EventChannel.forwardToChannel] 可将事件转发到指定 [SendChannel]. * 使用 [EventChannel.forwardToChannel] 可将事件转发到指定 [SendChannel].
*/ */
@NotStableForInheritance // since 2.12, before it was `final class`. @NotStableForInheritance // since 2.12, before it was `final class`.
public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi public constructor( public expect abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi public constructor(
public val baseEventClass: KClass<out BaseEvent>, baseEventClass: KClass<out BaseEvent>,
defaultCoroutineContext: CoroutineContext,
) {
/** /**
* 此事件通道的默认 [CoroutineScope.coroutineContext]. 将会被添加给所有注册的事件监听器. * 此事件通道的默认 [CoroutineScope.coroutineContext]. 将会被添加给所有注册的事件监听器.
*/ */
public val defaultCoroutineContext: CoroutineContext, public val defaultCoroutineContext: CoroutineContext
) {
/** public val baseEventClass: KClass<out BaseEvent>
* 创建事件监听并将监听结果发送在 [Channel]. 将返回值 [Channel] [关闭][Channel.close] 时将会同时关闭事件监听.
*
* @param capacity Channel 容量. 详见 [Channel] 构造.
*
* @see subscribeAlways
* @see Channel
*/
@Deprecated(
"Please use forwardToChannel instead.",
replaceWith = ReplaceWith(
"Channel<BaseEvent>(capacity).apply { forwardToChannel(this, coroutineContext, priority) }",
"kotlinx.coroutines.channels.Channel"
),
level = DeprecationLevel.ERROR,
)
@DeprecatedSinceMirai(warningSince = "2.10", errorSince = "2.12")
@MiraiExperimentalApi
public fun asChannel(
capacity: Int = Channel.RENDEZVOUS,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
@Suppress("UNUSED_PARAMETER") concurrency: ConcurrencyKind = CONCURRENT,
priority: EventPriority = EventPriority.NORMAL,
): Channel<out BaseEvent> =
Channel<BaseEvent>(capacity).apply { forwardToChannel(this, coroutineContext, priority) }
/** /**
* 创建事件监听并将监听结果转发到 [channel]. [Channel.send] 抛出 [ClosedSendChannelException] 时停止 [Listener] 监听和转发. * 创建事件监听并将监听结果转发到 [channel]. [Channel.send] 抛出 [ClosedSendChannelException] 时停止 [Listener] 监听和转发.
@ -139,16 +120,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
channel: SendChannel<@UnsafeVariance BaseEvent>, channel: SendChannel<@UnsafeVariance BaseEvent>,
coroutineContext: CoroutineContext = EmptyCoroutineContext, coroutineContext: CoroutineContext = EmptyCoroutineContext,
priority: EventPriority = EventPriority.MONITOR, priority: EventPriority = EventPriority.MONITOR,
): Listener<@UnsafeVariance BaseEvent> { ): Listener<@UnsafeVariance BaseEvent>
return subscribe(baseEventClass, coroutineContext, priority = priority) {
try {
channel.send(it)
ListeningStatus.LISTENING
} catch (_: ClosedSendChannelException) {
ListeningStatus.STOPPED
}
}
}
/** /**
* 通过 [Flow] 接收此通道内的所有事件. * 通过 [Flow] 接收此通道内的所有事件.
@ -216,9 +188,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
* @see filterIsInstance 过滤指定类型的事件 * @see filterIsInstance 过滤指定类型的事件
*/ */
@JvmSynthetic @JvmSynthetic
public fun filter(filter: suspend (event: BaseEvent) -> Boolean): EventChannel<BaseEvent> { public fun filter(filter: suspend (event: BaseEvent) -> Boolean): EventChannel<BaseEvent>
return FilterEventChannel(this, filter)
}
/** /**
* [EventChannel.filter] Java 版本. * [EventChannel.filter] Java 版本.
@ -258,32 +228,20 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
*/ */
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.LowPriorityInOverloadResolution @kotlin.internal.LowPriorityInOverloadResolution
public fun filter(filter: (event: BaseEvent) -> Boolean): EventChannel<BaseEvent> { public fun filter(filter: (event: BaseEvent) -> Boolean): EventChannel<BaseEvent>
return filter { runBIO { filter(it) } }
}
/** /**
* 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel] * 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel]
* @see filter 获取更多信息 * @see filter 获取更多信息
*/ */
@JvmSynthetic @JvmSynthetic
public inline fun <reified E : Event> filterIsInstance(): EventChannel<E> = public inline fun <reified E : Event> filterIsInstance(): EventChannel<E>
filterIsInstance(E::class)
/** /**
* 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel] * 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel]
* @see filter 获取更多信息 * @see filter 获取更多信息
*/ */
public fun <E : Event> filterIsInstance(kClass: KClass<out E>): EventChannel<E> { public fun <E : Event> filterIsInstance(kClass: KClass<out E>): EventChannel<E>
return filter { kClass.isInstance(it) }.cast()
}
/**
* 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel]
* @see filter 获取更多信息
*/
public fun <E : Event> filterIsInstance(clazz: Class<out E>): EventChannel<E> =
filterIsInstance(clazz.kotlin)
/** /**
@ -300,19 +258,13 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
*/ */
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.LowPriorityInOverloadResolution @kotlin.internal.LowPriorityInOverloadResolution
public fun exceptionHandler(coroutineExceptionHandler: CoroutineExceptionHandler): EventChannel<BaseEvent> { public fun exceptionHandler(coroutineExceptionHandler: CoroutineExceptionHandler): EventChannel<BaseEvent>
return context(coroutineExceptionHandler)
}
/** /**
* 创建一个新的 [EventChannel], [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler] * 创建一个新的 [EventChannel], [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler]
* @see context * @see context
*/ */
public fun exceptionHandler(coroutineExceptionHandler: (exception: Throwable) -> Unit): EventChannel<BaseEvent> { public fun exceptionHandler(coroutineExceptionHandler: (exception: Throwable) -> Unit): EventChannel<BaseEvent>
return context(CoroutineExceptionHandler { _, throwable ->
coroutineExceptionHandler(throwable)
})
}
/** /**
* 创建一个新的 [EventChannel], [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler] * 创建一个新的 [EventChannel], [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler]
@ -337,9 +289,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
* *
* @see CoroutineScope.globalEventChannel `GlobalEventChannel.parentScope()` 的扩展 * @see CoroutineScope.globalEventChannel `GlobalEventChannel.parentScope()` 的扩展
*/ */
public fun parentScope(coroutineScope: CoroutineScope): EventChannel<BaseEvent> { public fun parentScope(coroutineScope: CoroutineScope): EventChannel<BaseEvent>
return context(coroutineScope.coroutineContext)
}
/** /**
* 指定协程父 [Job]. 之后在此 [EventChannel] 下创建的事件监听器都会成为 [job] 的子任务, [job] 被取消时, 所有的事件监听器都会被取消. * 指定协程父 [Job]. 之后在此 [EventChannel] 下创建的事件监听器都会成为 [job] 的子任务, [job] 被取消时, 所有的事件监听器都会被取消.
@ -349,9 +299,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
* @see parentScope * @see parentScope
* @see context * @see context
*/ */
public fun parentJob(job: Job): EventChannel<BaseEvent> { public fun parentJob(job: Job): EventChannel<BaseEvent>
return context(job)
}
// endregion // endregion
@ -452,7 +400,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
concurrency: ConcurrencyKind = LOCKED, concurrency: ConcurrencyKind = LOCKED,
priority: EventPriority = EventPriority.NORMAL, priority: EventPriority = EventPriority.NORMAL,
noinline handler: suspend E.(E) -> ListeningStatus, noinline handler: suspend E.(E) -> ListeningStatus,
): Listener<E> = subscribe(E::class, coroutineContext, concurrency, priority, handler) ): Listener<E>
/** /**
* [subscribe] 的区别是接受 [eventClass] 参数, 而不使用 `reified` 泛型. 通常推荐使用具体化类型参数. * [subscribe] 的区别是接受 [eventClass] 参数, 而不使用 `reified` 泛型. 通常推荐使用具体化类型参数.
@ -467,10 +415,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
concurrency: ConcurrencyKind = LOCKED, concurrency: ConcurrencyKind = LOCKED,
priority: EventPriority = EventPriority.NORMAL, priority: EventPriority = EventPriority.NORMAL,
handler: suspend E.(E) -> ListeningStatus, handler: suspend E.(E) -> ListeningStatus,
): Listener<E> = subscribeInternal( ): Listener<E>
eventClass,
createListener(coroutineContext, concurrency, priority) { it.handler(it); }
)
/** /**
* 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件. * 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件.
@ -492,7 +437,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
concurrency: ConcurrencyKind = CONCURRENT, concurrency: ConcurrencyKind = CONCURRENT,
priority: EventPriority = EventPriority.NORMAL, priority: EventPriority = EventPriority.NORMAL,
noinline handler: suspend E.(E) -> Unit, noinline handler: suspend E.(E) -> Unit,
): Listener<E> = subscribeAlways(E::class, coroutineContext, concurrency, priority, handler) ): Listener<E>
/** /**
@ -506,10 +451,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
concurrency: ConcurrencyKind = CONCURRENT, concurrency: ConcurrencyKind = CONCURRENT,
priority: EventPriority = EventPriority.NORMAL, priority: EventPriority = EventPriority.NORMAL,
handler: suspend E.(E) -> Unit, handler: suspend E.(E) -> Unit,
): Listener<E> = subscribeInternal( ): Listener<E>
eventClass,
createListener(coroutineContext, concurrency, priority) { it.handler(it); ListeningStatus.LISTENING }
)
/** /**
* 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件, 只监听一次. * 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件, 只监听一次.
@ -527,7 +469,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
coroutineContext: CoroutineContext = EmptyCoroutineContext, coroutineContext: CoroutineContext = EmptyCoroutineContext,
priority: EventPriority = EventPriority.NORMAL, priority: EventPriority = EventPriority.NORMAL,
noinline handler: suspend E.(E) -> Unit, noinline handler: suspend E.(E) -> Unit,
): Listener<E> = subscribeOnce(E::class, coroutineContext, priority, handler) ): Listener<E>
/** /**
* @see subscribeOnce * @see subscribeOnce
@ -537,155 +479,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
coroutineContext: CoroutineContext = EmptyCoroutineContext, coroutineContext: CoroutineContext = EmptyCoroutineContext,
priority: EventPriority = EventPriority.NORMAL, priority: EventPriority = EventPriority.NORMAL,
handler: suspend E.(E) -> Unit, handler: suspend E.(E) -> Unit,
): Listener<E> = subscribeInternal( ): Listener<E>
eventClass,
createListener(coroutineContext, LOCKED, priority) { it.handler(it); ListeningStatus.STOPPED }
)
// endregion
/**
* 注册 [ListenerHost] 中的所有 [EventHandler] 标注的方法到这个 [EventChannel]. 查看 [EventHandler].
*
* @param coroutineContext [defaultCoroutineContext] 的基础上, 给事件监听协程的额外的 [CoroutineContext]
*
* @see subscribe
* @see EventHandler
* @see ListenerHost
*/
@JvmOverloads
public fun registerListenerHost(
host: ListenerHost,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
) {
val jobOfListenerHost: Job?
val coroutineContext0 = if (host is SimpleListenerHost) {
val listenerCoroutineContext = host.coroutineContext
val listenerJob = listenerCoroutineContext[Job]
val rsp = listenerCoroutineContext.minusKey(Job) +
coroutineContext +
(listenerCoroutineContext[CoroutineExceptionHandler] ?: EmptyCoroutineContext)
val registerCancelHook = when {
listenerJob === null -> false
// Registering cancellation hook is needless
// if [Job] of [EventChannel] is same as [Job] of [SimpleListenerHost]
(rsp[Job] ?: this.defaultCoroutineContext[Job]) === listenerJob -> false
else -> true
}
jobOfListenerHost = if (registerCancelHook) {
listenerCoroutineContext[Job]
} else {
null
}
rsp
} else {
jobOfListenerHost = null
coroutineContext
}
for (method in host.javaClass.declaredMethods) {
method.getAnnotation(EventHandler::class.java)?.let {
val listener = method.registerEventHandler(host, this, it, coroutineContext0)
// For [SimpleListenerHost.cancelAll]
jobOfListenerHost?.invokeOnCompletion { exception ->
listener.cancel(
when (exception) {
is CancellationException -> exception
is Throwable -> CancellationException(null, exception)
else -> null
}
)
}
}
}
}
// region Java API
/**
* Java API. 查看 [subscribeAlways] 获取更多信息.
*
* ```java
* eventChannel.subscribeAlways(GroupMessageEvent.class, (event) -> { });
* ```
*
* @see subscribe
* @see subscribeAlways
*/
@JvmOverloads
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.LowPriorityInOverloadResolution
public fun <E : Event> subscribeAlways(
eventClass: Class<out E>,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
concurrency: ConcurrencyKind = CONCURRENT,
priority: EventPriority = EventPriority.NORMAL,
handler: Consumer<E>,
): Listener<E> = subscribeInternal(
eventClass.kotlin,
createListener(coroutineContext, concurrency, priority) { event ->
runInterruptible(Dispatchers.IO) { handler.accept(event) }
ListeningStatus.LISTENING
}
)
/**
* Java API. 查看 [subscribe] 获取更多信息.
*
* ```java
* eventChannel.subscribe(GroupMessageEvent.class, (event) -> {
* return ListeningStatus.LISTENING;
* });
* ```
*
* @see subscribe
*/
@JvmOverloads
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.LowPriorityInOverloadResolution
public fun <E : Event> subscribe(
eventClass: Class<out E>,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
concurrency: ConcurrencyKind = CONCURRENT,
priority: EventPriority = EventPriority.NORMAL,
handler: java.util.function.Function<E, ListeningStatus>,
): Listener<E> = subscribeInternal(
eventClass.kotlin,
createListener(coroutineContext, concurrency, priority) { event ->
runInterruptible(Dispatchers.IO) { handler.apply(event) }
}
)
/**
* Java API. 查看 [subscribeOnce] 获取更多信息.
*
* ```java
* eventChannel.subscribeOnce(GroupMessageEvent.class, (event) -> { });
* ```
*
* @see subscribe
* @see subscribeOnce
*/
@JvmOverloads
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.LowPriorityInOverloadResolution
public fun <E : Event> subscribeOnce(
eventClass: Class<out E>,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
concurrency: ConcurrencyKind = CONCURRENT,
priority: EventPriority = EventPriority.NORMAL,
handler: Consumer<E>,
): Listener<E> = subscribeInternal(
eventClass.kotlin,
createListener(coroutineContext, concurrency, priority) { event ->
runInterruptible(Dispatchers.IO) { handler.accept(event) }
ListeningStatus.STOPPED
}
)
// endregion // endregion
@ -697,19 +491,12 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
protected abstract fun <E : Event> registerListener(eventClass: KClass<out E>, listener: Listener<E>) protected abstract fun <E : Event> registerListener(eventClass: KClass<out E>, listener: Listener<E>)
// to overcome visibility issue // to overcome visibility issue
internal fun <E : Event> registerListener0(eventClass: KClass<out E>, listener: Listener<E>) { internal fun <E : Event> registerListener0(eventClass: KClass<out E>, listener: Listener<E>)
return registerListener(eventClass, listener)
}
private fun <L : Listener<E>, E : Event> subscribeInternal(eventClass: KClass<out E>, listener: L): L {
registerListener(eventClass, listener)
return listener
}
/** /**
* Creates [Listener] instance using the [listenerBlock] action. * Creates [Listener] instance using the [listenerBlock] action.
*/ */
@Contract("_ -> new") // always creates new instance // @Contract("_ -> new") // always creates new instance
@MiraiInternalApi @MiraiInternalApi
protected abstract fun <E : Event> createListener( protected abstract fun <E : Event> createListener(
coroutineContext: CoroutineContext, coroutineContext: CoroutineContext,
@ -724,7 +511,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
concurrencyKind: ConcurrencyKind, concurrencyKind: ConcurrencyKind,
priority: EventPriority, priority: EventPriority,
listenerBlock: suspend (E) -> ListeningStatus, listenerBlock: suspend (E) -> ListeningStatus,
): Listener<E> = createListener(coroutineContext, concurrencyKind, priority, listenerBlock) ): Listener<E>
// endregion // endregion
} }

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") @file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@ -14,7 +14,8 @@ package net.mamoe.mirai.event
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.internal.LowPriorityInOverloadResolution import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**

View File

@ -19,6 +19,9 @@ import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.loadService import net.mamoe.mirai.utils.loadService
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**

View File

@ -18,6 +18,8 @@ import kotlinx.coroutines.sync.Mutex
import net.mamoe.mirai.event.EventPriority.* import net.mamoe.mirai.event.EventPriority.*
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
* 订阅者的状态 * 订阅者的状态

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress( @file:Suppress(
@ -22,6 +22,9 @@ import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.MessageSource.Key.quote import net.mamoe.mirai.message.data.MessageSource.Key.quote
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import kotlin.annotation.AnnotationTarget.CONSTRUCTOR import kotlin.annotation.AnnotationTarget.CONSTRUCTOR
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmSynthetic
/** /**

View File

@ -17,6 +17,8 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
import kotlin.reflect.KClass import kotlin.reflect.KClass

View File

@ -17,6 +17,8 @@ import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**

View File

@ -16,6 +16,8 @@ import kotlinx.coroutines.*
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**

View File

@ -23,6 +23,8 @@ import net.mamoe.mirai.internal.event.VerboseEvent
import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.utils.ExternalResource import net.mamoe.mirai.utils.ExternalResource
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**

View File

@ -24,6 +24,8 @@ import net.mamoe.mirai.message.data.source
import net.mamoe.mirai.message.isContextIdenticalWith import net.mamoe.mirai.message.isContextIdenticalWith
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**

View File

@ -22,6 +22,9 @@ import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**

View File

@ -20,6 +20,8 @@ import net.mamoe.mirai.internal.event.VerboseEvent
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
@ -105,7 +107,7 @@ public data class GroupTempMessagePreSendEvent @MiraiInternalApi constructor(
public override val target: NormalMember, public override val target: NormalMember,
/** 待发送的消息. 修改后将会同时应用于发送. */ /** 待发送的消息. 修改后将会同时应用于发送. */
public override var message: Message public override var message: Message
) : @kotlin.Suppress("DEPRECATION_ERROR") TempMessagePreSendEvent(target, message) { ) : @Suppress("DEPRECATION_ERROR") TempMessagePreSendEvent(target, message) {
public override val group: Group get() = target.group public override val group: Group get() = target.group
} }

View File

@ -18,6 +18,9 @@ import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.isSameClass
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
@ -78,9 +81,7 @@ public sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
@Suppress("DuplicatedCode") @Suppress("DuplicatedCode")
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (other !is FriendRecall || !isSameClass(this, other)) return false
other as FriendRecall
if (bot != other.bot) return false if (bot != other.bot) return false
if (!messageIds.contentEquals(other.messageIds)) return false if (!messageIds.contentEquals(other.messageIds)) return false
@ -123,9 +124,7 @@ public sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
@Suppress("DuplicatedCode") @Suppress("DuplicatedCode")
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (other !is GroupRecall || !isSameClass(this, other)) return false
other as GroupRecall
if (bot != other.bot) return false if (bot != other.bot) return false
if (authorId != other.authorId) return false if (authorId != other.authorId) return false

View File

@ -18,6 +18,8 @@ import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.OnlineMessageSource import net.mamoe.mirai.message.data.OnlineMessageSource
import net.mamoe.mirai.message.data.source import net.mamoe.mirai.message.data.source
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**

View File

@ -17,6 +17,8 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.event.AbstractEvent import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress("unused", "FunctionName") @file:Suppress("unused", "FunctionName")
@ -18,6 +18,8 @@ import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
// note: 若你使用 IntelliJ IDEA, 按 alt + 7 可打开结构 // note: 若你使用 IntelliJ IDEA, 按 alt + 7 可打开结构

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:JvmMultifileClass @file:JvmMultifileClass
@ -13,6 +13,8 @@
package net.mamoe.mirai.event.events package net.mamoe.mirai.event.events
import kotlinx.atomicfu.AtomicBoolean
import kotlinx.atomicfu.atomic
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.Mirai import net.mamoe.mirai.Mirai
@ -23,7 +25,9 @@ import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.internal.event.VerboseEvent import net.mamoe.mirai.internal.event.VerboseEvent
import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import java.util.concurrent.atomic.AtomicBoolean import kotlin.jvm.JvmField
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
@ -80,7 +84,7 @@ public data class NewFriendRequestEvent @MiraiInternalApi public constructor(
public val fromNick: String, public val fromNick: String,
) : BotEvent, Packet, AbstractEvent(), FriendInfoChangeEvent { ) : BotEvent, Packet, AbstractEvent(), FriendInfoChangeEvent {
@JvmField @JvmField
internal val responded: AtomicBoolean = AtomicBoolean(false) internal val responded: AtomicBoolean = atomic(false)
/** /**
* @return 申请人来自的群. 当申请人来自其他途径申请时为 `null` * @return 申请人来自的群. 当申请人来自其他途径申请时为 `null`

View File

@ -16,6 +16,8 @@
package net.mamoe.mirai.event.events package net.mamoe.mirai.event.events
import kotlinx.atomicfu.AtomicBoolean
import kotlinx.atomicfu.atomic
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.Mirai import net.mamoe.mirai.Mirai
@ -27,7 +29,7 @@ import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import java.util.concurrent.atomic.AtomicBoolean import kotlin.jvm.*
/** /**
* 机器人被踢出群或在其他客户端主动退出一个群. 在事件广播前 [Bot.groups] 就已删除这个群. * 机器人被踢出群或在其他客户端主动退出一个群. 在事件广播前 [Bot.groups] 就已删除这个群.
@ -353,7 +355,7 @@ public data class BotInvitedJoinGroupRequestEvent @MiraiInternalApi constructor(
public val invitor: Friend? get() = this.bot.getFriend(invitorId) public val invitor: Friend? get() = this.bot.getFriend(invitorId)
@JvmField @JvmField
internal val responded: AtomicBoolean = AtomicBoolean(false) internal val responded: AtomicBoolean = atomic(false)
@JvmBlockingBridge @JvmBlockingBridge
public suspend fun accept(): Unit = Mirai.acceptInvitedJoinGroupRequest(this) public suspend fun accept(): Unit = Mirai.acceptInvitedJoinGroupRequest(this)
@ -403,7 +405,7 @@ public data class MemberJoinRequestEvent @MiraiInternalApi constructor(
@JvmField @JvmField
@PublishedApi @PublishedApi
internal val responded: AtomicBoolean = AtomicBoolean(false) internal val responded: AtomicBoolean = atomic(false)
/** /**
* 同意这个请求 * 同意这个请求
@ -445,7 +447,7 @@ public data class MemberJoinRequestEvent @MiraiInternalApi constructor(
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
@JvmStatic @JvmStatic
@JvmName("copy\$default") // avoid being mangled @JvmName("copy\$default") // avoid being mangled
fun `copy$default`( fun copy_default(
var0: MemberJoinRequestEvent, var1: Bot, var2: Long, var4: String, var5: Long, var7: Long, var0: MemberJoinRequestEvent, var1: Bot, var2: Long, var4: String, var5: Long, var7: Long,
var9: String, var10: String, var11: Int, @Suppress("UNUSED_PARAMETER") var12: Any var9: String, var10: String, var11: Int, @Suppress("UNUSED_PARAMETER") var12: Any
): MemberJoinRequestEvent { ): MemberJoinRequestEvent {

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:JvmMultifileClass @file:JvmMultifileClass
@ -17,6 +17,9 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.Event
import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
* 有关一个 [Bot] 的事件 * 有关一个 [Bot] 的事件

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress("DuplicatedCode") @file:Suppress("DuplicatedCode")
@ -19,6 +19,9 @@ import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.message.isContextIdenticalWith import net.mamoe.mirai.message.isContextIdenticalWith
import net.mamoe.mirai.message.nextMessage import net.mamoe.mirai.message.nextMessage
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import kotlin.jvm.JvmInline
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
@ -404,7 +407,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
@Suppress("unused") @Suppress("unused")
@JvmName("invoke-RNyhSv4") @JvmName("invoke-RNyhSv4")
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
public fun MessageSelectionTimeoutChecker.invoke000(block: suspend () -> R): Void? { public fun MessageSelectionTimeoutChecker.invoke000(block: suspend () -> R): Nothing? {
invoke(block) invoke(block)
return null return null
} }
@ -417,7 +420,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
@JvmName("reply-RNyhSv4") @JvmName("reply-RNyhSv4")
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun MessageSelectionTimeoutChecker.reply000(block: suspend () -> Any?): Void? { public infix fun MessageSelectionTimeoutChecker.reply000(block: suspend () -> Any?): Nothing? {
reply(block) reply(block)
return null return null
} }
@ -430,7 +433,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
@JvmName("reply-sCZ5gAI") @JvmName("reply-sCZ5gAI")
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun MessageSelectionTimeoutChecker.reply000(message: String): Void? { public infix fun MessageSelectionTimeoutChecker.reply000(message: String): Nothing? {
reply(message) reply(message)
return null return null
} }
@ -443,7 +446,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
@JvmName("reply-AVDwu3U") @JvmName("reply-AVDwu3U")
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun MessageSelectionTimeoutChecker.reply000(message: Message): Void? { public infix fun MessageSelectionTimeoutChecker.reply000(message: Message): Nothing? {
reply(message) reply(message)
return null return null
} }
@ -457,7 +460,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
@JvmName("quoteReply-RNyhSv4") @JvmName("quoteReply-RNyhSv4")
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun MessageSelectionTimeoutChecker.quoteReply000(block: suspend () -> Any?): Void? { public infix fun MessageSelectionTimeoutChecker.quoteReply000(block: suspend () -> Any?): Nothing? {
reply(block) reply(block)
return null return null
} }
@ -470,7 +473,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
@JvmName("quoteReply-sCZ5gAI") @JvmName("quoteReply-sCZ5gAI")
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun MessageSelectionTimeoutChecker.quoteReply000(message: String): Void? { public infix fun MessageSelectionTimeoutChecker.quoteReply000(message: String): Nothing? {
reply(message) reply(message)
return null return null
} }
@ -483,7 +486,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
@JvmName("quoteReply-AVDwu3U") @JvmName("quoteReply-AVDwu3U")
@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN) @Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun MessageSelectionTimeoutChecker.quoteReply000(message: Message): Void? { public infix fun MessageSelectionTimeoutChecker.quoteReply000(message: Message): Nothing? {
reply(message) reply(message)
return null return null
} }

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:JvmMultifileClass @file:JvmMultifileClass
@ -25,6 +25,8 @@ import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
public typealias MessageEventSubscribersBuilder = MessageSubscribersBuilder<MessageEvent, Listener<MessageEvent>, Unit, Unit> public typealias MessageEventSubscribersBuilder = MessageSubscribersBuilder<MessageEvent, Listener<MessageEvent>, Unit, Unit>

View File

@ -13,7 +13,10 @@ import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.buildClassSerialDescriptor import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.modules.* import kotlinx.serialization.modules.PolymorphicModuleBuilder
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.overwriteWith
import kotlinx.serialization.modules.polymorphic
import net.mamoe.mirai.Mirai import net.mamoe.mirai.Mirai
import net.mamoe.mirai.message.MessageSerializers import net.mamoe.mirai.message.MessageSerializers
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
@ -21,9 +24,8 @@ import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.lateinitMutableProperty import net.mamoe.mirai.utils.lateinitMutableProperty
import net.mamoe.mirai.utils.map import net.mamoe.mirai.utils.map
import net.mamoe.mirai.utils.takeElementsFrom import net.mamoe.mirai.utils.takeElementsFrom
import kotlin.jvm.Synchronized
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.full.allSuperclasses
import kotlin.reflect.full.isSubclassOf
@MiraiInternalApi @MiraiInternalApi
public open class MessageSourceSerializerImpl(serialName: String) : public open class MessageSourceSerializerImpl(serialName: String) :
@ -208,37 +210,25 @@ internal object MessageSerializersImpl : MessageSerializers {
} }
} }
internal fun <M : Any> SerializersModule.overwritePolymorphicWith( internal expect fun <M : Any> SerializersModule.overwritePolymorphicWith(
type: KClass<M>, type: KClass<M>,
serializer: KSerializer<M> serializer: KSerializer<M>
): SerializersModule { ): SerializersModule
return overwriteWith(SerializersModule {
// contextual(type, serializer)
for (superclass in type.allSuperclasses) {
if (superclass.isFinal) continue
if (!superclass.isSubclassOf(SingleMessage::class)) continue
@Suppress("UNCHECKED_CAST")
polymorphic(superclass as KClass<Any>) {
subclass(type, serializer)
}
}
})
}
private inline fun <reified M : SingleMessage> SerializersModuleBuilder.hierarchicallyPolymorphic(serializer: KSerializer<M>) = //private inline fun <reified M : SingleMessage> SerializersModuleBuilder.hierarchicallyPolymorphic(serializer: KSerializer<M>) =
hierarchicallyPolymorphic(M::class, serializer) // hierarchicallyPolymorphic(M::class, serializer)
//
private fun <M : SingleMessage> SerializersModuleBuilder.hierarchicallyPolymorphic( //private fun <M : SingleMessage> SerializersModuleBuilder.hierarchicallyPolymorphic(
type: KClass<M>, // type: KClass<M>,
serializer: KSerializer<M> // serializer: KSerializer<M>
) { //) {
// contextual(type, serializer) // // contextual(type, serializer)
for (superclass in type.allSuperclasses) { // for (superclass in type.allSuperclasses) {
if (superclass.isFinal) continue // if (superclass.isFinal) continue
if (!superclass.isSubclassOf(SingleMessage::class)) continue // if (!superclass.isSubclassOf(SingleMessage::class)) continue
@Suppress("UNCHECKED_CAST") // @Suppress("UNCHECKED_CAST")
polymorphic(superclass as KClass<Any>) { // polymorphic(superclass as KClass<Any>) {
subclass(type, serializer) // subclass(type, serializer)
} // }
} // }
} //}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -10,8 +10,6 @@
package net.mamoe.mirai.internal.utils package net.mamoe.mirai.internal.utils
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import org.apache.logging.log4j.Marker
import org.apache.logging.log4j.MarkerManager
/** /**
* 内部添加 [Marker] 支持, 并兼容旧 [MiraiLogger] API. * 内部添加 [Marker] 支持, 并兼容旧 [MiraiLogger] API.

View File

@ -0,0 +1,15 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.utils
internal expect interface Marker {
fun addParents(vararg parent: Marker)
}

View File

@ -0,0 +1,14 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.utils
internal expect object MarkerManager {
fun getMarker(name: String): Marker
}

View File

@ -10,8 +10,6 @@
package net.mamoe.mirai.internal.utils package net.mamoe.mirai.internal.utils
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import java.text.SimpleDateFormat
import java.util.*
/** /**
@ -101,11 +99,8 @@ internal open class StdoutLogger constructor(
else debug(message.toString()) else debug(message.toString())
} }
protected open val timeFormat: SimpleDateFormat by threadLocal {
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
}
private val currentTimeFormatted get() = timeFormat.format(Date()) private val currentTimeFormatted get() = currentTimeFormatted(null)
@MiraiExperimentalApi("This is subject to change.") @MiraiExperimentalApi("This is subject to change.")
protected enum class Color(private val format: String) { protected enum class Color(private val format: String) {

View File

@ -8,85 +8,41 @@
*/ */
@file:Suppress("MemberVisibilityCanBePrivate", "unused") @file:Suppress("MemberVisibilityCanBePrivate", "unused")
@file:JvmBlockingBridge
package net.mamoe.mirai.message.action package net.mamoe.mirai.message.action
import kotlinx.coroutines.* import kotlinx.coroutines.Deferred
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.MessageSource.Key.recallIn import net.mamoe.mirai.message.data.MessageSource.Key.recallIn
import java.util.concurrent.CompletableFuture
/** /**
* [MessageSource.recallIn] 的结果. * [MessageSource.recallIn] 的结果.
* *
* @see MessageSource.recallIn * @see MessageSource.recallIn
*/ */
public class AsyncRecallResult internal constructor( public expect class AsyncRecallResult internal constructor(
/** /**
* 撤回时产生的异常. Kotlin [Deferred] API. * 撤回时产生的异常.
*/ */
public val exception: Deferred<Throwable?>, exception: Deferred<Throwable?>,
) { ) {
/** public val exception: Deferred<Throwable?>
* 撤回时产生的异常. Java [CompletableFuture] API.
*/
public val exceptionFuture: CompletableFuture<Throwable?> by lazy { exception.asCompletableFuture() }
/** /**
* 撤回是否成功. Kotlin [Deferred] API. * 撤回是否成功.
*/ */
public val isSuccess: Deferred<Boolean> by lazy { public val isSuccess: Deferred<Boolean>
CompletableDeferred<Boolean>().apply {
exception.invokeOnCompletion {
complete(it == null)
}
}
}
/**
* 撤回是否成功. Java [CompletableFuture] API.
*/
public val isSuccessFuture: CompletableFuture<Boolean> by lazy { isSuccess.asCompletableFuture() }
/** /**
* 等待撤回完成, 返回撤回时产生的异常. * 等待撤回完成, 返回撤回时产生的异常.
*/ */
@JvmBlockingBridge public suspend fun awaitException(): Throwable?
public suspend fun awaitException(): Throwable? {
return exception.await()
}
/** /**
* 等待撤回完成, 返回撤回的结果. * 等待撤回完成, 返回撤回的结果.
*/ */
@JvmBlockingBridge public suspend fun awaitIsSuccess(): Boolean
public suspend fun awaitIsSuccess(): Boolean {
return isSuccess.await()
}
} }
// copied from kotlinx-coroutines-jdk8
private fun <T> Deferred<T>.asCompletableFuture(): CompletableFuture<T> {
val future = CompletableFuture<T>()
setupCancellation(future)
invokeOnCompletion {
@OptIn(ExperimentalCoroutinesApi::class)
try {
future.complete(getCompleted())
} catch (t: Throwable) {
future.completeExceptionally(t)
}
}
return future
}
// copied from kotlinx-coroutines-jdk8
private fun Job.setupCancellation(future: CompletableFuture<*>) {
future.whenComplete { _, exception ->
cancel(exception?.let {
it as? CancellationException ?: CancellationException("CompletableFuture was completed exceptionally", it)
})
}
}

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
package net.mamoe.mirai.message.action package net.mamoe.mirai.message.action
@ -16,6 +16,8 @@ import net.mamoe.mirai.event.events.NudgeEvent
import net.mamoe.mirai.message.data.PokeMessage import net.mamoe.mirai.message.data.PokeMessage
import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* 一个 "戳一戳" 动作. * 一个 "戳一戳" 动作.

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress("unused", "NOTHING_TO_INLINE") @file:Suppress("unused", "NOTHING_TO_INLINE")
@ -17,6 +17,10 @@ import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.MessageChain.Companion.deserializeFromMiraiCode import net.mamoe.mirai.message.data.MessageChain.Companion.deserializeFromMiraiCode
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* Mirai 码相关操作. * Mirai 码相关操作.

View File

@ -24,6 +24,9 @@ import net.mamoe.mirai.message.code.CodableMessage
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**

View File

@ -19,6 +19,9 @@ import net.mamoe.mirai.message.code.CodableMessage
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
* "@全体成员". * "@全体成员".

View File

@ -22,6 +22,10 @@ import net.mamoe.mirai.message.MessageSerializers
import net.mamoe.mirai.message.data.MessageChain.Companion.serializeToJsonString import net.mamoe.mirai.message.data.MessageChain.Companion.serializeToJsonString
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds

View File

@ -1,22 +1,20 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress(
"MemberVisibilityCanBePrivate", "unused", "EXPERIMENTAL_API_USAGE",
"NOTHING_TO_INLINE", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE",
"INAPPLICABLE_JVM_NAME"
)
@file:JvmMultifileClass @file:JvmMultifileClass
@file:JvmName("MessageUtils") @file:JvmName("MessageUtils")
package net.mamoe.mirai.message.data package net.mamoe.mirai.message.data
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
* 约束一个 [MessageChain] 中只存在这一种类型的元素. 新元素将会替换旧元素, 保持原顺序. * 约束一个 [MessageChain] 中只存在这一种类型的元素. 新元素将会替换旧元素, 保持原顺序.
* *

View File

@ -7,8 +7,6 @@
* https://github.com/mamoe/mirai/blob/dev/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:OptIn(MiraiInternalApi::class)
package net.mamoe.mirai.message.data package net.mamoe.mirai.message.data
import io.ktor.utils.io.core.* import io.ktor.utils.io.core.*
@ -19,9 +17,9 @@ import kotlinx.serialization.protobuf.ProtoBuf
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import net.mamoe.mirai.message.MessageSerializers import net.mamoe.mirai.message.MessageSerializers
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.ConcurrentLinkedDeque
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import java.util.concurrent.ConcurrentLinkedQueue
/** /**
* 自定义消息 * 自定义消息
@ -117,7 +115,7 @@ public sealed class CustomMessage : SingleMessage {
} }
public companion object { public companion object {
private val factories: ConcurrentLinkedQueue<Factory<*>> = ConcurrentLinkedQueue() private val factories: MutableCollection<Factory<*>> = ConcurrentLinkedDeque()
internal fun register(factory: Factory<out CustomMessage>) { internal fun register(factory: Factory<out CustomMessage>) {
factories.removeAll { it::class == factory::class } factories.removeAll { it::class == factory::class }

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@ -19,7 +19,10 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.IMirai import net.mamoe.mirai.IMirai
import net.mamoe.mirai.utils.DeprecatedSinceMirai import net.mamoe.mirai.utils.DeprecatedSinceMirai
import net.mamoe.mirai.utils.isSameClass
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
@ -81,10 +84,7 @@ constructor(
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (other !is RichMessageOrigin || !isSameClass(this, other)) return false
@Suppress("DEPRECATION_ERROR")
other as RichMessageOrigin
if (origin != other.origin) return false if (origin != other.origin) return false
if (resourceId != other.resourceId) return false if (resourceId != other.resourceId) return false

View File

@ -19,8 +19,11 @@ import net.mamoe.mirai.message.code.CodableMessage
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.annotations.Range
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
import org.jetbrains.annotations.Range import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
import kotlin.random.Random import kotlin.random.Random
import kotlin.random.nextInt import kotlin.random.nextInt

View File

@ -19,6 +19,9 @@ import net.mamoe.mirai.message.code.CodableMessage
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.jvm.JvmField
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
* QQ 自带表情 * QQ 自带表情

View File

@ -25,6 +25,10 @@ import net.mamoe.mirai.message.code.CodableMessage
import net.mamoe.mirai.message.code.internal.appendStringAsMiraiCode import net.mamoe.mirai.message.code.internal.appendStringAsMiraiCode
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* 文件消息. * 文件消息.

View File

@ -18,6 +18,8 @@ import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* 闪照. 闪照的内容取决于 [image] 代表的图片. * 闪照. 闪照的内容取决于 [image] 代表的图片.

View File

@ -19,7 +19,8 @@ import net.mamoe.mirai.event.events.MessageEvent
import net.mamoe.mirai.message.data.ForwardMessage.DisplayStrategy import net.mamoe.mirai.message.data.ForwardMessage.DisplayStrategy
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmSynthetic
/** /**
* 未通过 [DisplayStrategy] 渲染的合并转发消息. [RawForwardMessage] 仅作为一个中间件, 用于 [ForwardMessageBuilder]. * 未通过 [DisplayStrategy] 渲染的合并转发消息. [RawForwardMessage] 仅作为一个中间件, 用于 [ForwardMessageBuilder].

View File

@ -18,6 +18,8 @@ import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import net.mamoe.mirai.utils.castOrNull import net.mamoe.mirai.utils.castOrNull
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/** /**
* 一些特殊的消息 * 一些特殊的消息

View File

@ -7,13 +7,9 @@
* https://github.com/mamoe/mirai/blob/dev/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:Suppress(
"MemberVisibilityCanBePrivate", "unused", "EXPERIMENTAL_API_USAGE",
"NOTHING_TO_INLINE", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE",
"INAPPLICABLE_JVM_NAME"
)
@file:JvmMultifileClass @file:JvmMultifileClass
@file:JvmName("MessageUtils") @file:JvmName("MessageUtils")
@file:Suppress("NOTHING_TO_INLINE")
package net.mamoe.mirai.message.data package net.mamoe.mirai.message.data
@ -27,7 +23,9 @@ import net.mamoe.mirai.message.code.MiraiCode.serializeToMiraiCode
import net.mamoe.mirai.message.data.MessageChain.Companion.serializeToJsonString import net.mamoe.mirai.message.data.MessageChain.Companion.serializeToJsonString
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import kotlin.internal.LowPriorityInOverloadResolution import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
* 可发送的或从服务器接收的消息. * 可发送的或从服务器接收的消息.
@ -200,7 +198,8 @@ public interface Message {
* *
* @param ignoreCase `true` 时忽略大小写 * @param ignoreCase `true` 时忽略大小写
*/ */
@LowPriorityInOverloadResolution @kotlin.internal.LowPriorityInOverloadResolution
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
public fun contentEquals(another: Message, ignoreCase: Boolean = false): Boolean = public fun contentEquals(another: Message, ignoreCase: Boolean = false): Boolean =
contentEquals(another, ignoreCase, false) contentEquals(another, ignoreCase, false)
@ -281,6 +280,7 @@ public interface Message {
/** 将 [another] 按顺序连接到这个消息的尾部. */ /** 将 [another] 按顺序连接到这个消息的尾部. */
@JvmName("plusIterableString") @JvmName("plusIterableString")
@Suppress("INAPPLICABLE_JVM_NAME")
public operator fun plus(another: Iterable<String>): MessageChain = public operator fun plus(another: Iterable<String>): MessageChain =
another.fold(this, Message::plus).toMessageChain() another.fold(this, Message::plus).toMessageChain()
@ -360,7 +360,7 @@ public inline fun Message.repeat(count: Int): MessageChain {
return this.toMessageChain() return this.toMessageChain()
} }
return buildMessageChain(count) { return buildMessageChain(count) {
repeat(count) { repeat(count) l@{
add(this@repeat) add(this@repeat)
} }
} }

View File

@ -34,9 +34,8 @@ import net.mamoe.mirai.message.data.MessageSource.Key.recall
import net.mamoe.mirai.message.data.MessageSource.Key.recallIn import net.mamoe.mirai.message.data.MessageSource.Key.recallIn
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import java.util.stream.Stream import kotlin.jvm.*
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
import kotlin.streams.asSequence
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_ABSTRACT_MESSAGE_KEYS as RAMK import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_ABSTRACT_MESSAGE_KEYS as RAMK
/** /**
@ -492,12 +491,6 @@ public inline fun messageChainOf(vararg messages: Message): MessageChain = messa
public fun Sequence<Message>.toMessageChain(): MessageChain = public fun Sequence<Message>.toMessageChain(): MessageChain =
LinearMessageChainImpl.create(ConstrainSingleHelper.constrainSingleMessages(this)) LinearMessageChainImpl.create(ConstrainSingleHelper.constrainSingleMessages(this))
/**
* 扁平化 [this] 并创建一个 [MessageChain].
*/
@JvmName("newChain")
public fun Stream<Message>.toMessageChain(): MessageChain = this.asSequence().toMessageChain()
/** /**
* 扁平化 [this] 并创建一个 [MessageChain]. * 扁平化 [this] 并创建一个 [MessageChain].
*/ */

View File

@ -15,6 +15,9 @@ package net.mamoe.mirai.message.data
import kotlin.contracts.InvocationKind.EXACTLY_ONCE import kotlin.contracts.InvocationKind.EXACTLY_ONCE
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
* 构建一个 [MessageChain]. 用法查看 [MessageChainBuilder]. * 构建一个 [MessageChain]. 用法查看 [MessageChainBuilder].

View File

@ -1,14 +1,16 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
package net.mamoe.mirai.message.data package net.mamoe.mirai.message.data
import kotlin.jvm.JvmField
/** /**
* 类型 Key. 由伴生对象实现, 表示一个 [Message] 对象的类型. * 类型 Key. 由伴生对象实现, 表示一个 [Message] 对象的类型.
* *

View File

@ -18,6 +18,7 @@ import net.mamoe.mirai.IMirai
import net.mamoe.mirai.message.data.visitor.MessageVisitor import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.isSameClass
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
/** /**
@ -71,9 +72,7 @@ public class MessageOrigin(
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (other !is MessageOrigin || !isSameClass(this, other)) return false
other as MessageOrigin
if (origin != other.origin) return false if (origin != other.origin) return false
if (resourceId != other.resourceId) return false if (resourceId != other.resourceId) return false

View File

@ -32,6 +32,10 @@ import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiInternalApi import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.NotStableForInheritance import net.mamoe.mirai.utils.NotStableForInheritance
import net.mamoe.mirai.utils.safeCast import net.mamoe.mirai.utils.safeCast
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
/** /**
* 消息源. 消息源存在于 [MessageChain] , 用于表示这个消息的来源, 也可以用来分辨 [MessageChain]. * 消息源. 消息源存在于 [MessageChain] , 用于表示这个消息的来源, 也可以用来分辨 [MessageChain].

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2021 Mamoe Technologies and contributors. * Copyright 2019-2022 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/dev/LICENSE
*/ */
@file:JvmMultifileClass @file:JvmMultifileClass
@ -20,6 +20,9 @@ import net.mamoe.mirai.contact.ContactOrBot
import net.mamoe.mirai.message.data.MessageSource.Key.quote import net.mamoe.mirai.message.data.MessageSource.Key.quote
import net.mamoe.mirai.message.data.MessageSource.Key.recall import net.mamoe.mirai.message.data.MessageSource.Key.recall
import net.mamoe.mirai.utils.currentTimeSeconds import net.mamoe.mirai.utils.currentTimeSeconds
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
* 将在线消息源转换为离线消息源. * 将在线消息源转换为离线消息源.

Some files were not shown because too many files have changed in this diff Show More