From 0abb317c975e58d46ba27b6cda4b4f22ea32efe5 Mon Sep 17 00:00:00 2001 From: "jiahua.liu" Date: Sat, 18 Jan 2020 00:38:45 +0800 Subject: [PATCH] HTTP API --- .../MiraiHttpApplication.kt | 40 ++++++++++++++++++- .../net.mamoe.mirai.api.http/Session.kt | 38 +++++++++++++----- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/MiraiHttpApplication.kt b/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/MiraiHttpApplication.kt index 0f01dbac1..088725e25 100644 --- a/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/MiraiHttpApplication.kt +++ b/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/MiraiHttpApplication.kt @@ -18,10 +18,48 @@ import io.ktor.util.pipeline.PipelineContext import io.ktor.util.pipeline.PipelineInterceptor import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.sendMessage +import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.hexToUBytes -fun main() { +fun main(args: Array) { + val logger = DefaultLogger("Mirai HTTP API") + //write default first + SessionManager.authKey = generateSessionKey()//用于验证的key, 使用和SessionKey相同的方法生成, 但意义不同 + var port = 8080//start port + + args.forEach { + if(it.contains("=")) { + when { + it.toLowerCase().contains("authkey") -> { + SessionManager.authKey = it.split("=")[1].trim() + if(it.length !in 8..128){ + logger.error("Expected authKey length is between 8 to 128") + SessionManager.authKey = generateSessionKey() + } + logger.info("Session Auth Key now is ${SessionManager.authKey}") + } + it.toLowerCase().contains("port") -> { + try { + port = it.split("=")[1].trim().toInt() + }catch (e:Exception){ + logger.error("Expected -port=xxxxx, xxxxx to be numbers") + } + if(port !in 1025..65535){ + logger.error("Expected -port=xxxxx, xxxxx > 1024 && <65536") + port = 8080 + } + logger.info("HTTP API Listening port now is $port") + } + } + } + if(it.contains("help")){ + logger.info("-authkey=XXXXXXXX to use custom Session Auth Key, note that key is case sensitive") + logger.info("-port=XXXXX to use custom listener port, default using 8080") + } + } + + Application(applicationEngineEnvironment {}).apply { mirai() } } diff --git a/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/Session.kt b/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/Session.kt index 0a1eddf09..1a03a01d1 100644 --- a/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/Session.kt +++ b/mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http/Session.kt @@ -1,8 +1,8 @@ package net.mamoe.mirai.api.http -import kotlinx.coroutines.CompletableJob -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.* +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonConfiguration import java.lang.StringBuilder import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext @@ -29,11 +29,25 @@ object SessionManager { val allSession:MutableMap = mutableMapOf() - fun createTempSession():TempSession = TempSession(EmptyCoroutineContext).also { allSession[it.key] = it } + lateinit var authKey:String + + + fun createTempSession():TempSession = TempSession(EmptyCoroutineContext).also {newTempSession -> + allSession[newTempSession.key] = newTempSession + //设置180000ms后检测并回收 + newTempSession.launch{ + delay(180000) + allSession[newTempSession.key]?.run { + if(this is TempSession) + closeSession(newTempSession.key) + } + } + } fun closeSession(sessionKey: String) = allSession.remove(sessionKey)?.also {it.close() } fun closeSession(session: Session) = closeSession(session.key) + } @@ -42,18 +56,22 @@ object SessionManager { /** * @author NaturalHG * 这个用于管理不同Client与Mirai HTTP的会话 + * + * [Session]均为内部操作用类 + * 需使用[SessionManager] */ abstract class Session internal constructor( - + coroutineContext: CoroutineContext ): CoroutineScope { - private val sessionJob = SupervisorJob() + val supervisorJob = SupervisorJob(coroutineContext[Job]) + final override val coroutineContext: CoroutineContext = supervisorJob + coroutineContext + val key:String = generateSessionKey() internal fun close(){ - sessionJob.cancel() + supervisorJob.complete() } - } @@ -63,7 +81,7 @@ abstract class Session internal constructor( * * TempSession在建立180s内没有转变为[AuthedSession]应被清除 */ -class TempSession internal constructor(override val coroutineContext: CoroutineContext) : Session() { +class TempSession internal constructor(coroutineContext: CoroutineContext) : Session(coroutineContext) { } @@ -71,7 +89,7 @@ class TempSession internal constructor(override val coroutineContext: CoroutineC * 任何[TempSession]认证后转化为一个[AuthedSession] * 在这一步[AuthedSession]应该已经有assigned的bot */ -class AuthedSession internal constructor(botNumber:Int, override val coroutineContext: CoroutineContext):Session(){ +class AuthedSession internal constructor(val botNumber:Int, coroutineContext: CoroutineContext):Session(coroutineContext){ }