mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-03 01:39:35 +08:00
Introduce multi-platform BotConfiguration structure; Add redirectNetworkLogToDirectory
functions, fix #371
This commit is contained in:
parent
5e7beddfdd
commit
f175d07c0a
@ -6,7 +6,7 @@
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
@file:Suppress("unused", "DEPRECATION_ERROR")
|
||||
@file:Suppress("unused", "DEPRECATION_ERROR", "EXPOSED_SUPER_CLASS")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
@ -17,7 +17,6 @@ import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.coroutines.coroutineContext
|
||||
import kotlin.jvm.JvmField
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmStatic
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
@ -35,8 +34,34 @@ import kotlin.jvm.JvmSynthetic
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
expect open class BotConfiguration() : BotConfigurationBase {
|
||||
/**
|
||||
* 设备信息覆盖. 在没有手动指定时将会通过日志警告, 并使用随机设备信息.
|
||||
* @see randomDeviceInfo 使用随机设备信息
|
||||
*/
|
||||
var deviceInfo: ((Context) -> DeviceInfo)?
|
||||
|
||||
/**
|
||||
* 使用随机设备信息.
|
||||
*
|
||||
* @see deviceInfo
|
||||
*/
|
||||
@ConfigurationDsl
|
||||
fun randomDeviceInfo()
|
||||
|
||||
companion object {
|
||||
/** 默认的配置实例. 可以进行修改 */
|
||||
@JvmStatic
|
||||
val Default: BotConfiguration
|
||||
}
|
||||
|
||||
fun copy(): BotConfiguration
|
||||
}
|
||||
|
||||
@MiraiInternalAPI
|
||||
@Suppress("PropertyName")
|
||||
open class BotConfiguration {
|
||||
@SinceMirai("1.1.0")
|
||||
internal open class BotConfigurationBase internal constructor() {
|
||||
/**
|
||||
* 日志记录器
|
||||
*
|
||||
@ -61,13 +86,6 @@ open class BotConfiguration {
|
||||
*/
|
||||
var networkLoggerSupplier: ((Bot) -> MiraiLogger) = { DefaultLogger("Net ${it.id}") }
|
||||
|
||||
/**
|
||||
* 设备信息覆盖. 在没有手动指定时将会通过日志警告, 并使用随机设备信息.
|
||||
* @see fileBasedDeviceInfo 使用指定文件存储设备信息
|
||||
* @see randomDeviceInfo 使用随机设备信息
|
||||
*/
|
||||
var deviceInfo: ((Context) -> DeviceInfo)? = deviceInfoStub
|
||||
|
||||
/** 父 [CoroutineContext]. [Bot] 创建后会使用 [SupervisorJob] 覆盖其 [Job], 但会将这个 [Job] 作为父 [Job] */
|
||||
var parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
|
||||
|
||||
@ -121,12 +139,6 @@ open class BotConfiguration {
|
||||
ANDROID_PAD(537062409)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** 默认的配置实例. 可以进行修改 */
|
||||
@JvmStatic
|
||||
val Default = BotConfiguration()
|
||||
}
|
||||
|
||||
/**
|
||||
* 不显示网络日志. 不推荐.
|
||||
* @see networkLoggerSupplier 更多日志处理方式
|
||||
@ -145,29 +157,6 @@ open class BotConfiguration {
|
||||
botLoggerSupplier = { _ -> SilentLogger }
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用文件存储设备信息.
|
||||
*
|
||||
* 此函数只在 JVM 和 Android 有效. 在其他平台将会抛出异常.
|
||||
* @param filepath 文件路径. 可相对于程序运行路径 (`user.dir`), 也可以是绝对路径.
|
||||
* @see deviceInfo
|
||||
*/
|
||||
@JvmOverloads
|
||||
@ConfigurationDsl
|
||||
fun fileBasedDeviceInfo(filepath: String = "device.json") {
|
||||
deviceInfo = getFileBasedDeviceInfoSupplier(filepath)
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用随机设备信息.
|
||||
*
|
||||
* @see deviceInfo
|
||||
*/
|
||||
@ConfigurationDsl
|
||||
fun randomDeviceInfo() {
|
||||
deviceInfo = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用当前协程的 [coroutineContext] 作为 [parentCoroutineContext].
|
||||
*
|
||||
@ -230,32 +219,12 @@ open class BotConfiguration {
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@DslMarker
|
||||
annotation class ConfigurationDsl
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val deviceInfoStub: (Context) -> DeviceInfo = {
|
||||
internal val deviceInfoStub: (Context) -> DeviceInfo = {
|
||||
@Suppress("DEPRECATION")
|
||||
MiraiLogger.warning("未指定设备信息, 已使用随机设备信息. 请查看 BotConfiguration.deviceInfo 以获取更多信息.")
|
||||
@Suppress("DEPRECATION")
|
||||
MiraiLogger.warning("Device info isn't specified. Please refer to BotConfiguration.deviceInfo for more information")
|
||||
SystemDeviceInfo()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMultiplatform::class)
|
||||
internal expect fun getFileBasedDeviceInfoSupplier(filename: String): ((Context) -> DeviceInfo)?
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@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")
|
||||
actual open class BotConfiguration : BotConfigurationBase() { // open for Java
|
||||
/**
|
||||
* 设备信息覆盖. 在没有手动指定时将会通过日志警告, 并使用随机设备信息.
|
||||
* @see fileBasedDeviceInfo 使用指定文件存储设备信息
|
||||
* @see randomDeviceInfo 使用随机设备信息
|
||||
*/
|
||||
actual var deviceInfo: ((Context) -> DeviceInfo)? = deviceInfoStub
|
||||
|
||||
/**
|
||||
* 使用随机设备信息.
|
||||
*
|
||||
* @see deviceInfo
|
||||
*/
|
||||
@ConfigurationDsl
|
||||
actual fun randomDeviceInfo() {
|
||||
deviceInfo = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 重定向 [网络日志][networkLoggerSupplier] 到指定目录. 若目录不存在将会自动创建 ([File.mkdirs])
|
||||
* @see DirectoryLogger
|
||||
* @see redirectNetworkLogToDirectory
|
||||
*/
|
||||
@JvmOverloads
|
||||
@ConfigurationDsl
|
||||
@SinceMirai("1.1.0")
|
||||
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
|
||||
fun redirectNetworkLogToFile(
|
||||
file: File = File("mirai.log"),
|
||||
identity: (bot: Bot) -> String = { "Net ${it.id}" }
|
||||
) {
|
||||
require(!file.isFile) { "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")
|
||||
fun redirectBotLogToDirectory(
|
||||
dir: File,
|
||||
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")
|
||||
fun redirectBotLogToFile(
|
||||
file: File,
|
||||
identity: (bot: Bot) -> String = { "Net ${it.id}" }
|
||||
) {
|
||||
require(!file.isFile) { "file must not be a dir" }
|
||||
file.createNewFile()
|
||||
botLoggerSupplier = { SingleFileLogger(identity(it), file) }
|
||||
}
|
||||
|
||||
actual companion object {
|
||||
/** 默认的配置实例. 可以进行修改 */
|
||||
@JvmStatic
|
||||
actual val Default = BotConfiguration()
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用文件存储设备信息.
|
||||
*
|
||||
* 此函数只在 JVM 和 Android 有效. 在其他平台将会抛出异常.
|
||||
* @param filepath 文件路径. 可相对于程序运行路径 (`user.dir`), 也可以是绝对路径.
|
||||
* @see deviceInfo
|
||||
*/
|
||||
@JvmOverloads
|
||||
@ConfigurationDsl
|
||||
fun fileBasedDeviceInfo(filepath: String = "device.json") {
|
||||
deviceInfo = getFileBasedDeviceInfoSupplier(filepath)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -154,7 +154,7 @@ actual abstract class LoginSolver {
|
||||
//////////////// internal
|
||||
///////////////////////////////
|
||||
|
||||
internal actual fun getFileBasedDeviceInfoSupplier(filename: String): ((Context) -> DeviceInfo)? {
|
||||
internal fun getFileBasedDeviceInfoSupplier(filename: String): ((Context) -> DeviceInfo)? {
|
||||
return {
|
||||
File(filename).loadAsDeviceInfo(it)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user