Browse Source

Remove Context
Simplify BotFactory

Him188 5 years ago
parent
commit
16c3e02521

+ 0 - 9
mirai-core-api/src/commonMain/kotlin/Bot.kt

@@ -111,15 +111,6 @@ public abstract class Bot internal constructor(
         }
     }
 
-    /**
-     * [Bot] 运行的 [Context].
-     *
-     * 在 JVM 的默认实现为 `class ContextImpl : Context`
-     * 在 Android 实现为 `android.content.Context`
-     */
-    @MiraiExperimentalApi
-    public abstract val context: Context
-
     /**
      * QQ 号码. 实际类型为 uint
      */

+ 17 - 40
mirai-core-api/src/commonMain/kotlin/BotFactory.kt

@@ -7,68 +7,45 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-@file:Suppress("FunctionName", "INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith")
-
 package net.mamoe.mirai
 
 import net.mamoe.mirai.utils.BotConfiguration
-import net.mamoe.mirai.utils.Context
-import net.mamoe.mirai.utils.SinceMirai
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmSynthetic
 
 /**
  * 构造 [Bot] 的工厂. 这是 [Bot] 唯一的构造方式.
  *
- * `mirai-core-qqandroid`: `QQAndroid`
- *
- * 在 JVM, 请查看 `BotFactoryJvm`
+ * @see IMirai.BotFactory
  */
