mirror of
https://github.com/jie65535/gc-opencommand-plugin.git
synced 2025-06-02 17:49:12 +08:00
Add multi server run console command
This commit is contained in:
parent
37dcd0f1a7
commit
4d08acd084
195
README.md
195
README.md
@ -5,8 +5,10 @@
|
|||||||
一个为第三方客户端开放GC命令执行接口的插件
|
一个为第三方客户端开放GC命令执行接口的插件
|
||||||
|
|
||||||
## 服务端安装
|
## 服务端安装
|
||||||
|
|
||||||
1. 在 [Release](https://github.com/jie65535/gc-opencommand-plugin/releases) 下载 `jar`
|
1. 在 [Release](https://github.com/jie65535/gc-opencommand-plugin/releases) 下载 `jar`
|
||||||
2. 放入 `plugins` 文件夹即可
|
2. 放入 `plugins` 文件夹即可
|
||||||
|
|
||||||
> 注意,如果出现以下错误:
|
> 注意,如果出现以下错误:
|
||||||
> ```log
|
> ```log
|
||||||
> INFO:PluginManager Enabling plugin: opencommand-plugin
|
> INFO:PluginManager Enabling plugin: opencommand-plugin
|
||||||
@ -17,24 +19,28 @@
|
|||||||
> 请使用v1.2.1版本插件,因为该报错表示你的服务端是旧版!
|
> 请使用v1.2.1版本插件,因为该报错表示你的服务端是旧版!
|
||||||
|
|
||||||
## 控制台连接
|
## 控制台连接
|
||||||
|
|
||||||
1. 首次启动时,会在 `plugins` 目录下生成一个 `opencommand-plugin` 目录,打开并编辑 `config.json`
|
1. 首次启动时,会在 `plugins` 目录下生成一个 `opencommand-plugin` 目录,打开并编辑 `config.json`
|
||||||
2. 设置 `consoleToken` 的值为你的连接秘钥,建议使用至少32字符的长随机字符串。
|
2. 设置 `consoleToken` 的值为你的连接秘钥,建议使用至少32字符的长随机字符串。
|
||||||
3. 重新启动服务端即可生效配置
|
3. 重新启动服务端即可生效配置
|
||||||
4. 在客户端中选择控制台身份,并填写你的 `consoleToken` 即可以控制台身份运行指令
|
4. 在客户端中选择控制台身份,并填写你的 `consoleToken` 即可以控制台身份运行指令
|
||||||
|
|
||||||
## 构建说明
|
## 构建说明
|
||||||
|
|
||||||
1. 克隆仓库
|
1. 克隆仓库
|
||||||
2. 在目录下新建 `lib` 目录
|
2. 在目录下新建 `lib` 目录
|
||||||
3. 将 `grasscutter-1.1.x-dev.jar` 放入 `lib` 目录
|
3. 将 `grasscutter-1.1.x-dev.jar` 放入 `lib` 目录
|
||||||
4. `gradle build`
|
4. `gradle build`
|
||||||
|
|
||||||
## 玩家使用流程
|
## 玩家使用流程
|
||||||
|
|
||||||
1. 在客户端中填写服务地址,确认是否支持
|
1. 在客户端中填写服务地址,确认是否支持
|
||||||
2. 填写UID,发送验证码
|
2. 填写UID,发送验证码
|
||||||
3. 将游戏内收到的**4位整数验证码**填入客户端校验
|
3. 将游戏内收到的**4位整数验证码**填入客户端校验
|
||||||
4. 享受便利!
|
4. 享受便利!
|
||||||
|
|
||||||
## 客户端请求流程
|
## 客户端请求流程
|
||||||
|
|
||||||
1. `ping` 确认是否支持 `opencommand` 插件
|
1. `ping` 确认是否支持 `opencommand` 插件
|
||||||
2. `sendCode` 向指定玩家发送验证码(1分钟内不允许重发),保存返回的 `token`
|
2. `sendCode` 向指定玩家发送验证码(1分钟内不允许重发),保存返回的 `token`
|
||||||
3. 使用 `token` 和**4位整数验证码**发送 `verify` 校验
|
3. 使用 `token` 和**4位整数验证码**发送 `verify` 校验
|
||||||
@ -43,6 +49,7 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
## `config.json`
|
## `config.json`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
// 控制台连接令牌
|
// 控制台连接令牌
|
||||||
@ -58,114 +65,210 @@
|
|||||||
// 多服务器通信密钥
|
// 多服务器通信密钥
|
||||||
"socketToken": "",
|
"socketToken": "",
|
||||||
// 多服务器Dispatch地址
|
// 多服务器Dispatch地址
|
||||||
"socketHost": "127.0.0.1"
|
"socketHost": "127.0.0.1",
|
||||||
|
// 多服务器显示名称
|
||||||
|
"socketDisplayName": ""
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## API `/opencommand/api`
|
## API `/opencommand/api`
|
||||||
|
|
||||||
示例
|
示例
|
||||||
|
|
||||||
```
|
```
|
||||||
https://127.0.0.1/opencommand/api
|
https://127.0.0.1/opencommand/api
|
||||||
```
|
```
|
||||||
|
|
||||||
### Request 请求
|
### Request 请求
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public final class JsonRequest {
|
public final class JsonRequest {
|
||||||
public String token = "";
|
public String token = "";
|
||||||
public String action = "";
|
public String action = "";
|
||||||
|
public String server = "";
|
||||||
public Object data = null;
|
public Object data = null;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Response 响应
|
### Response 响应
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public final class JsonResponse {
|
public final class JsonResponse {
|
||||||
public int retcode = 200;
|
public int retcode = 200;
|
||||||
public String message = "success";
|
public String message = "Success";
|
||||||
public Object data;
|
public Object data;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Actions 动作
|
### Actions 动作
|
||||||
|
|
||||||
#### `测试连接`
|
#### `测试连接`
|
||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| 请求参数 | 请求数据 | 类型 |
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
| ------- | --------- | ------ |
|
|--------|--------|----------|
|
||||||
| action | `ping` |`String`|
|
| action | `ping` | `String` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
| 返回参数 | 返回数据 | 类型 |
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
| ------- | --------- | ------ |
|
|---------|-----------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `Int` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `null` |`null` |
|
| data | `null` | `null` |
|
||||||
|
|
||||||
|
|
||||||
|
#### `获取在线玩家`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
|
|--------|----------|----------|
|
||||||
|
| action | `online` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
|
|---------|---------------------------------|--------------|
|
||||||
|
| retcode | `200` | `Int` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `{"count": 0, playerList": []}` | `JsonObject` |
|
||||||
|
|
||||||
#### `发送验证码`
|
#### `发送验证码`
|
||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| 请求参数 | 请求数据 | 类型 |
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
| ------- | --------- | ------ |
|
|--------|------------|----------|
|
||||||
| action | `sendCode`|`String`|
|
| action | `sendCode` | `String` |
|
||||||
| data | `uid` |`Int` |
|
| data | `uid` | `Int` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
| 返回参数 | 返回数据 | 类型 |
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
| ------- | --------- | ------ |
|
|---------|-----------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `Int` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `token` |`String`|
|
| data | `token` | `String` |
|
||||||
|
|
||||||
|
|
||||||
#### `验证验证码`
|
#### `验证验证码`
|
||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| 请求参数 | 请求数据 | 类型 |
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
| ------- | --------- | ------ |
|
|--------|----------|----------|
|
||||||
| action | `verify` |`String`|
|
| action | `verify` | `String` |
|
||||||
| token | `token` |`String`|
|
| token | `token` | `String` |
|
||||||
| data | `code` |`Int` |
|
| data | `code` | `Int` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
成功
|
成功
|
||||||
|
|
||||||
| 返回参数 | 返回数据 | 类型 |
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
| ------- | --------- | ------ |
|
|---------|-----------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `Int` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `null` | `null` |
|
| data | `null` | `null` |
|
||||||
|
|
||||||
失败
|
失败
|
||||||
|
|
||||||
| 返回参数 | 返回数据 | 类型 |
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
| ------- | -------------------- | ------ |
|
|---------|-----------------------|----------|
|
||||||
| retcode | `400` |`String`|
|
| retcode | `400` | `Int` |
|
||||||
| message | `Verification failed`|`String`|
|
| message | `Verification failed` | `String` |
|
||||||
| data | `null` |`null` |
|
| data | `null` | `null` |
|
||||||
|
|
||||||
#### `执行命令`
|
#### `执行命令`
|
||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| 请求参数 | 请求数据 | 类型 |
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
| ------- | ----------- | ------ |
|
|--------|-----------|----------|
|
||||||
| action | `command` |`String`|
|
| action | `command` | `String` |
|
||||||
| token | `token` |`String`|
|
| token | `token` | `String` |
|
||||||
| data | `command` |`String`|
|
| data | `command` | `String` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
成功
|
成功
|
||||||
|
|
||||||
| 返回参数 | 返回数据 | 类型 |
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
| ------- | ---------------- | ------ |
|
|---------|------------------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `Int` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `Command return` |`String`|
|
| data | `Command return` | `String` |
|
||||||
|
|
||||||
|
### 执行控制台命令
|
||||||
|
|
||||||
|
#### `获取运行模式`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
|
|--------|-----------|----------|
|
||||||
|
| action | `runmode` | `String` |
|
||||||
|
| token | `token` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
成功
|
||||||
|
|
||||||
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
|
|---------|-----------------------|----------|
|
||||||
|
| retcode | `200` | `Int` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `1 (多服务器) / 0 (单服务器)` | `Int` |
|
||||||
|
|
||||||
|
#### `获取多服务器列表`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
|
|--------|----------|----------|
|
||||||
|
| action | `server` | `String` |
|
||||||
|
| token | `token` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
成功
|
||||||
|
|
||||||
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
|
|---------|-----------|--------------|
|
||||||
|
| retcode | `200` | `Int` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `{}` | `JsonObject` |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"retcode": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
// 服务器 UUID
|
||||||
|
"13d82d0d-c7d9-47dd-830c-76588006ef6e": "2.8.0 服务器",
|
||||||
|
"e6b83224-a761-4023-be57-e054c5bb823a": "2.8.0 开发服务器"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `执行命令`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| 请求参数 | 请求数据 | 类型 |
|
||||||
|
|--------|-----------|----------|
|
||||||
|
| action | `command` | `String` |
|
||||||
|
| token | `token` | `String` |
|
||||||
|
| server | `UUID` | `String` |
|
||||||
|
| data | `command` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
成功
|
||||||
|
|
||||||
|
| 返回参数 | 返回数据 | 类型 |
|
||||||
|
|---------|------------------|----------|
|
||||||
|
| retcode | `200` | `Int` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `Command return` | `String` |
|
176
README_en-US.md
176
README_en-US.md
@ -60,6 +60,7 @@ https://127.0.0.1/opencommand/api
|
|||||||
public final class JsonRequest {
|
public final class JsonRequest {
|
||||||
public String token = "";
|
public String token = "";
|
||||||
public String action = "";
|
public String action = "";
|
||||||
|
public Seting server = "";
|
||||||
public Object data = null;
|
public Object data = null;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -68,7 +69,7 @@ public final class JsonRequest {
|
|||||||
```java
|
```java
|
||||||
public final class JsonResponse {
|
public final class JsonResponse {
|
||||||
public int retcode = 200;
|
public int retcode = 200;
|
||||||
public String message = "success";
|
public String message = "Success";
|
||||||
public Object data;
|
public Object data;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -78,79 +79,168 @@ public final class JsonResponse {
|
|||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| Request | Request data | type |
|
| Request | Request data | type |
|
||||||
| ------- | -------------- | ------ |
|
|---------|--------------|----------|
|
||||||
| action | `ping` |`String`|
|
| action | `ping` | `String` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
| Response | Response data | type |
|
| Response | Response data | type |
|
||||||
| -------- | --------------- | ------ |
|
|----------|---------------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `String` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `null` |`null` |
|
| data | `null` | `null` |
|
||||||
|
|
||||||
|
#### `Get online players`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| Request | Request data | type |
|
||||||
|
|---------|--------------|----------|
|
||||||
|
| action | `online` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
| Response | Response data | type |
|
||||||
|
|----------|---------------------------------|--------------|
|
||||||
|
| retcode | `200` | `String` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `{"count": 0, playerList": []}` | `JsonObject` |
|
||||||
|
|
||||||
#### `Send code`
|
#### `Send code`
|
||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| Request | Request data | type |
|
| Request | Request data | type |
|
||||||
| ------- | -------------- | ------ |
|
|---------|--------------|----------|
|
||||||
| action | `sendCode` |`String`|
|
| action | `sendCode` | `String` |
|
||||||
| data | `uid` |`Int` |
|
| data | `uid` | `Int` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
| Response | Response data | type |
|
| Response | Response data | type |
|
||||||
| -------- | --------------- | ------ |
|
|----------|---------------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `String` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `token` |`String`|
|
| data | `token` | `String` |
|
||||||
|
|
||||||
#### `Verify code`
|
#### `Verify code`
|
||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| Request | Request data | type |
|
| Request | Request data | type |
|
||||||
| ------- | -------------- | ------ |
|
|---------|--------------|----------|
|
||||||
| action | `verify` |`String`|
|
| action | `verify` | `String` |
|
||||||
| token | `token` |`String`|
|
| token | `token` | `String` |
|
||||||
| data | `code` |`Int` |
|
| data | `code` | `Int` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
Success
|
Success
|
||||||
|
|
||||||
| Response | Response data | type |
|
| Response | Response data | type |
|
||||||
| -------- | -------------- | ------ |
|
|----------|---------------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `String` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `null` | `null` |
|
| data | `null` | `null` |
|
||||||
|
|
||||||
Failed
|
Failed
|
||||||
|
|
||||||
| Response | Response data | type |
|
| Response | Response data | type |
|
||||||
| -------- | -------------------- | ------ |
|
|----------|-----------------------|----------|
|
||||||
| retcode | `400` |`String`|
|
| retcode | `400` | `String` |
|
||||||
| message | `Verification failed`|`String`|
|
| message | `Verification failed` | `String` |
|
||||||
| data | `null` |`null` |
|
| data | `null` | `null` |
|
||||||
|
|
||||||
#### `Run command`
|
#### `Run command`
|
||||||
|
|
||||||
##### Request
|
##### Request
|
||||||
|
|
||||||
| Request | Request data | type |
|
| Request | Request data | type |
|
||||||
| ------- | -------------- | ------ |
|
|---------|--------------|----------|
|
||||||
| action | `command` |`String`|
|
| action | `command` | `String` |
|
||||||
| token | `token` |`String`|
|
| token | `token` | `String` |
|
||||||
| data | `command` |`String`|
|
| data | `command` | `String` |
|
||||||
|
|
||||||
##### Response
|
##### Response
|
||||||
|
|
||||||
Success
|
Success
|
||||||
|
|
||||||
| Response | Response data | type |
|
| Response | Response data | type |
|
||||||
| -------- | ------------------ | ------ |
|
|----------|------------------|----------|
|
||||||
| retcode | `200` |`String`|
|
| retcode | `200` | `String` |
|
||||||
| message | `success` |`String`|
|
| message | `Success` | `String` |
|
||||||
| data | `Command return` |`String`|
|
| data | `Command return` | `String` |
|
||||||
|
|
||||||
|
### Run console command
|
||||||
|
|
||||||
|
#### `Get run mode`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| Request | Request data | Type |
|
||||||
|
|---------|--------------|----------|
|
||||||
|
| action | `runmode` | `String` |
|
||||||
|
| token | `token` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
Success
|
||||||
|
|
||||||
|
| Request | Response data | Type |
|
||||||
|
|---------|----------------------------------------|----------|
|
||||||
|
| retcode | `200` | `Int` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `1 (Multi server) / 0 (Single server)` | `Int` |
|
||||||
|
|
||||||
|
#### `Get mulit server list`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| Request | Request data | Type |
|
||||||
|
|---------|--------------|----------|
|
||||||
|
| action | `server` | `String` |
|
||||||
|
| token | `token` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
Success
|
||||||
|
|
||||||
|
| Request | Response data | Type |
|
||||||
|
|---------|---------------|--------------|
|
||||||
|
| retcode | `200` | `Int` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `{}` | `JsonObject` |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"retcode": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
// Server UUID
|
||||||
|
"13d82d0d-c7d9-47dd-830c-76588006ef6e": "2.8.0 Server",
|
||||||
|
"e6b83224-a761-4023-be57-e054c5bb823a": "2.8.0 Dev server"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `Run command`
|
||||||
|
|
||||||
|
##### Request
|
||||||
|
|
||||||
|
| Request | Request data | Type |
|
||||||
|
|---------|--------------|----------|
|
||||||
|
| action | `command` | `String` |
|
||||||
|
| token | `token` | `String` |
|
||||||
|
| server | `UUID` | `String` |
|
||||||
|
| data | `command` | `String` |
|
||||||
|
|
||||||
|
##### Response
|
||||||
|
|
||||||
|
Success
|
||||||
|
|
||||||
|
| Request | Response data | Type |
|
||||||
|
|---------|------------------|----------|
|
||||||
|
| retcode | `200` | `Int` |
|
||||||
|
| message | `Success` | `String` |
|
||||||
|
| data | `Command return` | `String` |
|
@ -15,9 +15,11 @@ import java.util.ArrayList;
|
|||||||
public final class EventListeners {
|
public final class EventListeners {
|
||||||
|
|
||||||
private static MessageHandler consoleMessageHandler;
|
private static MessageHandler consoleMessageHandler;
|
||||||
|
|
||||||
public static void setConsoleMessageHandler(MessageHandler handler) {
|
public static void setConsoleMessageHandler(MessageHandler handler) {
|
||||||
consoleMessageHandler = handler;
|
consoleMessageHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onCommandResponse(ReceiveCommandFeedbackEvent event) {
|
public static void onCommandResponse(ReceiveCommandFeedbackEvent event) {
|
||||||
if (consoleMessageHandler != null && event.getPlayer() == null) {
|
if (consoleMessageHandler != null && event.getPlayer() == null) {
|
||||||
consoleMessageHandler.setMessage(event.getMessage());
|
consoleMessageHandler.setMessage(event.getMessage());
|
||||||
|
@ -25,4 +25,5 @@ public class OpenCommandConfig {
|
|||||||
public int socketPort = 5746;
|
public int socketPort = 5746;
|
||||||
public String socketToken = "";
|
public String socketToken = "";
|
||||||
public String socketHost = "127.0.0.1";
|
public String socketHost = "127.0.0.1";
|
||||||
|
public String socketDisplayName = "";
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package com.github.jie65535.opencommand;
|
|||||||
|
|
||||||
import com.github.jie65535.opencommand.json.JsonRequest;
|
import com.github.jie65535.opencommand.json.JsonRequest;
|
||||||
import com.github.jie65535.opencommand.json.JsonResponse;
|
import com.github.jie65535.opencommand.json.JsonResponse;
|
||||||
|
import com.github.jie65535.opencommand.socket.SocketData;
|
||||||
import emu.grasscutter.command.CommandMap;
|
import emu.grasscutter.command.CommandMap;
|
||||||
import emu.grasscutter.server.http.Router;
|
import emu.grasscutter.server.http.Router;
|
||||||
import emu.grasscutter.utils.Crypto;
|
import emu.grasscutter.utils.Crypto;
|
||||||
@ -31,6 +32,7 @@ import io.javalin.Javalin;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -85,6 +87,11 @@ public final class OpenCommandHandler implements Router {
|
|||||||
} else if (req.action.equals("ping")) {
|
} else if (req.action.equals("ping")) {
|
||||||
response.json(new JsonResponse());
|
response.json(new JsonResponse());
|
||||||
return;
|
return;
|
||||||
|
} else if (req.action.equals("online")) {
|
||||||
|
var p = new ArrayList<String>();
|
||||||
|
plugin.getServer().getPlayers().forEach((uid, player) -> p.add(player.getNickname()));
|
||||||
|
response.json(new JsonResponse(200, "Success", new SocketData.OnlinePlayer(p)));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// token is required
|
// token is required
|
||||||
@ -118,6 +125,9 @@ public final class OpenCommandHandler implements Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else if (req.action.equals("runmode")) {
|
||||||
|
response.json(new JsonResponse(200, "Success", 0));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else if (codes.containsKey(req.token)) {
|
} else if (codes.containsKey(req.token)) {
|
||||||
if (req.action.equals("verify")) {
|
if (req.action.equals("verify")) {
|
||||||
|
@ -23,6 +23,7 @@ import com.github.jie65535.opencommand.socket.SocketData;
|
|||||||
import com.github.jie65535.opencommand.socket.SocketDataWait;
|
import com.github.jie65535.opencommand.socket.SocketDataWait;
|
||||||
import com.github.jie65535.opencommand.socket.SocketServer;
|
import com.github.jie65535.opencommand.socket.SocketServer;
|
||||||
import com.github.jie65535.opencommand.socket.packet.HttpPacket;
|
import com.github.jie65535.opencommand.socket.packet.HttpPacket;
|
||||||
|
import com.github.jie65535.opencommand.socket.packet.RunConsoleCommand;
|
||||||
import com.github.jie65535.opencommand.socket.packet.player.Player;
|
import com.github.jie65535.opencommand.socket.packet.player.Player;
|
||||||
import com.github.jie65535.opencommand.socket.packet.player.PlayerEnum;
|
import com.github.jie65535.opencommand.socket.packet.player.PlayerEnum;
|
||||||
import emu.grasscutter.command.CommandMap;
|
import emu.grasscutter.command.CommandMap;
|
||||||
@ -92,6 +93,9 @@ public final class OpenCommandOnlyHttpHandler implements Router {
|
|||||||
} else if (req.action.equals("ping")) {
|
} else if (req.action.equals("ping")) {
|
||||||
response.json(new JsonResponse());
|
response.json(new JsonResponse());
|
||||||
return;
|
return;
|
||||||
|
} else if (req.action.equals("online")) {
|
||||||
|
response.json(new JsonResponse(200, "Success", SocketData.getOnlinePlayer()));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// token is required
|
// token is required
|
||||||
@ -110,20 +114,40 @@ public final class OpenCommandOnlyHttpHandler implements Router {
|
|||||||
response.json(new JsonResponse());
|
response.json(new JsonResponse());
|
||||||
return;
|
return;
|
||||||
} else if (req.action.equals("command")) {
|
} else if (req.action.equals("command")) {
|
||||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
var server = SocketServer.getClientInfoByUuid(req.server);
|
||||||
synchronized (plugin) {
|
if (server == null) {
|
||||||
try {
|
response.json(new JsonResponse(404, "Server Not Found."));
|
||||||
plugin.getLogger().info(String.format("IP: %s run command in console > %s", request.ip(), req.data));
|
return;
|
||||||
var resultCollector = new MessageHandler();
|
|
||||||
EventListeners.setConsoleMessageHandler(resultCollector);
|
|
||||||
CommandMap.getInstance().invoke(null, null, req.data.toString());
|
|
||||||
response.json(new JsonResponse(resultCollector.getMessage()));
|
|
||||||
} catch (Exception e) {
|
|
||||||
plugin.getLogger().warn("Run command failed.", e);
|
|
||||||
EventListeners.setConsoleMessageHandler(null);
|
|
||||||
response.json(new JsonResponse(500, "error", e.getLocalizedMessage()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
plugin.getLogger().info(String.format("IP: %s run command in console > %s", request.ip(), req.data));
|
||||||
|
var wait = new SocketDataWait<HttpPacket>(2000L) {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpPacket initData(HttpPacket data) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void timeout() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SocketServer.sendPacketAndWait(server.ip, new RunConsoleCommand(req.data.toString()), wait);
|
||||||
|
var data = wait.getData();
|
||||||
|
if (data == null) {
|
||||||
|
response.json(new JsonResponse(408, "Timeout"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
response.json(new JsonResponse(data.code, data.message, data.data));
|
||||||
|
return;
|
||||||
|
} else if (req.action.equals("server")) {
|
||||||
|
response.json(new JsonResponse(200, "Success", SocketServer.getOnlineClient()));
|
||||||
|
return;
|
||||||
|
} else if (req.action.equals("runmode")) {
|
||||||
|
response.json(new JsonResponse(200, "Success", 1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (codes.containsKey(req.token)) {
|
} else if (codes.containsKey(req.token)) {
|
||||||
@ -143,7 +167,8 @@ public final class OpenCommandOnlyHttpHandler implements Router {
|
|||||||
if (req.action.equals("command")) {
|
if (req.action.equals("command")) {
|
||||||
SocketDataWait<HttpPacket> socketDataWait = new SocketDataWait<>(1000L * 10L) {
|
SocketDataWait<HttpPacket> socketDataWait = new SocketDataWait<>(1000L * 10L) {
|
||||||
@Override
|
@Override
|
||||||
public void run() {}
|
public void run() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpPacket initData(HttpPacket data) {
|
public HttpPacket initData(HttpPacket data) {
|
||||||
@ -152,7 +177,6 @@ public final class OpenCommandOnlyHttpHandler implements Router {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void timeout() {
|
public void timeout() {
|
||||||
response.json(new JsonResponse(408, "Wait server timeout"));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -173,7 +197,7 @@ public final class OpenCommandOnlyHttpHandler implements Router {
|
|||||||
|
|
||||||
HttpPacket httpPacket = socketDataWait.getData();
|
HttpPacket httpPacket = socketDataWait.getData();
|
||||||
if (httpPacket == null) {
|
if (httpPacket == null) {
|
||||||
response.json(new JsonResponse(500, "error", "Server connect failed."));
|
response.json(new JsonResponse(500, "error", "Wait timeout"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
response.json(new JsonResponse(httpPacket.code, httpPacket.message));
|
response.json(new JsonResponse(httpPacket.code, httpPacket.message));
|
||||||
|
@ -35,7 +35,10 @@ import java.io.IOException;
|
|||||||
public final class OpenCommandPlugin extends Plugin {
|
public final class OpenCommandPlugin extends Plugin {
|
||||||
|
|
||||||
private static OpenCommandPlugin instance;
|
private static OpenCommandPlugin instance;
|
||||||
public static OpenCommandPlugin getInstance() { return instance; }
|
|
||||||
|
public static OpenCommandPlugin getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
private OpenCommandConfig config;
|
private OpenCommandConfig config;
|
||||||
|
|
||||||
@ -82,19 +85,19 @@ public final class OpenCommandPlugin extends Plugin {
|
|||||||
var configFile = new File(getDataFolder(), "config.json");
|
var configFile = new File(getDataFolder(), "config.json");
|
||||||
if (!configFile.exists()) {
|
if (!configFile.exists()) {
|
||||||
config = new OpenCommandConfig();
|
config = new OpenCommandConfig();
|
||||||
try (var file = new FileWriter(configFile)){
|
try (var file = new FileWriter(configFile)) {
|
||||||
file.write(Grasscutter.getGsonFactory().toJson(config));
|
file.write(Grasscutter.getGsonFactory().toJson(config));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
getLogger().error("Unable to write to config file.");
|
getLogger().error("[OpenCommand] Unable to write to config file.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
getLogger().error("Unable to save config file.");
|
getLogger().error("[OpenCommand] Unable to save config file.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try (var file = new FileReader(configFile)) {
|
try (var file = new FileReader(configFile)) {
|
||||||
config = Grasscutter.getGsonFactory().fromJson(file, OpenCommandConfig.class);
|
config = Grasscutter.getGsonFactory().fromJson(file, OpenCommandConfig.class);
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
config = new OpenCommandConfig();
|
config = new OpenCommandConfig();
|
||||||
getLogger().error("There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
getLogger().error("[OpenCommand] There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 启动Socket
|
// 启动Socket
|
||||||
@ -110,7 +113,7 @@ public final class OpenCommandPlugin extends Plugin {
|
|||||||
try {
|
try {
|
||||||
SocketServer.startServer();
|
SocketServer.startServer();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
getLogger().error("Unable to start socket server.", e);
|
getLogger().error("[OpenCommand] Unable to start socket server.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,5 +20,6 @@ package com.github.jie65535.opencommand.json;
|
|||||||
public final class JsonRequest {
|
public final class JsonRequest {
|
||||||
public String token = "";
|
public String token = "";
|
||||||
public String action = "";
|
public String action = "";
|
||||||
|
public String server = "";
|
||||||
public Object data = null;
|
public Object data = null;
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ package com.github.jie65535.opencommand.json;
|
|||||||
|
|
||||||
public final class JsonResponse {
|
public final class JsonResponse {
|
||||||
public int retcode = 200;
|
public int retcode = 200;
|
||||||
public String message = "success";
|
public String message = "Success";
|
||||||
public Object data;
|
public Object data;
|
||||||
|
|
||||||
public JsonResponse() {
|
public JsonResponse() {
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.github.jie65535.opencommand.socket;
|
||||||
|
|
||||||
|
public class ClientInfo {
|
||||||
|
|
||||||
|
public final String uuid;
|
||||||
|
public final SocketServer.ClientThread clientThread;
|
||||||
|
public final String ip;
|
||||||
|
|
||||||
|
public ClientInfo(String uuid, String ip, SocketServer.ClientThread clientThread) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.clientThread = clientThread;
|
||||||
|
this.ip = ip;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.github.jie65535.opencommand.socket;
|
package com.github.jie65535.opencommand.socket;
|
||||||
|
|
||||||
|
import com.github.jie65535.opencommand.EventListeners;
|
||||||
import com.github.jie65535.opencommand.OpenCommandConfig;
|
import com.github.jie65535.opencommand.OpenCommandConfig;
|
||||||
import com.github.jie65535.opencommand.OpenCommandPlugin;
|
import com.github.jie65535.opencommand.OpenCommandPlugin;
|
||||||
import com.github.jie65535.opencommand.socket.packet.*;
|
import com.github.jie65535.opencommand.socket.packet.*;
|
||||||
@ -33,6 +34,14 @@ public class SocketClient {
|
|||||||
// 连接服务器
|
// 连接服务器
|
||||||
public static void connectServer() {
|
public static void connectServer() {
|
||||||
if (connect) return;
|
if (connect) return;
|
||||||
|
if (clientThread != null) {
|
||||||
|
mLogger.warn("[OpenCommand] Retry connecting to the server after 15 seconds");
|
||||||
|
try {
|
||||||
|
Thread.sleep(15000);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
OpenCommandConfig config = OpenCommandPlugin.getInstance().getConfig();
|
OpenCommandConfig config = OpenCommandPlugin.getInstance().getConfig();
|
||||||
mLogger = OpenCommandPlugin.getInstance().getLogger();
|
mLogger = OpenCommandPlugin.getInstance().getLogger();
|
||||||
clientThread = new ClientThread(config.socketHost, config.socketPort);
|
clientThread = new ClientThread(config.socketHost, config.socketPort);
|
||||||
@ -160,6 +169,24 @@ public class SocketClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RunConsoleCommand:
|
||||||
|
var consoleCommand = Grasscutter.getGsonFactory().fromJson(packet.data, RunConsoleCommand.class);
|
||||||
|
var plugin = OpenCommandPlugin.getInstance();
|
||||||
|
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||||
|
synchronized (plugin) {
|
||||||
|
try {
|
||||||
|
var resultCollector = new MessageHandler();
|
||||||
|
EventListeners.setConsoleMessageHandler(resultCollector);
|
||||||
|
CommandMap.getInstance().invoke(null, null, consoleCommand.command);
|
||||||
|
sendPacket(new HttpPacket(resultCollector.getMessage()), packet.packetID);
|
||||||
|
} catch (Exception e) {
|
||||||
|
mLogger.warn("[OpenCommand] Run command failed.", e);
|
||||||
|
EventListeners.setConsoleMessageHandler(null);
|
||||||
|
sendPacket(new HttpPacket(500, "error", e.getLocalizedMessage()), packet.packetID);
|
||||||
|
} finally {
|
||||||
|
EventListeners.setConsoleMessageHandler(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -206,18 +233,12 @@ public class SocketClient {
|
|||||||
|
|
||||||
socket = new Socket(ip, port);
|
socket = new Socket(ip, port);
|
||||||
os = socket.getOutputStream();
|
os = socket.getOutputStream();
|
||||||
mLogger.info("[OpenCommand]Connect to server: " + ip + ":" + port);
|
mLogger.info("[OpenCommand] Connect to server: " + ip + ":" + port);
|
||||||
SocketClient.sendPacket(new AuthPacket(OpenCommandPlugin.getInstance().getConfig().socketToken));
|
SocketClient.sendPacket(new AuthPacket(OpenCommandPlugin.getInstance().getConfig().socketToken, OpenCommandPlugin.getInstance().getConfig().socketDisplayName));
|
||||||
receiveThread = new ReceiveThread(socket);
|
receiveThread = new ReceiveThread(socket);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
connect = false;
|
connect = false;
|
||||||
mLogger.warn("[OpenCommand]Connect to server failed: " + ip + ":" + port);
|
mLogger.warn("[OpenCommand] Connect to server failed: " + ip + ":" + port);
|
||||||
mLogger.warn("[OpenCommand] Retry connecting to the server after 15 seconds");
|
|
||||||
try {
|
|
||||||
Thread.sleep(15000);
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
connectServer();
|
connectServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.github.jie65535.opencommand.socket;
|
|||||||
|
|
||||||
import com.github.jie65535.opencommand.socket.packet.player.PlayerList;
|
import com.github.jie65535.opencommand.socket.packet.player.PlayerList;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@ -27,4 +28,21 @@ public class SocketData {
|
|||||||
});
|
});
|
||||||
return ret.get();
|
return ret.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OnlinePlayer getOnlinePlayer() {
|
||||||
|
ArrayList<String> player = new ArrayList<>();
|
||||||
|
playerList.forEach((address, playerMap) -> playerMap.playerMap.forEach((uid, name) -> player.add(name)));
|
||||||
|
return new OnlinePlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class OnlinePlayer {
|
||||||
|
public int count;
|
||||||
|
public ArrayList<String> playerList;
|
||||||
|
|
||||||
|
public OnlinePlayer(ArrayList<String> playerList) {
|
||||||
|
this.playerList = playerList;
|
||||||
|
this.count = playerList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,16 +14,34 @@ import java.net.Socket;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
// Socket 服务器
|
// Socket 服务器
|
||||||
public class SocketServer {
|
public class SocketServer {
|
||||||
// 客户端超时时间
|
// 客户端超时时间
|
||||||
private static final int TIMEOUT = 5000;
|
private static final int TIMEOUT = 5000;
|
||||||
private static final HashMap<String, ClientThread> clientList = new HashMap<>();
|
private static final HashMap<String, ClientInfo> clientList = new HashMap<>();
|
||||||
|
|
||||||
private static final HashMap<String, Integer> clientTimeout = new HashMap<>();
|
private static final HashMap<String, Integer> clientTimeout = new HashMap<>();
|
||||||
private static Logger mLogger;
|
private static Logger mLogger;
|
||||||
|
|
||||||
|
public static HashMap<String, String> getOnlineClient() {
|
||||||
|
HashMap<String, String> onlineClient = new HashMap<>();
|
||||||
|
for (var key : clientList.entrySet()) {
|
||||||
|
onlineClient.put(key.getValue().uuid, key.getValue().clientThread.getDisplayName());
|
||||||
|
}
|
||||||
|
return onlineClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientInfo getClientInfoByUuid(String uuid) {
|
||||||
|
for (var key : clientList.entrySet()) {
|
||||||
|
if (key.getValue().uuid.equals(uuid)) {
|
||||||
|
return key.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void startServer() throws IOException {
|
public static void startServer() throws IOException {
|
||||||
int port = OpenCommandPlugin.getInstance().getConfig().socketPort;
|
int port = OpenCommandPlugin.getInstance().getConfig().socketPort;
|
||||||
mLogger = OpenCommandPlugin.getInstance().getLogger();
|
mLogger = OpenCommandPlugin.getInstance().getLogger();
|
||||||
@ -34,7 +52,7 @@ public class SocketServer {
|
|||||||
// 向全部客户端发送数据
|
// 向全部客户端发送数据
|
||||||
public static boolean sendAllPacket(BasePacket packet) {
|
public static boolean sendAllPacket(BasePacket packet) {
|
||||||
var p = SocketUtils.getPacket(packet);
|
var p = SocketUtils.getPacket(packet);
|
||||||
HashMap<String, ClientThread> old = (HashMap<String, ClientThread>) clientList.clone();
|
HashMap<String, ClientThread> old = (HashMap<String, ClientThread>) clientList.clone();
|
||||||
for (var client : old.entrySet()) {
|
for (var client : old.entrySet()) {
|
||||||
if (!client.getValue().sendPacket(p)) {
|
if (!client.getValue().sendPacket(p)) {
|
||||||
mLogger.warn("[OpenCommand] Send packet to client {} failed", client.getKey());
|
mLogger.warn("[OpenCommand] Send packet to client {} failed", client.getKey());
|
||||||
@ -49,7 +67,21 @@ public class SocketServer {
|
|||||||
var p = SocketUtils.getPacket(packet);
|
var p = SocketUtils.getPacket(packet);
|
||||||
var client = clientList.get(address);
|
var client = clientList.get(address);
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
if (client.sendPacket(p)) {
|
if (client.clientThread.sendPacket(p)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
mLogger.warn("[OpenCommand] Send packet to client {} failed", address);
|
||||||
|
clientList.remove(address);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean sendPacketAndWait(String address, BasePacket packet, SocketDataWait<?> wait) {
|
||||||
|
var p = SocketUtils.getPacketAndPackID(packet);
|
||||||
|
var client = clientList.get(address);
|
||||||
|
if (client != null) {
|
||||||
|
wait.uid = p.get(0);
|
||||||
|
if (client.clientThread.sendPacket(p.get(1), wait)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mLogger.warn("[OpenCommand] Send packet to client {} failed", address);
|
mLogger.warn("[OpenCommand] Send packet to client {} failed", address);
|
||||||
@ -66,7 +98,7 @@ public class SocketServer {
|
|||||||
var client = clientList.get(clientID);
|
var client = clientList.get(clientID);
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
socketDataWait.uid = p.get(0);
|
socketDataWait.uid = p.get(0);
|
||||||
if (!client.sendPacket(p.get(1), socketDataWait)) {
|
if (!client.clientThread.sendPacket(p.get(1), socketDataWait)) {
|
||||||
mLogger.warn("[OpenCommand] Send packet to client {} failed", clientID);
|
mLogger.warn("[OpenCommand] Send packet to client {} failed", clientID);
|
||||||
clientList.remove(clientID);
|
clientList.remove(clientID);
|
||||||
return false;
|
return false;
|
||||||
@ -97,13 +129,14 @@ public class SocketServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 客户端数据包处理
|
// 客户端数据包处理
|
||||||
private static class ClientThread extends Thread {
|
static class ClientThread extends Thread {
|
||||||
private final Socket socket;
|
private final Socket socket;
|
||||||
private InputStream is;
|
private InputStream is;
|
||||||
private OutputStream os;
|
private OutputStream os;
|
||||||
private final String address;
|
private final String address;
|
||||||
private final String token;
|
private final String token;
|
||||||
private boolean auth = false;
|
private boolean auth = false;
|
||||||
|
private String displayName = "";
|
||||||
|
|
||||||
private final HashMap<String, SocketDataWait<?>> socketDataWaitList = new HashMap<>();
|
private final HashMap<String, SocketDataWait<?>> socketDataWaitList = new HashMap<>();
|
||||||
|
|
||||||
@ -147,11 +180,12 @@ public class SocketServer {
|
|||||||
String data = SocketUtils.readString(is);
|
String data = SocketUtils.readString(is);
|
||||||
Packet packet = Grasscutter.getGsonFactory().fromJson(data, Packet.class);
|
Packet packet = Grasscutter.getGsonFactory().fromJson(data, Packet.class);
|
||||||
if (packet.type == PacketEnum.AuthPacket) {
|
if (packet.type == PacketEnum.AuthPacket) {
|
||||||
AuthPacket authPacket = Grasscutter.getGsonFactory().fromJson(data, AuthPacket.class);
|
AuthPacket authPacket = Grasscutter.getGsonFactory().fromJson(packet.data, AuthPacket.class);
|
||||||
if (authPacket.token.equals(token)) {
|
if (authPacket.token.equals(token)) {
|
||||||
auth = true;
|
auth = true;
|
||||||
mLogger.info("[OpenCommand] Client {} auth success", address);
|
displayName = authPacket.displayName;
|
||||||
clientList.put(address, this);
|
mLogger.info("[OpenCommand] Client {} auth success, name: {}", address, displayName);
|
||||||
|
clientList.put(address, new ClientInfo(UUID.randomUUID().toString(), address, this));
|
||||||
clientTimeout.put(address, 0);
|
clientTimeout.put(address, 0);
|
||||||
} else {
|
} else {
|
||||||
mLogger.warn("[OpenCommand] Client {} auth failed", address);
|
mLogger.warn("[OpenCommand] Client {} auth failed", address);
|
||||||
@ -196,6 +230,10 @@ public class SocketServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待客户端连接
|
// 等待客户端连接
|
||||||
|
@ -17,12 +17,12 @@ public class SocketUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取打包后的数据包
|
* 获取打包后的数据包
|
||||||
|
*
|
||||||
* @param bPacket 数据包
|
* @param bPacket 数据包
|
||||||
* @return 打包后的数据包
|
* @return 打包后的数据包
|
||||||
*/
|
*/
|
||||||
public static String getPacket(BasePacket bPacket) {
|
public static String getPacket(BasePacket bPacket) {
|
||||||
Packet packet = new Packet();
|
Packet packet = new Packet();
|
||||||
packet.token = OpenCommandPlugin.getInstance().getConfig().socketToken;
|
|
||||||
packet.type = bPacket.getType();
|
packet.type = bPacket.getType();
|
||||||
packet.data = bPacket.getPacket();
|
packet.data = bPacket.getPacket();
|
||||||
packet.packetID = UUID.randomUUID().toString();
|
packet.packetID = UUID.randomUUID().toString();
|
||||||
@ -31,12 +31,12 @@ public class SocketUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取打包后的数据包
|
* 获取打包后的数据包
|
||||||
|
*
|
||||||
* @param bPacket BasePacket
|
* @param bPacket BasePacket
|
||||||
* @return list[0] 是包ID, list[1] 是数据包
|
* @return list[0] 是包ID, list[1] 是数据包
|
||||||
*/
|
*/
|
||||||
public static List<String> getPacketAndPackID(BasePacket bPacket) {
|
public static List<String> getPacketAndPackID(BasePacket bPacket) {
|
||||||
Packet packet = new Packet();
|
Packet packet = new Packet();
|
||||||
packet.token = OpenCommandPlugin.getInstance().getConfig().socketToken;
|
|
||||||
packet.type = bPacket.getType();
|
packet.type = bPacket.getType();
|
||||||
packet.data = bPacket.getPacket();
|
packet.data = bPacket.getPacket();
|
||||||
packet.packetID = UUID.randomUUID().toString();
|
packet.packetID = UUID.randomUUID().toString();
|
||||||
@ -49,13 +49,13 @@ public class SocketUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取打包后的数据包
|
* 获取打包后的数据包
|
||||||
* @param bPacket 数据包
|
*
|
||||||
|
* @param bPacket 数据包
|
||||||
* @param packetID 数据包ID
|
* @param packetID 数据包ID
|
||||||
* @return 打包后的数据包
|
* @return 打包后的数据包
|
||||||
*/
|
*/
|
||||||
public static String getPacketAndPackID(BasePacket bPacket, String packetID) {
|
public static String getPacketAndPackID(BasePacket bPacket, String packetID) {
|
||||||
Packet packet = new Packet();
|
Packet packet = new Packet();
|
||||||
packet.token = OpenCommandPlugin.getInstance().getConfig().socketToken;
|
|
||||||
packet.type = bPacket.getType();
|
packet.type = bPacket.getType();
|
||||||
packet.data = bPacket.getPacket();
|
packet.data = bPacket.getPacket();
|
||||||
packet.packetID = packetID;
|
packet.packetID = packetID;
|
||||||
@ -64,6 +64,7 @@ public class SocketUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 读整数
|
* 读整数
|
||||||
|
*
|
||||||
* @param is 输入流
|
* @param is 输入流
|
||||||
* @return 整数
|
* @return 整数
|
||||||
*/
|
*/
|
||||||
@ -77,32 +78,34 @@ public class SocketUtils {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
return values[0]<<24 | values[1]<<16 | values[2]<<8 | values[3];
|
return values[0] << 24 | values[1] << 16 | values[2] << 8 | values[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写整数
|
* 写整数
|
||||||
* @param os 输出流
|
*
|
||||||
|
* @param os 输出流
|
||||||
* @param value 整数
|
* @param value 整数
|
||||||
*/
|
*/
|
||||||
public static void writeInt(OutputStream os, int value) {
|
public static void writeInt(OutputStream os, int value) {
|
||||||
int[] values = new int[4];
|
int[] values = new int[4];
|
||||||
values[0] = (value>>24)&0xFF;
|
values[0] = (value >> 24) & 0xFF;
|
||||||
values[1] = (value>>16)&0xFF;
|
values[1] = (value >> 16) & 0xFF;
|
||||||
values[2] = (value>>8)&0xFF;
|
values[2] = (value >> 8) & 0xFF;
|
||||||
values[3] = (value)&0xFF;
|
values[3] = (value) & 0xFF;
|
||||||
|
|
||||||
try{
|
try {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
os.write(values[i]);
|
os.write(values[i]);
|
||||||
}
|
}
|
||||||
}catch (IOException e){
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读字符串
|
* 读字符串
|
||||||
|
*
|
||||||
* @param is 输入流
|
* @param is 输入流
|
||||||
* @return 字符串
|
* @return 字符串
|
||||||
*/
|
*/
|
||||||
@ -120,15 +123,16 @@ public class SocketUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 写字符串
|
* 写字符串
|
||||||
|
*
|
||||||
* @param os 输出流
|
* @param os 输出流
|
||||||
* @param s 字符串
|
* @param s 字符串
|
||||||
* @return 是否成功
|
* @return 是否成功
|
||||||
*/
|
*/
|
||||||
public static boolean writeString(OutputStream os,String s) {
|
public static boolean writeString(OutputStream os, String s) {
|
||||||
try {
|
try {
|
||||||
byte[] bytes = s.getBytes();
|
byte[] bytes = s.getBytes();
|
||||||
int len = bytes.length;
|
int len = bytes.length;
|
||||||
writeInt(os,len);
|
writeInt(os, len);
|
||||||
os.write(bytes);
|
os.write(bytes);
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -4,8 +4,10 @@ import emu.grasscutter.Grasscutter;
|
|||||||
|
|
||||||
public class AuthPacket extends BasePacket {
|
public class AuthPacket extends BasePacket {
|
||||||
public String token;
|
public String token;
|
||||||
|
public String displayName;
|
||||||
|
|
||||||
public AuthPacket(String token) {
|
public AuthPacket(String token, String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,4 +20,9 @@ public class AuthPacket extends BasePacket {
|
|||||||
public PacketEnum getType() {
|
public PacketEnum getType() {
|
||||||
return PacketEnum.AuthPacket;
|
return PacketEnum.AuthPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AuthPacket [token=" + token + ", displayName=" + displayName + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import emu.grasscutter.Grasscutter;
|
|||||||
|
|
||||||
// http返回数据
|
// http返回数据
|
||||||
public class HttpPacket extends BasePacket {
|
public class HttpPacket extends BasePacket {
|
||||||
public int code;
|
public int code = 200;
|
||||||
public String message;
|
public String message = "Success";
|
||||||
public String data;
|
public String data;
|
||||||
|
|
||||||
public HttpPacket(int code, String message, String data) {
|
public HttpPacket(int code, String message, String data) {
|
||||||
@ -18,6 +18,9 @@ public class HttpPacket extends BasePacket {
|
|||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
public HttpPacket(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPacket() {
|
public String getPacket() {
|
||||||
|
@ -2,13 +2,12 @@ package com.github.jie65535.opencommand.socket.packet;
|
|||||||
|
|
||||||
// 数据包结构
|
// 数据包结构
|
||||||
public class Packet {
|
public class Packet {
|
||||||
public String token;
|
|
||||||
public PacketEnum type;
|
public PacketEnum type;
|
||||||
public String data;
|
public String data;
|
||||||
public String packetID;
|
public String packetID;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Packet [token=" + token + ", type=" + type + ", data=" + data + ", packetID=" + packetID + "]";
|
return "Packet [type=" + type + ", data=" + data + ", packetID=" + packetID + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,6 @@ public enum PacketEnum {
|
|||||||
Player,
|
Player,
|
||||||
HttpPacket,
|
HttpPacket,
|
||||||
AuthPacket,
|
AuthPacket,
|
||||||
|
RunConsoleCommand,
|
||||||
HeartBeat
|
HeartBeat
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.github.jie65535.opencommand.socket.packet;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
|
||||||
|
public class RunConsoleCommand extends BasePacket {
|
||||||
|
public String command;
|
||||||
|
|
||||||
|
public RunConsoleCommand(String command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPacket() {
|
||||||
|
return Grasscutter.getGsonFactory().toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PacketEnum getType() {
|
||||||
|
return PacketEnum.RunConsoleCommand;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user