mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-04 15:40:13 +08:00
Merge remote-tracking branch 'origin/dev' into 1.x
# Conflicts: # build.gradle.kts # mirai-core-api/src/commonMain/kotlin/event/events/bot.kt # mirai-core-api/src/commonMain/kotlin/event/events/friend.kt
This commit is contained in:
commit
26fdf6b22d
45
.travis.yml
45
.travis.yml
@ -1,45 +0,0 @@
|
||||
language: android
|
||||
|
||||
jdk: oraclejdk8
|
||||
### need JDK11
|
||||
|
||||
env:
|
||||
global:
|
||||
- ANDROID_API_LEVEL=28
|
||||
- ANDROID_BUILD_TOOLS_VERSION=28.0.3
|
||||
- ANDROID_ABI=armeabi-v7a
|
||||
|
||||
android:
|
||||
components:
|
||||
- tools
|
||||
- platform-tools
|
||||
- tools
|
||||
- extra-android-m2repository
|
||||
licenses:
|
||||
- 'android-sdk-preview-license-52d11cd2'
|
||||
- 'android-sdk-license-.+'
|
||||
- 'google-gdk-license-.+'
|
||||
|
||||
before_install:
|
||||
- touch $HOME/.android/repositories.cfg
|
||||
- yes | sdkmanager "platforms;android-28"
|
||||
- yes | sdkmanager "build-tools;28.0.3"
|
||||
|
||||
### need JDK8( SDK manager thing)
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/
|
||||
- $HOME/.android/build-cache
|
||||
|
||||
before_script:
|
||||
- chmod +x gradlew
|
||||
|
||||
script:
|
||||
- ./gradlew clean build
|
||||
- ./gradlew test
|
@ -16,6 +16,12 @@ mirai 欢迎一切形式的代码贡献。你可以通过以下几种途径向 m
|
||||
|
||||
### 能做什么?
|
||||
|
||||
#### 分支
|
||||
|
||||
- `master`: 最新稳定版
|
||||
- `1.x`: 1.x 现有版本的开发
|
||||
- `dev`: 2.0 重构版本的开发
|
||||
|
||||
**请基于 `master` 分支进行文档修改; 基于 `dev` 分支进行其他修改 (否则你的修改可能被关闭或不会立即合并)**
|
||||
|
||||
- 代码优化: 优化任何功能设计或实现, 或是引入一个新的设计(请先通过 issue 与维护者达成共识)
|
||||
@ -25,7 +31,7 @@ mirai 欢迎一切形式的代码贡献。你可以通过以下几种途径向 m
|
||||
### 注意事项
|
||||
- 尽量不要引用新的库
|
||||
- 遵守 Kotlin 官方代码规范(提交前使用 IDE 格式化代码 (commit 时勾选 'Reformat code'))
|
||||
- 不要手动拆解数据包. 请一定使用 `kotlinx.serialization` 拆解 ProtoBuf, 使用 `net.mamoe.mirai.qqandroid.utils.io.serialization.Tars` 拆解 Tars 数据包, 使用 `kotlinx.serialization` 拆解 Json 数据.
|
||||
- 不要手动拆解数据包. 请一定使用 `kotlinx.serialization` 拆解 ProtoBuf, 使用 `net.mamoe.mirai.internal.utils.io.serialization.Tars` 拆解 Tars 数据包, 使用 `kotlinx.serialization` 拆解 Json 数据.
|
||||
|
||||
## 社区
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
theme: jekyll-theme-cayman
|
430
build.gradle.kts
430
build.gradle.kts
@ -2,33 +2,35 @@
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.jetbrains.dokka.gradle.DokkaTask
|
||||
import java.time.Duration
|
||||
import kotlin.math.pow
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
// maven(url = "https://mirrors.huaweicloud.com/repository/maven")
|
||||
maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
|
||||
maven(url = "https://kotlin.bintray.com/kotlinx")
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
google()
|
||||
mavenCentral()
|
||||
maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
|
||||
maven(url = "https://kotlin.bintray.com/kotlinx")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:${Versions.Android.androidGradlePlugin}")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.Kotlin.compiler}")
|
||||
classpath("org.jetbrains.kotlin:kotlin-serialization:${Versions.Kotlin.compiler}")
|
||||
classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${Versions.Kotlin.atomicFU}")
|
||||
classpath("org.jetbrains.kotlinx:binary-compatibility-validator:${Versions.Kotlin.binaryValidator}")
|
||||
classpath("com.android.tools.build:gradle:${Versions.androidGradlePlugin}")
|
||||
classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${Versions.atomicFU}")
|
||||
classpath("org.jetbrains.kotlinx:binary-compatibility-validator:${Versions.binaryValidator}")
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("org.jetbrains.dokka") version Versions.Kotlin.dokka apply false
|
||||
kotlin("jvm") version Versions.kotlinCompiler
|
||||
kotlin("plugin.serialization") version Versions.kotlinCompiler
|
||||
id("org.jetbrains.dokka") version Versions.dokka apply false
|
||||
id("net.mamoe.kotlin-jvm-blocking-bridge") version Versions.blockingBridge apply false
|
||||
id("com.jfrog.bintray") version Versions.Publishing.bintray
|
||||
id("com.jfrog.bintray") version Versions.bintray
|
||||
}
|
||||
|
||||
// https://github.com/kotlin/binary-compatibility-validator
|
||||
@ -57,7 +59,7 @@ runCatching {
|
||||
|
||||
allprojects {
|
||||
group = "net.mamoe"
|
||||
version = Versions.Mirai.version
|
||||
version = Versions.project
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
@ -68,225 +70,143 @@ allprojects {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
if (this@subprojects.name == "java-test") {
|
||||
return@subprojects
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
if (name == "mirai-core-all") {
|
||||
return@afterEvaluate
|
||||
configureJvmTarget()
|
||||
configureMppShadow()
|
||||
configureEncoding()
|
||||
configureKotlinTestSettings()
|
||||
configureKotlinCompilerSettings()
|
||||
configureKotlinExperimentalUsages()
|
||||
|
||||
if (isKotlinJvmProject) {
|
||||
configureFlattenSourceSets()
|
||||
}
|
||||
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
val kotlin =
|
||||
runCatching {
|
||||
(this as ExtensionAware).extensions.getByName("kotlin") as? org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
}.getOrNull() ?: return@afterEvaluate
|
||||
configureDokka()
|
||||
}
|
||||
}
|
||||
|
||||
val shadowJvmJar by tasks.creating(ShadowJar::class) sd@{
|
||||
|
||||
group = "mirai"
|
||||
archiveClassifier.set("-all")
|
||||
|
||||
val compilations =
|
||||
kotlin.targets.filter { it.platformType == org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm }
|
||||
.map { it.compilations["main"] }
|
||||
|
||||
compilations.forEach {
|
||||
dependsOn(it.compileKotlinTask)
|
||||
from(it.output)
|
||||
fun Project.configureDokka() {
|
||||
apply(plugin = "org.jetbrains.dokka")
|
||||
tasks {
|
||||
val dokka by getting(DokkaTask::class) {
|
||||
outputFormat = "html"
|
||||
outputDirectory = "$buildDir/dokka"
|
||||
}
|
||||
val dokkaMarkdown by creating(DokkaTask::class) {
|
||||
outputFormat = "markdown"
|
||||
outputDirectory = "$buildDir/dokka-markdown"
|
||||
}
|
||||
val dokkaGfm by creating(DokkaTask::class) {
|
||||
outputFormat = "gfm"
|
||||
outputDirectory = "$buildDir/dokka-gfm"
|
||||
}
|
||||
}
|
||||
for (task in tasks.filterIsInstance<DokkaTask>()) {
|
||||
task.configuration {
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai"
|
||||
skipDeprecated = true
|
||||
}
|
||||
|
||||
println(project.configurations.joinToString())
|
||||
|
||||
from(project.configurations.getByName("jvmRuntimeClasspath"))
|
||||
|
||||
this.exclude { file ->
|
||||
file.name.endsWith(".sf", ignoreCase = true)
|
||||
for (suppressedPackage in arrayOf(
|
||||
"net.mamoe.mirai.internal",
|
||||
"net.mamoe.mirai.event.internal",
|
||||
"net.mamoe.mirai.utils.internal",
|
||||
"net.mamoe.mirai.internal"
|
||||
)) {
|
||||
perPackageOption {
|
||||
prefix = suppressedPackage
|
||||
suppress = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.manifest {
|
||||
this.attributes(
|
||||
"Manifest-Version" to 1,
|
||||
"Implementation-Vendor" to "Mamoe Technologies",
|
||||
"Implementation-Title" to this@afterEvaluate.name.toString(),
|
||||
"Implementation-Version" to this@afterEvaluate.version.toString()
|
||||
)
|
||||
}
|
||||
@Suppress("NOTHING_TO_INLINE") // or error
|
||||
fun Project.configureJvmTarget() {
|
||||
tasks.withType(KotlinJvmCompile::class.java) {
|
||||
kotlinOptions.jvmTarget = "11"
|
||||
}
|
||||
|
||||
extensions.findByType(JavaPluginExtension::class.java)?.run {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.configureMppShadow() {
|
||||
val kotlin =
|
||||
runCatching {
|
||||
(this as ExtensionAware).extensions.getByName("kotlin") as? KotlinMultiplatformExtension
|
||||
}.getOrNull() ?: return
|
||||
|
||||
val shadowJvmJar by tasks.creating(ShadowJar::class) sd@{
|
||||
group = "mirai"
|
||||
archiveClassifier.set("-all")
|
||||
|
||||
val compilations =
|
||||
kotlin.targets.filter { it.platformType == KotlinPlatformType.jvm }
|
||||
.map { it.compilations["main"] }
|
||||
|
||||
compilations.forEach {
|
||||
dependsOn(it.compileKotlinTask)
|
||||
from(it.output)
|
||||
}
|
||||
|
||||
println(project.configurations.joinToString())
|
||||
|
||||
from(project.configurations.getByName("jvmRuntimeClasspath"))
|
||||
|
||||
this.exclude { file ->
|
||||
file.name.endsWith(".sf", ignoreCase = true)
|
||||
}
|
||||
|
||||
/*
|
||||
val shadowJarMd5 = tasks.register("shadowJarMd5") {
|
||||
dependsOn("shadowJvmJar")
|
||||
|
||||
val outFiles = shadowJvmJar.outputs.files.associateWith { file ->
|
||||
File(file.parentFile, file.name.removeSuffix(".jar").removeSuffix("-all") + "-all.jar.md5")
|
||||
}
|
||||
|
||||
outFiles.forEach { (_, output) ->
|
||||
outputs.files(output)
|
||||
}
|
||||
|
||||
doLast {
|
||||
for ((origin, output) in outFiles) {
|
||||
output
|
||||
.also { it.createNewFile() }
|
||||
.writeText(origin.inputStream().md5().toUHexString("").trim(Char::isWhitespace))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.getByName("publish").dependsOn(this)
|
||||
tasks.getByName("bintrayUpload").dependsOn(this)
|
||||
}.get()
|
||||
*/
|
||||
|
||||
val githubUpload by tasks.creating {
|
||||
group = "mirai"
|
||||
dependsOn(shadowJvmJar)
|
||||
|
||||
doFirst {
|
||||
timeout.set(Duration.ofHours(3))
|
||||
findLatestFile().let { (_, file) ->
|
||||
val filename = file.name
|
||||
println("Uploading file $filename")
|
||||
runCatching {
|
||||
upload.GitHub.upload(
|
||||
file,
|
||||
project,
|
||||
"mirai-repo",
|
||||
"shadow/${project.name}/$filename"
|
||||
)
|
||||
}.exceptionOrNull()?.let {
|
||||
System.err.println("GitHub Upload failed")
|
||||
it.printStackTrace() // force show stacktrace
|
||||
throw it
|
||||
}
|
||||
runCatching {
|
||||
upload.GitHub.upload(
|
||||
file.inputStream().use { upload.GitHub.run { it.md5().hex().toByteArray(Charsets.UTF_8) } },
|
||||
project,
|
||||
"mirai-repo",
|
||||
"shadow/${project.name}/$filename.md5"
|
||||
)
|
||||
}.exceptionOrNull()?.let {
|
||||
System.err.println("GitHub Upload failed")
|
||||
it.printStackTrace() // force show stacktrace
|
||||
throw it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply(plugin = "org.jetbrains.dokka")
|
||||
this.tasks {
|
||||
val dokka by getting(DokkaTask::class) {
|
||||
outputFormat = "html"
|
||||
outputDirectory = "$buildDir/dokka"
|
||||
}
|
||||
val dokkaMarkdown by creating(DokkaTask::class) {
|
||||
outputFormat = "markdown"
|
||||
outputDirectory = "$buildDir/dokka-markdown"
|
||||
}
|
||||
val dokkaGfm by creating(DokkaTask::class) {
|
||||
outputFormat = "gfm"
|
||||
outputDirectory = "$buildDir/dokka-gfm"
|
||||
}
|
||||
}
|
||||
|
||||
val dokkaGitHubUpload by tasks.creating {
|
||||
group = "mirai"
|
||||
|
||||
val dokkaTaskName = "dokka"
|
||||
|
||||
dependsOn(tasks.getByName(dokkaTaskName))
|
||||
doFirst {
|
||||
val baseDir = file("./build/$dokkaTaskName/${project.name}")
|
||||
|
||||
timeout.set(Duration.ofHours(6))
|
||||
file("build/$dokkaTaskName/").walk()
|
||||
.filter { it.isFile }
|
||||
.map { old ->
|
||||
if (old.name == "index.md") File(old.parentFile, "README.md").also { new -> old.renameTo(new) }
|
||||
else old
|
||||
}
|
||||
// optimize md
|
||||
.forEach { file ->
|
||||
if (file.endsWith(".md")) {
|
||||
file.writeText(
|
||||
file.readText().replace("index.md", "README.md", ignoreCase = true)
|
||||
.replace(Regex("""```\n([\s\S]*?)```""")) {
|
||||
"\n" + """
|
||||
```kotlin
|
||||
$it
|
||||
```
|
||||
""".trimIndent()
|
||||
})
|
||||
} /* else if (file.name == "README.md") {
|
||||
file.writeText(file.readText().replace(Regex("""(\n\n\|\s)""")) {
|
||||
"\n\n" + """"
|
||||
|||
|
||||
|:----------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|
|
||||
""".trimIndent()
|
||||
})
|
||||
}*/
|
||||
val filename = file.toRelativeString(baseDir)
|
||||
println("Uploading file $filename")
|
||||
runCatching {
|
||||
upload.GitHub.upload(
|
||||
file,
|
||||
project,
|
||||
"mirai-doc",
|
||||
"${project.name}/${project.version}/$filename"
|
||||
)
|
||||
}.exceptionOrNull()?.let {
|
||||
System.err.println("GitHub Upload failed")
|
||||
it.printStackTrace() // force show stacktrace
|
||||
throw it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.manifest {
|
||||
this.attributes(
|
||||
"Manifest-Version" to 1,
|
||||
"Implementation-Vendor" to "Mamoe Technologies",
|
||||
"Implementation-Title" to this.name.toString(),
|
||||
"Implementation-Version" to this.version.toString()
|
||||
)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
tasks.filterIsInstance<DokkaTask>().forEach { task ->
|
||||
with(task) {
|
||||
configuration {
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai"
|
||||
skipDeprecated = true
|
||||
fun Project.configureEncoding() {
|
||||
tasks.withType(JavaCompile::class.java) {
|
||||
options.encoding = "UTF8"
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.configureKotlinTestSettings() {
|
||||
tasks.withType(Test::class) {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
when {
|
||||
isKotlinJvmProject -> {
|
||||
dependencies {
|
||||
testImplementation(kotlin("test-junit5"))
|
||||
|
||||
testApi("org.junit.jupiter:junit-jupiter-api:5.2.0")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
|
||||
}
|
||||
}
|
||||
isKotlinMpp -> {
|
||||
kotlinSourceSets?.forEach { sourceSet ->
|
||||
if (sourceSet.name == "common") {
|
||||
sourceSet.dependencies {
|
||||
implementation(kotlin("test"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
}
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai.internal"
|
||||
suppress = true
|
||||
}
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai.event.internal"
|
||||
suppress = true
|
||||
}
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai.utils.internal"
|
||||
suppress = true
|
||||
}
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai.qqandroid.utils"
|
||||
suppress = true
|
||||
}
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai.qqandroid.contact"
|
||||
suppress = true
|
||||
}
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai.qqandroid.message"
|
||||
suppress = true
|
||||
}
|
||||
perPackageOption {
|
||||
prefix = "net.mamoe.mirai.qqandroid.network"
|
||||
suppress = true
|
||||
} else {
|
||||
sourceSet.dependencies {
|
||||
implementation(kotlin("test-junit5"))
|
||||
|
||||
implementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
|
||||
implementation("org.junit.jupiter:junit-jupiter-engine:5.2.0")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,21 +214,61 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun Project.findLatestFile(): Map.Entry<String, File> {
|
||||
return File(projectDir, "build/libs").walk()
|
||||
.filter { it.isFile }
|
||||
.onEach { println("all files=$it") }
|
||||
.filter { it.name.matches(Regex("""${project.name}-[0-9][0-9]*(\.[0-9]*)*.*\.jar""")) }
|
||||
.onEach { println("matched file: ${it.name}") }
|
||||
.associateBy { it.nameWithoutExtension.substringAfterLast('-') }
|
||||
.onEach { println("versions: $it") }
|
||||
.maxBy { (version, _) ->
|
||||
version.split('.').let {
|
||||
if (it.size == 2) it + "0"
|
||||
else it
|
||||
}.reversed().foldIndexed(0) { index: Int, acc: Int, s: String ->
|
||||
acc + 100.0.pow(index).toInt() * (s.toIntOrNull() ?: 0)
|
||||
}
|
||||
} ?: error("cannot find any file to upload")
|
||||
fun Project.configureKotlinCompilerSettings() {
|
||||
val kotlinCompilations = kotlinCompilations ?: return
|
||||
for (kotlinCompilation in kotlinCompilations) with(kotlinCompilation) {
|
||||
if (isKotlinJvmProject) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
this as KotlinCompilation<KotlinJvmOptions>
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs += "-Xjvm-default=all"
|
||||
}
|
||||
}
|
||||
|
||||
val experimentalAnnotations = arrayOf(
|
||||
"kotlin.RequiresOptIn",
|
||||
"kotlin.contracts.ExperimentalContracts",
|
||||
"kotlin.experimental.ExperimentalTypeInference",
|
||||
"net.mamoe.mirai.utils.MiraiInternalAPI",
|
||||
"net.mamoe.mirai.utils.MiraiExperimentalAPI",
|
||||
"net.mamoe.mirai.LowLevelAPI",
|
||||
"kotlinx.serialization.ExperimentalSerializationApi"
|
||||
)
|
||||
|
||||
fun Project.configureKotlinExperimentalUsages() {
|
||||
val sourceSets = kotlinSourceSets ?: return
|
||||
|
||||
for (target in sourceSets) {
|
||||
experimentalAnnotations.forEach { a ->
|
||||
target.languageSettings.useExperimentalAnnotation(a)
|
||||
target.languageSettings.progressiveMode = true
|
||||
target.languageSettings.enableLanguageFeature("InlineClasses")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.configureFlattenSourceSets() {
|
||||
sourceSets {
|
||||
findByName("main")?.apply {
|
||||
resources.setSrcDirs(listOf(projectDir.resolve("resources")))
|
||||
java.setSrcDirs(listOf(projectDir.resolve("src")))
|
||||
}
|
||||
findByName("test")?.apply {
|
||||
resources.setSrcDirs(listOf(projectDir.resolve("resources")))
|
||||
java.setSrcDirs(listOf(projectDir.resolve("test")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val Project.kotlinSourceSets get() = extensions.findByName("kotlin").safeAs<KotlinProjectExtension>()?.sourceSets
|
||||
|
||||
val Project.kotlinTargets
|
||||
get() =
|
||||
extensions.findByName("kotlin").safeAs<KotlinSingleTargetExtension>()?.target?.let { listOf(it) }
|
||||
?: extensions.findByName("kotlin").safeAs<KotlinMultiplatformExtension>()?.targets
|
||||
|
||||
val Project.isKotlinJvmProject: Boolean get() = extensions.findByName("kotlin") is KotlinJvmProjectExtension
|
||||
val Project.isKotlinMpp: Boolean get() = extensions.findByName("kotlin") is KotlinMultiplatformExtension
|
||||
|
||||
val Project.kotlinCompilations
|
||||
get() = kotlinTargets?.flatMap { it.compilations }
|
@ -1,7 +1,6 @@
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "NOTHING_TO_INLINE", "RemoveRedundantBackticks")
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
@ -9,7 +8,6 @@ import org.gradle.api.tasks.TaskContainer
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import upload.Bintray
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@ -54,7 +52,7 @@ internal fun org.gradle.api.Project.`publishing`(configure: org.gradle.api.publi
|
||||
(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("publishing", configure)
|
||||
|
||||
|
||||
inline fun Project.setupPublishing(
|
||||
inline fun Project.configurePublishing(
|
||||
artifactId: String,
|
||||
bintrayRepo: String = "mirai",
|
||||
bintrayPkgName: String = artifactId,
|
||||
|
@ -1,49 +1,64 @@
|
||||
@file:Suppress("ObjectPropertyName", "ObjectPropertyName", "unused")
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
object Versions {
|
||||
object Mirai {
|
||||
const val version = "1.3.1"
|
||||
}
|
||||
const val project = "2.0-M1"
|
||||
|
||||
object Kotlin {
|
||||
const val compiler = "1.4.10"
|
||||
const val stdlib = "1.4.10"
|
||||
const val coroutines = "1.3.9"
|
||||
const val atomicFU = "0.14.4"
|
||||
const val serialization = "1.0.0-RC"
|
||||
const val ktor = "1.4.0"
|
||||
const val binaryValidator = "0.2.3"
|
||||
const val kotlinCompiler = "1.4.10"
|
||||
const val kotlinStdlib = "1.4.10"
|
||||
const val coroutines = "1.3.9"
|
||||
const val atomicFU = "0.14.4"
|
||||
const val serialization = "1.0.0-RC"
|
||||
const val ktor = "1.4.1"
|
||||
|
||||
const val io = "0.1.16"
|
||||
const val coroutinesIo = "0.1.16"
|
||||
const val dokka = "0.10.1"
|
||||
}
|
||||
const val binaryValidator = "0.2.3"
|
||||
|
||||
val blockingBridge = "1.0.5"
|
||||
const val io = "0.1.16"
|
||||
const val coroutinesIo = "0.1.16"
|
||||
const val dokka = "0.10.1"
|
||||
|
||||
object Android {
|
||||
const val androidGradlePlugin = "3.5.3"
|
||||
}
|
||||
const val blockingBridge = "1.1.0"
|
||||
|
||||
object Publishing {
|
||||
const val bintray = "1.8.5"
|
||||
}
|
||||
const val androidGradlePlugin = "3.5.3"
|
||||
|
||||
object Logging {
|
||||
const val slf4j = "1.7.30"
|
||||
const val log4j = "2.13.3"
|
||||
}
|
||||
const val bintray = "1.8.5"
|
||||
|
||||
const val slf4j = "1.7.30"
|
||||
const val log4j = "2.13.3"
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$version"
|
||||
|
||||
@Suppress("unused")
|
||||
fun ktor(id: String, version: String = Versions.Kotlin.ktor) = "io.ktor:ktor-$id:$version"
|
||||
fun ktor(id: String, version: String = Versions.ktor) = "io.ktor:ktor-$id:$version"
|
||||
|
||||
|
||||
val `kotlinx-coroutines-core` = kotlinx("coroutines-core", Versions.coroutines)
|
||||
val `kotlinx-serialization-core` = kotlinx("serialization-core", Versions.serialization)
|
||||
val `kotlinx-serialization-json` = kotlinx("serialization-json", Versions.serialization)
|
||||
val `kotlinx-serialization-protobuf` = kotlinx("serialization-protobuf", Versions.serialization)
|
||||
const val `kotlinx-atomicfu` = "org.jetbrains.kotlinx:atomicfu:${Versions.atomicFU}"
|
||||
val `kotlinx-io` = kotlinx("io", Versions.io)
|
||||
val `kotlinx-io-jvm` = kotlinx("io-jvm", Versions.io)
|
||||
val `kotlinx-coroutines-io` = kotlinx("coroutines-io", Versions.coroutinesIo)
|
||||
val `kotlinx-coroutines-io-jvm` = kotlinx("coroutines-io-jvm", Versions.coroutinesIo)
|
||||
|
||||
val `ktor-serialization` = ktor("serialization", Versions.ktor)
|
||||
|
||||
val `ktor-client-core` = ktor("client-core", Versions.ktor)
|
||||
val `ktor-client-cio` = ktor("client-cio", Versions.ktor)
|
||||
val `ktor-client-android` = ktor("client-android", Versions.ktor)
|
||||
val `ktor-network` = ktor("network", Versions.ktor)
|
||||
val `ktor-client-okhttp` = ktor("client-okhttp", Versions.ktor)
|
||||
val `ktor-client-serialization-jvm` = ktor("client-serialization-jvm", Versions.ktor)
|
||||
|
||||
const val slf4j = "org.slf4j:slf4j-api:" + Versions.slf4j
|
||||
const val `log4j-api` = "org.apache.logging.log4j:log4j-api:" + Versions.log4j
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package upload
|
||||
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.request.forms.*
|
||||
import io.ktor.client.statement.*
|
||||
import io.ktor.http.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
object CuiCloud {
|
||||
private fun getUrl(project: Project): String {
|
||||
kotlin.runCatching {
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
val cui_cloud_url: String by project
|
||||
return cui_cloud_url
|
||||
}
|
||||
|
||||
System.getProperty("cui_cloud_url", null)?.let {
|
||||
return it.trim()
|
||||
}
|
||||
File(File(System.getProperty("user.dir")).parent, "/cuiUrl.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")), "/cuiUrl.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
error("cannot find url for CuiCloud")
|
||||
}
|
||||
|
||||
private fun getKey(project: Project): String {
|
||||
kotlin.runCatching {
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
val cui_cloud_key: String by project
|
||||
return cui_cloud_key
|
||||
}
|
||||
|
||||
System.getProperty("cui_cloud_key", null)?.let {
|
||||
return it.trim()
|
||||
}
|
||||
File(File(System.getProperty("user.dir")).parent, "/cuiToken.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")), "/cuiToken.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
error("cannot find key for CuiCloud")
|
||||
}
|
||||
|
||||
fun upload(file: File, project: Project) {
|
||||
val cuiCloudUrl = getUrl(project)
|
||||
val key = getKey(project)
|
||||
|
||||
|
||||
val bytes = file.readBytes()
|
||||
|
||||
runBlocking {
|
||||
var first = true
|
||||
retryCatching(1000) {
|
||||
if (!first) {
|
||||
println()
|
||||
println()
|
||||
println("Upload failed. Waiting 15s")
|
||||
delay(15_000)
|
||||
}
|
||||
first = false
|
||||
uploadToCuiCloud(
|
||||
cuiCloudUrl,
|
||||
key,
|
||||
"/mirai/${project.name}/${file.nameWithoutExtension}.mp4",
|
||||
bytes
|
||||
)
|
||||
}.getOrThrow()
|
||||
}
|
||||
}
|
||||
|
||||
@UseExperimental(ExperimentalStdlibApi::class)
|
||||
private suspend fun uploadToCuiCloud(
|
||||
cuiCloudUrl: String,
|
||||
cuiToken: String,
|
||||
filePath: String,
|
||||
content: ByteArray
|
||||
) {
|
||||
println("filePath=$filePath")
|
||||
println("content=${content.size / 1024 / 1024} MB")
|
||||
|
||||
val response = withContext(Dispatchers.IO) {
|
||||
Http.post<HttpResponse>(cuiCloudUrl) {
|
||||
body = MultiPartFormDataContent(
|
||||
formData {
|
||||
append("base64", Base64.getEncoder().encodeToString(content))
|
||||
append("filePath", filePath)
|
||||
append("large", "true")
|
||||
append("key", cuiToken)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
println(response.status)
|
||||
|
||||
val buffer = ByteArray(4096)
|
||||
val resp = buildList<Byte> {
|
||||
while (true) {
|
||||
val read = response.content.readAvailable(buffer, 0, buffer.size)
|
||||
if (read == -1) {
|
||||
break
|
||||
}
|
||||
addAll(buffer.toList().take(read))
|
||||
}
|
||||
}
|
||||
println(String(resp.toByteArray()))
|
||||
|
||||
if (!response.status.isSuccess()) {
|
||||
error("Cui cloud response: ${response.status}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
|
||||
@kotlin.internal.InlineOnly
|
||||
internal inline fun <R> retryCatching(n: Int, onFailure: () -> Unit = {}, block: () -> R): Result<R> {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
|
||||
}
|
||||
require(n >= 0) { "param n for retryCatching must not be negative" }
|
||||
var exception: Throwable? = null
|
||||
repeat(n) {
|
||||
try {
|
||||
return Result.success(block())
|
||||
} catch (e: Throwable) {
|
||||
try {
|
||||
exception?.addSuppressed(e)
|
||||
} catch (e: Throwable) {
|
||||
}
|
||||
exception = e
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
return Result.failure(exception!!)
|
||||
}
|
||||
|
||||
inline fun <E> buildList(builderAction: MutableList<E>.() -> Unit): List<E> {
|
||||
return ArrayList<E>().apply(builderAction)
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package upload
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
import io.ktor.client.features.*
|
||||
import io.ktor.client.request.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import org.jsoup.Connection
|
||||
import org.jsoup.Jsoup
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
internal val Http = HttpClient(CIO) {
|
||||
engine {
|
||||
requestTimeout = 600_000
|
||||
}
|
||||
install(HttpTimeout) {
|
||||
socketTimeoutMillis = 600_000
|
||||
requestTimeoutMillis = 600_000
|
||||
connectTimeoutMillis = 600_000
|
||||
}
|
||||
}
|
||||
|
||||
object GitHub {
|
||||
|
||||
private fun getGithubToken(project: Project): String {
|
||||
kotlin.runCatching {
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
val github_token: String by project
|
||||
return github_token
|
||||
}
|
||||
|
||||
System.getProperty("github_token", null)?.let {
|
||||
return it.trim()
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")).parent, "/token.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")), "/token.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
error(
|
||||
"Cannot find github token, " +
|
||||
"please specify by creating a file token.txt in project dir, " +
|
||||
"or by providing JVM parameter 'github_token'"
|
||||
)
|
||||
}
|
||||
|
||||
fun ByteArray.hex(): String = buildString(size * 2) {
|
||||
this@hex.forEach { byte ->
|
||||
val uint = Integer.toHexString(byte.toInt() and 0xFF)
|
||||
if (uint.length == 1) append('0')
|
||||
append(uint)
|
||||
}
|
||||
}
|
||||
|
||||
fun upload(file: File, project: Project, repo: String, targetFilePath: String) = upload(
|
||||
file.readBytes(), project, repo, targetFilePath
|
||||
)
|
||||
|
||||
fun upload(source: ByteArray, project: Project, repo: String, targetFilePath: String) = runBlocking {
|
||||
val token = getGithubToken(project)
|
||||
println("token.length=${token.length}")
|
||||
val url = "https://api.github.com/repos/project-mirai/$repo/contents/$targetFilePath"
|
||||
retryCatching(100, onFailure = { delay(30_000) }) { // 403 forbidden?
|
||||
Http.put<String>("$url?access_token=$token") {
|
||||
val sha = retryCatching(3, onFailure = { delay(30_000) }) {
|
||||
getGithubSha(
|
||||
repo,
|
||||
targetFilePath,
|
||||
"master",
|
||||
project
|
||||
)
|
||||
}.getOrNull()
|
||||
println("sha=$sha")
|
||||
val content = String(Base64.getEncoder().encode(source))
|
||||
body = """
|
||||
{
|
||||
"message": "Automatically upload on release ${project.name}:${project.version}",
|
||||
"content": "$content"
|
||||
${if (sha == null) "" else """, "sha": "$sha" """}
|
||||
}
|
||||
""".trimIndent()
|
||||
}.let {
|
||||
println("Upload response: $it")
|
||||
}
|
||||
delay(1000)
|
||||
}.getOrThrow()
|
||||
}
|
||||
|
||||
|
||||
private suspend fun getGithubSha(
|
||||
repo: String,
|
||||
filePath: String,
|
||||
branch: String,
|
||||
project: Project
|
||||
): String? {
|
||||
fun String.asJson(): JsonObject {
|
||||
return JsonParser.parseString(this).asJsonObject
|
||||
}
|
||||
|
||||
/*
|
||||
* 只能获取1M以内/branch为master的sha
|
||||
* */
|
||||
class TargetTooLargeException : Exception("Target TOO Large")
|
||||
|
||||
suspend fun getShaSmart(repo: String, filePath: String, project: Project): String? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val response = Jsoup
|
||||
.connect(
|
||||
"https://api.github.com/repos/project-mirai/$repo/contents/$filePath?access_token=" + getGithubToken(
|
||||
project
|
||||
)
|
||||
)
|
||||
.ignoreContentType(true)
|
||||
.ignoreHttpErrors(true)
|
||||
.method(Connection.Method.GET)
|
||||
.execute()
|
||||
if (response.statusCode() == 404) {
|
||||
null
|
||||
} else {
|
||||
val p = response.body().asJson()
|
||||
if (p.has("message") && p["message"].asString == "This API returns blobs up to 1 MB in size. The requested blob is too large to fetch via the API, but you can use the Git Data API to request blobs up to 100 MB in size.") {
|
||||
throw TargetTooLargeException()
|
||||
}
|
||||
p.get("sha").asString
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getShaStupid(
|
||||
repo: String,
|
||||
filePath: String,
|
||||
branch: String,
|
||||
project: Project
|
||||
): String? {
|
||||
val resp = withContext(Dispatchers.IO) {
|
||||
Jsoup
|
||||
.connect(
|
||||
"https://api.github.com/repos/project-mirai/$repo/git/ref/heads/$branch?access_token=" + getGithubToken(
|
||||
project
|
||||
)
|
||||
)
|
||||
.ignoreContentType(true)
|
||||
.ignoreHttpErrors(true)
|
||||
.method(Connection.Method.GET)
|
||||
.execute()
|
||||
}
|
||||
if (resp.statusCode() == 404) {
|
||||
println("Branch Not Found")
|
||||
return null
|
||||
}
|
||||
val info = resp.body().asJson().get("object").asJsonObject.get("url").asString
|
||||
var parentNode = withContext(Dispatchers.IO) {
|
||||
Jsoup.connect(info + "?access_token=" + getGithubToken(project)).ignoreContentType(true)
|
||||
.method(Connection.Method.GET)
|
||||
.execute().body().asJson().get("tree").asJsonObject.get("url").asString
|
||||
}
|
||||
filePath.split("/").forEach { subPath ->
|
||||
withContext(Dispatchers.IO) {
|
||||
Jsoup.connect(parentNode + "?access_token=" + getGithubToken(project)).ignoreContentType(true)
|
||||
.method(Connection.Method.GET).execute().body().asJson().get("tree").asJsonArray
|
||||
}.forEach list@{
|
||||
with(it.asJsonObject) {
|
||||
if (this.get("path").asString == subPath) {
|
||||
parentNode = this.get("url").asString
|
||||
return@list
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
check(parentNode.contains("/blobs/"))
|
||||
return parentNode.substringAfterLast("/")
|
||||
}
|
||||
|
||||
return if (branch == "master") {
|
||||
try {
|
||||
getShaSmart(repo, filePath, project)
|
||||
} catch (e: TargetTooLargeException) {
|
||||
getShaStupid(repo, filePath, branch, project)
|
||||
}
|
||||
} else {
|
||||
getShaStupid(repo, filePath, branch, project)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,16 +3,13 @@ import java.io.OutputStream
|
||||
import java.security.MessageDigest
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* * Copyright 2020 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/master/LICENSE
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun ByteArray.toUHexString(
|
||||
separator: String = " ",
|
||||
|
@ -1,49 +0,0 @@
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
java
|
||||
}
|
||||
|
||||
description = "Binary and source compatibility validator for mirai-core and mirai-core-qqandroid"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
all {
|
||||
languageSettings.enableLanguageFeature("InlineClasses")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.Experimental")
|
||||
}
|
||||
|
||||
main {
|
||||
dependencies {
|
||||
api(kotlin("stdlib", Versions.Kotlin.stdlib))
|
||||
runtimeOnly(project(":mirai-core-qqandroid"))
|
||||
compileOnly("net.mamoe:mirai-core-qqandroid:0.38.0")
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
dependencies {
|
||||
api(kotlin("stdlib", Versions.Kotlin.stdlib))
|
||||
api(kotlin("test"))
|
||||
api(kotlin("test-junit"))
|
||||
runtimeOnly(project(":mirai-core-qqandroid"))
|
||||
compileOnly("net.mamoe:mirai-core-qqandroid:0.38.0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package compatibility;
|
||||
|
||||
import net.mamoe.mirai.Bot;
|
||||
import net.mamoe.mirai.BotFactoryJvm;
|
||||
import net.mamoe.mirai.message.data.MessageUtils;
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
public class CompatibilityTest {
|
||||
public static void main(String[] args) {
|
||||
Bot bot = BotFactoryJvm.newBot(Long.parseLong(System.getenv("qq")), System.getenv("password"));
|
||||
|
||||
bot.getFriend(123).sendMessage(MessageUtils.newChain("")
|
||||
.plus("")
|
||||
.plus(MessageUtils.newImage("")));
|
||||
bot.getFriend(123).sendMessage("");
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package compatibility
|
||||
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
internal class CombinedMessageTest {
|
||||
|
||||
|
||||
@Test
|
||||
fun testAsSequence() {
|
||||
var message: Message = "Hello ".toMessage()
|
||||
message += "World"
|
||||
|
||||
assertEquals(
|
||||
"Hello World",
|
||||
(message as CombinedMessage).asSequence().joinToString(separator = "")
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsSequence2() {
|
||||
var message: Message = "Hello ".toMessage()
|
||||
message += listOf(
|
||||
PlainText("W"),
|
||||
PlainText("o"),
|
||||
PlainText("r") + PlainText("ld")
|
||||
).asMessageChain()
|
||||
|
||||
assertEquals(
|
||||
"Hello World",
|
||||
(message as CombinedMessage).asSequence().joinToString(separator = "")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Iterator<T>.joinToString(
|
||||
separator: CharSequence = ", ",
|
||||
prefix: CharSequence = "",
|
||||
postfix: CharSequence = "",
|
||||
limit: Int = -1,
|
||||
truncated: CharSequence = "...",
|
||||
transform: ((T) -> CharSequence)? = null
|
||||
): String {
|
||||
return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString()
|
||||
}
|
||||
|
||||
fun <T, A : Appendable> Iterator<T>.joinTo(
|
||||
buffer: A,
|
||||
separator: CharSequence = ", ",
|
||||
prefix: CharSequence = "",
|
||||
postfix: CharSequence = "",
|
||||
limit: Int = -1,
|
||||
truncated: CharSequence = "...",
|
||||
transform: ((T) -> CharSequence)? = null
|
||||
): A {
|
||||
buffer.append(prefix)
|
||||
var count = 0
|
||||
for (element in this) {
|
||||
if (++count > 1) buffer.append(separator)
|
||||
if (limit < 0 || count <= limit) {
|
||||
buffer.appendElement(element, transform)
|
||||
} else break
|
||||
}
|
||||
if (limit in 0 until count) buffer.append(truncated)
|
||||
buffer.append(postfix)
|
||||
return buffer
|
||||
}
|
||||
|
||||
internal fun <T> Appendable.appendElement(element: T, transform: ((T) -> CharSequence)?) {
|
||||
when {
|
||||
transform != null -> append(transform(element))
|
||||
element is CharSequence? -> append(element)
|
||||
element is Char -> append(element)
|
||||
else -> append(element.toString())
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package compatibility
|
||||
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.PlainText
|
||||
import org.junit.Test
|
||||
|
||||
|
||||
internal class TestKotlinCompatibility {
|
||||
|
||||
@Test
|
||||
fun testMessageChain() {
|
||||
val x = PlainText("te") + PlainText("st")
|
||||
|
||||
println(Message::class.java.declaredMethods.joinToString("\n"))
|
||||
println()
|
||||
println(x::class.java.declaredMethods.joinToString("\n"))
|
||||
}
|
||||
}
|
@ -20,9 +20,9 @@
|
||||
mirai 项目整体由 核心 (`mirai-core`) 与 控制台(`mirai-console`) 组成.
|
||||
|
||||
|
||||
- [`mirai-core`](../mirai-core) 是机器人服务支持**库**. 提供所有机器人相关 API. **本身只包含抽象类和接口, 使用时还需要同时依赖协议模块**.
|
||||
- [`mirai-core`](../mirai-core-api) 是机器人服务支持**库**. 提供所有机器人相关 API. **本身只包含抽象类和接口, 使用时还需要同时依赖协议模块**.
|
||||
可用的协议模块:
|
||||
- [`mirai-core-qqandroid`](../mirai-core-qqandroid): Android QQ 8.3.0 版本协议实现.
|
||||
- [`mirai-core-qqandroid`](../mirai-core): Android QQ 8.3.0 版本协议实现.
|
||||
|
||||
`mirai-core` 设计为一个 **`支持库`**, 意味着它可以被独立依赖, 在任意项目中使用. 详见下文.
|
||||
|
||||
|
@ -5,9 +5,9 @@ apiValidation {
|
||||
]
|
||||
|
||||
ignoredPackages += [
|
||||
"net.mamoe.mirai.qqandroid.contact",
|
||||
"net.mamoe.mirai.qqandroid.message",
|
||||
"net.mamoe.mirai.qqandroid.network",
|
||||
"net.mamoe.mirai.qqandroid.utils"
|
||||
"net.mamoe.mirai.internal.contact",
|
||||
"net.mamoe.mirai.internal.message",
|
||||
"net.mamoe.mirai.internal.network",
|
||||
"net.mamoe.mirai.internal.utils"
|
||||
]
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
java
|
||||
}
|
||||
|
||||
description = "Java compatibility validator for mirai-core and mirai-core-qqandroid"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
all {
|
||||
languageSettings.enableLanguageFeature("InlineClasses")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.Experimental")
|
||||
}
|
||||
|
||||
main {
|
||||
dependencies {
|
||||
api(kotlin("stdlib", Versions.Kotlin.stdlib))
|
||||
api(project(":mirai-core-qqandroid"))
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
dependencies {
|
||||
api(kotlin("stdlib", Versions.Kotlin.stdlib))
|
||||
api(kotlin("test"))
|
||||
api(kotlin("test-junit"))
|
||||
api(project(":mirai-core-qqandroid"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package test;
|
||||
|
||||
import net.mamoe.mirai.Bot;
|
||||
import net.mamoe.mirai.contact.Contact;
|
||||
import net.mamoe.mirai.contact.QQ;
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
public class MPPCompatibilityTest {
|
||||
public static void main(String[] args) {
|
||||
final QQ next = Bot.getInstances().get(0).getFriends().iterator().next();
|
||||
((Contact) next).sendMessage("");
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ plugins {
|
||||
id("net.mamoe.kotlin-jvm-blocking-bridge")
|
||||
}
|
||||
|
||||
version = Versions.Mirai.version
|
||||
version = Versions.project
|
||||
description = "Mirai core shadowed"
|
||||
|
||||
java {
|
||||
@ -22,39 +22,12 @@ tasks.withType(JavaCompile::class.java) {
|
||||
}
|
||||
|
||||
kotlin {
|
||||
explicitApiWarning()
|
||||
|
||||
sourceSets.all {
|
||||
target.compilations.all {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
|
||||
//useIR = true
|
||||
}
|
||||
}
|
||||
languageSettings.apply {
|
||||
enableLanguageFeature("InlineClasses")
|
||||
progressiveMode = true
|
||||
|
||||
useExperimentalAnnotation("kotlin.Experimental")
|
||||
useExperimentalAnnotation("kotlin.RequiresOptIn")
|
||||
|
||||
useExperimentalAnnotation("net.mamoe.mirai.utils.MiraiInternalAPI")
|
||||
useExperimentalAnnotation("net.mamoe.mirai.utils.MiraiExperimentalAPI")
|
||||
useExperimentalAnnotation("net.mamoe.mirai.console.ConsoleFrontEndImplementation")
|
||||
useExperimentalAnnotation("net.mamoe.mirai.console.util.ConsoleExperimentalApi")
|
||||
useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
|
||||
useExperimentalAnnotation("kotlin.experimental.ExperimentalTypeInference")
|
||||
useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
|
||||
useExperimentalAnnotation("kotlinx.serialization.ExperimentalSerializationApi")
|
||||
useExperimentalAnnotation("net.mamoe.mirai.console.util.ConsoleInternalApi")
|
||||
}
|
||||
}
|
||||
explicitApi()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":mirai-core"))
|
||||
api(project(":mirai-core-qqandroid"))
|
||||
api(project(":mirai-core-api"))
|
||||
}
|
||||
|
||||
setupPublishing("mirai-core-all")
|
||||
configurePublishing("mirai-core-all")
|
10
mirai-core-api/README.md
Normal file
10
mirai-core-api/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# mirai-core
|
||||
|
||||
mirai 的核心公开 API.
|
||||
|
||||
mirai 为多协议设计, `mirai-core` 只提供基础框架和抽象数据类.
|
||||
具体的各协议实现为 `mirai-core-PROTOCOL`, 这些协议模块都继承自 `mirai-core`.
|
||||
|
||||
可用的协议模块:
|
||||
- [`mirai-core-qqandroid`](../mirai-core): Android QQ 8.3.0 版本协议实现.
|
||||
|
@ -4,16 +4,19 @@ plugins {
|
||||
kotlin("multiplatform")
|
||||
id("kotlinx-atomicfu")
|
||||
kotlin("plugin.serialization")
|
||||
id("signing")
|
||||
id("net.mamoe.kotlin-jvm-blocking-bridge")
|
||||
`maven-publish`
|
||||
id("com.jfrog.bintray")
|
||||
}
|
||||
|
||||
description = "Mirai Protocol implementation for QQ Android"
|
||||
description = "Mirai API module"
|
||||
|
||||
val isAndroidSDKAvailable: Boolean by project
|
||||
|
||||
kotlin {
|
||||
explicitApi()
|
||||
|
||||
if (isAndroidSDKAvailable) {
|
||||
apply(from = rootProject.file("gradle/android.gradle"))
|
||||
android("android") {
|
||||
@ -34,84 +37,78 @@ kotlin {
|
||||
)
|
||||
}
|
||||
|
||||
jvm("jvm") {
|
||||
jvm {
|
||||
withJava()
|
||||
}
|
||||
|
||||
sourceSets.apply {
|
||||
all {
|
||||
languageSettings.enableLanguageFeature("InlineClasses")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.Experimental")
|
||||
languageSettings.useExperimentalAnnotation("net.mamoe.mirai.utils.MiraiInternalAPI")
|
||||
languageSettings.useExperimentalAnnotation("net.mamoe.mirai.utils.MiraiExperimentalAPI")
|
||||
languageSettings.useExperimentalAnnotation("net.mamoe.mirai.LowLevelAPI")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.experimental.ExperimentalTypeInference")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.time.ExperimentalTime")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
|
||||
languageSettings.useExperimentalAnnotation("kotlinx.serialization.ExperimentalSerializationApi")
|
||||
languageSettings.useExperimentalAnnotation("net.mamoe.mirai.utils.UnstableExternalImage")
|
||||
|
||||
languageSettings.progressiveMode = true
|
||||
|
||||
dependencies {
|
||||
api(project(":mirai-core"))
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
api1(kotlinx("serialization-core", Versions.Kotlin.serialization))
|
||||
api(kotlinx("coroutines-core", Versions.Kotlin.coroutines))
|
||||
implementation1(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
|
||||
api1("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}")
|
||||
api1(kotlinx("io", Versions.Kotlin.io))
|
||||
implementation1(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
|
||||
}
|
||||
}
|
||||
api(kotlin("serialization"))
|
||||
api(kotlin("reflect"))
|
||||
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("script-runtime"))
|
||||
api1(`kotlinx-serialization-core`)
|
||||
implementation1(`kotlinx-serialization-protobuf`)
|
||||
api1(`kotlinx-io`)
|
||||
api1(`kotlinx-coroutines-io`)
|
||||
api(`kotlinx-coroutines-core`)
|
||||
|
||||
implementation1(`kotlinx-atomicfu`)
|
||||
|
||||
api1(`ktor-client-cio`)
|
||||
api1(`ktor-client-core`)
|
||||
api1(`ktor-network`)
|
||||
}
|
||||
}
|
||||
|
||||
if (isAndroidSDKAvailable) {
|
||||
val androidMain by getting {
|
||||
androidMain {
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
api(kotlin("reflect"))
|
||||
|
||||
val androidTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test", Versions.Kotlin.compiler))
|
||||
implementation(kotlin("test-junit", Versions.Kotlin.compiler))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation(kotlin("test-common"))
|
||||
api1(`kotlinx-io-jvm`)
|
||||
api1(`kotlinx-coroutines-io-jvm`)
|
||||
|
||||
api1(`ktor-client-android`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val jvmMain by getting {
|
||||
dependencies {
|
||||
implementation("org.bouncycastle:bcprov-jdk15on:1.64")
|
||||
api1(kotlinx("io-jvm", Versions.Kotlin.io))
|
||||
// api(kotlinx("coroutines-debug", Versions.Kotlin.coroutines))
|
||||
api(kotlin("reflect"))
|
||||
compileOnly(`log4j-api`)
|
||||
compileOnly(slf4j)
|
||||
|
||||
api1(`kotlinx-io-jvm`)
|
||||
api1(`kotlinx-coroutines-io-jvm`)
|
||||
}
|
||||
}
|
||||
|
||||
val jvmTest by getting {
|
||||
dependencies {
|
||||
dependsOn(commonTest)
|
||||
implementation(kotlin("test", Versions.Kotlin.compiler))
|
||||
implementation(kotlin("test-junit", Versions.Kotlin.compiler))
|
||||
implementation("org.pcap4j:pcap4j-distribution:1.8.2")
|
||||
api("org.pcap4j:pcap4j-distribution:1.8.2")
|
||||
|
||||
runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.androidMain: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
|
||||
get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("androidMain")
|
||||
|
||||
val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.androidTest: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
|
||||
get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("androidTest")
|
||||
|
||||
|
||||
val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.jvmMain: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
|
||||
get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("jvmMain")
|
||||
|
||||
val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.jvmTest: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
|
||||
get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("jvmTest")
|
||||
|
||||
|
||||
fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) =
|
||||
implementation(dependencyNotation) {
|
||||
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
|
||||
@ -132,7 +129,6 @@ fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNo
|
||||
|
||||
apply(from = rootProject.file("gradle/publish.gradle"))
|
||||
|
||||
|
||||
tasks.withType<com.jfrog.bintray.gradle.tasks.BintrayUploadTask> {
|
||||
doFirst {
|
||||
publishing.publications
|
@ -6,7 +6,6 @@
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress(
|
||||
"EXPERIMENTAL_API_USAGE", "unused", "FunctionName", "NOTHING_TO_INLINE", "UnusedImport",
|
||||
"EXPERIMENTAL_OVERRIDE", "CanBeParameter", "MemberVisibilityCanBePrivate"
|
||||
@ -236,7 +235,7 @@ public abstract class Bot internal constructor(
|
||||
@PlannedRemoval("1.2.0")
|
||||
@Deprecated(
|
||||
"use extension.",
|
||||
replaceWith = ReplaceWith("image.queryUrl()", imports = ["net.mamoe.mirai.message.data.queryUrl"]),
|
||||
replaceWith = ReplaceWith("image.queryUrl()", imports = ["queryUrl"]),
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
@JvmSynthetic
|
@ -13,6 +13,7 @@ package net.mamoe.mirai.contact
|
||||
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.utils.asHumanReadable
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlin.time.seconds
|
||||
|
||||
/**
|
||||
@ -38,6 +39,7 @@ public class MessageTooLargeException(
|
||||
*
|
||||
* @see Group.sendMessage
|
||||
*/
|
||||
@OptIn(ExperimentalTime::class)
|
||||
public class BotIsBeingMutedException(
|
||||
public val target: Group
|
||||
) : RuntimeException("bot is being muted, remaining ${target.botMuteRemaining.seconds.asHumanReadable} seconds")
|
@ -1,6 +1,9 @@
|
||||
package net.mamoe.mirai.data
|
||||
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
@ -37,7 +37,7 @@ import kotlin.jvm.JvmName
|
||||
//
|
||||
//
|
||||
////
|
||||
//// 此文件存放所有 `net.mamoe.mirai.event.subscribeMessages` 已弃用的函数.
|
||||
//// 此文件存放所有 `subscribeMessages` 已弃用的函数.
|
||||
////
|
||||
//
|
||||
//
|
@ -16,8 +16,9 @@ package net.mamoe.mirai.event.events
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.message.action.Nudge
|
||||
import net.mamoe.mirai.message.MessageEvent
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.SinceMirai
|
||||
@ -246,7 +247,7 @@ public data class BotNudgedEvent internal constructor(
|
||||
* @see MessageEvent.subject
|
||||
*/
|
||||
@MiraiExperimentalAPI
|
||||
@SinceMirai("1.3.2")
|
||||
@SinceMirai("2.0.0")
|
||||
public val BotNudgedEvent.subject: Contact
|
||||
get() = when (val inlineFrom = from) {
|
||||
is Member -> inlineFrom.group
|
@ -20,8 +20,8 @@ import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.User
|
||||
import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.event.internal.MiraiAtomicBoolean
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.message.action.Nudge
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.SinceMirai
|
||||
import net.mamoe.mirai.utils.internal.runBlocking
|
@ -22,8 +22,8 @@ import net.mamoe.mirai.contact.MemberPermission
|
||||
import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.event.BroadcastControllable
|
||||
import net.mamoe.mirai.event.internal.MiraiAtomicBoolean
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.message.action.Nudge
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.SinceMirai
|
||||
import net.mamoe.mirai.utils.internal.runBlocking
|
@ -19,12 +19,12 @@ import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.event.CancellableEvent
|
||||
import net.mamoe.mirai.event.events.ImageUploadEvent.Failed
|
||||
import net.mamoe.mirai.event.events.ImageUploadEvent.Succeed
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.PlannedRemoval
|
||||
import net.mamoe.mirai.utils.SinceMirai
|
||||
@ -403,7 +403,7 @@ public sealed class ImageUploadEvent : BotEvent, BotActiveEvent, AbstractEvent()
|
||||
message = """
|
||||
以 MessagePreSendEvent 和 MessagePostSendEvent 替换.
|
||||
""",
|
||||
replaceWith = ReplaceWith("MessagePreSendEvent", "net.mamoe.mirai.event.events.MessagePreSendEvent"),
|
||||
replaceWith = ReplaceWith("MessagePreSendEvent", "MessagePreSendEvent"),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
public sealed class MessageSendEvent : BotEvent, BotActiveEvent, AbstractEvent() {
|
||||
@ -415,7 +415,7 @@ public sealed class MessageSendEvent : BotEvent, BotActiveEvent, AbstractEvent()
|
||||
message = """
|
||||
以 GroupMessagePreSendEvent 和 GroupMessagePostSendEvent 替换.
|
||||
""",
|
||||
replaceWith = ReplaceWith("GroupMessagePreSendEvent", "net.mamoe.mirai.event.events.GroupMessagePreSendEvent"),
|
||||
replaceWith = ReplaceWith("GroupMessagePreSendEvent", "GroupMessagePreSendEvent"),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
public data class GroupMessageSendEvent internal constructor(
|
||||
@ -429,7 +429,7 @@ public sealed class MessageSendEvent : BotEvent, BotActiveEvent, AbstractEvent()
|
||||
""",
|
||||
replaceWith = ReplaceWith(
|
||||
"FriendMessagePreSendEvent",
|
||||
"net.mamoe.mirai.event.events.FriendMessagePreSendEvent"
|
||||
"FriendMessagePreSendEvent"
|
||||
),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
@ -442,7 +442,7 @@ public sealed class MessageSendEvent : BotEvent, BotActiveEvent, AbstractEvent()
|
||||
message = """
|
||||
以 TempMessagePreSendEvent 和 TempMessagePostSendEvent 替换.
|
||||
""",
|
||||
replaceWith = ReplaceWith("TempMessagePreSendEvent", "net.mamoe.mirai.event.events.TempMessagePreSendEvent"),
|
||||
replaceWith = ReplaceWith("TempMessagePreSendEvent", "TempMessagePreSendEvent"),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
public data class TempMessageSendEvent internal constructor(
|
@ -6,7 +6,6 @@
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai
|
||||
|
||||
/**
|
@ -1,14 +1,11 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* * Copyright 2020 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/master/LICENSE
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.message.action
|
||||
|
||||
import net.mamoe.kjbb.JvmBlockingBridge
|
@ -209,6 +209,7 @@ internal inline fun <T : CustomMessageMetadata> T.customToStringImpl(factory: Cu
|
||||
return (factory as CustomMessage.Factory<T>).dump(this)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
@JvmOverloads
|
||||
@Suppress("DuplicatedCode") // false positive. foreach is not common to UByteArray and ByteArray
|
||||
internal fun ByteArray.toUHexString(
|
@ -22,7 +22,6 @@
|
||||
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import net.mamoe.kjbb.JvmBlockingBridge
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.Contact
|
||||
import net.mamoe.mirai.message.code.CodableMessage
|
||||
@ -193,7 +192,7 @@ public fun Image(imageId: String): OfflineImage = when {
|
||||
* @return 原图 HTTP 下载链接 (非 HTTPS)
|
||||
* @throws IllegalStateException 当无任何 [Bot] 在线时抛出 (因为无法获取相关协议)
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
//@JvmBlockingBridge
|
||||
@JvmSynthetic
|
||||
public suspend fun Image.queryUrl(): String {
|
||||
@Suppress("DEPRECATION")
|
@ -52,7 +52,7 @@ public data class PlainText(
|
||||
*/
|
||||
@Deprecated(
|
||||
"为和 mirai code 区分, 请使用 PlainText(this)",
|
||||
ReplaceWith("PlainText(this)", "net.mamoe.mirai.message.data.PlainText"),
|
||||
ReplaceWith("PlainText(this)", "PlainText"),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
@JvmSynthetic
|
@ -48,7 +48,7 @@ internal const val ONLINE_OFFLINE_DEPRECATION_MESSAGE = """
|
||||
@Deprecated(
|
||||
ONLINE_OFFLINE_DEPRECATION_MESSAGE,
|
||||
level = DeprecationLevel.ERROR,
|
||||
replaceWith = ReplaceWith("Image", "net.mamoe.mirai.message.data.Image")
|
||||
replaceWith = ReplaceWith("Image", "Image")
|
||||
)
|
||||
@Suppress("EXPOSED_SUPER_INTERFACE")
|
||||
public interface OnlineImage : Image, ConstOriginUrlAware {
|
||||
@ -69,7 +69,7 @@ public interface OnlineImage : Image, ConstOriginUrlAware {
|
||||
@Deprecated(
|
||||
ONLINE_OFFLINE_DEPRECATION_MESSAGE,
|
||||
level = DeprecationLevel.ERROR,
|
||||
replaceWith = ReplaceWith("Image", "net.mamoe.mirai.message.data.Image")
|
||||
replaceWith = ReplaceWith("Image", "Image")
|
||||
)
|
||||
public interface OfflineImage : Image {
|
||||
public companion object Key : Message.Key<OfflineImage> {
|
||||
@ -96,7 +96,7 @@ public suspend fun OfflineImage.queryUrl(): String {
|
||||
@Deprecated(
|
||||
ONLINE_OFFLINE_DEPRECATION_MESSAGE,
|
||||
level = DeprecationLevel.ERROR,
|
||||
replaceWith = ReplaceWith("Image", "net.mamoe.mirai.message.data.Image")
|
||||
replaceWith = ReplaceWith("Image", "Image")
|
||||
)
|
||||
@Serializable
|
||||
public data class OfflineGroupImage(
|
||||
@ -124,7 +124,7 @@ public data class OfflineGroupImage(
|
||||
@Deprecated(
|
||||
ONLINE_OFFLINE_DEPRECATION_MESSAGE,
|
||||
level = DeprecationLevel.ERROR,
|
||||
replaceWith = ReplaceWith("Image", "net.mamoe.mirai.message.data.Image")
|
||||
replaceWith = ReplaceWith("Image", "Image")
|
||||
)
|
||||
public abstract class OnlineGroupImage : GroupImage(), OnlineImage
|
||||
|
||||
@ -137,7 +137,7 @@ public abstract class OnlineGroupImage : GroupImage(), OnlineImage
|
||||
@Deprecated(
|
||||
ONLINE_OFFLINE_DEPRECATION_MESSAGE,
|
||||
level = DeprecationLevel.ERROR,
|
||||
replaceWith = ReplaceWith("Image", "net.mamoe.mirai.message.data.Image")
|
||||
replaceWith = ReplaceWith("Image", "Image")
|
||||
)
|
||||
@Serializable
|
||||
public data class OfflineFriendImage(
|
||||
@ -161,7 +161,7 @@ public data class OfflineFriendImage(
|
||||
@Deprecated(
|
||||
ONLINE_OFFLINE_DEPRECATION_MESSAGE,
|
||||
level = DeprecationLevel.ERROR,
|
||||
replaceWith = ReplaceWith("Image", "net.mamoe.mirai.message.data.Image")
|
||||
replaceWith = ReplaceWith("Image", "Image")
|
||||
)
|
||||
public abstract class OnlineFriendImage : FriendImage(), OnlineImage
|
||||
|
@ -23,9 +23,9 @@ import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.OnlineMessageSource
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
@ -35,7 +35,7 @@ import kotlin.jvm.JvmName
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "use MessageEvent",
|
||||
replaceWith = ReplaceWith("MessageEvent", "net.mamoe.mirai.message.MessageEvent"),
|
||||
replaceWith = ReplaceWith("MessageEvent", "MessageEvent"),
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
public abstract class MessagePacketBase<out TSender : User, out TSubject : Contact> : Packet, BotEvent,
|
||||
@ -51,7 +51,7 @@ public abstract class MessagePacketBase<out TSender : User, out TSubject : Conta
|
||||
|
||||
@Deprecated(
|
||||
message = "Ambiguous name. Use MessageEvent instead",
|
||||
replaceWith = ReplaceWith("MessageEvent", "net.mamoe.mirai.message.MessageEvent"),
|
||||
replaceWith = ReplaceWith("MessageEvent", "MessageEvent"),
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
@ -68,7 +68,7 @@ public abstract class MessagePacket : MessagePacketBase<User, Contact>(),
|
||||
|
||||
@Deprecated(
|
||||
message = "Ambiguous name. Use MessageEvent instead",
|
||||
replaceWith = ReplaceWith("MessageEvent", "net.mamoe.mirai.message.MessageEvent"),
|
||||
replaceWith = ReplaceWith("MessageEvent", "MessageEvent"),
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
@ -85,7 +85,7 @@ public abstract class ContactMessage : MessagePacket(),
|
||||
|
||||
@Deprecated(
|
||||
message = "Ambiguous name. Use FriendMessageEvent instead",
|
||||
replaceWith = ReplaceWith("FriendMessageEvent", "net.mamoe.mirai.message.FriendMessageEvent"),
|
||||
replaceWith = ReplaceWith("FriendMessageEvent", "FriendMessageEvent"),
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
@ -101,7 +101,7 @@ public abstract class FriendMessage : MessageEvent() {
|
||||
|
||||
@Deprecated(
|
||||
message = "Ambiguous name. Use GroupMessageEvent instead",
|
||||
replaceWith = ReplaceWith("GroupMessageEvent", "net.mamoe.mirai.message.GroupMessageEvent"),
|
||||
replaceWith = ReplaceWith("GroupMessageEvent", "GroupMessageEvent"),
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
@ -118,7 +118,7 @@ public abstract class GroupMessage : MessageEvent() {
|
||||
|
||||
@Deprecated(
|
||||
message = "Ambiguous name. Use TempMessageEvent instead",
|
||||
replaceWith = ReplaceWith("TempMessageEvent", "net.mamoe.mirai.message.TempMessageEvent"),
|
||||
replaceWith = ReplaceWith("TempMessageEvent", "TempMessageEvent"),
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
public abstract class TempMessage : MessageEvent() {
|
@ -7,7 +7,7 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.qqandroid.network
|
||||
package net.mamoe.mirai.internal.network
|
||||
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user