-public expect interface BotFactory {
+public interface BotFactory {
     /**
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
-    @JvmName("newBot")
-    public fun Bot(
-        context: Context,
-        qq: Long,
-        password: String,
-        configuration: BotConfiguration = BotConfiguration.Default
-    ): Bot
+    public fun newBot(qq: Long, password: String, configuration: BotConfiguration = BotConfiguration.Default): Bot
 
     /**
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
-    @JvmName("newBot")
-    public fun Bot(
-        context: Context,
-        qq: Long,
-        passwordMd5: ByteArray,
-        configuration: BotConfiguration = BotConfiguration.Default
-    ): Bot
+    public fun newBot(qq: Long, passwordMd5: ByteArray, configuration: BotConfiguration): Bot
+
+    public companion object INSTANCE : BotFactory {
+        override fun newBot(qq: Long, password: String, configuration: BotConfiguration): Bot {
+            return Mirai.BotFactory.newBot(qq, password, configuration)
+        }
 
-    @SinceMirai("1.3.0")
-    public companion object INSTANCE : BotFactory
+        override fun newBot(qq: Long, passwordMd5: ByteArray, configuration: BotConfiguration): Bot {
+            return Mirai.BotFactory.newBot(qq, passwordMd5, configuration)
+        }
+    }
 }
 
 /**
  * 使用指定的 [配置][configuration] 构造 [Bot] 实例
  */
-@JvmSynthetic
-public inline fun BotFactory.Bot(
-    context: Context,
-    qq: Long,
-    password: String,
-    configuration: (BotConfiguration.() -> Unit)
-): Bot = this.Bot(context, qq, password, BotConfiguration().apply(configuration))
+public inline fun BotFactory.newBot(qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot =
+    this.newBot(qq, password, BotConfiguration().apply(configuration))
 
 /**
  * 使用指定的 [配置][configuration] 构造 [Bot] 实例
  */
-@JvmSynthetic
-public inline fun BotFactory.Bot(
-    context: Context,
-    qq: Long,
-    password: ByteArray,
-    configuration: (BotConfiguration.() -> Unit)
-): Bot = this.Bot(context, qq, password, BotConfiguration().apply(configuration))
+public inline fun BotFactory.newBot(qq: Long, password: ByteArray, configuration: (BotConfiguration.() -> Unit)): Bot =
+    this.newBot(qq, password, BotConfiguration().apply(configuration))

+ 173 - 60
mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.common.kt

@@ -15,7 +15,7 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.serialization.json.Json
 import net.mamoe.mirai.Bot
-import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
+import java.io.File
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.coroutines.coroutineContext
@@ -33,65 +33,18 @@ import kotlin.coroutines.coroutineContext
  *    inheritCoroutineContext() // 使用 `coroutineScope` 的 Job 作为父 Job
  * }
  * ```
+ *
+ * Java 使用方法:
+ * ```java
+ * Bot bot = BotFactory.newBot(..., new BotConfiguration() {{
+ *     setBogLoggerSupplier((Bot bot) -> { ... })
+ *     fileBasedDeviceInfo()
+ *     ...
+ * }})
+ * ```
  */
-public expect open class BotConfiguration() : BotConfigurationBase {
-    /**
-     * 设备信息覆盖. 在没有手动指定时将会通过日志警告, 并使用随机设备信息.
-     * @see randomDeviceInfo 使用随机设备信息
-     */
-    public var deviceInfo: ((Context) -> DeviceInfo)?
-
-    /**
-     * 使用随机设备信息.
-     *
-     * @see deviceInfo
-     */
-    @ConfigurationDsl
-    public fun randomDeviceInfo()
-
-    /**
-     * 使用特定由 [DeviceInfo] 序列化产生的 JSON 的设备信息
-     *
-     * @see deviceInfo
-     */
-    @SinceMirai("1.2.0")
-    public fun loadDeviceInfoJson(json: String)
-
-    /**
-     * 协议类型, 服务器仅允许使用不同协议同时登录.
-     */
-    public enum class MiraiProtocol {
-        /**
-         * Android 手机.
-         */
-        ANDROID_PHONE,
-
-        /**
-         * Android 平板.
-         */
-        ANDROID_PAD,
-
-        /**
-         * Android 手表.
-         * */
-        @SinceMirai("1.1.0")
-        ANDROID_WATCH;
-
-
-        internal val id: Long
-    }
-
-    public companion object {
-        /** 默认的配置实例. 可以进行修改 */
-        @JvmStatic
-        public val Default: BotConfiguration
-    }
-
-    public fun copy(): BotConfiguration
-}
-
-@SinceMirai("1.1.0")
-public open class BotConfigurationBase internal constructor() {
+@Suppress("PropertyName")
+public open class BotConfiguration { // open for Java
     /**
      * 日志记录器
      *
@@ -143,6 +96,13 @@ public open class BotConfigurationBase internal constructor() {
     /** 使用协议类型 */
     public var protocol: MiraiProtocol = MiraiProtocol.ANDROID_PAD
 
+    /**
+     * 设备信息覆盖. 在没有手动指定时将会通过日志警告, 并使用随机设备信息.
+     * @see fileBasedDeviceInfo 使用指定文件存储设备信息
+     * @see randomDeviceInfo 使用随机设备信息
+     */
+    public var deviceInfo: ((Bot) -> DeviceInfo)? = deviceInfoStub
+
     /** 缓存策略  */
     @SinceMirai("1.0.0")
     @MiraiExperimentalApi
@@ -160,6 +120,159 @@ public open class BotConfigurationBase internal constructor() {
         }
     }.getOrElse { Json {} }
 
+    /**
+     * 使用随机设备信息.
+     *
+     * @see deviceInfo
+     */
+    @ConfigurationDsl
+    public fun randomDeviceInfo() {
+        deviceInfo = null
+    }
+
+    /**
+     * 使用特定由 [DeviceInfo] 序列化产生的 JSON 的设备信息
+     *
+     * @see deviceInfo
+     */
+    @SinceMirai("1.2.0")
+    public fun loadDeviceInfoJson(json: String) {
+        deviceInfo = {
+            this.json.decodeFromString(DeviceInfo.serializer(), json)
+        }
+    }
+
+    /**
+     * 重定向 [网络日志][networkLoggerSupplier] 到指定目录. 若目录不存在将会自动创建 ([File.mkdirs])
+     * @see DirectoryLogger
+     * @see redirectNetworkLogToDirectory
+     */
+    @JvmOverloads
+    @ConfigurationDsl
+    @SinceMirai("1.1.0")
+    public fun redirectNetworkLogToDirectory(
+        dir: File = File("logs"),
+        retain: Long = 1.weeksToMillis,
+        identity: (bot: Bot) -> String = { "Net ${it.id}" }
+    ) {
+        require(!dir.isFile) { "dir must not be a file" }
+        dir.mkdirs()
+        networkLoggerSupplier = { DirectoryLogger(identity(it), dir, retain) }
+    }
+
+    /**
+     * 重定向 [网络日志][networkLoggerSupplier] 到指定文件.
+     * 日志将会逐行追加到此文件. 若文件不存在将会自动创建 ([File.createNewFile])
+     * @see SingleFileLogger
+     * @see redirectNetworkLogToDirectory
+     */
+    @JvmOverloads
+    @SinceMirai("1.1.0")
+    @ConfigurationDsl
+    public fun redirectNetworkLogToFile(
+        file: File = File("mirai.log"),
+        identity: (bot: Bot) -> String = { "Net ${it.id}" }
+    ) {
+        require(!file.isDirectory) { "file must not be a dir" }
+        file.createNewFile()
+        networkLoggerSupplier = { SingleFileLogger(identity(it), file) }
+    }
+
+    /**
+     * 重定向 [Bot 日志][botLoggerSupplier] 到指定目录. 若目录不存在将会自动创建 ([File.mkdirs])
+     * @see DirectoryLogger
+     * @see redirectBotLogToFile
+     */
+    @JvmOverloads
+    @ConfigurationDsl
+    @SinceMirai("1.1.0")
+    public fun redirectBotLogToDirectory(
+        dir: File = File("logs"),
+        retain: Long = 1.weeksToMillis,
+        identity: (bot: Bot) -> String = { "Net ${it.id}" }
+    ) {
+        require(!dir.isFile) { "dir must not be a file" }
+        dir.mkdirs()
+        botLoggerSupplier = { DirectoryLogger(identity(it), dir, retain) }
+    }
+
+    /**
+     * 重定向 [Bot 日志][botLoggerSupplier] 到指定文件.
+     * 日志将会逐行追加到此文件. 若文件不存在将会自动创建 ([File.createNewFile])
+     * @see SingleFileLogger
+     * @see redirectBotLogToDirectory
+     */
+    @JvmOverloads
+    @ConfigurationDsl
+    @SinceMirai("1.1.0")
+    public fun redirectBotLogToFile(
+        file: File = File("mirai.log"),
+        identity: (bot: Bot) -> String = { "Net ${it.id}" }
+    ) {
+        require(!file.isDirectory) { "file must not be a dir" }
+        file.createNewFile()
+        botLoggerSupplier = { SingleFileLogger(identity(it), file) }
+    }
+
+    @Suppress("ACTUAL_WITHOUT_EXPECT")
+    public enum class MiraiProtocol constructor(
+        /** 协议模块使用的 ID */
+        @JvmField internal val id: Long
+    ) {
+        /**
+         * Android 手机.
+         */
+        ANDROID_PHONE(537062845),
+
+        /**
+         * Android 平板.
+         */
+        ANDROID_PAD(537062409),
+
+        /**
+         * Android 手表.
+         * */
+        @SinceMirai("1.1.0")
+        ANDROID_WATCH(537061176)
+    }
+
+    public companion object {
+        /** 默认的配置实例. 可以进行修改 */
+        @JvmStatic
+        public val Default: BotConfiguration = BotConfiguration()
+    }
+
+    /**
+     * 使用文件存储设备信息.
+     *
+     * 此函数只在 JVM 和 Android 有效. 在其他平台将会抛出异常.
+     * @param filepath 文件路径. 可相对于程序运行路径 (`user.dir`), 也可以是绝对路径.
+     * @see deviceInfo
+     */
+    @JvmOverloads
+    @ConfigurationDsl
+    public fun fileBasedDeviceInfo(filepath: String = "device.json") {
+        deviceInfo = getFileBasedDeviceInfoSupplier(filepath)
+    }
+
+    public fun copy(): BotConfiguration {
+        return BotConfiguration().also { new ->
+            new.botLoggerSupplier = botLoggerSupplier
+            new.networkLoggerSupplier = networkLoggerSupplier
+            new.deviceInfo = deviceInfo
+            new.parentCoroutineContext = parentCoroutineContext
+            new.heartbeatPeriodMillis = heartbeatPeriodMillis
+            new.heartbeatTimeoutMillis = heartbeatTimeoutMillis
+            new.firstReconnectDelayMillis = firstReconnectDelayMillis
+            new.reconnectPeriodMillis = reconnectPeriodMillis
+            new.reconnectionRetryTimes = reconnectionRetryTimes
+            new.loginSolver = loginSolver
+            new.protocol = protocol
+            new.fileCacheStrategy = fileCacheStrategy
+        }
+    }
+
+
     /**
      * 不显示网络日志. 不推荐.
      * @see networkLoggerSupplier 更多日志处理方式
@@ -242,7 +355,7 @@ public open class BotConfigurationBase internal constructor() {
     public annotation class ConfigurationDsl
 }
 
-internal val deviceInfoStub: (Context) -> DeviceInfo = {
+internal val deviceInfoStub: (Bot) -> DeviceInfo = {
     @Suppress("DEPRECATION")
     MiraiLogger.warning("未指定设备信息, 已使用随机设备信息. 请查看 BotConfiguration.deviceInfo 以获取更多信息.")
     @Suppress("DEPRECATION")

+ 0 - 16
mirai-core-api/src/commonMain/kotlin/utils/Context.common.kt

@@ -1,16 +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 AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-/**
- * On Android, typealias to `android.content.Context`
- * On JVM, empty class.
- */
-public expect abstract class Context

+ 1 - 1
mirai-core-api/src/commonMain/kotlin/utils/LoginSolver.kt

@@ -175,7 +175,7 @@ public class StandardCharImageLoginSolver(
 //////////////// internal
 ///////////////////////////////
 
-internal fun BotConfiguration.getFileBasedDeviceInfoSupplier(filename: String): (Context) -> DeviceInfo {
+internal fun BotConfiguration.getFileBasedDeviceInfoSupplier(filename: String): (Bot) -> DeviceInfo {
     return {
         File(filename).loadAsDeviceInfo(json)
     }

+ 0 - 210
mirai-core-api/src/jvmMain/kotlin/BotFactory.kt

@@ -1,210 +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 AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-@file:Suppress("FunctionName", "INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith")
-@file:JvmName("BotFactoryJvm")
-
-package net.mamoe.mirai
-
-import net.mamoe.mirai.utils.BotConfiguration
-import net.mamoe.mirai.utils.Context
-import net.mamoe.mirai.utils.ContextImpl
-import net.mamoe.mirai.utils.SinceMirai
-
-/**
- * 构造 [Bot] 的工厂. 这是 [Bot] 唯一的构造方式.
- *
- * 请添加模块依赖 `mirai-core-qqandroid` 以获取协议支持.
- *
- * ### 自动选择协议模块并构造 [Bot]
- * 在 Kotlin 使用包级函数 [Bot], 在 Java 使用 `BotFactoryJvm.newBot`
- *
- * mirai 通过 [Class.forName] 查找可用的协议实现, 如 `net.mamoe.mirai.internal.QQAndroid`
- *
- * ### 手动选择协议模块并构造 [Bot]
- * 引用 `net.mamoe.mirai.internal.QQAndroid` 并使用其成员函数 [Bot]
- */
-public actual interface BotFactory {
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    public actual fun Bot(
-        context: Context,
-        qq: Long,
-        password: String,
-        configuration: BotConfiguration
-    ): Bot
-
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    public fun Bot(qq: Long, password: String, configuration: BotConfiguration = BotConfiguration.Default): Bot
-
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    public actual fun Bot(
-        context: Context,
-        qq: Long,
-        passwordMd5: ByteArray,
-        configuration: BotConfiguration
-    ): Bot
-
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    public fun Bot(
-        qq: Long,
-        passwordMd5: ByteArray,
-        configuration: BotConfiguration
-    ): Bot
-
-    @SinceMirai("1.3.0")
-    public actual companion object INSTANCE : BotFactory {
-        @Suppress("ACTUAL_WITHOUT_EXPECT")
-        actual override fun Bot(context: Context, qq: Long, password: String, configuration: BotConfiguration): Bot {
-            return factory.Bot(context, qq, password, configuration)
-        }
-
-        override fun Bot(qq: Long, password: String, configuration: BotConfiguration): Bot {
-            return factory.Bot(qq, password, configuration)
-        }
-
-        @Suppress("ACTUAL_WITHOUT_EXPECT")
-        actual override fun Bot(
-            context: Context,
-            qq: Long,
-            passwordMd5: ByteArray,
-            configuration: BotConfiguration
-        ): Bot {
-            return factory.Bot(context, qq, passwordMd5, configuration)
-        }
-
-        override fun Bot(qq: Long, passwordMd5: ByteArray, configuration: BotConfiguration): Bot {
-            return factory.Bot(qq, passwordMd5, configuration)
-        }
-    }
-}
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- *
- * Java 调用方式: `BotFactoryJvm.newBot(...)`
- */
-@JvmName("newBot")
-@JvmOverloads
-public fun Bot(
-    context: Context,
-    qq: Long,
-    password: String,
-    configuration: BotConfiguration = BotConfiguration.Default
-): Bot =
-    factory.Bot(context, qq, password, configuration)
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- */
-@JvmSynthetic
-public inline fun Bot(context: Context, qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot =
-    factory.Bot(context, qq, password, configuration)
-
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- *
- * Java 调用方式: `BotFactoryJvm.newBot(...)`
- */
-@JvmName("newBot")
-@JvmOverloads
-public fun Bot(qq: Long, password: String, configuration: BotConfiguration = BotConfiguration.Default): Bot =
-    factory.Bot(ContextImpl(), qq, password, configuration)
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- */
-@JvmSynthetic
-public inline fun Bot(qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot =
-    factory.Bot(ContextImpl(), qq, password, configuration)
-
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- *
- * Java 调用方式: `BotFactoryJvm.newBot(...)`
- */
-@JvmName("newBot")
-@JvmOverloads
-public fun Bot(
-    context: Context,
-    qq: Long,
-    passwordMd5: ByteArray,
-    configuration: BotConfiguration = BotConfiguration.Default
-): Bot =
-    factory.Bot(context, qq, passwordMd5, configuration)
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- */
-@JvmSynthetic
-public inline fun Bot(
-    context: Context,
-    qq: Long,
-    passwordMd5: ByteArray,
-    configuration: (BotConfiguration.() -> Unit)
-): Bot =
-    factory.Bot(context, qq, passwordMd5, BotConfiguration().apply(configuration))
-
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- *
- * Java 调用方式: `BotFactoryJvm.newBot(...)`
- */
-@JvmName("newBot")
-@JvmOverloads
-public fun Bot(qq: Long, passwordMd5: ByteArray, configuration: BotConfiguration = BotConfiguration.Default): Bot =
-    factory.Bot(ContextImpl(), qq, passwordMd5, configuration)
-
-/**
- * 自动加载现有协议的 [BotFactory], 并使用指定的 [配置][configuration] 构造 [Bot] 实例
- */
-@JvmSynthetic
-public inline fun Bot(qq: Long, passwordMd5: ByteArray, configuration: (BotConfiguration.() -> Unit)): Bot =
-    factory.Bot(ContextImpl(), qq, passwordMd5, BotConfiguration().apply(configuration))
-
-
-// Do not use ServiceLoader. Probably not working on MPP
-@PublishedApi
-internal val factory: BotFactory = run {
-    runCatching {
-        Class.forName("net.mamoe.mirai.timpc.TIMPC").kotlin.objectInstance as BotFactory
-    }.getOrElse {
-        runCatching {
-            Class.forName("net.mamoe.mirai.internal.QQAndroid").kotlin.objectInstance as BotFactory
-        }.getOrNull()
-    }
-} ?: error(
-    """
-    No BotFactory found. Please ensure that you've added dependency of protocol modules.
-    Available modules:
-    - net.mamoe:mirai-core-timpc (stays at 0.12.0)
-    - net.mamoe:mirai-core-qqandroid (recommended)
-    You should have at lease one protocol module installed.
-    -------------------------------------------------------
-    找不到 BotFactory. 请确保你依赖了至少一个协议模块.
-    可用的协议模块: 
-    - net.mamoe:mirai-core-timpc (0.12.0 后停止更新)
-    - net.mamoe:mirai-core-qqandroid (推荐)
-    请添加上述任一模块的依赖(与 mirai-core 版本相同)
-    """.trimIndent()
-)

+ 0 - 200
mirai-core-api/src/jvmMain/kotlin/utils/BotConfiguration.kt

@@ -1,200 +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 AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-@file:Suppress("unused", "DEPRECATION_ERROR", "EXPOSED_SUPER_CLASS")
-
-package net.mamoe.mirai.utils
-
-import net.mamoe.mirai.Bot
-import java.io.File
-
-/**
- * [Bot] 配置.
- *
- * Kotlin 使用方法:
- * ```
- * val bot = Bot(...) {
- *    // 在这里配置 Bot
- *
- *    bogLoggerSupplier = { bot -> ... }
- *    fileBasedDeviceInfo()
- *    inheritCoroutineContext() // 使用 `coroutineScope` 的 Job 作为父 Job
- * }
- * ```
- *
- * Java 使用方法:
- * ```java
- * Bot bot = BotFactory.newBot(..., new BotConfiguration() {{
- *     setBogLoggerSupplier((Bot bot) -> { ... })
- *     fileBasedDeviceInfo()
- *     ...
- * }})
- * ```
- */
-@Suppress("PropertyName")
-public actual open class BotConfiguration : BotConfigurationBase() { // open for Java
-    /**
-     * 设备信息覆盖. 在没有手动指定时将会通过日志警告, 并使用随机设备信息.
-     * @see fileBasedDeviceInfo 使用指定文件存储设备信息
-     * @see randomDeviceInfo 使用随机设备信息
-     */
-    public actual var deviceInfo: ((Context) -> DeviceInfo)? = deviceInfoStub
-
-    /**
-     * 使用随机设备信息.
-     *
-     * @see deviceInfo
-     */
-    @ConfigurationDsl
-    public actual fun randomDeviceInfo() {
-        deviceInfo = null
-    }
-
-    /**
-     * 使用特定由 [DeviceInfo] 序列化产生的 JSON 的设备信息
-     *
-     * @see deviceInfo
-     */
-    @SinceMirai("1.2.0")
-    public actual fun loadDeviceInfoJson(json: String) {
-        deviceInfo = { context ->
-            this.json.decodeFromString(DeviceInfo.serializer(), json)
-        }
-    }
-
-    /**
-     * 重定向 [网络日志][networkLoggerSupplier] 到指定目录. 若目录不存在将会自动创建 ([File.mkdirs])
-     * @see DirectoryLogger
-     * @see redirectNetworkLogToDirectory
-     */
-    @JvmOverloads
-    @ConfigurationDsl
-    @SinceMirai("1.1.0")
-    public fun redirectNetworkLogToDirectory(
-        dir: File = File("logs"),
-        retain: Long = 1.weeksToMillis,
-        identity: (bot: Bot) -> String = { "Net ${it.id}" }
-    ) {
-        require(!dir.isFile) { "dir must not be a file" }
-        dir.mkdirs()
-        networkLoggerSupplier = { DirectoryLogger(identity(it), dir, retain) }
-    }
-
-    /**
-     * 重定向 [网络日志][networkLoggerSupplier] 到指定文件.
-     * 日志将会逐行追加到此文件. 若文件不存在将会自动创建 ([File.createNewFile])
-     * @see SingleFileLogger
-     * @see redirectNetworkLogToDirectory
-     */
-    @JvmOverloads
-    @SinceMirai("1.1.0")
-    @ConfigurationDsl
-    public fun redirectNetworkLogToFile(
-        file: File = File("mirai.log"),
-        identity: (bot: Bot) -> String = { "Net ${it.id}" }
-    ) {
-        require(!file.isDirectory) { "file must not be a dir" }
-        file.createNewFile()
-        networkLoggerSupplier = { SingleFileLogger(identity(it), file) }
-    }
-
-    /**
-     * 重定向 [Bot 日志][botLoggerSupplier] 到指定目录. 若目录不存在将会自动创建 ([File.mkdirs])
-     * @see DirectoryLogger
-     * @see redirectBotLogToFile
-     */
-    @JvmOverloads
-    @ConfigurationDsl
-    @SinceMirai("1.1.0")
-    public fun redirectBotLogToDirectory(
-        dir: File = File("logs"),
-        retain: Long = 1.weeksToMillis,
-        identity: (bot: Bot) -> String = { "Net ${it.id}" }
-    ) {
-        require(!dir.isFile) { "dir must not be a file" }
-        dir.mkdirs()
-        botLoggerSupplier = { DirectoryLogger(identity(it), dir, retain) }
-    }
-
-    /**
-     * 重定向 [Bot 日志][botLoggerSupplier] 到指定文件.
-     * 日志将会逐行追加到此文件. 若文件不存在将会自动创建 ([File.createNewFile])
-     * @see SingleFileLogger
-     * @see redirectBotLogToDirectory
-     */
-    @JvmOverloads
-    @ConfigurationDsl
-    @SinceMirai("1.1.0")
-    public fun redirectBotLogToFile(
-        file: File = File("mirai.log"),
-        identity: (bot: Bot) -> String = { "Net ${it.id}" }
-    ) {
-        require(!file.isDirectory) { "file must not be a dir" }
-        file.createNewFile()
-        botLoggerSupplier = { SingleFileLogger(identity(it), file) }
-    }
-
-    @Suppress("ACTUAL_WITHOUT_EXPECT")
-    public actual enum class MiraiProtocol actual constructor(
-        /** 协议模块使用的 ID */
-        @JvmField internal actual val id: Long
-    ) {
-        /**
-         * Android 手机.
-         */
-        ANDROID_PHONE(537062845),
-
-        /**
-         * Android 平板.
-         */
-        ANDROID_PAD(537062409),
-
-        /**
-         * Android 手表.
-         * */
-        @SinceMirai("1.1.0")
-        ANDROID_WATCH(537061176)
-    }
-
-    public actual companion object {
-        /** 默认的配置实例. 可以进行修改 */
-        @JvmStatic
-        public actual val Default: BotConfiguration = BotConfiguration()
-    }
-
-    /**
-     * 使用文件存储设备信息.
-     *
-     * 此函数只在 JVM 和 Android 有效. 在其他平台将会抛出异常.
-     * @param filepath 文件路径. 可相对于程序运行路径 (`user.dir`), 也可以是绝对路径.
-     * @see deviceInfo
-     */
-    @JvmOverloads
-    @ConfigurationDsl
-    public fun fileBasedDeviceInfo(filepath: String = "device.json") {
-        deviceInfo = getFileBasedDeviceInfoSupplier(filepath)
-    }
-
-    public actual fun copy(): BotConfiguration {
-        return BotConfiguration().also { new ->
-            new.botLoggerSupplier = botLoggerSupplier
-            new.networkLoggerSupplier = networkLoggerSupplier
-            new.deviceInfo = deviceInfo
-            new.parentCoroutineContext = parentCoroutineContext
-            new.heartbeatPeriodMillis = heartbeatPeriodMillis
-            new.heartbeatTimeoutMillis = heartbeatTimeoutMillis
-            new.firstReconnectDelayMillis = firstReconnectDelayMillis
-            new.reconnectPeriodMillis = reconnectPeriodMillis
-            new.reconnectionRetryTimes = reconnectionRetryTimes
-            new.loginSolver = loginSolver
-            new.protocol = protocol
-            new.fileCacheStrategy = fileCacheStrategy
-        }
-    }
-}

+ 0 - 14
mirai-core-api/src/jvmMain/kotlin/utils/Context.kt

@@ -1,14 +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 AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-public actual abstract class Context
-
-public open class ContextImpl : Context()

+ 6 - 10
mirai-core/src/commonMain/kotlin/BotFactory.kt

@@ -15,31 +15,27 @@ package net.mamoe.mirai.internal
 
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.BotFactory
-import net.mamoe.mirai.internal.BotFactoryImpl.Bot
 import net.mamoe.mirai.utils.BotConfiguration
-import net.mamoe.mirai.utils.Context
-import kotlin.jvm.JvmName
 
 /**
  * QQ for Android
  */
 @Suppress("INAPPLICABLE_JVM_NAME")
-expect object BotFactoryImpl : BotFactory {
+object BotFactoryImpl : BotFactory {
 
     /**
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
-    @JvmName("newBot")
-    override fun Bot(context: Context, qq: Long, password: String, configuration: BotConfiguration): Bot
+    override fun newBot(qq: Long, password: String, configuration: BotConfiguration): Bot {
+        return QQAndroidBot(BotAccount(qq, password), configuration)
+    }
 
     /**
      * 使用指定的 [配置][configuration] 构造 [Bot] 实例
      */
-    @JvmName("newBot")
-    override fun Bot(
-        context: Context,
+    override fun newBot(
         qq: Long,
         passwordMd5: ByteArray,
         configuration: BotConfiguration
-    ): Bot
+    ): Bot = QQAndroidBot(BotAccount(qq, passwordMd5), configuration)
 }

+ 0 - 3
mirai-core/src/commonMain/kotlin/BotImpl.kt

@@ -37,11 +37,8 @@ import kotlin.time.ExperimentalTime
 import kotlin.time.measureTime
 
 internal abstract class BotImpl<N : BotNetworkHandler> constructor(
-    context: Context,
     configuration: BotConfiguration
 ) : Bot(configuration), CoroutineScope {
-    override val context: Context by context.unsafeWeakRef()
-
     final override val logger: MiraiLogger by lazy { configuration.botLoggerSupplier(this) }
 
     // region network

+ 7 - 10
mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt

@@ -28,7 +28,6 @@ import net.mamoe.mirai.network.LoginFailedException
 import net.mamoe.mirai.utils.*
 import kotlin.contracts.contract
 import kotlin.coroutines.CoroutineContext
-import kotlin.jvm.JvmField
 import net.mamoe.mirai.internal.network.protocol.data.jce.FriendInfo as JceFriendInfo
 
 internal fun Bot.asQQAndroidBot(): QQAndroidBot {
@@ -41,23 +40,21 @@ internal fun Bot.asQQAndroidBot(): QQAndroidBot {
 
 @Suppress("INVISIBLE_MEMBER", "BooleanLiteralArgument", "OverridingDeprecatedMember")
 internal class QQAndroidBot constructor(
-    context: Context,
     account: BotAccount,
     configuration: BotConfiguration
-) : QQAndroidBotBase(context, account, configuration)
+) : QQAndroidBotBase(account, configuration)
 
 
 internal abstract class QQAndroidBotBase constructor(
-    context: Context,
     private val account: BotAccount,
     configuration: BotConfiguration
-) : BotImpl<QQAndroidBotNetworkHandler>(context, configuration) {
+) : BotImpl<QQAndroidBotNetworkHandler>(configuration) {
+    @Suppress("LeakingThis")
     val client: QQAndroidClient =
         QQAndroidClient(
-            context,
             account,
-            bot = @Suppress("LeakingThis") this as QQAndroidBot,
-            device = configuration.deviceInfo?.invoke(context) ?: DeviceInfo.random()
+            bot = this as QQAndroidBot,
+            device = configuration.deviceInfo?.invoke(this) ?: DeviceInfo.random()
         )
     internal var firstLoginSucceed: Boolean = false
 
@@ -127,7 +124,7 @@ internal abstract class QQAndroidBotBase constructor(
 
 internal val EMPTY_BYTE_ARRAY = ByteArray(0)
 
-private fun RichMessage.Templates.longMessage(brief: String, resId: String, timeSeconds: Long): RichMessage {
+internal fun RichMessage.Templates.longMessage(brief: String, resId: String, timeSeconds: Long): RichMessage {
     val limited: String = if (brief.length > 30) {
         brief.take(30) + "…"
     } else {
@@ -154,7 +151,7 @@ private fun RichMessage.Templates.longMessage(brief: String, resId: String, time
 }
 
 
-private fun RichMessage.Templates.forwardMessage(
+internal fun RichMessage.Templates.forwardMessage(
     resId: String,
     timeSeconds: Long,
     preview: String,

+ 0 - 2
mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt

@@ -72,7 +72,6 @@ internal object DefaultServerList : Set<Pair<String, Int>> by setOf(
  */
 @PublishedApi
 internal open class QQAndroidClient(
-    context: Context,
     val account: BotAccount,
     val ecdh: ECDH = ECDH(),
     val device: DeviceInfo,
@@ -115,7 +114,6 @@ internal open class QQAndroidClient(
 
     var onlineStatus: OnlineStatus = OnlineStatus.ONLINE
 
-    val context: Context by context.unsafeWeakRef()
     val bot: QQAndroidBot by bot.unsafeWeakRef()
 
     var tgtgtKey: ByteArray = generateTgtgtKey(device.guid)

+ 0 - 66
mirai-core/src/jvmMain/kotlin/BotFactoryImpl.kt

@@ -1,66 +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 AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-@file:Suppress("FunctionName", "OverridingDeprecatedMember")
-
-package net.mamoe.mirai.internal
-
-import net.mamoe.mirai.Bot
-import net.mamoe.mirai.BotFactory
-import net.mamoe.mirai.internal.BotFactoryImpl.Bot
-import net.mamoe.mirai.utils.BotConfiguration
-import net.mamoe.mirai.utils.Context
-
-/**
- * QQ for Android
- */
-@Suppress("INAPPLICABLE_JVM_NAME")
-actual object BotFactoryImpl : BotFactory {
-
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    actual override fun Bot(context: Context, qq: Long, password: String, configuration: BotConfiguration): Bot {
-        return QQAndroidBot(context, BotAccount(qq, password), configuration)
-    }
-
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    override fun Bot(qq: Long, password: String, configuration: BotConfiguration): Bot =
-        QQAndroidBot(BotAccount(qq, password), configuration)
-
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    actual override fun Bot(
-        context: Context,
-        qq: Long,
-        passwordMd5: ByteArray,
-        configuration: BotConfiguration
-    ): Bot = QQAndroidBot(context, BotAccount(qq, passwordMd5), configuration)
-
-    /**
-     * 使用指定的 [配置][configuration] 构造 [Bot] 实例
-     */
-    @JvmName("newBot")
-    override fun Bot(
-        qq: Long,
-        passwordMd5: ByteArray,
-        configuration: BotConfiguration
-    ): Bot = QQAndroidBot(BotAccount(qq, passwordMd5), configuration)
-}
-
-/**
- * 使用指定的 [配置][configuration] 构造 [Bot] 实例
- */
-inline fun BotFactoryImpl.Bot(qq: Long, password: String, configuration: (BotConfiguration.() -> Unit)): Bot =
-    this.Bot(qq, password, BotConfiguration().apply(configuration))

+ 0 - 17
mirai-core/src/jvmMain/kotlin/QQAndroidBot.jvm.kt

@@ -1,17 +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 AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-package net.mamoe.mirai.internal
-
-import net.mamoe.mirai.utils.BotConfiguration
-import net.mamoe.mirai.utils.ContextImpl
-
-
-@Suppress("FunctionName")
-internal fun QQAndroidBot(account: BotAccount, configuration: BotConfiguration): QQAndroidBot =
-    QQAndroidBot(ContextImpl(), account, configuration)