mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-18 02:10:21 +08:00
Merge pull request #661 from BTreeNewBee/maaHTTP
feta.Maa-HTTP+Websocket接口实现
This commit is contained in:
18
src/Java/Maaj/Maa-HTTP-Server-startup.bat
Normal file
18
src/Java/Maaj/Maa-HTTP-Server-startup.bat
Normal file
@@ -0,0 +1,18 @@
|
||||
@echo off
|
||||
cd /d %~dp0
|
||||
set javaPath=%cd%
|
||||
cd ..
|
||||
::显示上级目录路径
|
||||
|
||||
::设置要临时加入到path环境变量中的路径
|
||||
set My_PATH=%cd%
|
||||
|
||||
set PATH=%PATH%;%My_PATH%
|
||||
|
||||
cd javaPath
|
||||
|
||||
::下面写你其它脚本命令
|
||||
|
||||
java -jar .\Maa-HTTP-0.0.1.jar -port=8848
|
||||
|
||||
pause
|
||||
562
src/Java/Maaj/Readme.md
Normal file
562
src/Java/Maaj/Readme.md
Normal file
@@ -0,0 +1,562 @@
|
||||
# Maa-HTTP接口实现
|
||||
|
||||
本项目为通过JNA(Java-Native-Access)调用Maa核心实现的HTTP+WebSocket接口实现.
|
||||
|
||||
## 接口实现情况
|
||||
|
||||
| 功能名称 | 接口路径(命令) | HTTP实现 | WebSocket实现 |
|
||||
|:-------|:--------------|:-------|:------------|
|
||||
| 获取版本号 | getVersion | Yes | Yes |
|
||||
| 创建连接 | connect | Yes | Yes |
|
||||
| 添加任务 | appendTask | Yes | Yes |
|
||||
| 设定任务参数 | setTaskParams | Yes | Yes |
|
||||
| 开始执行 | start | Yes | Yes |
|
||||
| 停止执行 | stop | Yes | Yes |
|
||||
| 销毁实例 | destroy | Yes | Yes |
|
||||
| 列出实例连接 | listInstance | Yes | Yes |
|
||||
| 消息回调通知 | callBack | No | Yes |
|
||||
|
||||
## 环境依赖
|
||||
|
||||
1. JDK1.8 +
|
||||
2. Maa v3.9.0-alpha +
|
||||
|
||||
## 如何编译
|
||||
|
||||
.\gradlew.bat jar
|
||||
|
||||
## 使用方法
|
||||
|
||||
1. 把他丢进Maa文件夹下,形成如下文件结构.
|
||||
|
||||
```
|
||||
MeoAssistantArknights_v3.9.0-beta.8
|
||||
│ MeoAsstGui.exe
|
||||
│ MeoAssistant.dll
|
||||
│ ...
|
||||
└───Java-HTTP
|
||||
│ Maa-HTTP-0.0.1.jar
|
||||
│ Maa-HTTP-Server-startup.bat
|
||||
```
|
||||
|
||||
2. 双击Maa-HTTP-Server-startup.bat启动.
|
||||
3. 默认端口号8848钛金端口,如需修改,请修改 Maa-HTTP-Server-startup.bat 中的-port=8848 .
|
||||
4. 当你看到如下内容则启动成功.
|
||||
|
||||
```
|
||||
2022-05-31 22:20:03.000 [main] INFO Application - Autoreload is disabled because the development mode is off.
|
||||
2022-05-31 22:20:03.407 [main] INFO Application - Application started in 0.458 seconds.
|
||||
2022-05-31 22:20:03.407 [main] INFO Application - Application started: io.ktor.server.application.Application@fac80
|
||||
2022-05-31 22:20:03.717 [DefaultDispatcher-worker-1] INFO Application - Responding at http://0.0.0.0:8848
|
||||
```
|
||||
|
||||
## 接口文档
|
||||
|
||||
### HTTP部分
|
||||
|
||||
提供了如下功能
|
||||
|
||||
| 功能名称 | 接口路径 |
|
||||
|:-------|:--------------|
|
||||
| 获取版本号 | getVersion |
|
||||
| 创建连接 | connect |
|
||||
| 添加任务 | appendTask |
|
||||
| 设定任务参数 | setTaskParams |
|
||||
| 开始执行 | start |
|
||||
| 停止执行 | stop |
|
||||
| 销毁实例 | destroy |
|
||||
| 列出连接 | listInstance |
|
||||
|
||||
---
|
||||
|
||||
#### 接口名称 获取版本号
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/getVersion
|
||||
|
||||
###### 2) 调用方式:HTTP get
|
||||
|
||||
###### 3) 请求参数: 无
|
||||
|
||||
###### 4) 返回结果示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"version": "v3.9.0-beta"
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 创建连接
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/connect
|
||||
|
||||
###### 2) 调用方式:HTTP post
|
||||
|
||||
###### 3) 请求参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"adbPath": "C:\\MeoAssistantArknights3\\platform-tools\\adb.exe",
|
||||
"host": "127.0.0.1:62001",
|
||||
"detailJson": ""
|
||||
}
|
||||
```
|
||||
|
||||
###### Post参数:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |-----------------|--------|-----|-----|
|
||||
| adbPath | ADB地址 | String | Y | - |
|
||||
| host | 实例地址 | String | Y | - |
|
||||
| detailJson | 有什么用我也不知道,反正就是有 | String | N | - |
|
||||
|
||||
###### 4) 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "46b9d5cd60382f100b336b17d6817f8eda255f73",
|
||||
"result": true
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
###### 5) 请求返回结果参数说明:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-------------|---------|---- |
|
||||
| id | 给连接实例创建的ID | String | - |
|
||||
| result | 是否成功 | Boolean | - |
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 c
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/appendTask
|
||||
|
||||
###### 2) 调用方式:HTTP post
|
||||
|
||||
###### 3) 请求参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "46b9d5cd60382f100b336b17d6817f8eda255f73",
|
||||
"type": "Fight",
|
||||
"params": {
|
||||
"stage": "LastBattle"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
###### Post参数:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |-------------------------------------------------------------------------------------------------------------------------------|--------|---- |-----|
|
||||
| id | 创建连接返回的实例ID | String | Y | - |
|
||||
| type | 任务类型,此次示例为刷理智战斗,详情参考[集成文档](https://raw.githubusercontent.com/MaaAssistantArknights/MaaAssistantArknights/master/docs/集成文档.md) | String | Y | - |
|
||||
| params | 任务参数 | Json | Y | - |
|
||||
|
||||
###### 4) 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "46b9d5cd60382f100b336b17d6817f8eda255f73",
|
||||
"taskId": 0
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
###### 5) 请求返回结果参数说明:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|------------|--------|---- |
|
||||
| id | 实例ID | String | - |
|
||||
| taskId | 任务ID,为0则失败 | Int | - |
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 设定任务参数
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/setTaskParams
|
||||
|
||||
###### 2) 调用方式:HTTP post
|
||||
|
||||
###### 3) 请求参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "46b9d5cd60382f100b336b17d6817f8eda255f73",
|
||||
"type": "Fight",
|
||||
"taskId": 0,
|
||||
"params": {
|
||||
"stage": "LastBattle"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
###### Post参数:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |-------------------------------------------------------------------------------------------------------------------------------|--------|---- |-----|
|
||||
| id | 创建连接返回的实例ID | String | Y | - |
|
||||
| taskId | 任务ID | Int | Y | - |
|
||||
| type | 任务类型,此次示例为刷理智战斗,详情参考[集成文档](https://raw.githubusercontent.com/MaaAssistantArknights/MaaAssistantArknights/master/docs/集成文档.md) | String | Y | - |
|
||||
| params | 任务参数 | Json | Y | - |
|
||||
|
||||
###### 4) 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "46b9d5cd60382f100b336b17d6817f8eda255f73",
|
||||
"result": false
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
###### 5) 请求返回结果参数说明:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-------------|---------|---- |
|
||||
| id | 给连接实例创建的ID | String | - |
|
||||
| result | 是否成功 | Boolean | - |
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 开始执行
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/start
|
||||
|
||||
###### 2) 调用方式:HTTP post
|
||||
|
||||
###### 3) 请求参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "ccd76e0c367511158ca774ff951a22e8bb62f5d3"
|
||||
}
|
||||
```
|
||||
|
||||
###### Post参数:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |--------|--------|---- |-----|
|
||||
| id | 创建连接返回的实例ID | String | Y | - |
|
||||
|
||||
###### 4) 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "ccd76e0c367511158ca774ff951a22e8bb62f5d3",
|
||||
"result": true
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
###### 5) 请求返回结果参数说明:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-------------|---------|---- |
|
||||
| id | 给连接实例创建的ID | String | - |
|
||||
| result | 是否成功 | Boolean | - |
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 停止执行,清空任务链
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/stop
|
||||
|
||||
###### 2) 调用方式:HTTP post
|
||||
|
||||
###### 3) 请求参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "ccd76e0c367511158ca774ff951a22e8bb62f5d3"
|
||||
}
|
||||
```
|
||||
|
||||
###### Post参数:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |--------|--------|---- |-----|
|
||||
| id | 创建连接返回的实例ID | String | Y | - |
|
||||
|
||||
###### 4) 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "ccd76e0c367511158ca774ff951a22e8bb62f5d3",
|
||||
"result": true
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
###### 5) 请求返回结果参数说明:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-------------|---------|---- |
|
||||
| id | 给连接实例创建的ID | String | - |
|
||||
| result | 是否成功 | Boolean | - |
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 销毁实例
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/destroy
|
||||
|
||||
###### 2) 调用方式:HTTP post
|
||||
|
||||
###### 3) 请求参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "ccd76e0c367511158ca774ff951a22e8bb62f5d3"
|
||||
}
|
||||
```
|
||||
|
||||
###### Post参数:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |--------|--------|---- |-----|
|
||||
| id | 创建连接返回的实例ID | String | Y | - |
|
||||
|
||||
###### 4) 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "ccd76e0c367511158ca774ff951a22e8bb62f5d3",
|
||||
"result": true
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
###### 5) 请求返回结果参数说明:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-------------|---------|---- |
|
||||
| id | 给连接实例创建的ID | String | - |
|
||||
| result | 是否成功 | Boolean | - |
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 列出实例连接
|
||||
|
||||
###### 1) 请求地址
|
||||
|
||||
> http://127.0.0.1:8848/API/V1/listInstance
|
||||
|
||||
###### 2) 调用方式:HTTP get
|
||||
|
||||
###### 3) 请求参数: 无
|
||||
|
||||
###### 4) 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"list": [
|
||||
{
|
||||
"id": "ccd76e0c367511158ca774ff951a22e8bb62f5d3",
|
||||
"host": "127.0.0.1:62026",
|
||||
"adbPath": "C:\\Users\\atmzx\\Desktop\\MeoAssistantArknights3\\platform-tools\\adb.exe",
|
||||
"uuid": "",
|
||||
"status": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
###### 5) 请求返回结果参数说明:
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-------------|--------|---- |
|
||||
| id | 实例ID | String | - |
|
||||
| host | 连接的Host | String | - |
|
||||
| adbPath | 使用的Adb地址 | String | - |
|
||||
| uuid | 设备备ID,保留 | String | - |
|
||||
| status | 0待机中,1任务执行中 | Int | - |
|
||||
|
||||
### WebSocket部分
|
||||
|
||||
请求地址(没错跟HTTP同样是8848钛金端口
|
||||
|
||||
> ws://127.0.0.1:8848/API/V1
|
||||
|
||||
提供了如下功能
|
||||
|
||||
| 功能名称 | 命令 |
|
||||
|:-------|:--------------|
|
||||
| 获取版本号 | getVersion |
|
||||
| 创建连接 | connect |
|
||||
| 添加任务 | appendTask |
|
||||
| 设定任务参数 | setTaskParams |
|
||||
| 开始执行 | start |
|
||||
| 停止执行 | stop |
|
||||
| 销毁实例 | destroy |
|
||||
| 列出实例连接 | listInstance |
|
||||
| 消息回调通知 | callBack |
|
||||
|
||||
所有的的WebSocket接口跟HTTP接口请求响应参数均完全一致
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 获取版本号
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "getVersion",
|
||||
"msgId": 114514,
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |-----------------------------------|--------|---- |-----|
|
||||
| command | 操作命令 | String |,Y | - |
|
||||
| msgId | 消息ID,服务端收到此次请求,会用同一个ID答复,便于请求响应关联 | Int | Y | - |
|
||||
| data | 请求参数,请参考同名接口的HTTP接口文档,与HTTP接口完全一致 | Json | Y | - |
|
||||
|
||||
###### 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"version": "v3.9.0-beta"
|
||||
},
|
||||
"command": "getVersion",
|
||||
"msgId": 114514,
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-----------------------------------|--------|---- |
|
||||
| command | 操作命令,与请求一致 | String | - |
|
||||
| msgId | 消息ID,此次请求的消息ID为114514则响应也是114514 | Int | - |
|
||||
| data | 响应内容,请参考同名接口的HTTP接口文档,与HTTP接口完全一致 | Json | - |
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 创建连接
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "connect",
|
||||
"msgId": 114514,
|
||||
"data": {
|
||||
"adbPath": "C:\\Users\\atmzx\\Desktop\\MeoAssistantArknights3\\platform-tools\\adb.exe",
|
||||
"host": "127.0.0.1:62001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 必填 | 备注 |
|
||||
| ---- |---------------------------------|--------|---- |-----|
|
||||
| command | 操作命令 | String |,Y | - |
|
||||
| msgId | 消息ID,服务端收到此次请求,会用同一个ID答复,便于请求响应关联 | Int | Y | - |
|
||||
| data | 请求参数,请参考同名接口的HTTP文档,与HTTP接口完全一致 | Json | Y | - |
|
||||
|
||||
###### 请求返回结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "46b9d5cd60382f100b336b17d6817f8eda255f73",
|
||||
"result": true
|
||||
},
|
||||
"command": "connect",
|
||||
"msgId": 114514,
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-----------------------------------|--------|---- |
|
||||
| command | 操作命令,与请求一致 | String | - |
|
||||
| msgId | 消息ID,此次请求的消息ID为114514则响应也是114514 | Int | - |
|
||||
| data | 响应内容,请参考同名接口的HTTP接口文档,与HTTP接口完全一致 | Json | - |
|
||||
|
||||
appendTask setTaskParams start stop等接口不再描述,均可遵循以上规则,参考HTTP接口文档实现。
|
||||
|
||||
|
||||
---
|
||||
|
||||
##### 接口名称 回调消息
|
||||
|
||||
###### 返回结果示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "46b9d5cd60382f100b336b17d6817f8eda255f73",
|
||||
"logId": 1,
|
||||
"msg": 2,
|
||||
"details": {
|
||||
"uuid": "",
|
||||
"details": {
|
||||
"adb": "C:\\MeoAssistantArknights3\\platform-tools\\adb.exe",
|
||||
"address": "127.0.0.1:62001",
|
||||
"config": "General",
|
||||
"width": 1280,
|
||||
"height": 720
|
||||
},
|
||||
"what": "ResolutionGetted",
|
||||
"why": ""
|
||||
}
|
||||
},
|
||||
"command": "callBack",
|
||||
"msgId": 0,
|
||||
"code": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段名称 | 字段说明 | 类型 | 备注 |
|
||||
|------|-----------------------------------|--------|---- |
|
||||
| command | 操作命令,callBack类型 | String | - |
|
||||
| msgId | 消息ID,callBack 一律为0 | Int | - |
|
||||
| data | 响应内容,详情参考[集成文档](https://raw.githubusercontent.com/MaaAssistantArknights/MaaAssistantArknights/master/docs/集成文档.md) | Json | - |
|
||||
@@ -1,18 +1,103 @@
|
||||
val ktor_version = "2.0.2"
|
||||
val kotlin_version = "1.6.10"
|
||||
val logback_version = "1.2.11"
|
||||
val appName = "Maa-HTTP"
|
||||
|
||||
plugins {
|
||||
id("java")
|
||||
application
|
||||
kotlin("jvm") version "1.6.10"
|
||||
kotlin("plugin.serialization") version "1.6.10"
|
||||
id("edu.sc.seis.launch4j") version "2.5.3"
|
||||
}
|
||||
|
||||
version = "1.0-SNAPSHOT"
|
||||
group = "com.iguigui"
|
||||
version = "0.0.1"
|
||||
application {
|
||||
mainClass.set("com.iguigui.maaj.ApplicationKt")
|
||||
val isDevelopment: Boolean = project.ext.has("development")
|
||||
applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//JNA
|
||||
implementation("net.java.dev.jna:jna:5.11.0")
|
||||
implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
|
||||
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")
|
||||
implementation("io.ktor:ktor-server-call-logging:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-double-receive:$ktor_version")
|
||||
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3")
|
||||
}
|
||||
|
||||
tasks.getByName<Test>("test") {
|
||||
useJUnitPlatform()
|
||||
|
||||
|
||||
tasks.jar {
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
|
||||
manifest {
|
||||
attributes(
|
||||
mapOf(
|
||||
"Main-Class" to "com.iguigui.maaj.ApplicationKt",
|
||||
"Implementation-Title" to "Maa-HTTP",
|
||||
"Manifest-Version" to "1.0.0"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from(configurations.runtimeClasspath.get().map {
|
||||
if (it.isDirectory) it else zipTree(it)
|
||||
})
|
||||
val sourcesMain = sourceSets.main.get()
|
||||
sourcesMain.allSource.forEach { println("add from sources: ${it.name}") }
|
||||
from(sourcesMain.output)
|
||||
}
|
||||
|
||||
launch4j {
|
||||
mainClassName = "com.iguigui.maaj.ApplicationKt"
|
||||
icon = "${projectDir}/icons/myApp.ico"
|
||||
}
|
||||
|
||||
tasks.withType<edu.sc.seis.launch4j.tasks.DefaultLaunch4jTask> {
|
||||
outfile = "${appName}.exe"
|
||||
mainClassName = "com.iguigui.maaj.ApplicationKt"
|
||||
icon = "$projectDir/icon.ico"
|
||||
productName = "${appName}"
|
||||
}
|
||||
|
||||
tasks.register<edu.sc.seis.launch4j.tasks.Launch4jLibraryTask>("createFastStart") {
|
||||
outfile = "${appName}.exe"
|
||||
mainClassName = "com.iguigui.maaj.ApplicationKt"
|
||||
icon = "$projectDir/icon.ico"
|
||||
fileDescription = "The lightning fast implementation"
|
||||
}
|
||||
tasks.register<edu.sc.seis.launch4j.tasks.Launch4jLibraryTask>("MyApp-memory") {
|
||||
fileDescription = "The default implementation with increased heap size"
|
||||
maxHeapPercent = 50
|
||||
}
|
||||
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
val compileKotlin: org.jetbrains.kotlin.gradle.tasks.KotlinCompile by tasks
|
||||
compileKotlin.kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
|
||||
val compileTestKotlin: org.jetbrains.kotlin.gradle.tasks.KotlinCompile by tasks
|
||||
compileTestKotlin.kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
257
src/Java/Maaj/gradlew
vendored
257
src/Java/Maaj/gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -17,101 +17,67 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MSYS* | MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
@@ -121,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -132,7 +98,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@@ -140,95 +106,80 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
@@ -1,2 +1,16 @@
|
||||
rootProject.name = "Maaj"
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven { url = uri("https://repo.spring.io/milestone") }
|
||||
maven { url = uri("https://repo.spring.io/snapshot") }
|
||||
gradlePluginPortal()
|
||||
}
|
||||
resolutionStrategy {
|
||||
eachPlugin {
|
||||
if (requested.id.id == "org.springframework.boot") {
|
||||
useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rootProject.name = "Maa-HTTP"
|
||||
|
||||
|
||||
80
src/Java/Maaj/src/main/java/com/iguigui/maaj/Application.kt
Normal file
80
src/Java/Maaj/src/main/java/com/iguigui/maaj/Application.kt
Normal file
@@ -0,0 +1,80 @@
|
||||
package com.iguigui.maaj
|
||||
|
||||
import com.iguigui.maaj.routing.httpRouting
|
||||
import com.iguigui.maaj.routing.wsRouting
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import io.ktor.server.netty.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.plugins.callloging.*
|
||||
import io.ktor.server.plugins.contentnegotiation.*
|
||||
import io.ktor.server.plugins.cors.routing.*
|
||||
import io.ktor.server.plugins.doublereceive.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.websocket.*
|
||||
import io.ktor.util.logging.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import org.slf4j.event.Level
|
||||
|
||||
|
||||
fun main(args: Array<String>): Unit = EngineMain.main(args)
|
||||
|
||||
fun Application.module() {
|
||||
configure()
|
||||
httpRouting()
|
||||
wsRouting()
|
||||
}
|
||||
|
||||
|
||||
lateinit var logger : Logger
|
||||
|
||||
fun Application.configure() {
|
||||
logger = log
|
||||
//Input and output serialize
|
||||
install(ContentNegotiation) {
|
||||
json(Json {
|
||||
encodeDefaults = true
|
||||
isLenient = true
|
||||
allowSpecialFloatingPointValues = true
|
||||
allowStructuredMapKeys = true
|
||||
prettyPrint = false
|
||||
useArrayPolymorphism = false
|
||||
})
|
||||
}
|
||||
install(CORS) {
|
||||
allowCredentials = true
|
||||
anyHost()
|
||||
}
|
||||
install(WebSockets) {
|
||||
pingPeriod = java.time.Duration.ofSeconds(15)
|
||||
timeout = java.time.Duration.ofSeconds(15)
|
||||
maxFrameSize = Long.MAX_VALUE
|
||||
masking = false
|
||||
}
|
||||
//Provides the ability to receive a request body several times.
|
||||
install(DoubleReceive) {
|
||||
}
|
||||
//Logging request body.
|
||||
install(CallLogging) {
|
||||
level = Level.INFO
|
||||
format { call ->
|
||||
val status = call.response.status()
|
||||
val httpMethod = call.request.httpMethod
|
||||
val queryParameters = call.request.rawQueryParameters
|
||||
when (httpMethod) {
|
||||
HttpMethod.Get -> "Status: $status, HTTP method: $httpMethod, Uri: ${call.request.uri}, QueryParameters: $queryParameters "
|
||||
HttpMethod.Post -> runBlocking {
|
||||
"Status: $status, HTTP method: $httpMethod, Uri: ${call.request.uri} ,Body: ${
|
||||
call.receive<JsonElement>().toString()
|
||||
} "
|
||||
}
|
||||
else -> {
|
||||
"Status: $status, HTTP method: $httpMethod, Uri: ${call.request.uri}, QueryParameters: $queryParameters "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
19
src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/msgEnum.kt
Normal file
19
src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/msgEnum.kt
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.iguigui.maaj.dto
|
||||
|
||||
/* Global Info */
|
||||
val INTERNAL_ERROR = 0 // 内部错误
|
||||
val INIT_FAILED = 1 // 初始化失败
|
||||
val CONNECTION_INFO = 2 // 连接相关信息
|
||||
val ALL_TASKS_COMPLETED = 3 // 全部任务完成
|
||||
|
||||
/* TaskChain Info */
|
||||
val TASK_CHAIN_ERROR = 10000 // 任务链执行/识别错误
|
||||
val TASK_CHAIN_START = 10001 // 任务链开始
|
||||
val TASK_CHAIN_COMPLETED = 10002 // 任务链完成
|
||||
val TASK_CHAIN_EXTRA_INFO = 10003 // 任务链额外信息
|
||||
|
||||
/* SubTask Info */
|
||||
val SUB_TASK_ERROR = 20000 // 原子任务执行/识别错误
|
||||
val SUB_TASK_START = 20001 // 原子任务开始
|
||||
val SUB_TASK_COMPLETED = 20002 // 原子任务完成
|
||||
val SUB_TASK_EXTRA_INFO = 20003 // 原子任务额外信息
|
||||
179
src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/request.kt
Normal file
179
src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/request.kt
Normal file
@@ -0,0 +1,179 @@
|
||||
package com.iguigui.maaj.dto
|
||||
|
||||
import com.iguigui.maaj.util.Json
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
|
||||
|
||||
@Serializable
|
||||
data class ConnectRequest(
|
||||
@SerialName("adbPath")
|
||||
val adbPath: String,
|
||||
@SerialName("host")
|
||||
val host: String,
|
||||
@SerialName("detailJson")
|
||||
val detailJson: String = ""
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class AppendTaskRequest(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("type")
|
||||
val type: String,
|
||||
@SerialName("params")
|
||||
val params: JsonElement
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SetTaskParamsRequest(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("type")
|
||||
val type: String,
|
||||
@SerialName("taskId")
|
||||
val taskId: Int,
|
||||
@SerialName("params")
|
||||
val params: JsonElement
|
||||
)
|
||||
|
||||
@Serializable
|
||||
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?,
|
||||
@SerialName("stone")
|
||||
val stone: Int?,
|
||||
@SerialName("times")
|
||||
val times: Int?
|
||||
) : Task()
|
||||
|
||||
|
||||
@Serializable
|
||||
data class Recruit(
|
||||
@SerialName("confirm")
|
||||
val confirm: List<Int>,
|
||||
@SerialName("expedite")
|
||||
val expedite: Boolean?,
|
||||
@SerialName("expedite_times")
|
||||
val expediteTimes: Int?,
|
||||
@SerialName("refresh")
|
||||
val refresh: Boolean?,
|
||||
@SerialName("select")
|
||||
val select: List<Int>,
|
||||
@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<String>,
|
||||
@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<String>?,
|
||||
@SerialName("buy_first")
|
||||
val buyFirst: List<String>?,
|
||||
@SerialName("shopping")
|
||||
val shopping: Boolean?
|
||||
) : Task()
|
||||
|
||||
|
||||
@Serializable
|
||||
class Award : Task()
|
||||
|
||||
@Serializable
|
||||
data class Roguelike(
|
||||
@SerialName("mode")
|
||||
val mode: Int?,
|
||||
@SerialName("opers")
|
||||
val opers: List<Oper>
|
||||
) : 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 StartRequest(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class StopRequest(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class DestroyRequest(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
)
|
||||
|
||||
@SerialName("connect")
|
||||
@Serializable
|
||||
data class WsRequest(
|
||||
@SerialName("data")
|
||||
val `data`: JsonElement,
|
||||
@SerialName("command")
|
||||
val command: String,
|
||||
@SerialName("msgId")
|
||||
val msgId: Int = 0
|
||||
)
|
||||
|
||||
|
||||
fun Task.toJsonString() = Json.encodeToString(this)
|
||||
|
||||
|
||||
|
||||
141
src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/response.kt
Normal file
141
src/Java/Maaj/src/main/java/com/iguigui/maaj/dto/response.kt
Normal file
@@ -0,0 +1,141 @@
|
||||
package com.iguigui.maaj.dto
|
||||
|
||||
import com.iguigui.maaj.util.Json
|
||||
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("data")
|
||||
val data: JsonElement = EmptyBaseData.toJsonElement(),
|
||||
@SerialName("code")
|
||||
val code: Int = 0,
|
||||
@SerialName("message")
|
||||
val message: String = "success"
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class WsResponse(
|
||||
@SerialName("data")
|
||||
val data: JsonElement,
|
||||
@SerialName("command")
|
||||
val command: String,
|
||||
@SerialName("msgId")
|
||||
val msgId: Int = 0,
|
||||
@SerialName("code")
|
||||
val code: Int = 0,
|
||||
@SerialName("message")
|
||||
val message: String = "success"
|
||||
)
|
||||
|
||||
@Serializable
|
||||
sealed class BaseData
|
||||
|
||||
@Serializable
|
||||
data class GetVersionResponse(
|
||||
@SerialName("version")
|
||||
val version: String
|
||||
) : BaseData()
|
||||
|
||||
@Serializable
|
||||
data class ConnectResponse(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("result")
|
||||
val result: Boolean
|
||||
) : BaseData()
|
||||
|
||||
|
||||
@Serializable
|
||||
data class ListInstanceResponse(
|
||||
@SerialName("list")
|
||||
val list: List<MaaInstanceInfo>
|
||||
) : BaseData()
|
||||
|
||||
@Serializable
|
||||
data class MaaInstanceInfo(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("host")
|
||||
val host: String,
|
||||
@SerialName("adbPath")
|
||||
val adbPath: String,
|
||||
@SerialName("uuid")
|
||||
val uuid: String,
|
||||
@SerialName("status")
|
||||
val status: Int,
|
||||
) : BaseData()
|
||||
|
||||
@Serializable
|
||||
data class AppendTaskResponse(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("taskId")
|
||||
val taskId: Int
|
||||
) : BaseData()
|
||||
|
||||
|
||||
@Serializable
|
||||
data class SetTaskParamsResponse(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("result")
|
||||
val result: Boolean
|
||||
) : BaseData()
|
||||
|
||||
|
||||
@Serializable
|
||||
data class StartResponse(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("result")
|
||||
val result: Boolean
|
||||
) : BaseData()
|
||||
|
||||
@Serializable
|
||||
data class StopResponse(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("result")
|
||||
val result: Boolean
|
||||
) : BaseData()
|
||||
|
||||
|
||||
|
||||
@Serializable
|
||||
data class CallBackLog(
|
||||
@SerialName("id")
|
||||
val id: String,
|
||||
@SerialName("logId")
|
||||
val logId: Long,
|
||||
@SerialName("msg")
|
||||
val msg: Int,
|
||||
@SerialName("details")
|
||||
val details: JsonElement,
|
||||
) : BaseData()
|
||||
|
||||
|
||||
@Serializable
|
||||
object EmptyBaseData : BaseData()
|
||||
|
||||
fun BaseData.toJsonElement() =
|
||||
Json.encodeToJsonElement(Json.encodeToJsonElement(this).jsonObject.filterNot { it.key == "type" })
|
||||
|
||||
|
||||
fun BaseData.wapperToHttpResponse() =
|
||||
HttpResponse(Json.encodeToJsonElement(Json.encodeToJsonElement(this).jsonObject.filterNot { it.key == "type" }))
|
||||
|
||||
fun BaseData.wapperToWsResponse(command: String, msgId: Int) =
|
||||
WsResponse(
|
||||
Json.encodeToJsonElement(Json.encodeToJsonElement(this).jsonObject.filterNot { it.key == "type" }),
|
||||
command,
|
||||
msgId
|
||||
)
|
||||
|
||||
fun WsResponse.toJsonString() = Json.encodeToJsonElement(Json.encodeToJsonElement(this).jsonObject.filterNot { it.key == "type" }).toString()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.iguigui.maaj;
|
||||
package com.iguigui.maaj.easySample;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
@@ -8,7 +8,7 @@ import java.util.Scanner;
|
||||
public class MaaJavaSample {
|
||||
|
||||
/**
|
||||
* Maa的Java调用实例实现,项目需依赖JNA库。
|
||||
* Maa的Java调用实例实现,最简示例仅需依赖第三方JNA库。
|
||||
* 仅在Windows下进行过测试,未在Linux下测试过(相信强大的Linux用户自己可以解决问题!
|
||||
*
|
||||
* --------特别提醒----------
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.iguigui.maaj;
|
||||
package com.iguigui.maaj.easySample;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.win32.StdCallLibrary;
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.iguigui.maaj.routing
|
||||
|
||||
import com.iguigui.maaj.dto.*
|
||||
import com.iguigui.maaj.service.MaaService
|
||||
import com.iguigui.maaj.service.MaaService.appendTask
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
|
||||
|
||||
fun Application.httpRouting() {
|
||||
|
||||
routing {
|
||||
route("/API/V1") {
|
||||
get("/getVersion") {
|
||||
val version = MaaService.getVersion()
|
||||
call.respond(GetVersionResponse(version).wapperToHttpResponse())
|
||||
}
|
||||
post("/connect") {
|
||||
with(call.receive<ConnectRequest>()) {
|
||||
val connect = MaaService.connect(adbPath, host, detailJson)
|
||||
call.respond(connect.wapperToHttpResponse())
|
||||
}
|
||||
}
|
||||
post("/appendTask") {
|
||||
with(call.receive<AppendTaskRequest>()) {
|
||||
val result = appendTask(
|
||||
id,
|
||||
type,
|
||||
params.jsonObject.toString()
|
||||
)
|
||||
call.respond(AppendTaskResponse(id, result).wapperToHttpResponse())
|
||||
}
|
||||
}
|
||||
post("/setTaskParams") {
|
||||
with(call.receive<SetTaskParamsRequest>()) {
|
||||
val result = MaaService.setTaskParams(
|
||||
id,
|
||||
taskId,
|
||||
params.jsonObject.toString()
|
||||
)
|
||||
call.respond(SetTaskParamsResponse(id, result).wapperToHttpResponse())
|
||||
}
|
||||
}
|
||||
post("/start") {
|
||||
val startRequest = call.receive<StartRequest>()
|
||||
val result = MaaService.start(startRequest.id)
|
||||
call.respond(StartResponse(startRequest.id, result).wapperToHttpResponse())
|
||||
}
|
||||
post("/stop") {
|
||||
val stopRequest = call.receive<StopRequest>()
|
||||
val result = MaaService.stop(stopRequest.id)
|
||||
call.respond(StartResponse(stopRequest.id, result).wapperToHttpResponse())
|
||||
}
|
||||
post("/destroy") {
|
||||
val destroy = call.receive<DestroyRequest>()
|
||||
MaaService.destroy(destroy.id)
|
||||
call.respond(EmptyBaseData.wapperToHttpResponse())
|
||||
}
|
||||
get("/listInstance") {
|
||||
val list = MaaService.listInstance()
|
||||
call.respond(ListInstanceResponse(list).wapperToHttpResponse())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.iguigui.maaj.routing
|
||||
|
||||
import com.iguigui.maaj.dto.*
|
||||
import com.iguigui.maaj.logger
|
||||
import com.iguigui.maaj.service.Connection
|
||||
import com.iguigui.maaj.service.MaaService
|
||||
import com.iguigui.maaj.service.MaaService.addConnection
|
||||
import com.iguigui.maaj.service.MaaService.appendTask
|
||||
import com.iguigui.maaj.service.MaaService.removeConnection
|
||||
import com.iguigui.maaj.util.Json
|
||||
import io.ktor.websocket.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.websocket.*
|
||||
import io.ktor.websocket.*
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import java.util.*
|
||||
import kotlin.collections.LinkedHashSet
|
||||
|
||||
|
||||
fun Application.wsRouting() {
|
||||
routing {
|
||||
webSocket("/API/V1") {
|
||||
val connection = Connection(this)
|
||||
logger.info("Ws connection connected ! connection : ${connection.session} ")
|
||||
addConnection(connection)
|
||||
try {
|
||||
for (frame in incoming) {
|
||||
frame as? Frame.Text ?: continue
|
||||
val receivedText = frame.readText()
|
||||
logger.info(receivedText)
|
||||
val wsRequest = Json.decodeFromString(WsRequest.serializer(), receivedText)
|
||||
var response: BaseData? = null
|
||||
when (wsRequest.command) {
|
||||
"getVersion" -> {
|
||||
response = GetVersionResponse(MaaService.getVersion())
|
||||
}
|
||||
"connect" -> {
|
||||
with(Json.decodeFromJsonElement(ConnectRequest.serializer(), wsRequest.data)) {
|
||||
response = MaaService.connect(adbPath, host, detailJson)
|
||||
}
|
||||
}
|
||||
"appendTask" -> {
|
||||
with(Json.decodeFromJsonElement(AppendTaskRequest.serializer(), wsRequest.data)) {
|
||||
val result = appendTask(
|
||||
id,
|
||||
type,
|
||||
params.jsonObject.toString()
|
||||
)
|
||||
response = AppendTaskResponse(id, result)
|
||||
}
|
||||
}
|
||||
"setTaskParams" -> {
|
||||
with(Json.decodeFromJsonElement(SetTaskParamsRequest.serializer(), wsRequest.data)) {
|
||||
val result = MaaService.setTaskParams(
|
||||
id,
|
||||
taskId,
|
||||
params.jsonObject.toString()
|
||||
)
|
||||
response = SetTaskParamsResponse(id, result)
|
||||
}
|
||||
}
|
||||
"start" -> {
|
||||
val startRequest =
|
||||
Json.decodeFromJsonElement(StartRequest.serializer(), wsRequest.data)
|
||||
val result = MaaService.start(startRequest.id)
|
||||
response = StartResponse(startRequest.id, result)
|
||||
}
|
||||
"stop" -> {
|
||||
val stopRequest =
|
||||
Json.decodeFromJsonElement(StopRequest.serializer(), wsRequest.data)
|
||||
val result = MaaService.stop(stopRequest.id)
|
||||
response = StopResponse(stopRequest.id, result)
|
||||
}
|
||||
"destroy" -> {
|
||||
val destroyRequest =
|
||||
Json.decodeFromJsonElement(DestroyRequest.serializer(), wsRequest.data)
|
||||
MaaService.destroy(destroyRequest.id)
|
||||
response = EmptyBaseData
|
||||
}
|
||||
"listInstance" -> {
|
||||
val list = MaaService.listInstance()
|
||||
response = ListInstanceResponse(list)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
response?.let {
|
||||
send(it.wapperToWsResponse(wsRequest.command, wsRequest.msgId).toJsonString())
|
||||
}
|
||||
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Ws Exception $e.message")
|
||||
logger.warn(e.stackTraceToString())
|
||||
} finally {
|
||||
logger.info("Ws connection disconnected ! connection : $connection ")
|
||||
removeConnection(connection)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.iguigui.maaj.service
|
||||
|
||||
import io.ktor.websocket.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class Connection(val session: DefaultWebSocketSession) {
|
||||
companion object {
|
||||
var lastId = AtomicInteger(0)
|
||||
}
|
||||
val name = "user${lastId.getAndIncrement()}"
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.iguigui.maaj.service
|
||||
|
||||
import com.iguigui.maaj.dto.CallBackLog
|
||||
import com.iguigui.maaj.dto.*
|
||||
import com.iguigui.maaj.easySample.MeoAssistant
|
||||
import com.iguigui.maaj.logger
|
||||
import com.iguigui.maaj.util.Json
|
||||
import com.sun.jna.Pointer
|
||||
import io.ktor.server.application.*
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
import kotlin.reflect.KFunction1
|
||||
|
||||
class MaaInstance(
|
||||
private val instance: MeoAssistant,
|
||||
val id: String,
|
||||
val adbPath: String,
|
||||
val host: String,
|
||||
private val detailJson: String,
|
||||
val callBackAction: KFunction1<CallBackLog, Unit>
|
||||
) :
|
||||
MeoAssistant.AsstApiCallback {
|
||||
|
||||
// constructor(
|
||||
// instance: MeoAssistant,
|
||||
// id: String,
|
||||
// adbPath: String,
|
||||
// host: String,
|
||||
// pointer: Pointer,
|
||||
// detailJson: String
|
||||
// ) : this(
|
||||
// instance,
|
||||
// id,
|
||||
// adbPath,
|
||||
// host,
|
||||
// detailJson
|
||||
// ) {
|
||||
// this.pointer = pointer
|
||||
// }
|
||||
|
||||
lateinit var pointer: Pointer
|
||||
|
||||
var uuid = ""
|
||||
|
||||
//状态码,0初始化未运行 1运行中
|
||||
var status = 0
|
||||
|
||||
// private var logQueue: ArrayBlockingQueue<CallBackLog> = ArrayBlockingQueue(100)
|
||||
//
|
||||
private var msgId = AtomicLong(0)
|
||||
|
||||
|
||||
override fun callback(msg: Int, detail_json: String, custom_arg: String) {
|
||||
val callBackLog = CallBackLog(id, msgId.getAndIncrement(), msg, Json.parseToJsonElement(detail_json))
|
||||
logger.info("callBackLog = $callBackLog")
|
||||
callBackAction.call(callBackLog)
|
||||
when (msg) {
|
||||
INTERNAL_ERROR,
|
||||
INIT_FAILED,
|
||||
ALL_TASKS_COMPLETED,
|
||||
TASK_CHAIN_ERROR,
|
||||
TASK_CHAIN_COMPLETED,
|
||||
SUB_TASK_ERROR,
|
||||
SUB_TASK_COMPLETED -> status = 0
|
||||
//也不知道啥算正在运行,姑且认为任务链开始和原子任务开始肯定是在运行中吧
|
||||
TASK_CHAIN_START,
|
||||
SUB_TASK_START -> status = 1
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
fun connect(): Boolean = instance.AsstConnect(pointer, adbPath, host, detailJson)
|
||||
|
||||
fun appendTask(type: String, params: String) = instance.AsstAppendTask(pointer, type, params)
|
||||
|
||||
fun setTaskParams(taskId: Int, params: String) = instance.AsstSetTaskParams(pointer, taskId, params)
|
||||
|
||||
fun start(): Boolean {
|
||||
msgId.set(0)
|
||||
return instance.AsstStart(pointer)
|
||||
}
|
||||
|
||||
fun stop() = instance.AsstStop(pointer)
|
||||
fun destroy() = instance.AsstDestroy(pointer)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.iguigui.maaj.service
|
||||
|
||||
import com.iguigui.maaj.dto.*
|
||||
import com.iguigui.maaj.easySample.MeoAssistant
|
||||
import com.iguigui.maaj.logger
|
||||
import com.sun.jna.Native
|
||||
import io.ktor.websocket.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.io.File
|
||||
import java.security.MessageDigest
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
|
||||
object MaaService {
|
||||
|
||||
private var instancePool: ConcurrentHashMap<String, MaaInstance> = ConcurrentHashMap()
|
||||
|
||||
private val wsConnection = Collections.synchronizedSet<Connection?>(LinkedHashSet())
|
||||
|
||||
val meoAssistant: MeoAssistant by lazy {
|
||||
var maaPath = File(File("").absolutePath).parent
|
||||
logger.info("maaPath $maaPath")
|
||||
// maaPath = "C:\\Users\\atmzx\\Desktop\\MeoAssistantArknights3"
|
||||
System.setProperty("jna.library.path", maaPath)
|
||||
val load = Native.load("MeoAssistant", MeoAssistant::class.java)
|
||||
load.AsstLoadResource(maaPath)
|
||||
load
|
||||
}
|
||||
|
||||
fun connect(adbPath: String, host: String, detailJson: String): ConnectResponse {
|
||||
val id = sha1(host)
|
||||
// if (instancePool.containsKey(id)) {
|
||||
// return ConnectResponse(id, true)
|
||||
// }
|
||||
val maaInstance = MaaInstance(meoAssistant, id, adbPath, host, detailJson, ::callBackLog)
|
||||
maaInstance.pointer = meoAssistant.AsstCreateEx(maaInstance, maaInstance.id)
|
||||
val connect = maaInstance.connect()
|
||||
if (!connect) {
|
||||
return ConnectResponse("", false)
|
||||
}
|
||||
instancePool[id] = maaInstance
|
||||
return ConnectResponse(id, true)
|
||||
}
|
||||
|
||||
fun appendTask(id: String, type: String, detailJson: String) =
|
||||
instancePool[id]?.appendTask(type, detailJson) ?: 0
|
||||
|
||||
|
||||
fun setTaskParams(id: String, taskId: Int, detailJson: String) =
|
||||
instancePool[id]?.setTaskParams(taskId, detailJson) ?: false
|
||||
|
||||
fun start(id: String) = instancePool[id]?.start() ?: false
|
||||
|
||||
fun stop(id: String) = instancePool[id]?.stop() ?: false
|
||||
|
||||
fun getVersion(): String = meoAssistant.AsstGetVersion()
|
||||
|
||||
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<MaaInstanceInfo> =
|
||||
instancePool.values.map { e -> MaaInstanceInfo(e.id, e.host, e.adbPath, e.uuid, e.status) }.toList()
|
||||
|
||||
fun destroy(id: String) {
|
||||
instancePool[id]?.destroy()
|
||||
instancePool.remove(id)
|
||||
}
|
||||
|
||||
|
||||
fun callBackLog(message: CallBackLog) {
|
||||
runBlocking {
|
||||
wsConnection.forEach { it.session.send(message.wapperToWsResponse("callBack", 0).toJsonString()) }
|
||||
}
|
||||
}
|
||||
|
||||
fun addConnection(connection: Connection) {
|
||||
this.wsConnection += connection
|
||||
}
|
||||
|
||||
fun removeConnection(connection: Connection) {
|
||||
this.wsConnection -= connection
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.iguigui.maaj.util
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
val Json by lazy {
|
||||
Json {
|
||||
ignoreUnknownKeys = true
|
||||
encodeDefaults = true
|
||||
}
|
||||
}
|
||||
8
src/Java/Maaj/src/main/resources/application.conf
Normal file
8
src/Java/Maaj/src/main/resources/application.conf
Normal file
@@ -0,0 +1,8 @@
|
||||
ktor {
|
||||
deployment {
|
||||
port = 8848
|
||||
}
|
||||
application {
|
||||
modules = [ com.iguigui.maaj.ApplicationKt.module ]
|
||||
}
|
||||
}
|
||||
13
src/Java/Maaj/src/main/resources/log4j2.xml
Normal file
13
src/Java/Maaj/src/main/resources/log4j2.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<AppenderRef ref="Console" />
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
13
src/Java/Maaj/src/main/resources/logback-fileAppender.xml
Normal file
13
src/Java/Maaj/src/main/resources/logback-fileAppender.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<configuration>
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>Maaj.log</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="info">
|
||||
<appender-ref ref="FILE"/>
|
||||
</root>
|
||||
<logger name="io.netty" level="INFO"/>
|
||||
</configuration>
|
||||
32
src/Java/Maaj/src/main/resources/logback.xml
Normal file
32
src/Java/Maaj/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="trace">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
<logger name="io.netty" level="INFO"/>
|
||||
|
||||
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>log/maa-http.log </file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!-- rollover daily -->
|
||||
<fileNamePattern>maa-http-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
|
||||
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
|
||||
<maxFileSize>10MB</maxFileSize>
|
||||
<maxHistory>10</maxHistory>
|
||||
<totalSizeCap>100MB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="info">
|
||||
<appender-ref ref="ROLLING"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.iguigui.maaj.routing;
|
||||
|
||||
import com.iguigui.maaj.configure
|
||||
import com.iguigui.maaj.dto.GetVersionResponse
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.HttpStatusCode.Companion.OK
|
||||
import io.ktor.server.testing.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import kotlin.test.Test
|
||||
|
||||
class HttpRoutingKtTest {
|
||||
|
||||
|
||||
// @Test
|
||||
// fun testGetApiV1Getversion() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.get("/API/V1/getVersion").apply {
|
||||
// Assert.assertEquals(status,OK)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testPostApiV1Connect() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.post("/API/V1/connect").apply {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testPostApiV1Appendtask() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.post("/API/V1/appendTask").apply {
|
||||
// TODO("Please write your test here")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testPostApiV1Settaskparams() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.post("/API/V1/setTaskParams").apply {
|
||||
// TODO("Please write your test here")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testPostApiV1Start() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.post("/API/V1/start").apply {
|
||||
// TODO("Please write your test here")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testPostApiV1Stop() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.post("/API/V1/stop").apply {
|
||||
// TODO("Please write your test here")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testPostApiV1Destroy() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.post("/API/V1/destroy").apply {
|
||||
// TODO("Please write your test here")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testGetApiV1Listinstance() = testApplication {
|
||||
// application {
|
||||
// httpRouting()
|
||||
// }
|
||||
// client.get("/API/V1/listInstance").apply {
|
||||
// TODO("Please write your test here")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user