From fe70187881c622b498cf1bb88e7bf640eef5e3fd Mon Sep 17 00:00:00 2001
From: Karlatemp <kar@kasukusakura.com>
Date: Mon, 14 Nov 2022 00:28:23 +0800
Subject: [PATCH] [core/debug] Add utils for debug running; Update docs for
 launch debug run

---
 docs/contributing/README.md                   | 12 ++++-
 mirai-core/src/jvmTest/README.md              | 51 +++++++++++++++++++
 .../kotlin/directboot/DebugRunHelper.kt       | 31 +++++++++++
 .../jvmTest/kotlin/directboot/envprepare.kt   | 26 ++++++++++
 4 files changed, 119 insertions(+), 1 deletion(-)
 create mode 100644 mirai-core/src/jvmTest/README.md
 create mode 100644 mirai-core/src/jvmTest/kotlin/directboot/DebugRunHelper.kt
 create mode 100644 mirai-core/src/jvmTest/kotlin/directboot/envprepare.kt

diff --git a/docs/contributing/README.md b/docs/contributing/README.md
index 9dda9e283..fbe55ad12 100644
--- a/docs/contributing/README.md
+++ b/docs/contributing/README.md
@@ -189,11 +189,21 @@ projects.mirai-logging.enabled=false
 - `jvm;android;!others` 指定启用 `jvm` 和 `android` 目标,禁用其他所有目标
 - `jvm;macosX64;!others` 指定启用 `jvm` 和 `macosX64` 目标,禁用其他所有目标
 
+
+### 直接启动 mirai-core 本地测试
+
+一般情况下, 只要 JVM 平台测试通过其他平台也能测试通过
+
+在 JVM 平台直接启动 mirai-core, 见 [mirai-core/jvmTest](/mirai-core/src/jvmTest/README.md)
+
+在 native 平台直接启动 mirai-core, 见 [mirai-core/nativeTest](/mirai-core/src/nativeTest/kotlin/local/README.md)
+
+
 ## 构建
 
 查看 [Building](Building.md)
 
-## 寻找带解决的问题
+## 寻找待解决的问题
 
 可以在 [issues](https://github.com/mamoe/mirai/issues) 查看 mirai
 遇到的所有问题,或在里程碑查看版本计划.
diff --git a/mirai-core/src/jvmTest/README.md b/mirai-core/src/jvmTest/README.md
new file mode 100644
index 000000000..c10b5d010
--- /dev/null
+++ b/mirai-core/src/jvmTest/README.md
@@ -0,0 +1,51 @@
+# mirai-core - jvm test - debug run
+
+-------------
+
+!! IMPORTANT !!
+
+在 `jvmTest` 直接启动 `mirai-core` 前, 您必须先阅读此篇的内容
+
+否则你可能会遇到一些问题
+
+-----------------------------------
+
+## 测试启动点配置
+
+在直接启动前, 首先需要手动创建一个专属于自己本地测试的测试启动点
+
+> mirai-core 自带 `jvmTest/kotlin/local` 的忽略, 您只需要在 `jvmTest/kotlin` 手动创建此文件夹即可
+
+在 `jvmTest/kotlin/local` 创建一个新的 kotlin 文件, 并写入以下内容
+
+```kotlin
+fun main() {
+    prepareEnvironmentForDebugRun()
+    // .....
+
+    val bot = DebugRunHelper.newBot(/* ..... */) {
+    }
+    bot as QQAndroidBot
+
+    runBlocking {
+        bot.login()
+
+        bot.eventChannel.subscribeAlways<MessageEvent> {
+            //......
+        }
+        bot.join()
+    }
+}
+```
+
+---------------
+
+## 测试数据存储
+
+Intellij IDEA 直接以默认配置运行程序时, 程序的工作目录都是顶层根目录 (`$rootProject/`)
+
+即在测试代码中的文件相关的操作都是相对 `$rootProject` 而言的
+
+`$rootProject/test` 在 `$rootProject/.gitignore` 中被声明完全忽略
+
+所以 `$rootProject/test` 可以用于存储测试数据, 如果目前本地环境中没有 `test` 文件夹, 可以手动创建
diff --git a/mirai-core/src/jvmTest/kotlin/directboot/DebugRunHelper.kt b/mirai-core/src/jvmTest/kotlin/directboot/DebugRunHelper.kt
new file mode 100644
index 000000000..85ad194c3
--- /dev/null
+++ b/mirai-core/src/jvmTest/kotlin/directboot/DebugRunHelper.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.directboot
+
+import kotlinx.coroutines.Dispatchers
+import net.mamoe.mirai.BotFactory
+import net.mamoe.mirai.internal.QQAndroidBot
+import net.mamoe.mirai.utils.BotConfiguration
+import java.io.File
+
+internal object DebugRunHelper {
+    fun newBot(id: Long, pwd: String, conf: BotConfiguration.(botid: Long) -> Unit): QQAndroidBot {
+        val bot = BotFactory.newBot(id, pwd) {
+            parentCoroutineContext = Dispatchers.IO
+
+            workingDir = File("test/session/$id").also { it.mkdirs() }.absoluteFile
+            cacheDir = workingDir.resolve("cache").absoluteFile
+            this.fileBasedDeviceInfo(File("test/session/$id/device.json").absolutePath)
+
+            conf(id)
+        }
+        return bot as QQAndroidBot
+    }
+}
\ No newline at end of file
diff --git a/mirai-core/src/jvmTest/kotlin/directboot/envprepare.kt b/mirai-core/src/jvmTest/kotlin/directboot/envprepare.kt
new file mode 100644
index 000000000..fa48603ce
--- /dev/null
+++ b/mirai-core/src/jvmTest/kotlin/directboot/envprepare.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.directboot
+
+import net.mamoe.mirai.internal.message.source.MessageSourceSequenceIdAwaiter
+
+internal fun prepareEnvironmentForDebugRun() {
+
+    System.setProperty("mirai.network.packet.logger", "true")
+    System.setProperty("mirai.event.show.verbose.events", "true")
+    System.setProperty("mirai.network.state.observer.logging", "full")
+    System.setProperty("mirai.network.handle.selector.logging", "true")
+    System.setProperty("mirai.network.handler.selector.logging", "true")
+    System.setProperty("mirai.resource.creation.stack.enabled", "true")
+
+    MessageSourceSequenceIdAwaiter.setInstance(MessageSourceSequenceIdAwaiter())
+
+}
+