From bc9795fb3c07e3cc481dec556d642f8b6bb9fe01 Mon Sep 17 00:00:00 2001 From: iguigui Date: Wed, 25 May 2022 20:52:24 +0800 Subject: [PATCH] =?UTF-8?q?Maa=20HTTP=20server=20DTO=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Java/Maaj/build.gradle.kts | 1 + .../main/java/com/iguigui/maaj/Application.kt | 68 ++++-------- .../main/java/com/iguigui/maaj/dto/request.kt | 102 +++++++++++++++++- .../java/com/iguigui/maaj/dto/response.kt | 74 +++++++++++++ .../com/iguigui/maaj/routing/HttpRouting.kt | 45 ++++++++ .../com/iguigui/maaj/routing/WsRouting.kt | 26 +++++ .../com/iguigui/maaj/service/MaaInstance.kt | 9 +- .../com/iguigui/maaj/service/MaaService.kt | 34 ++++-- 8 files changed, 300 insertions(+), 59 deletions(-) create mode 100644 src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/response.kt create mode 100644 src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/HttpRouting.kt create mode 100644 src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/WsRouting.kt diff --git a/src/Java/Maaj/build.gradle.kts b/src/Java/Maaj/build.gradle.kts index 478983a488..10fa7daedc 100644 --- a/src/Java/Maaj/build.gradle.kts +++ b/src/Java/Maaj/build.gradle.kts @@ -27,6 +27,7 @@ dependencies { implementation("io.ktor:ktor-server-netty-jvm:$ktor_version") implementation("io.ktor:ktor-server-content-negotiation:$ktor_version") implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version") + implementation("io.ktor:ktor-server-cors:$ktor_version") implementation("io.ktor:ktor-server-websockets:$ktor_version") implementation("ch.qos.logback:logback-classic:$logback_version") testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version") diff --git a/src/Java/Maaj/src/main/java/com/iguigui/maaj/Application.kt b/src/Java/Maaj/src/main/java/com/iguigui/maaj/Application.kt index eb631a74c2..73026406be 100644 --- a/src/Java/Maaj/src/main/java/com/iguigui/maaj/Application.kt +++ b/src/Java/Maaj/src/main/java/com/iguigui/maaj/Application.kt @@ -1,64 +1,42 @@ package com.iguigui.maaj -import com.iguigui.maaj.dto.* -import com.iguigui.maaj.service.MaaService +import com.iguigui.maaj.routing.httpRouting +import com.iguigui.maaj.routing.wsRouting +import io.ktor.serialization.kotlinx.json.* import io.ktor.server.netty.* import io.ktor.server.application.* import io.ktor.server.plugins.contentnegotiation.* -import io.ktor.server.request.* -import io.ktor.server.routing.* +import io.ktor.server.plugins.cors.routing.* import io.ktor.server.websocket.* -import io.ktor.websocket.* -import java.time.Duration -import io.ktor.serialization.kotlinx.json.* +import kotlinx.serialization.json.Json fun main(args: Array): Unit = EngineMain.main(args) fun Application.module() { - configureRouting() + configure() + httpRouting() + wsRouting() } -fun Application.configureRouting() { +fun Application.configure(){ install(ContentNegotiation) { - json() + json(Json { + encodeDefaults = true + isLenient = true + allowSpecialFloatingPointValues = true + allowStructuredMapKeys = true + prettyPrint = false + useArrayPolymorphism = false + }) + } + install(CORS) { + allowCredentials = true + anyHost() } install(WebSockets) { - pingPeriod = Duration.ofSeconds(15) - timeout = Duration.ofSeconds(15) + pingPeriod = java.time.Duration.ofSeconds(15) + timeout = java.time.Duration.ofSeconds(15) maxFrameSize = Long.MAX_VALUE masking = false } - routing { - - post("/connect") { - val connect = call.receive() - MaaService.connect(connect.adbPath, connect.host, "") - } - - post("/appendTask") { - val appendTask = call.receive() - MaaService.appendTask(appendTask.host, appendTask.type, appendTask.params.toJsonString()) - } - - post("/start") { - val start = call.receive() - MaaService.start(start.host) - } - - post("/stop") { - val stop = call.receive() - MaaService.stop(stop.host) - } - - - webSocket("/") { - send("You are connected!") - for (frame in incoming) { - frame as? Frame.Text ?: continue - val receivedText = frame.readText() - println("接收到信息 : $receivedText") - send("You said: $receivedText") - } - } - } } diff --git a/src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/request.kt b/src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/request.kt index d7fcb2c8f1..5a2c950e95 100644 --- a/src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/request.kt +++ b/src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/request.kt @@ -8,7 +8,7 @@ import kotlinx.serialization.encodeToString sealed class WsRequest @Serializable -data class Connect( +data class ConnectRequest( @SerialName("adbPath") val adbPath: String, @SerialName("host") @@ -16,7 +16,7 @@ data class Connect( ) @Serializable -data class AppendTask( +data class AppendTaskRequest( @SerialName("host") val host: String, @SerialName("type") @@ -30,11 +30,105 @@ sealed class Task @Serializable data class Fight( + @SerialName("medicine") + val medicine: Int?, + @SerialName("penguin_id") + val penguinId: String?, + @SerialName("report_to_penguin") + val reportToPenguin: Boolean?, + @SerialName("server") + val server: String?, @SerialName("stage") - val stage: String + val stage: String?, + @SerialName("stone") + val stone: Int?, + @SerialName("times") + val times: Int? ) : Task() +@Serializable +data class Recruit( + @SerialName("confirm") + val confirm: List, + @SerialName("expedite") + val expedite: Boolean?, + @SerialName("expedite_times") + val expediteTimes: Int?, + @SerialName("refresh") + val refresh: Boolean?, + @SerialName("select") + val select: List, + @SerialName("set_time") + val setTime: Boolean?, + @SerialName("times") + val times: Int? +) : Task() + + +@Serializable +data class Infrast( + @SerialName("drones") + val drones: String?, + @SerialName("facility") + val facility: List, + @SerialName("mode") + val mode: Int?, + @SerialName("replenish") + val replenish: Boolean?, + @SerialName("threshold") + val threshold: Double? +) : Task() + + +@Serializable +class Visit : Task() + +@Serializable +data class Mall( + @SerialName("blacklist") + val blacklist: List?, + @SerialName("buy_first") + val buyFirst: List?, + @SerialName("shopping") + val shopping: Boolean? +) : Task() + + +@Serializable +class Award : Task() + +@Serializable +data class Roguelike( + @SerialName("mode") + val mode: Int?, + @SerialName("opers") + val opers: List +) : Task() + + +@Serializable +data class Oper( + @SerialName("name") + val name: String, + @SerialName("skill") + val skill: Int?, + @SerialName("skill_usage") + val skillUsage: Int? +) + +@Serializable +data class Copilot( + @SerialName("filename") + val filename: String, + @SerialName("formation") + val formation: Boolean, + @SerialName("stage_name") + val stageName: String? +) + + + @Serializable data class Start( @SerialName("host") @@ -51,7 +145,7 @@ data class Stop( @Serializable data class ConnectWs( @SerialName("data") - val `data`: Connect, + val `data`: ConnectRequest, @SerialName("type") val type: String ) : WsRequest() diff --git a/src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/response.kt b/src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/response.kt new file mode 100644 index 0000000000..cf6b654eda --- /dev/null +++ b/src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/response.kt @@ -0,0 +1,74 @@ +package com.iguigui.maaj.dto + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.encodeToJsonElement +import kotlinx.serialization.json.jsonObject + + +@Serializable +data class HttpResponse( + @SerialName("version") + val data: JsonElement = EmptyBaseData.toJsonElement(), + @SerialName("code") + val code: Int = 0, + @SerialName("message") + val message: String = "success" +) + +@Serializable +data class WsResponse( + @SerialName("version") + val data: JsonElement, + @SerialName("type") + val type: String, + @SerialName("code") + val code: Int, + @SerialName("message") + val message: String +) + +@Serializable +sealed class BaseData + +@Serializable +data class GetVersion( + @SerialName("version") + val version: String +) : BaseData() + +@Serializable +data class ConnectResponse( + @SerialName("version") + val id: String +) : BaseData() + + +@Serializable +data class ListInstance( + @SerialName("version") + val list: List +) : BaseData() + +@Serializable +data class MaaInstanceInfo( + @SerialName("id") + val id: String, + @SerialName("host") + val host: String, + @SerialName("adbPath") + val adbPath: String, + @SerialName("status") + val status: Int, +) : BaseData() + + +object EmptyBaseData : BaseData() + +fun BaseData.toJsonElement() = + Json.encodeToJsonElement(Json.encodeToJsonElement(this).jsonObject.filterNot { it.key == "type" }) + + + diff --git a/src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/HttpRouting.kt b/src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/HttpRouting.kt new file mode 100644 index 0000000000..4f8a328b68 --- /dev/null +++ b/src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/HttpRouting.kt @@ -0,0 +1,45 @@ +package com.iguigui.maaj.routing + +import com.iguigui.maaj.dto.* +import com.iguigui.maaj.service.MaaService +import io.ktor.server.application.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* + + +fun Application.httpRouting() { + + routing { + route("/v1") { + get("/getVersion") { + val version = MaaService.getVersion() + call.respond(HttpResponse(GetVersion(version).toJsonElement())) + } + get("/listInstance") { + val list = MaaService.listInstance() + call.respond(HttpResponse(ListInstance(list).toJsonElement())) + } + post("/connect") { + val connect = call.receive() + val id = MaaService.connect(connect.adbPath, connect.host, "") + call.respond(HttpResponse(ConnectResponse(id).toJsonElement())) + } + post("/appendTask") { + val appendTask = call.receive() + MaaService.appendTask(appendTask.host, appendTask.type, appendTask.params.toJsonString()) + call.respond(HttpResponse()) + } + post("/start") { + val start = call.receive() + MaaService.start(start.host) + call.respond(HttpResponse()) + } + post("/stop") { + val stop = call.receive() + MaaService.stop(stop.host) + call.respond(HttpResponse()) + } + } + } +} diff --git a/src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/WsRouting.kt b/src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/WsRouting.kt new file mode 100644 index 0000000000..c52fb9d4b7 --- /dev/null +++ b/src/Java/Maaj/src/main/java/com/iguigui/maaj/routing/WsRouting.kt @@ -0,0 +1,26 @@ +package com.iguigui.maaj.routing + +import com.iguigui.maaj.dto.* +import io.ktor.serialization.kotlinx.json.* +import io.ktor.server.application.* +import io.ktor.server.plugins.contentnegotiation.* +import io.ktor.server.request.* +import io.ktor.server.routing.* +import io.ktor.server.websocket.* +import io.ktor.websocket.* + + +fun Application.wsRouting() { + + routing { + webSocket("/v1") { + send("You are connected!") + for (frame in incoming) { + frame as? Frame.Text ?: continue + val receivedText = frame.readText() + println("接收到信息 : $receivedText") + send("You said: $receivedText") + } + } + } +} diff --git a/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaInstance.kt b/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaInstance.kt index ee409d7315..2e3160c0b8 100644 --- a/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaInstance.kt +++ b/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaInstance.kt @@ -8,9 +8,10 @@ class MaaInstance(private val instance: MeoAssistant, val id: String, val adbPat constructor( instance: MeoAssistant, - pointer: Pointer, - id: String, adbPath: String, - host: String + id: String, + adbPath: String, + host: String, + pointer: Pointer ) : this( instance, id, @@ -22,6 +23,8 @@ class MaaInstance(private val instance: MeoAssistant, val id: String, val adbPat lateinit var pointer: Pointer + var status = 0 + override fun callback(msg: Int, detail_json: String?, custom_arg: String?) { System.out.printf("回调msg : %s , 回调 detail_json : %s ,回调 custom_arg : %s \n", msg, detail_json, custom_arg) } diff --git a/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaService.kt b/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaService.kt index 38d0b6cdd6..de32f37da6 100644 --- a/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaService.kt +++ b/src/Java/Maaj/src/main/java/com/iguigui/maaj/service/MaaService.kt @@ -1,11 +1,12 @@ package com.iguigui.maaj.service +import com.iguigui.maaj.dto.MaaInstanceInfo import com.iguigui.maaj.easySample.MeoAssistant import com.sun.jna.Native import java.io.File -import java.util.* +import java.security.MessageDigest import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicBoolean + object MaaService { @@ -22,18 +23,18 @@ object MaaService { load } - fun connect(adbPath: String, host: String, detailJson: String): Boolean { + fun connect(adbPath: String, host: String, detailJson: String): String { if (instancePool.containsKey(host)) { - return false + return sha1(host) } val maaInstance = MaaInstance(meoAssistant, host, adbPath, host) maaInstance.pointer = meoAssistant.AsstCreateEx(maaInstance, maaInstance.id) maaInstance.connect() instancePool.putIfAbsent(host, maaInstance) - return true + return sha1(host) } - fun appendTask(host: String,type:String, detailJson: String): Int { + fun appendTask(host: String, type: String, detailJson: String): Int { val appendTask = instancePool[host]?.appendTask(type, detailJson) return appendTask ?: 0 } @@ -42,6 +43,25 @@ object MaaService { fun stop(host: String) = instancePool[host]?.stop() - private fun generatorId() = UUID.randomUUID().toString() + fun getVersion() = "3.9.0" + + private fun sha1(password: String): String { + val messageDigest = MessageDigest.getInstance("SHA") + val digests = messageDigest.digest(password.toByteArray()) + val stringBuilder = StringBuilder() + for (i in digests.indices) { + var halfbyte = digests[i].toInt() ushr 4 and 0x0F + for (j in 0..1) { + stringBuilder.append( + if (0 <= halfbyte && halfbyte <= 9) ('0'.code + halfbyte).toChar() else ('a'.code + (halfbyte - 10)).toChar() + ) + halfbyte = digests[i].toInt() and 0x0F + } + } + return stringBuilder.toString() + } + + fun listInstance(): List = + instancePool.values.map { e -> MaaInstanceInfo(e.id, e.host, e.id, e.status) }.toList() }