Skip to content

Commit

Permalink
add BotBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
MrXiaoM committed Feb 4, 2024
1 parent c1620a3 commit b7927f7
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 18 deletions.
16 changes: 16 additions & 0 deletions docs/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ dependencies {
</dependency>
```

连接到 Onebot

```kotlin
// 正向 WebSocket
val bot1 = BotBuilder.positive("ws://127.0.0.1:5800")
.token("114514")
.connect()
// 反向 WebSocket
val bot2 = BotBuilder.reversed(5700)
.token("114514")
.connect()
// connect() 返回值为 null 时登录失败
```

当前未编写多 Bot 支持,**请勿**在生产环境中连接多个实例。

# 向 Onebot 发送自定义 action

预设的 action 类型列表另请参见 [ActionPathEnum.java](/onebot/src/main/java/cn/evole/onebot/sdk/enums/ActionPathEnum.java) (以下应当填写的是字符串 path 的值)
Expand Down
2 changes: 2 additions & 0 deletions overflow-core-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ dependencies {
implementation("net.mamoe:mirai-core-utils")

implementation("me.him188:kotlin-jvm-blocking-bridge-runtime:3.0.0-180.1")

implementation("org.slf4j:slf4j-api:2.0.5")
}
118 changes: 118 additions & 0 deletions overflow-core-api/src/main/kotlin/top/mrxiaom/overflow/BotBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package top.mrxiaom.overflow

import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.Bot
import org.slf4j.Logger

/**
* Onebot 连接向导
*/
public class BotBuilder private constructor(
private var url: String = "ws://127.0.0.1:8080",
private var reversedPort: Int = -1,
private var token: String = "",
private var retryTimes: Int = 5,
private var retryWaitMills: Long = 5000L,
private var retryRestMills: Long = 60000L,
private var printInfo: Boolean = false,
private var logger: Logger? = null
) {
/**
* 设置用于连接时鉴权的 token
*
* 将 token 设为空则不进行鉴权
*/
public fun token(token: String): BotBuilder = apply {
this.token = token
}

/**
* 设置尝试重连次数,设为 -1 时禁用自动重连
*/
public fun retryTimes(retryTimes: Int): BotBuilder = apply {
this.retryTimes = retryTimes
}

/**
* 设置重连等待间隔时间
*/
public fun retryWaitMills(retryWaitMills: Long): BotBuilder = apply {
this.retryWaitMills = retryWaitMills
}

/**
* 设置重连休息时间
*
* 重连次数耗尽后,会进入休息状态,休息结束后重置重连次数,再次尝试重连
*
* 设为 -1 禁用此功能
*/
public fun retryRestMills(retryRestMills: Long): BotBuilder = apply {
this.retryRestMills = retryRestMills
}

/**
* 禁止打印连接时额外状态信息
*
* 如 Overflow 版本、连接地址、Onebot 协议端版本等
*/
public fun noPrintInfo(): BotBuilder = apply {
this.printInfo = false
}

/**
* 覆写用于 Onebot 的日志记录器
*/
public fun overrideLogger(logger: Logger): BotBuilder = apply {
this.logger = logger
}

/**
* 连接到 Onebot
*
* @return 连接失败时,将返回 null
*/
@JvmBlockingBridge
public suspend fun connect(): Bot? {
return OverflowAPI.get().botStarter.start(
url = url,
reversedPort = reversedPort,
token = token,
retryTimes = retryTimes,
retryWaitMills = retryWaitMills,
retryRestMills = retryRestMills,
printInfo = printInfo,
logger = logger
)
}

companion object {
/**
* 正向 WebSocket 连接
*/
@JvmStatic
fun positive(host: String): BotBuilder = BotBuilder().also { it.url = host }

/**
* 反向 WebSocket 连接
*/
@JvmStatic
fun reversed(port: Int): BotBuilder {
if (port !in 1..65535) throw IllegalStateException("无效的反向 WebSocket 端口号")
return BotBuilder().also { it.reversedPort = port }
}
}
}

public interface IBotStarter {
public suspend fun start(
url: String,
reversedPort: Int,
token: String,
retryTimes: Int,
retryWaitMills: Long,
retryRestMills: Long,
printInfo: Boolean,
logger: Logger?
): Bot?
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.message.data.*

interface OverflowAPI {
val botStarter: IBotStarter
/**
* 以 Onebot 格式新建图片消息
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import top.mrxiaom.overflow.BotBuilder
import top.mrxiaom.overflow.BuildConstants
import top.mrxiaom.overflow.IBotStarter
import top.mrxiaom.overflow.OverflowAPI
import top.mrxiaom.overflow.contact.RemoteBot
import top.mrxiaom.overflow.internal.contact.BotWrapper
import top.mrxiaom.overflow.internal.contact.BotWrapper.Companion.wrap
import top.mrxiaom.overflow.internal.contact.FriendWrapper
Expand Down Expand Up @@ -141,7 +144,29 @@ class Overflow : IMirai, CoroutineScope, LowLevelApiAccessor, OverflowAPI {

@JvmOverloads
@JvmBlockingBridge
suspend fun start(printInfo: Boolean = false, logger: Logger = LoggerFactory.getLogger("Onebot")): Boolean {
suspend fun start(
printInfo: Boolean = false,
logger: Logger = LoggerFactory.getLogger("Onebot")
): Boolean {
return start0(
printInfo = printInfo,
logger = logger
) != null
}

private suspend fun start0(
botConfig: BotConfig = BotConfig(
url = config.wsHost,
reversedPort = config.reversedWSPort,
token = config.token,
isAccessToken = config.token.isNotBlank(),
retryTimes = config.retryTimes,
retryWaitMills = config.retryWaitMills,
retryRestMills = config.retryRestMills,
),
printInfo: Boolean = false,
logger: Logger = LoggerFactory.getLogger("Onebot")
): Bot? {
val reversed = config.reversedWSPort in 1..65535
if (printInfo) {
logger.info("Overflow v$version 正在运行")
Expand All @@ -152,17 +177,7 @@ class Overflow : IMirai, CoroutineScope, LowLevelApiAccessor, OverflowAPI {
}
}

val service = ConnectFactory.create(
BotConfig(
url = config.wsHost,
reversedPort = config.reversedWSPort,
token = config.token,
isAccessToken = config.token.isNotBlank(),
retryTimes = config.retryTimes,
retryWaitMills = config.retryWaitMills,
retryRestMills = config.retryRestMills,
), logger
)
val service = ConnectFactory.create(botConfig, logger)
val dispatchers: EventBus
val botImpl: cn.evolvefield.onebot.client.core.Bot
if (reversed) {
Expand All @@ -172,7 +187,7 @@ class Overflow : IMirai, CoroutineScope, LowLevelApiAccessor, OverflowAPI {
logger.error("未连接到 Onebot")
if (!isNotExit) exitProcess(1)
}
return false
return null
}
dispatchers = ws.first.createEventBus()
botImpl = ws.second
Expand All @@ -184,7 +199,7 @@ class Overflow : IMirai, CoroutineScope, LowLevelApiAccessor, OverflowAPI {
if (!isNotExit) exitProcess(1)

}
return false
return null
}
dispatchers = ws.createEventBus()
botImpl = ws.createBot().also { BotFactoryImpl.internalBot = it }
Expand All @@ -198,7 +213,7 @@ class Overflow : IMirai, CoroutineScope, LowLevelApiAccessor, OverflowAPI {
logger.error("未连接到 Onebot")
if (!isNotExit) exitProcess(1)
}
return false
return null
}
if (printInfo) {
logger.info("服务端版本信息\n${versionInfo.toPrettyString()}")
Expand All @@ -208,10 +223,36 @@ class Overflow : IMirai, CoroutineScope, LowLevelApiAccessor, OverflowAPI {
dispatchers.addGroupListeners(bot)
dispatchers.addFriendListeners(bot)

BotOnlineEvent(bot).broadcast()
return true
return bot.also { it.eventDispatcher.broadcastAsync(BotOnlineEvent(bot)) }
}

override val botStarter: IBotStarter = object : IBotStarter {
override suspend fun start(
url: String,
reversedPort: Int,
token: String,
retryTimes: Int,
retryWaitMills: Long,
retryRestMills: Long,
printInfo: Boolean,
logger: Logger?
): Bot? {
val botConfig = BotConfig(
url = url,
reversedPort = reversedPort,
token = token,
isAccessToken = token.isNotBlank(),
retryTimes = retryTimes,
retryWaitMills = retryWaitMills,
retryRestMills = retryRestMills,
)
return if (logger != null) {
start0(botConfig, printInfo, logger)
} else {
start0(botConfig, printInfo)
}
}
}

override fun imageFromFile(file: String): Image = OnebotMessages.imageFromFile(file)
override fun audioFromFile(file: String): Audio = OnebotMessages.audioFromFile(file)
override fun videoFromFile(file: String): ShortVideo = OnebotMessages.videoFromFile(file)
Expand Down

0 comments on commit b7927f7

Please sign in to comment.