Commit a831dd6b authored by Him188's avatar Him188

Merge remote-tracking branch 'origin/master'

parents 1a4ad94d ff74ee3c
...@@ -18,10 +18,48 @@ import io.ktor.util.pipeline.PipelineContext ...@@ -18,10 +18,48 @@ import io.ktor.util.pipeline.PipelineContext
import io.ktor.util.pipeline.PipelineInterceptor import io.ktor.util.pipeline.PipelineInterceptor
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.sendMessage 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.hexToBytes
import net.mamoe.mirai.utils.io.hexToUBytes import net.mamoe.mirai.utils.io.hexToUBytes
fun main() { fun main(args: Array<String>) {
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() } Application(applicationEngineEnvironment {}).apply { mirai() }
} }
......
package net.mamoe.mirai.api.http package net.mamoe.mirai.api.http
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.*
import kotlinx.coroutines.SupervisorJob import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import java.lang.StringBuilder
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
tailrec fun generateSessionKey(): String { tailrec fun generateSessionKey():String{
fun generateRandomSessionKey(): String { fun generateRandomSessionKey(): String {
val all = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm" val all = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm"
return buildString(capacity = 8) { return buildString(capacity = 8) {
...@@ -16,7 +18,7 @@ tailrec fun generateSessionKey(): String { ...@@ -16,7 +18,7 @@ tailrec fun generateSessionKey(): String {
} }
val key = generateRandomSessionKey() val key = generateRandomSessionKey()
if (!SessionManager.allSession.containsKey(key)) { if(!SessionManager.allSession.containsKey(key)){
return key return key
} }
...@@ -25,36 +27,55 @@ tailrec fun generateSessionKey(): String { ...@@ -25,36 +27,55 @@ tailrec fun generateSessionKey(): String {
object SessionManager { object SessionManager {
val allSession: MutableMap<String, Session> = mutableMapOf() val allSession:MutableMap<String,Session> = mutableMapOf()
fun createTempSession(): TempSession = TempSession(EmptyCoroutineContext).also { allSession[it.key] = it } lateinit var authKey:String
fun closeSession(sessionKey: String) = allSession.remove(sessionKey)?.also { it.close() }
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) fun closeSession(session: Session) = closeSession(session.key)
} }
/** /**
* @author NaturalHG * @author NaturalHG
* 这个用于管理不同Client与Mirai HTTP的会话 * 这个用于管理不同Client与Mirai HTTP的会话
*
* [Session]均为内部操作用类
* 需使用[SessionManager]
*/ */
abstract class Session internal constructor( abstract class Session internal constructor(
coroutineContext: CoroutineContext coroutineContext: CoroutineContext
) : CoroutineScope { ): CoroutineScope {
private val supervisorJob = SupervisorJob() val supervisorJob = SupervisorJob(coroutineContext[Job])
final override val coroutineContext: CoroutineContext = supervisorJob + coroutineContext final override val coroutineContext: CoroutineContext = supervisorJob + coroutineContext
val key: String = generateSessionKey() val key:String = generateSessionKey()
internal fun close() { internal fun close(){
supervisorJob.cancel() supervisorJob.complete()
} }
} }
/** /**
* 任何新链接建立后分配一个[TempSession] * 任何新链接建立后分配一个[TempSession]
* *
...@@ -68,7 +89,7 @@ class TempSession internal constructor(coroutineContext: CoroutineContext) : Ses ...@@ -68,7 +89,7 @@ class TempSession internal constructor(coroutineContext: CoroutineContext) : Ses
* 任何[TempSession]认证后转化为一个[AuthedSession] * 任何[TempSession]认证后转化为一个[AuthedSession]
* 在这一步[AuthedSession]应该已经有assigned的bot * 在这一步[AuthedSession]应该已经有assigned的bot
*/ */
class AuthedSession internal constructor(botNumber: Int, coroutineContext: CoroutineContext) : Session(coroutineContext) { class AuthedSession internal constructor(val botNumber:Int, coroutineContext: CoroutineContext):Session(coroutineContext){
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment