mirror of
https://github.com/mamoe/mirai.git
synced 2024-12-26 00:20:10 +08:00
Implement multiplatform modules
This commit is contained in:
parent
ce87400998
commit
ff2a8acb0c
@ -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.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
|
||||
import java.io.File
|
||||
|
||||
private val miraiPlatform = Attribute.of(
|
||||
"net.mamoe.mirai.platform",
|
||||
@ -35,6 +30,9 @@ private val miraiPlatform = Attribute.of(
|
||||
fun Project.configureHMPPJvm() {
|
||||
extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
|
||||
jvm("jvmBase") {
|
||||
compilations.all {
|
||||
this.compileKotlinTask.enabled = false // IDE complain
|
||||
}
|
||||
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) // avoid resolving by others
|
||||
// attributes.attribute(miraiPlatform, "jvmBase")
|
||||
}
|
||||
@ -57,16 +55,18 @@ fun Project.configureHMPPJvm() {
|
||||
|
||||
val nativeMainSets = mutableListOf<KotlinSourceSet>()
|
||||
val nativeTestSets = mutableListOf<KotlinSourceSet>()
|
||||
val nativeTargets = mutableListOf<KotlinNativeTarget>()
|
||||
|
||||
if (ideaActive) {
|
||||
when {
|
||||
val target = when {
|
||||
Os.isFamily(Os.FAMILY_MAC) -> if (Os.isArch("aarch64")) macosArm64("native") else macosX64("native")
|
||||
Os.isFamily(Os.FAMILY_WINDOWS) -> mingwX64("native")
|
||||
else -> linuxX64("native")
|
||||
}
|
||||
nativeTargets.add(target)
|
||||
} else {
|
||||
// 1.6.0
|
||||
val nativeTargets: List<String> = arrayOf(
|
||||
val nativeTargetNames: List<String> = arrayOf(
|
||||
// serialization doesn't support those commented targets
|
||||
// "androidNativeArm32, androidNativeArm64, androidNativeX86, androidNativeX64",
|
||||
"iosArm32, iosArm64, iosX64, iosSimulatorArm64",
|
||||
@ -77,11 +77,12 @@ fun Project.configureHMPPJvm() {
|
||||
"mingwX64",
|
||||
// "wasm32" // linuxArm32Hfp, mingwX86
|
||||
).flatMap { it.split(",") }.map { it.trim() }
|
||||
presets.filter { it.name in nativeTargets }
|
||||
presets.filter { it.name in nativeTargetNames }
|
||||
.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())
|
||||
nativeTestSets.add(target.compilations[TEST_COMPILATION_NAME].kotlinSourceSets.first())
|
||||
nativeTargets.add(target)
|
||||
}
|
||||
|
||||
if (!ideaActive) {
|
||||
@ -95,31 +96,8 @@ fun Project.configureHMPPJvm() {
|
||||
}
|
||||
}
|
||||
|
||||
// nativeTarget.apply {
|
||||
// val myrust by compilations.getByName("main").cinterops.creating {
|
||||
// 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"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
configureNativeInterop("main", projectDir.resolve("src/nativeMainInterop"), nativeTargets)
|
||||
configureNativeInterop("test", projectDir.resolve("src/nativeTestInterop"), nativeTargets)
|
||||
|
||||
|
||||
val sourceSets = kotlinSourceSets.orEmpty()
|
||||
@ -143,9 +121,181 @@ fun Project.configureHMPPJvm() {
|
||||
androidMain.dependsOn(jvmBaseMain)
|
||||
|
||||
jvmTest.dependsOn(jvmBaseTest)
|
||||
androidTest.dependsOn(commonTest)
|
||||
androidTest.dependsOn(jvmBaseTest)
|
||||
|
||||
nativeMain.dependsOn(commonMain)
|
||||
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))
|
||||
}
|
@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
|
||||
|
||||
fun Project.useIr() {
|
||||
@ -41,7 +42,6 @@ fun Project.preConfigureJvmTarget() {
|
||||
val defaultVer = jvmVersion()
|
||||
|
||||
tasks.withType(KotlinJvmCompile::class.java) {
|
||||
kotlinOptions.languageVersion = "1.6"
|
||||
kotlinOptions.jvmTarget = defaultVer.toString()
|
||||
kotlinOptions.freeCompilerArgs += "-Xjvm-default=all"
|
||||
|
||||
@ -61,8 +61,8 @@ fun Project.preConfigureJvmTarget() {
|
||||
fun Project.configureJvmTarget() {
|
||||
val defaultVer = jvmVersion()
|
||||
|
||||
tasks.withType(KotlinJvmCompile::class)
|
||||
.filter { it.name.startsWith("compileTestKotlin") }
|
||||
tasks.withType(KotlinCompile::class)
|
||||
.filter { it.name.contains("test", ignoreCase = true) }
|
||||
.forEach { task ->
|
||||
task.kotlinOptions.freeCompilerArgs += "-Xopt-in=net.mamoe.mirai.utils.TestOnly"
|
||||
}
|
||||
|
@ -22,11 +22,11 @@ object Versions {
|
||||
val consoleIntellij = "221-$project-162-1" // idea-mirai-kotlin-patch
|
||||
val consoleTerminal = project
|
||||
|
||||
const val kotlinCompiler = "1.6.21"
|
||||
const val kotlinCompiler = "1.7.0-RC"
|
||||
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 atomicFU = "0.17.2"
|
||||
@ -38,8 +38,8 @@ object Versions {
|
||||
const val io = "0.1.16"
|
||||
const val coroutinesIo = "0.1.16"
|
||||
|
||||
const val blockingBridge = "2.1.0-162.1"
|
||||
const val dynamicDelegation = "0.3.0-162.4"
|
||||
const val blockingBridge = "2.1.0-170.1"
|
||||
const val dynamicDelegation = "0.3.0-170.1"
|
||||
|
||||
const val androidGradlePlugin = "4.1.1"
|
||||
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-client-core` = ktor("client-core-jvm", Versions.ktor)
|
||||
val `ktor-client-cio` = ktor("client-cio-jvm", Versions.ktor)
|
||||
val `ktor-client-core` = ktor("client-core", Versions.ktor)
|
||||
val `ktor-client-cio` = ktor("client-cio", Versions.ktor)
|
||||
val `ktor-client-okhttp` = ktor("client-okhttp", 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-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
|
||||
|
||||
|
@ -13,6 +13,7 @@ org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 --illegal-access=permit -Dkot
|
||||
org.gradle.parallel=true
|
||||
org.gradle.vfs.watch=true
|
||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
kotlin.native.binary.memoryModel=experimental
|
||||
kotlin.native.enableDependencyPropagation=false
|
||||
#kotlin.mpp.enableCompatibilityMetadataVariant=true
|
||||
#kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
@ -21,4 +22,5 @@ gnsp.disableApplyOnlyOnRootProjectEnforcement=true
|
||||
# We may target 15 with Kotlin 1.5 IR
|
||||
mirai.android.target.api.level=24
|
||||
# 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
11
install.sh
Normal 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
|
@ -10,7 +10,6 @@
|
||||
package net.mamoe.console.integrationtest
|
||||
|
||||
import net.mamoe.console.integrationtest.testpoints.MCITBSelfAssertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.objectweb.asm.ClassReader
|
||||
import java.io.File
|
||||
import java.lang.management.ManagementFactory
|
||||
@ -22,6 +21,7 @@ import kotlin.io.path.inputStream
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.name
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.plugin.jvm.JvmPluginDescription
|
||||
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
|
||||
import net.mamoe.mirai.utils.touch
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -40,13 +39,14 @@ internal object PluginDataRenameToIdTest : AbstractTestPointAsPlugin() {
|
||||
}
|
||||
|
||||
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(
|
||||
"""
|
||||
test: a
|
||||
""".trimIndent()
|
||||
)
|
||||
File("data/PluginDataRenameToIdTest/test.txt").touch()
|
||||
File("data/PluginDataRenameToIdTest/test.txt").createNewFile()
|
||||
File("data/PluginDataRenameToIdTest/testdata.yml").writeText(
|
||||
"""
|
||||
test: a
|
||||
|
@ -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.testFramework.AbstractConsoleInstanceTest
|
||||
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.temporal.TemporalAccessor
|
||||
import kotlin.reflect.KClass
|
||||
@ -158,7 +155,6 @@ class TestTemporalArgCommand : CompositeCommand(owner, "testtemporal") {
|
||||
private val sender get() = ConsoleCommandSender
|
||||
private val owner get() = ConsoleCommandOwner
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
|
||||
@OptIn(ExperimentalCommandDescriptors::class)
|
||||
internal class InstanceTestCommand : AbstractConsoleInstanceTest() {
|
||||
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 compositeCommand by lazy { TestCompositeCommand() }
|
||||
|
||||
@BeforeEach
|
||||
@BeforeTest
|
||||
fun grantPermission() {
|
||||
ConsoleCommandSender.permit(simpleCommand.permission)
|
||||
ConsoleCommandSender.permit(compositeCommand.permission)
|
||||
|
@ -12,6 +12,7 @@
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.Bot
|
||||
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.utils.md5
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -32,7 +33,7 @@ import kotlin.test.assertEquals
|
||||
internal class LoginCommandTest : AbstractCommandTest() {
|
||||
|
||||
@Test
|
||||
suspend fun `login with provided password`() {
|
||||
fun `login with provided password`() = runBlocking {
|
||||
val myId = 123L
|
||||
val myPwd = "password001"
|
||||
|
||||
@ -52,7 +53,7 @@ internal class LoginCommandTest : AbstractCommandTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
suspend fun `login with saved plain password`() {
|
||||
fun `login with saved plain password`() = runBlocking {
|
||||
val myId = 123L
|
||||
val myPwd = "password001"
|
||||
|
||||
@ -81,7 +82,7 @@ internal class LoginCommandTest : AbstractCommandTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
suspend fun `login with saved md5 password`() {
|
||||
fun `login with saved md5 password`() = runBlocking {
|
||||
val myId = 123L
|
||||
val myPwd = "password001"
|
||||
|
||||
|
@ -17,7 +17,7 @@ import net.mamoe.mirai.event.events.BotOnlineEvent
|
||||
import net.mamoe.mirai.event.globalEventChannel
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class AutoLoginTest : AbstractConsoleInstanceTest() {
|
||||
|
@ -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.testFramework.AbstractConsoleInstanceTest
|
||||
import net.mamoe.mirai.console.util.JavaFriendlyApi
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
|
@ -19,9 +19,9 @@ import net.mamoe.mirai.message.data.PlainText
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.message.data.messageChainOf
|
||||
import net.mamoe.mirai.utils.mapPrimitive
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import java.nio.file.Path
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertSame
|
||||
|
||||
|
@ -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.name
|
||||
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
|
||||
class PluginMovingTests : AbstractConsoleInstanceTest() {
|
||||
private val mockPluginWithName = object : KotlinPlugin(JvmPluginDescription("org.test1.test1", "1.0.0", "test1")) {}
|
||||
|
@ -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.GlobalComponentStorageImpl
|
||||
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
internal class GlobalComponentStorageTest : AbstractConsoleInstanceTest() {
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
|
||||
@Suppress("ClassName")
|
||||
internal class TestALC_PathBased {
|
||||
|
@ -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.PermissionImpl
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.*
|
||||
|
||||
internal class PermissionServiceTest {
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFails
|
||||
|
||||
internal class PermissionsBasicsTest {
|
||||
|
@ -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.KotlinPlugin
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import kotlin.test.BeforeTest
|
||||
|
||||
abstract class AbstractConsoleInstanceTest {
|
||||
val mockPlugin by lazy { mockKotlinPlugin() }
|
||||
private lateinit var implementation: MiraiConsoleImplementation
|
||||
val consoleImplementation: MiraiConsoleImplementation by ::implementation
|
||||
|
||||
@BeforeEach
|
||||
@BeforeTest
|
||||
protected open fun initializeConsole() {
|
||||
this.implementation = MockConsoleImplementation().apply { start() }
|
||||
CommandManager
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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
|
||||
|
||||
import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest
|
||||
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
|
||||
|
||||
class FrameworkInstanceTest : AbstractConsoleInstanceTest() {
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.util
|
||||
|
||||
//import kotlinx.coroutines.*
|
||||
//import org.junit.jupiter.api.Test
|
||||
//import kotlin.test.Test
|
||||
//import java.util.concurrent.atomic.AtomicInteger
|
||||
//import kotlin.coroutines.resume
|
||||
//import kotlin.test.assertEquals
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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
|
||||
|
||||
import net.mamoe.mirai.console.util.SemVersion.Companion.test
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFails
|
||||
|
||||
internal class TestSemVersion {
|
||||
|
@ -20,7 +20,7 @@ description = "Mirai Console compiler annotations"
|
||||
kotlin {
|
||||
explicitApi()
|
||||
|
||||
configureHMPPJvm()
|
||||
configureHMPP()
|
||||
}
|
||||
|
||||
configureMppPublishing()
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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 {
|
||||
delete()
|
||||
writeText("""
|
||||
writeText(
|
||||
"""
|
||||
org.gradle.daemon=false
|
||||
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
buildFile = File(tempDir, "build.gradle")
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.PrintWriter
|
||||
import kotlin.test.Test
|
||||
|
||||
class KotlinTransitiveDependenciesIntegrationTest {
|
||||
@Test
|
||||
|
@ -12,9 +12,9 @@
|
||||
package net.mamoe.mirai.console.gradle
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
|
||||
class TestPluginApply : AbstractTest() {
|
||||
|
||||
|
@ -45,8 +45,10 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
|
||||
try {
|
||||
languageSettings.optIn("kotlin.RequiresOptIn")
|
||||
} catch (e: NoSuchMethodError) {
|
||||
@Suppress("DEPRECATION")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn")
|
||||
// User is using < 1.6
|
||||
target.compilations.forEach { compilation ->
|
||||
compilation.kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
||||
}
|
||||
}
|
||||
dependencies { configureDependencies(project, this@configureSourceSet, target) }
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
package creator
|
||||
|
||||
import net.mamoe.mirai.console.intellij.wizard.sortVersionsDescending
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class MiraiVersionKindTest {
|
||||
|
@ -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.isValidQualifiedClassName
|
||||
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.assertTrue
|
||||
|
||||
|
@ -26,7 +26,7 @@ description = "Mirai API module"
|
||||
|
||||
kotlin {
|
||||
explicitApi()
|
||||
configureHMPPJvm()
|
||||
configureHMPP()
|
||||
|
||||
|
||||
sourceSets {
|
||||
@ -36,6 +36,7 @@ kotlin {
|
||||
api(`kotlinx-serialization-core`)
|
||||
api(`kotlinx-serialization-json`)
|
||||
api(`kotlinx-coroutines-core`) // don't remove it, otherwise IDE will complain
|
||||
implementation(`ktor-client-core`)
|
||||
|
||||
implementation(project(":mirai-core-utils"))
|
||||
implementation(project(":mirai-console-compiler-annotations"))
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("unused", "NOTHING_TO_INLINE")
|
||||
@ -12,6 +12,7 @@
|
||||
package net.mamoe.mirai
|
||||
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 构造 [Bot] 的工厂. 这是 [Bot] 唯一的构造方式.
|
||||
|
@ -15,7 +15,6 @@
|
||||
package net.mamoe.mirai
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.okhttp.*
|
||||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.contact.*
|
||||
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.MessageSource.Key.recall
|
||||
import net.mamoe.mirai.utils.*
|
||||
import java.util.ServiceLoader
|
||||
import kotlin.reflect.full.companionObjectInstance
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* [IMirai] 实例.
|
||||
@ -336,11 +336,10 @@ public suspend inline fun IMirai.recallMessage(bot: Bot, message: MessageChain):
|
||||
@PublishedApi // for tests and potential public uses.
|
||||
@Suppress("ClassName")
|
||||
internal object _MiraiInstance {
|
||||
private var instance: IMirai? = null
|
||||
|
||||
@JvmStatic
|
||||
fun set(instance: IMirai) {
|
||||
this.instance = instance
|
||||
miraiInstance = instance
|
||||
}
|
||||
|
||||
/**
|
||||
@ -348,15 +347,14 @@ internal object _MiraiInstance {
|
||||
*/
|
||||
@JvmStatic
|
||||
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
|
||||
internal fun findMiraiInstance(): IMirai {
|
||||
ServiceLoader.load(IMirai::class.java).firstOrNull()?.let { return it }
|
||||
|
||||
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()
|
||||
return loadService(IMirai::class, "net.mamoe.mirai.internal.MiraiImpl")
|
||||
}
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import net.mamoe.mirai.utils.WeakRef
|
||||
import kotlin.annotation.AnnotationTarget.*
|
||||
|
||||
/**
|
||||
@ -52,7 +51,7 @@ public interface LowLevelApiAccessor {
|
||||
public suspend fun refreshKeys(bot: Bot)
|
||||
|
||||
/**
|
||||
* 构造一个 [Friend] 对象. 它持有对 [Bot] 的弱引用([WeakRef]).
|
||||
* 构造一个 [Friend] 对象.
|
||||
*
|
||||
* [Bot] 无法管理这个对象, 但这个对象会以 [Bot] 的 [Job] 作为父 Job.
|
||||
* 因此, 当 [Bot] 被关闭后, 这个对象也会被关闭.
|
||||
@ -61,7 +60,7 @@ public interface LowLevelApiAccessor {
|
||||
public fun newFriend(bot: Bot, friendInfo: FriendInfo): Friend
|
||||
|
||||
/**
|
||||
* 构造一个 [Stranger] 对象. 它持有对 [Bot] 的弱引用([WeakRef]).
|
||||
* 构造一个 [Stranger] 对象.
|
||||
*
|
||||
* [Bot] 无法管理这个对象, 但这个对象会以 [Bot] 的 [Job] 作为父 Job.
|
||||
* 因此, 当 [Bot] 被关闭后, 这个对象也会被关闭.
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.recallMessage
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.ExternalResource.Companion.sendAsImageTo
|
||||
import net.mamoe.mirai.utils.ExternalResource.Companion.uploadAsImage
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 联系对象, 即可以与 [Bot] 互动的对象. 包含 [用户][User], 和 [群][Group].
|
||||
*/
|
||||
@NotStableForInheritance
|
||||
public interface Contact : ContactOrBot, CoroutineScope {
|
||||
public expect interface Contact : ContactOrBot, CoroutineScope {
|
||||
/**
|
||||
* 这个联系对象所属 [Bot].
|
||||
*/
|
||||
@ -67,7 +67,7 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
* 发送纯文本消息
|
||||
* @see sendMessage
|
||||
*/
|
||||
public suspend fun sendMessage(message: String): MessageReceipt<Contact> = this.sendMessage(message.toPlainText())
|
||||
public open suspend fun sendMessage(message: String): MessageReceipt<Contact>
|
||||
|
||||
/**
|
||||
* 上传一个 [资源][ExternalResource] 作为图片以备发送.
|
||||
@ -90,81 +90,23 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
|
||||
@JvmBlockingBridge
|
||||
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]
|
||||
*
|
||||
* @see Contact.sendMessage 最终调用, 发送消息.
|
||||
*/
|
||||
@JvmStatic
|
||||
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)
|
||||
public suspend fun <C : Contact> C.sendImage(resource: ExternalResource): MessageReceipt<C>
|
||||
|
||||
/**
|
||||
* 将文件作为图片上传, 但不发送
|
||||
* @throws OverFileSizeMaxException
|
||||
*/
|
||||
@Throws(OverFileSizeMaxException::class)
|
||||
@Throws(OverFileSizeMaxException::class, CancellationException::class)
|
||||
@JvmStatic
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXTENSION_SHADOWED_BY_MEMBER")
|
||||
@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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "unused")
|
||||
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
import net.mamoe.mirai.utils.ConcurrentLinkedDeque
|
||||
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 {
|
||||
|
||||
@MiraiInternalApi
|
||||
public constructor() : this(ConcurrentLinkedQueue())
|
||||
public constructor() : this(ConcurrentLinkedDeque())
|
||||
|
||||
/**
|
||||
* 获取一个 [Contact.id] 为 [id] 的元素. 在不存在时返回 `null`.
|
||||
|
@ -12,6 +12,7 @@ package net.mamoe.mirai.contact
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* 拥有 [id] 的对象.
|
||||
|
@ -23,6 +23,8 @@ import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.ExternalResource
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 群.
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.isContentEmpty
|
||||
import net.mamoe.mirai.message.data.toPlainText
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.ExperimentalTime
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.PermissionDeniedException
|
||||
import net.mamoe.mirai.contact.announcement.Announcement.Companion.publishAnnouncement
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.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 {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AnnouncementImage
|
||||
if (other !is AnnouncementImage || !isSameClass(this, other)) return false
|
||||
|
||||
if (id != other.id) return false
|
||||
if (height != other.height) return false
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.Serializable
|
||||
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 {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AnnouncementParameters
|
||||
if (other !is AnnouncementParameters || !isSameClass(this, other)) return false
|
||||
|
||||
if (image != other.image) return false
|
||||
if (sendToNewMember != other.sendToNewMember) return false
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.contract
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,9 @@ import net.mamoe.mirai.utils.map
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 表示在本地构建的 [Announcement].
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.PermissionDeniedException
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import java.time.Instant
|
||||
|
||||
|
||||
/**
|
||||
@ -65,7 +64,7 @@ public interface OnlineAnnouncement : Announcement {
|
||||
/**
|
||||
* 公告发出的时间,为 EpochSecond (自 1970-01-01T00:00:00Z 的秒数)
|
||||
*
|
||||
* @see Instant.ofEpochSecond
|
||||
* @see java.time.Instant.ofEpochSecond
|
||||
*/
|
||||
public val publicationTime: Long
|
||||
|
||||
|
@ -17,7 +17,7 @@ import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.contact.FileSupported
|
||||
import net.mamoe.mirai.contact.PermissionDeniedException
|
||||
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
|
||||
public val AbsoluteFileFolder.extension: String
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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 net.mamoe.mirai.contact.PermissionDeniedException
|
||||
import net.mamoe.mirai.utils.ExternalResource
|
||||
import net.mamoe.mirai.utils.JavaFriendlyAPI
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
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
|
||||
*/
|
||||
@NotStableForInheritance
|
||||
public interface AbsoluteFolder : AbsoluteFileFolder {
|
||||
public expect interface AbsoluteFolder : AbsoluteFileFolder {
|
||||
/**
|
||||
* 当前快照中文件数量, 当有文件更新时(上传/删除文件) 该属性不会更新.
|
||||
*
|
||||
@ -43,7 +42,7 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
|
||||
/**
|
||||
* 当该目录为空时返回 `true`.
|
||||
*/
|
||||
public fun isEmpty(): Boolean = contentsCount == 0
|
||||
public open fun isEmpty(): Boolean
|
||||
|
||||
/**
|
||||
* 返回更新了文件或目录信息 ([lastModifiedTime] 等) 的, 指向相同文件的 [AbsoluteFileFolder].
|
||||
@ -64,42 +63,18 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
|
||||
*/
|
||||
public suspend fun folders(): Flow<AbsoluteFolder>
|
||||
|
||||
/**
|
||||
* 获取该目录下所有子目录列表.
|
||||
*
|
||||
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [folders], 因此不建议在 Kotlin 使用. 在 Kotlin 请使用 [folders].
|
||||
*/
|
||||
@JavaFriendlyAPI
|
||||
public suspend fun foldersStream(): Stream<AbsoluteFolder>
|
||||
|
||||
|
||||
/**
|
||||
* 获取该目录下所有文件列表.
|
||||
*/
|
||||
public suspend fun files(): Flow<AbsoluteFile>
|
||||
|
||||
/**
|
||||
* 获取该目录下所有文件列表.
|
||||
*
|
||||
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [files], 因此不建议在 Kotlin 使用. 在 Kotlin 请使用 [files].
|
||||
*/
|
||||
@JavaFriendlyAPI
|
||||
public suspend fun filesStream(): Stream<AbsoluteFile>
|
||||
|
||||
|
||||
/**
|
||||
* 获取该目录下所有文件和子目录列表.
|
||||
*/
|
||||
public suspend fun children(): Flow<AbsoluteFileFolder>
|
||||
|
||||
/**
|
||||
* 获取该目录下所有文件和子目录列表.
|
||||
*
|
||||
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [children], 因此不建议在 Kotlin 使用. 在 Kotlin 请使用 [children].
|
||||
*/
|
||||
@JavaFriendlyAPI
|
||||
public suspend fun childrenStream(): Stream<AbsoluteFileFolder>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// resolve and upload
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -144,16 +119,6 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
|
||||
path: String
|
||||
): Flow<AbsoluteFile>
|
||||
|
||||
/**
|
||||
* 根据路径获取指向的所有路径为 [path] 的文件列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件.
|
||||
*
|
||||
* 实现细节: 为了适合 Java 调用, 实现类似为阻塞式的 [resolveFiles], 因此不建议在 Kotlin 使用. 在 Kotlin 请使用 [resolveFiles].
|
||||
*/
|
||||
@JavaFriendlyAPI
|
||||
public suspend fun resolveFilesStream(
|
||||
path: String
|
||||
): Stream<AbsoluteFile>
|
||||
|
||||
/**
|
||||
* 根据路径获取指向的所有路径为 [path] 的文件和目录列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件和目录.
|
||||
*/
|
||||
@ -161,16 +126,6 @@ public interface AbsoluteFolder : AbsoluteFileFolder {
|
||||
path: String
|
||||
): 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.
|
||||
* @see id
|
||||
*/
|
||||
public const val ROOT_FOLDER_ID: String = "/"
|
||||
@Suppress("CONST_VAL_WITHOUT_INITIALIZER") // compiler bug
|
||||
public const val ROOT_FOLDER_ID: String
|
||||
}
|
||||
}
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.NotStableForInheritance
|
||||
import net.mamoe.mirai.utils.ProgressionCallback
|
||||
import java.io.File
|
||||
import java.util.stream.Stream
|
||||
import kotlin.jvm.JvmOverloads
|
||||
|
||||
/**
|
||||
* 表示远程文件列表 (管理器).
|
||||
@ -46,7 +45,7 @@ import java.util.stream.Stream
|
||||
*
|
||||
* # 绝对路径与相对路径
|
||||
*
|
||||
* mirai 文件系统的绝对路径与相对路径与 Java [File] 实现的相同.
|
||||
* mirai 文件系统的绝对路径与相对路径与 Java [java.io.File] 实现的相同.
|
||||
*
|
||||
* 以 `/` 起始的路径表示绝对路径, 基于根目录 [root] 处理. 其他路径均表示相对路径.
|
||||
*
|
||||
@ -64,11 +63,11 @@ import java.util.stream.Stream
|
||||
*
|
||||
* 一个目录 ([AbsoluteFolder]) 可以包含多个子文件, 根目录还可以包含多个子目录 (详见下文 '目录结构限制').
|
||||
*
|
||||
* 使用 [AbsoluteFolder.children] 可以获得其内子目录和文件列表 [Flow]. [AbsoluteFolder.childrenStream] 提供适合 Java 的 [Stream] 实现.
|
||||
* 使用 [AbsoluteFolder.children] 可以获得其内子目录和文件列表 [Flow]. [AbsoluteFolder.childrenStream] 提供适合 Java 的 [java.util.stream.Stream] 实现.
|
||||
* 使用 [AbsoluteFolder.folders] 或 [AbsoluteFolder.files] 可以特定地只获取子目录或文件列表. 这些函数也有其 `*Stream` 实现.
|
||||
*
|
||||
* 若要根据确定的文件或目录名称获取其 [AbsoluteFileFolder] 实例, 可使用 [AbsoluteFolder.resolveFiles] 或 [AbsoluteFolder.resolveFiles].
|
||||
* 注意 [AbsoluteFolder.resolveFiles] 返回 [Flow] (其 Stream 版返回 [Stream]), 因为服务器允许多个文件有相同名称. (详见下文 '允许重名').
|
||||
* 注意 [AbsoluteFolder.resolveFiles] 返回 [Flow] (其 Stream 版返回 [java.util.stream.Stream]), 因为服务器允许多个文件有相同名称. (详见下文 '允许重名').
|
||||
*
|
||||
* 若已知文件 [AbsoluteFile.id], 可通过 [AbsoluteFolder.resolveFileById] 获得该文件.
|
||||
*
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.contact.Contact
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import kotlin.jvm.JvmField
|
||||
|
||||
/**
|
||||
* @since 2.8
|
||||
|
@ -16,8 +16,6 @@ import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.contact.Friend
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.utils.JavaFriendlyAPI
|
||||
import java.util.stream.Stream
|
||||
|
||||
/**
|
||||
* 漫游消息记录管理器. 可通过 [RoamingSupported.roamingMessages] 获得. 目前仅 [Friend] 实现 [RoamingSupported].
|
||||
@ -25,13 +23,13 @@ import java.util.stream.Stream
|
||||
* @since 2.8
|
||||
* @see RoamingSupported
|
||||
*/
|
||||
public interface RoamingMessages {
|
||||
public expect interface RoamingMessages {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Get list
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 查询指定时间段内的漫游消息记录. Java Stream 方法查看 [getMessagesStream].
|
||||
* 查询指定时间段内的漫游消息记录.
|
||||
*
|
||||
* 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
|
||||
* 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
|
||||
@ -55,7 +53,7 @@ public interface RoamingMessages {
|
||||
): Flow<MessageChain>
|
||||
|
||||
/**
|
||||
* 查询所有漫游消息记录. Java Stream 方法查看 [getAllMessagesStream].
|
||||
* 查询所有漫游消息记录.
|
||||
*
|
||||
* 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
|
||||
* 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
|
||||
@ -70,57 +68,7 @@ public interface RoamingMessages {
|
||||
*
|
||||
* @param filter 过滤器.
|
||||
*/
|
||||
public suspend fun getAllMessages(
|
||||
public open suspend fun getAllMessages(
|
||||
filter: RoamingMessageFilter? = null
|
||||
): Flow<MessageChain> = getMessagesIn(0, Long.MAX_VALUE, filter)
|
||||
|
||||
/**
|
||||
* 查询指定时间段内的漫游消息记录. 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)
|
||||
): Flow<MessageChain>
|
||||
}
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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 net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import kotlin.jvm.JvmStatic
|
||||
|
||||
/**
|
||||
* 群荣誉信息
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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.NewFriendRequestEvent
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmStatic
|
||||
|
||||
@Serializable
|
||||
@SerialName("RequestEventData")
|
||||
|
@ -18,6 +18,8 @@ import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
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] 时产生的异常只会由监听方处理.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
@Suppress("TOP_LEVEL_FUNCTIONS_NOT_SUPPORTED") // compiler bug
|
||||
public suspend fun <E : Event> E.broadcast(): E {
|
||||
Mirai.broadcastEvent(this)
|
||||
return this
|
||||
|
@ -25,12 +25,14 @@ import net.mamoe.mirai.IMirai
|
||||
import net.mamoe.mirai.event.ConcurrencyKind.CONCURRENT
|
||||
import net.mamoe.mirai.event.ConcurrencyKind.LOCKED
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.internal.event.registerEventHandler
|
||||
import net.mamoe.mirai.utils.*
|
||||
import org.jetbrains.annotations.Contract
|
||||
import java.util.function.Consumer
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import net.mamoe.mirai.utils.context
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
@ -54,7 +56,7 @@ import kotlin.reflect.KClass
|
||||
*
|
||||
* ### 对通道的操作
|
||||
* - 过滤通道: 通过 [EventChannel.filter]. 例如 `filter { it is BotEvent }` 得到一个只能监听到 [BotEvent] 的事件通道.
|
||||
* - 转换为 Kotlin 协程 [Channel]: [EventChannel.asChannel]
|
||||
* - 转换为 Kotlin 协程 [Channel]: [EventChannel.forwardToChannel]
|
||||
* - 添加 [CoroutineContext]: [context], [parentJob], [parentScope], [exceptionHandler]
|
||||
*
|
||||
* ### 创建事件监听
|
||||
@ -80,38 +82,17 @@ import kotlin.reflect.KClass
|
||||
* 使用 [EventChannel.forwardToChannel] 可将事件转发到指定 [SendChannel].
|
||||
*/
|
||||
@NotStableForInheritance // since 2.12, before it was `final class`.
|
||||
public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi public constructor(
|
||||
public val baseEventClass: KClass<out BaseEvent>,
|
||||
public expect abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi public constructor(
|
||||
baseEventClass: KClass<out BaseEvent>,
|
||||
|
||||
defaultCoroutineContext: CoroutineContext,
|
||||
) {
|
||||
/**
|
||||
* 此事件通道的默认 [CoroutineScope.coroutineContext]. 将会被添加给所有注册的事件监听器.
|
||||
*/
|
||||
public val defaultCoroutineContext: CoroutineContext,
|
||||
) {
|
||||
/**
|
||||
* 创建事件监听并将监听结果发送在 [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) }
|
||||
public val defaultCoroutineContext: CoroutineContext
|
||||
|
||||
public val baseEventClass: KClass<out BaseEvent>
|
||||
|
||||
/**
|
||||
* 创建事件监听并将监听结果转发到 [channel]. 当 [Channel.send] 抛出 [ClosedSendChannelException] 时停止 [Listener] 监听和转发.
|
||||
@ -139,16 +120,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
channel: SendChannel<@UnsafeVariance BaseEvent>,
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
priority: EventPriority = EventPriority.MONITOR,
|
||||
): Listener<@UnsafeVariance BaseEvent> {
|
||||
return subscribe(baseEventClass, coroutineContext, priority = priority) {
|
||||
try {
|
||||
channel.send(it)
|
||||
ListeningStatus.LISTENING
|
||||
} catch (_: ClosedSendChannelException) {
|
||||
ListeningStatus.STOPPED
|
||||
}
|
||||
}
|
||||
}
|
||||
): Listener<@UnsafeVariance BaseEvent>
|
||||
|
||||
/**
|
||||
* 通过 [Flow] 接收此通道内的所有事件.
|
||||
@ -216,9 +188,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
* @see filterIsInstance 过滤指定类型的事件
|
||||
*/
|
||||
@JvmSynthetic
|
||||
public fun filter(filter: suspend (event: BaseEvent) -> Boolean): EventChannel<BaseEvent> {
|
||||
return FilterEventChannel(this, filter)
|
||||
}
|
||||
public fun filter(filter: suspend (event: BaseEvent) -> Boolean): EventChannel<BaseEvent>
|
||||
|
||||
/**
|
||||
* [EventChannel.filter] 的 Java 版本.
|
||||
@ -258,32 +228,20 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
*/
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@kotlin.internal.LowPriorityInOverloadResolution
|
||||
public fun filter(filter: (event: BaseEvent) -> Boolean): EventChannel<BaseEvent> {
|
||||
return filter { runBIO { filter(it) } }
|
||||
}
|
||||
public fun filter(filter: (event: BaseEvent) -> Boolean): EventChannel<BaseEvent>
|
||||
|
||||
/**
|
||||
* 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel]
|
||||
* @see filter 获取更多信息
|
||||
*/
|
||||
@JvmSynthetic
|
||||
public inline fun <reified E : Event> filterIsInstance(): EventChannel<E> =
|
||||
filterIsInstance(E::class)
|
||||
public inline fun <reified E : Event> filterIsInstance(): EventChannel<E>
|
||||
|
||||
/**
|
||||
* 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel]
|
||||
* @see filter 获取更多信息
|
||||
*/
|
||||
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)
|
||||
public fun <E : Event> filterIsInstance(kClass: KClass<out E>): EventChannel<E>
|
||||
|
||||
|
||||
/**
|
||||
@ -300,19 +258,13 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
*/
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@kotlin.internal.LowPriorityInOverloadResolution
|
||||
public fun exceptionHandler(coroutineExceptionHandler: CoroutineExceptionHandler): EventChannel<BaseEvent> {
|
||||
return context(coroutineExceptionHandler)
|
||||
}
|
||||
public fun exceptionHandler(coroutineExceptionHandler: CoroutineExceptionHandler): EventChannel<BaseEvent>
|
||||
|
||||
/**
|
||||
* 创建一个新的 [EventChannel], 该 [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler]
|
||||
* @see context
|
||||
*/
|
||||
public fun exceptionHandler(coroutineExceptionHandler: (exception: Throwable) -> Unit): EventChannel<BaseEvent> {
|
||||
return context(CoroutineExceptionHandler { _, throwable ->
|
||||
coroutineExceptionHandler(throwable)
|
||||
})
|
||||
}
|
||||
public fun exceptionHandler(coroutineExceptionHandler: (exception: Throwable) -> Unit): EventChannel<BaseEvent>
|
||||
|
||||
/**
|
||||
* 创建一个新的 [EventChannel], 该 [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler]
|
||||
@ -337,9 +289,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
*
|
||||
* @see CoroutineScope.globalEventChannel `GlobalEventChannel.parentScope()` 的扩展
|
||||
*/
|
||||
public fun parentScope(coroutineScope: CoroutineScope): EventChannel<BaseEvent> {
|
||||
return context(coroutineScope.coroutineContext)
|
||||
}
|
||||
public fun parentScope(coroutineScope: CoroutineScope): EventChannel<BaseEvent>
|
||||
|
||||
/**
|
||||
* 指定协程父 [Job]. 之后在此 [EventChannel] 下创建的事件监听器都会成为 [job] 的子任务, 当 [job] 被取消时, 所有的事件监听器都会被取消.
|
||||
@ -349,9 +299,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
* @see parentScope
|
||||
* @see context
|
||||
*/
|
||||
public fun parentJob(job: Job): EventChannel<BaseEvent> {
|
||||
return context(job)
|
||||
}
|
||||
public fun parentJob(job: Job): EventChannel<BaseEvent>
|
||||
|
||||
// endregion
|
||||
|
||||
@ -452,7 +400,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
concurrency: ConcurrencyKind = LOCKED,
|
||||
priority: EventPriority = EventPriority.NORMAL,
|
||||
noinline handler: suspend E.(E) -> ListeningStatus,
|
||||
): Listener<E> = subscribe(E::class, coroutineContext, concurrency, priority, handler)
|
||||
): Listener<E>
|
||||
|
||||
/**
|
||||
* 与 [subscribe] 的区别是接受 [eventClass] 参数, 而不使用 `reified` 泛型. 通常推荐使用具体化类型参数.
|
||||
@ -467,10 +415,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
concurrency: ConcurrencyKind = LOCKED,
|
||||
priority: EventPriority = EventPriority.NORMAL,
|
||||
handler: suspend E.(E) -> ListeningStatus,
|
||||
): Listener<E> = subscribeInternal(
|
||||
eventClass,
|
||||
createListener(coroutineContext, concurrency, priority) { it.handler(it); }
|
||||
)
|
||||
): Listener<E>
|
||||
|
||||
/**
|
||||
* 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件.
|
||||
@ -492,7 +437,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
concurrency: ConcurrencyKind = CONCURRENT,
|
||||
priority: EventPriority = EventPriority.NORMAL,
|
||||
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,
|
||||
priority: EventPriority = EventPriority.NORMAL,
|
||||
handler: suspend E.(E) -> Unit,
|
||||
): Listener<E> = subscribeInternal(
|
||||
eventClass,
|
||||
createListener(coroutineContext, concurrency, priority) { it.handler(it); ListeningStatus.LISTENING }
|
||||
)
|
||||
): Listener<E>
|
||||
|
||||
/**
|
||||
* 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件, 只监听一次.
|
||||
@ -527,7 +469,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
priority: EventPriority = EventPriority.NORMAL,
|
||||
noinline handler: suspend E.(E) -> Unit,
|
||||
): Listener<E> = subscribeOnce(E::class, coroutineContext, priority, handler)
|
||||
): Listener<E>
|
||||
|
||||
/**
|
||||
* @see subscribeOnce
|
||||
@ -537,155 +479,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
priority: EventPriority = EventPriority.NORMAL,
|
||||
handler: suspend E.(E) -> Unit,
|
||||
): Listener<E> = subscribeInternal(
|
||||
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
|
||||
}
|
||||
)
|
||||
): Listener<E>
|
||||
|
||||
// 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>)
|
||||
|
||||
// to overcome visibility issue
|
||||
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
|
||||
}
|
||||
internal fun <E : Event> registerListener0(eventClass: KClass<out E>, listener: Listener<E>)
|
||||
|
||||
/**
|
||||
* Creates [Listener] instance using the [listenerBlock] action.
|
||||
*/
|
||||
@Contract("_ -> new") // always creates new instance
|
||||
// @Contract("_ -> new") // always creates new instance
|
||||
@MiraiInternalApi
|
||||
protected abstract fun <E : Event> createListener(
|
||||
coroutineContext: CoroutineContext,
|
||||
@ -724,7 +511,7 @@ public abstract class EventChannel<out BaseEvent : Event> @MiraiInternalApi publ
|
||||
concurrencyKind: ConcurrencyKind,
|
||||
priority: EventPriority,
|
||||
listenerBlock: suspend (E) -> ListeningStatus,
|
||||
): Listener<E> = createListener(coroutineContext, concurrencyKind, priority, listenerBlock)
|
||||
): Listener<E>
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@ -14,7 +14,8 @@ package net.mamoe.mirai.event
|
||||
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.internal.LowPriorityInOverloadResolution
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,9 @@ import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.loadService
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,8 @@ import kotlinx.coroutines.sync.Mutex
|
||||
import net.mamoe.mirai.event.EventPriority.*
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* 订阅者的状态
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@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.utils.DeprecatedSinceMirai
|
||||
import kotlin.annotation.AnnotationTarget.CONSTRUCTOR
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,8 @@ import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
|
@ -17,6 +17,8 @@ import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,8 @@ import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
|
@ -23,6 +23,8 @@ import net.mamoe.mirai.internal.event.VerboseEvent
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.utils.ExternalResource
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,8 @@ import net.mamoe.mirai.message.data.source
|
||||
import net.mamoe.mirai.message.isContextIdenticalWith
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,9 @@ import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,8 @@ import net.mamoe.mirai.internal.event.VerboseEvent
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
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 var message: Message
|
||||
) : @kotlin.Suppress("DEPRECATION_ERROR") TempMessagePreSendEvent(target, message) {
|
||||
) : @Suppress("DEPRECATION_ERROR") TempMessagePreSendEvent(target, message) {
|
||||
public override val group: Group get() = target.group
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,9 @@ import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
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")
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as FriendRecall
|
||||
if (other !is FriendRecall || !isSameClass(this, other)) return false
|
||||
|
||||
if (bot != other.bot) return false
|
||||
if (!messageIds.contentEquals(other.messageIds)) return false
|
||||
@ -123,9 +124,7 @@ public sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
|
||||
@Suppress("DuplicatedCode")
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as GroupRecall
|
||||
if (other !is GroupRecall || !isSameClass(this, other)) return false
|
||||
|
||||
if (bot != other.bot) return false
|
||||
if (authorId != other.authorId) return false
|
||||
|
@ -18,6 +18,8 @@ import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.message.data.OnlineMessageSource
|
||||
import net.mamoe.mirai.message.data.source
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,8 @@ import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@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.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
// note: 若你使用 IntelliJ IDEA, 按 alt + 7 可打开结构
|
||||
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -13,6 +13,8 @@
|
||||
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
import kotlinx.atomicfu.AtomicBoolean
|
||||
import kotlinx.atomicfu.atomic
|
||||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.Bot
|
||||
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.network.Packet
|
||||
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,
|
||||
) : BotEvent, Packet, AbstractEvent(), FriendInfoChangeEvent {
|
||||
@JvmField
|
||||
internal val responded: AtomicBoolean = AtomicBoolean(false)
|
||||
internal val responded: AtomicBoolean = atomic(false)
|
||||
|
||||
/**
|
||||
* @return 申请人来自的群. 当申请人来自其他途径申请时为 `null`
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
import kotlinx.atomicfu.AtomicBoolean
|
||||
import kotlinx.atomicfu.atomic
|
||||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.Bot
|
||||
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.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.jvm.*
|
||||
|
||||
/**
|
||||
* 机器人被踢出群或在其他客户端主动退出一个群. 在事件广播前 [Bot.groups] 就已删除这个群.
|
||||
@ -353,7 +355,7 @@ public data class BotInvitedJoinGroupRequestEvent @MiraiInternalApi constructor(
|
||||
public val invitor: Friend? get() = this.bot.getFriend(invitorId)
|
||||
|
||||
@JvmField
|
||||
internal val responded: AtomicBoolean = AtomicBoolean(false)
|
||||
internal val responded: AtomicBoolean = atomic(false)
|
||||
|
||||
@JvmBlockingBridge
|
||||
public suspend fun accept(): Unit = Mirai.acceptInvitedJoinGroupRequest(this)
|
||||
@ -403,7 +405,7 @@ public data class MemberJoinRequestEvent @MiraiInternalApi constructor(
|
||||
|
||||
@JvmField
|
||||
@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)
|
||||
@JvmStatic
|
||||
@JvmName("copy\$default") // avoid being mangled
|
||||
fun `copy$default`(
|
||||
fun copy_default(
|
||||
var0: MemberJoinRequestEvent, var1: Bot, var2: Long, var4: String, var5: Long, var7: Long,
|
||||
var9: String, var10: String, var11: Int, @Suppress("UNUSED_PARAMETER") var12: Any
|
||||
): MemberJoinRequestEvent {
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -17,6 +17,9 @@ import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 有关一个 [Bot] 的事件
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@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.nextMessage
|
||||
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")
|
||||
@JvmName("invoke-RNyhSv4")
|
||||
@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)
|
||||
return null
|
||||
}
|
||||
@ -417,7 +420,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
|
||||
|
||||
@JvmName("reply-RNyhSv4")
|
||||
@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)
|
||||
return null
|
||||
}
|
||||
@ -430,7 +433,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
|
||||
|
||||
@JvmName("reply-sCZ5gAI")
|
||||
@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)
|
||||
return null
|
||||
}
|
||||
@ -443,7 +446,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
|
||||
|
||||
@JvmName("reply-AVDwu3U")
|
||||
@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)
|
||||
return null
|
||||
}
|
||||
@ -457,7 +460,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
|
||||
|
||||
@JvmName("quoteReply-RNyhSv4")
|
||||
@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)
|
||||
return null
|
||||
}
|
||||
@ -470,7 +473,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
|
||||
|
||||
@JvmName("quoteReply-sCZ5gAI")
|
||||
@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)
|
||||
return null
|
||||
}
|
||||
@ -483,7 +486,7 @@ public abstract class MessageSelectBuilderUnit<M : MessageEvent, R> @PublishedAp
|
||||
|
||||
@JvmName("quoteReply-AVDwu3U")
|
||||
@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)
|
||||
return null
|
||||
}
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -25,6 +25,8 @@ import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
public typealias MessageEventSubscribersBuilder = MessageSubscribersBuilder<MessageEvent, Listener<MessageEvent>, Unit, Unit>
|
||||
|
||||
|
@ -13,7 +13,10 @@ import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
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.message.MessageSerializers
|
||||
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.map
|
||||
import net.mamoe.mirai.utils.takeElementsFrom
|
||||
import kotlin.jvm.Synchronized
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.allSuperclasses
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
|
||||
@MiraiInternalApi
|
||||
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>,
|
||||
serializer: KSerializer<M>
|
||||
): 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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
): SerializersModule
|
||||
|
||||
private inline fun <reified M : SingleMessage> SerializersModuleBuilder.hierarchicallyPolymorphic(serializer: KSerializer<M>) =
|
||||
hierarchicallyPolymorphic(M::class, serializer)
|
||||
|
||||
private fun <M : SingleMessage> SerializersModuleBuilder.hierarchicallyPolymorphic(
|
||||
type: KClass<M>,
|
||||
serializer: KSerializer<M>
|
||||
) {
|
||||
// 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>) =
|
||||
// hierarchicallyPolymorphic(M::class, serializer)
|
||||
//
|
||||
//private fun <M : SingleMessage> SerializersModuleBuilder.hierarchicallyPolymorphic(
|
||||
// type: KClass<M>,
|
||||
// serializer: KSerializer<M>
|
||||
//) {
|
||||
// // 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)
|
||||
// }
|
||||
// }
|
||||
//}
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 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
|
||||
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import org.apache.logging.log4j.Marker
|
||||
import org.apache.logging.log4j.MarkerManager
|
||||
|
||||
/**
|
||||
* 内部添加 [Marker] 支持, 并兼容旧 [MiraiLogger] API.
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -10,8 +10,6 @@
|
||||
package net.mamoe.mirai.internal.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())
|
||||
}
|
||||
|
||||
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.")
|
||||
protected enum class Color(private val format: String) {
|
||||
|
@ -8,85 +8,41 @@
|
||||
*/
|
||||
|
||||
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
@file:JvmBlockingBridge
|
||||
|
||||
package net.mamoe.mirai.message.action
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Deferred
|
||||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.recallIn
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* [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?>,
|
||||
) {
|
||||
/**
|
||||
* 撤回时产生的异常. Java [CompletableFuture] API.
|
||||
*/
|
||||
public val exceptionFuture: CompletableFuture<Throwable?> by lazy { exception.asCompletableFuture() }
|
||||
public val exception: Deferred<Throwable?>
|
||||
|
||||
/**
|
||||
* 撤回是否成功. Kotlin [Deferred] API.
|
||||
* 撤回是否成功.
|
||||
*/
|
||||
public val isSuccess: Deferred<Boolean> by lazy {
|
||||
CompletableDeferred<Boolean>().apply {
|
||||
exception.invokeOnCompletion {
|
||||
complete(it == null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回是否成功. Java [CompletableFuture] API.
|
||||
*/
|
||||
public val isSuccessFuture: CompletableFuture<Boolean> by lazy { isSuccess.asCompletableFuture() }
|
||||
public val isSuccess: Deferred<Boolean>
|
||||
|
||||
/**
|
||||
* 等待撤回完成, 返回撤回时产生的异常.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun awaitException(): Throwable? {
|
||||
return exception.await()
|
||||
}
|
||||
public suspend fun awaitException(): Throwable?
|
||||
|
||||
/**
|
||||
* 等待撤回完成, 返回撤回的结果.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun awaitIsSuccess(): Boolean {
|
||||
return isSuccess.await()
|
||||
}
|
||||
public suspend fun awaitIsSuccess(): Boolean
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
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.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 一个 "戳一戳" 动作.
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@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.Companion.deserializeFromMiraiCode
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* Mirai 码相关操作.
|
||||
|
@ -24,6 +24,9 @@ import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,9 @@ import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* "@全体成员".
|
||||
|
@ -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.visitor.MessageVisitor
|
||||
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.Companion.seconds
|
||||
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/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:JvmName("MessageUtils")
|
||||
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* 约束一个 [MessageChain] 中只存在这一种类型的元素. 新元素将会替换旧元素, 保持原顺序.
|
||||
*
|
||||
|
@ -7,8 +7,6 @@
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:OptIn(MiraiInternalApi::class)
|
||||
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import io.ktor.utils.io.core.*
|
||||
@ -19,9 +17,9 @@ import kotlinx.serialization.protobuf.ProtoBuf
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import net.mamoe.mirai.message.MessageSerializers
|
||||
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.MiraiInternalApi
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
|
||||
/**
|
||||
* 自定义消息
|
||||
@ -117,7 +115,7 @@ public sealed class CustomMessage : SingleMessage {
|
||||
}
|
||||
|
||||
public companion object {
|
||||
private val factories: ConcurrentLinkedQueue<Factory<*>> = ConcurrentLinkedQueue()
|
||||
private val factories: MutableCollection<Factory<*>> = ConcurrentLinkedDeque()
|
||||
|
||||
internal fun register(factory: Factory<out CustomMessage>) {
|
||||
factories.removeAll { it::class == factory::class }
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
@ -19,7 +19,10 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.IMirai
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.isSameClass
|
||||
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 {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
other as RichMessageOrigin
|
||||
if (other !is RichMessageOrigin || !isSameClass(this, other)) return false
|
||||
|
||||
if (origin != other.origin) return false
|
||||
if (resourceId != other.resourceId) return false
|
||||
|
@ -19,8 +19,11 @@ import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.annotations.Range
|
||||
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.nextInt
|
||||
|
||||
|
@ -19,6 +19,9 @@ import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.jvm.JvmField
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* QQ 自带表情
|
||||
|
@ -25,6 +25,10 @@ import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.code.internal.appendStringAsMiraiCode
|
||||
import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.*
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 文件消息.
|
||||
|
@ -18,6 +18,8 @@ import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 闪照. 闪照的内容取决于 [image] 代表的图片.
|
||||
|
@ -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.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.*
|
||||
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 未通过 [DisplayStrategy] 渲染的合并转发消息. [RawForwardMessage] 仅作为一个中间件, 用于 [ForwardMessageBuilder].
|
||||
|
@ -18,6 +18,8 @@ import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import net.mamoe.mirai.utils.castOrNull
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* 一些特殊的消息
|
||||
|
@ -7,13 +7,9 @@
|
||||
* 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:JvmName("MessageUtils")
|
||||
@file:Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
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.visitor.MessageVisitor
|
||||
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` 时忽略大小写
|
||||
*/
|
||||
@LowPriorityInOverloadResolution
|
||||
@kotlin.internal.LowPriorityInOverloadResolution
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
public fun contentEquals(another: Message, ignoreCase: Boolean = false): Boolean =
|
||||
contentEquals(another, ignoreCase, false)
|
||||
|
||||
@ -281,6 +280,7 @@ public interface Message {
|
||||
|
||||
/** 将 [another] 按顺序连接到这个消息的尾部. */
|
||||
@JvmName("plusIterableString")
|
||||
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||
public operator fun plus(another: Iterable<String>): MessageChain =
|
||||
another.fold(this, Message::plus).toMessageChain()
|
||||
|
||||
@ -360,7 +360,7 @@ public inline fun Message.repeat(count: Int): MessageChain {
|
||||
return this.toMessageChain()
|
||||
}
|
||||
return buildMessageChain(count) {
|
||||
repeat(count) {
|
||||
repeat(count) l@{
|
||||
add(this@repeat)
|
||||
}
|
||||
}
|
||||
|
@ -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.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.*
|
||||
import java.util.stream.Stream
|
||||
import kotlin.jvm.*
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.streams.asSequence
|
||||
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 =
|
||||
LinearMessageChainImpl.create(ConstrainSingleHelper.constrainSingleMessages(this))
|
||||
|
||||
/**
|
||||
* 扁平化 [this] 并创建一个 [MessageChain].
|
||||
*/
|
||||
@JvmName("newChain")
|
||||
public fun Stream<Message>.toMessageChain(): MessageChain = this.asSequence().toMessageChain()
|
||||
|
||||
/**
|
||||
* 扁平化 [this] 并创建一个 [MessageChain].
|
||||
*/
|
||||
|
@ -15,6 +15,9 @@ package net.mamoe.mirai.message.data
|
||||
|
||||
import kotlin.contracts.InvocationKind.EXACTLY_ONCE
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 构建一个 [MessageChain]. 用法查看 [MessageChainBuilder].
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import kotlin.jvm.JvmField
|
||||
|
||||
/**
|
||||
* 类型 Key. 由伴生对象实现, 表示一个 [Message] 对象的类型.
|
||||
*
|
||||
|
@ -18,6 +18,7 @@ import net.mamoe.mirai.IMirai
|
||||
import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.isSameClass
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
|
||||
/**
|
||||
@ -71,9 +72,7 @@ public class MessageOrigin(
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as MessageOrigin
|
||||
if (other !is MessageOrigin || !isSameClass(this, other)) return false
|
||||
|
||||
if (origin != other.origin) return false
|
||||
if (resourceId != other.resourceId) return false
|
||||
|
@ -32,6 +32,10 @@ import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.NotStableForInheritance
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 消息源. 消息源存在于 [MessageChain] 中, 用于表示这个消息的来源, 也可以用来分辨 [MessageChain].
|
||||
|
@ -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 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@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.recall
|
||||
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
Loading…
Reference in New Issue
Block a user