Skip to content

Commit bd4b528

Browse files
committed
controller
1 parent 964a4cf commit bd4b528

File tree

13 files changed

+234
-92
lines changed

13 files changed

+234
-92
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ out/
3737
### MIRAI ###
3838
device.json
3939
src/main/java/onebot/
40+
src/main/java/dto/
4041

4142

4243
### Mac ###

build.gradle.kts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ repositories {
4848
dependencies {
4949
implementation("net.mamoe:mirai-core-qqandroid:1.3.0")
5050
implementation("com.squareup.okhttp3:okhttp:4.8.0")
51-
implementation("com.google.protobuf:protobuf-javalite:3.8.0")
51+
// implementation("com.google.protobuf:protobuf-javalite:3.8.0")
52+
53+
implementation("com.google.protobuf:protobuf-java:3.12.2")
54+
implementation("com.googlecode.protobuf-java-format:protobuf-java-format:1.4")
55+
implementation("com.google.protobuf:protobuf-java-util:3.12.2")
56+
// implementation("com.googlecode.protobuf:protobuf-java-format:1.2")
5257

5358
implementation("org.springframework.boot:spring-boot-starter-web")
5459
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
@@ -72,10 +77,10 @@ protobuf {
7277
generateProtoTasks {
7378
all().forEach {
7479
it.builtins{
75-
remove("java")
76-
id("java"){
77-
option("lite")
78-
}
80+
// remove("java")
81+
// id("java"){
82+
// option("lite")
83+
// }
7984
}
8085
}
8186
}

src/main/kotlin/net/lz1998/mirai/SpringMiraiClientApplication.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package net.lz1998.mirai
22

33
import org.springframework.boot.autoconfigure.SpringBootApplication
44
import org.springframework.boot.runApplication
5+
import org.springframework.context.annotation.Bean
6+
import org.springframework.context.annotation.Configuration
7+
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter
58

69
@SpringBootApplication
710
class SpringMiraiClientApplication
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.lz1998.mirai.config
2+
3+
import org.springframework.context.annotation.Bean
4+
import org.springframework.context.annotation.Configuration
5+
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter
6+
7+
@Configuration
8+
class ProtobufConfig {
9+
@Bean
10+
fun createProtobufConverter(): ProtobufHttpMessageConverter {
11+
return ProtobufHttpMessageConverter();
12+
}
13+
}
Lines changed: 16 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,39 @@
11
package net.lz1998.mirai.controller
22

3+
import dto.HttpDto
34
import kotlinx.coroutines.GlobalScope
45
import kotlinx.coroutines.launch
5-
import kotlinx.coroutines.runBlocking
66
import net.lz1998.mirai.service.BotService
7-
import net.lz1998.mirai.service.LoginDataType
8-
import net.lz1998.mirai.service.myLoginSolver
97
import org.springframework.beans.factory.annotation.Autowired
10-
import org.springframework.http.MediaType
11-
import org.springframework.web.bind.annotation.RequestMapping
12-
import org.springframework.web.bind.annotation.RestController
8+
import org.springframework.web.bind.annotation.*
139

1410
@RestController
11+
@RequestMapping("/bot")
1512
class BotController {
1613

1714
@Autowired
1815
lateinit var botService: BotService
1916

2017

2118
// 创建一个机器人并登陆
22-
@RequestMapping("/createBot")
23-
fun createBot(botId: Long, password: String): String {
24-
GlobalScope.launch { // TODO 是否可以优化? suspend报错怎么解决?
25-
val bot = botService.botMap[botId]
26-
if (bot != null) { // 机器人已存在,直接登陆
27-
bot.bot.login()
28-
return@launch
29-
} else { // 机器人不存在,创建
30-
botService.createBot(botId, password)
31-
}
32-
}
33-
return "ok"
34-
}
35-
36-
// 获取机器人状态
37-
@RequestMapping("/getStatus")
38-
fun getStatus(botId: Long): String {
39-
// 机器人不存在
40-
val bot = botService.botMap[botId] ?: return "NOT_CREATED"
41-
42-
// 机器人在线
43-
if (bot.bot.isOnline) {
44-
return "ONLINE"
45-
}
46-
47-
// 机器人需要登陆
48-
val loginData = myLoginSolver.getLoginData(botId)
49-
if (loginData != null) {
50-
return loginData.type.name // 登陆类型
51-
}
52-
53-
// 其他状态
54-
return "UNKNOWN"
19+
@RequestMapping("/create/v1", produces = ["application/x-protobuf"], consumes = ["application/x-protobuf"])
20+
fun createBot(@RequestBody param: HttpDto.CreateBotReq): HttpDto.CreateBotResp {
21+
botService.createBot(param.botId, param.password)
22+
return HttpDto.CreateBotResp.newBuilder().build()
5523
}
5624

57-
// 通过轮询获取登陆验证url
58-
@RequestMapping("/getLoginUrl")
59-
fun getLoginUrl(botId: Long): String? {
60-
val loginData = myLoginSolver.getLoginData(botId) ?: return null
61-
return if (loginData.type != LoginDataType.PIC_CAPTCHA) {
62-
loginData.url
63-
} else {
64-
null
65-
}
25+
@RequestMapping("/list/v1", produces = ["application/x-protobuf"], consumes = ["application/x-protobuf"])
26+
fun listBot(@RequestBody param: HttpDto.ListBotReq): HttpDto.ListBotResp {
27+
val botList = botService.listBot()
28+
return HttpDto.ListBotResp.newBuilder().addAllBotList(botList).build()
6629
}
6730

68-
// 通过轮询获取登陆图片验证码
69-
@RequestMapping("/getLoginImage", produces = [MediaType.IMAGE_JPEG_VALUE])
70-
fun getLoginData(botId: Long): ByteArray? {
71-
val loginData = myLoginSolver.getLoginData(botId) ?: return null
72-
return if (loginData.type == LoginDataType.PIC_CAPTCHA) {
73-
loginData.data
74-
} else {
75-
null
31+
@RequestMapping("/login/v1", produces = ["application/x-protobuf"], consumes = ["application/x-protobuf"])
32+
fun botLoginAsync(@RequestBody param: HttpDto.BotLoginAsyncReq): HttpDto.BotLoginAsyncResp {
33+
GlobalScope.launch {
34+
botService.botLogin(param.botId)
7635
}
36+
return HttpDto.BotLoginAsyncResp.newBuilder().build()
7737
}
7838

79-
// 处理登陆
80-
@RequestMapping("/solveLogin")
81-
fun solveLogin(botId: Long, result: String): String {
82-
myLoginSolver.solveLogin(botId, result)
83-
return "ok"
84-
}
8539
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package net.lz1998.mirai.controller
2+
3+
import dto.HttpDto
4+
import net.lz1998.mirai.service.MyLoginSolver
5+
import org.springframework.beans.factory.annotation.Autowired
6+
import org.springframework.web.bind.annotation.RequestBody
7+
import org.springframework.web.bind.annotation.RequestMapping
8+
import org.springframework.web.bind.annotation.RestController
9+
10+
@RestController
11+
@RequestMapping("/captcha")
12+
class CaptchaController {
13+
14+
@Autowired
15+
lateinit var myLoginSolver: MyLoginSolver
16+
17+
@RequestMapping("/list/v1", produces = ["application/x-protobuf"], consumes = ["application/x-protobuf"])
18+
fun getCaptchaList(@RequestBody param: HttpDto.GetCaptchaListReq): HttpDto.GetCaptchaListResp {
19+
val captchaList = myLoginSolver.getCaptchaList()
20+
return HttpDto.GetCaptchaListResp.newBuilder().addAllCaptchaList(captchaList).build()
21+
}
22+
23+
@RequestMapping("/solve/v1", produces = ["application/x-protobuf"], consumes = ["application/x-protobuf"])
24+
fun solveCaptcha(@RequestBody param: HttpDto.SolveCaptchaReq): HttpDto.SolveCaptchaResp {
25+
myLoginSolver.solveLogin(param.botId, param.result)
26+
return HttpDto.SolveCaptchaResp.newBuilder().build()
27+
}
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.lz1998.mirai.controller
2+
3+
import org.springframework.context.annotation.Configuration
4+
import org.springframework.web.servlet.config.annotation.CorsRegistry
5+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
6+
7+
@Configuration
8+
class CorsConf : WebMvcConfigurer {
9+
override fun addCorsMappings(registry: CorsRegistry) {
10+
registry.addMapping("/**")
11+
//是否发送Cookie
12+
.allowCredentials(true)
13+
//放行哪些原始域
14+
.allowedOrigins("*")
15+
.allowedMethods("GET", "POST", "PUT", "DELETE")
16+
// .allowedHeaders("*")
17+
// .exposedHeaders("*")
18+
19+
}
20+
}

src/main/kotlin/net/lz1998/mirai/entity/RemoteBot.kt

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,9 @@ interface RemoteBot {
1414
var botId: Long
1515
var password: String
1616

17-
suspend fun initBot() {
18-
bot = Bot(botId, password) {
19-
fileBasedDeviceInfo("device.json")
20-
loginSolver = myLoginSolver
21-
noNetworkLog()
22-
}.alsoLogin()
23-
bot.subscribeAlways<BotEvent> {
24-
onBotEvent(this)
25-
}
26-
bot.subscribeAlways<MessageEvent> {
27-
val messageSource = this.source // 撤回消息用
28-
bot.messageSourceLru.put(messageSource.id, messageSource)
29-
}
30-
}
17+
fun initBot()
18+
19+
suspend fun login()
3120

3221
// 执行并返回结果
3322
suspend fun onRemoteApi(req: OnebotFrame.Frame): OnebotFrame.Frame

src/main/kotlin/net/lz1998/mirai/entity/WebSocketBotClient.kt

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import kotlinx.coroutines.Dispatchers
44
import kotlinx.coroutines.GlobalScope
55
import kotlinx.coroutines.launch
66
import kotlinx.coroutines.withContext
7+
import net.lz1998.mirai.ext.messageSourceLru
8+
import net.lz1998.mirai.service.myLoginSolver
79
import net.lz1998.mirai.utils.*
810
import net.lz1998.mirai.utils.toFrame
911
import net.mamoe.mirai.Bot
1012
import net.mamoe.mirai.event.events.BotEvent
13+
import net.mamoe.mirai.event.subscribeAlways
14+
import net.mamoe.mirai.message.MessageEvent
1115
import okhttp3.*
1216
import okio.ByteString
1317
import okio.ByteString.Companion.toByteString
@@ -84,9 +88,24 @@ class WebsocketBotClient(override var botId: Long, override var password: String
8488
}
8589

8690

87-
override suspend fun initBot() {
91+
override fun initBot() {
8892
wsClient = httpClient.newWebSocket(wsRequest, wsListener)
89-
super.initBot()
93+
bot = Bot(botId, password) {
94+
fileBasedDeviceInfo("device.json")
95+
loginSolver = myLoginSolver
96+
noNetworkLog()
97+
}
98+
bot.subscribeAlways<BotEvent> {
99+
onBotEvent(this)
100+
}
101+
bot.subscribeAlways<MessageEvent> {
102+
val messageSource = this.source // 撤回消息用
103+
bot.messageSourceLru.put(messageSource.id, messageSource)
104+
}
105+
}
106+
107+
override suspend fun login() {
108+
bot.login()
90109
}
91110

92111
override suspend fun onRemoteApi(req: OnebotFrame.Frame): OnebotFrame.Frame {
@@ -122,7 +141,6 @@ class WebsocketBotClient(override var botId: Long, override var password: String
122141
if (!ok) {
123142
wsConnect()
124143
}
125-
126144
}
127145

128146
}
Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.lz1998.mirai.service
22

3+
import dto.HttpDto
34
import net.lz1998.mirai.entity.RemoteBot
45
import net.lz1998.mirai.entity.WebsocketBotClient
56
import org.springframework.stereotype.Service
@@ -8,10 +9,25 @@ import org.springframework.stereotype.Service
89
class BotService {
910
val botMap = mutableMapOf<Long, RemoteBot>()
1011

11-
suspend fun createBot(botId: Long, password: String) {
12-
val bot = WebsocketBotClient(botId, password, "ws://127.0.0.1:8081/ws/cq/")
13-
bot.initBot()
14-
botMap[botId] = bot
12+
@Synchronized
13+
fun createBot(botId: Long, password: String) {
14+
var bot = botMap[botId]
15+
if (bot == null) {
16+
bot = WebsocketBotClient(botId, password, "ws://127.0.0.1:8081/ws/cq/")
17+
bot.initBot()
18+
botMap[botId] = bot
19+
}
20+
}
21+
22+
fun listBot(): Collection<HttpDto.Bot> {
23+
return botMap.values.map { remoteBot ->
24+
HttpDto.Bot.newBuilder().setBotId(remoteBot.botId).setIsOnline(remoteBot.bot.isOnline).build()
25+
}
26+
}
27+
28+
suspend fun botLogin(botId: Long) {
29+
val bot = botMap[botId]
30+
bot?.bot?.login()
1531
}
1632
}
1733

0 commit comments

Comments
 (0)