{"id":20120925,"url":"https://github.com/jie65535/gc-opencommand-plugin","last_synced_at":"2025-04-05T09:09:13.763Z","repository":{"id":37700564,"uuid":"491711999","full_name":"jie65535/gc-opencommand-plugin","owner":"jie65535","description":"A plugin that open the GC command execution interface for third-party clients","archived":false,"fork":false,"pushed_at":"2024-05-31T10:49:59.000Z","size":170,"stargazers_count":378,"open_issues_count":1,"forks_count":55,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-29T08:07:29.150Z","etag":null,"topics":["grasscutter","grasscutter-plugin","java"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jie65535.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-13T00:52:57.000Z","updated_at":"2025-03-29T01:45:39.000Z","dependencies_parsed_at":"2025-02-10T20:44:40.997Z","dependency_job_id":"50aa7d00-2d3e-4eb8-8ca8-8ec5923bc79a","html_url":"https://github.com/jie65535/gc-opencommand-plugin","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jie65535%2Fgc-opencommand-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jie65535%2Fgc-opencommand-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jie65535%2Fgc-opencommand-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jie65535%2Fgc-opencommand-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jie65535","download_url":"https://codeload.github.com/jie65535/gc-opencommand-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247312081,"owners_count":20918344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grasscutter","grasscutter-plugin","java"],"created_at":"2024-11-13T19:24:18.930Z","updated_at":"2025-04-05T09:09:13.728Z","avatar_url":"https://github.com/jie65535.png","language":"Java","readme":"# gc-opencommand-plugin\n\n中文 | [English](README_en-US.md)\n\n一个为第三方客户端开放GC命令执行接口的插件\n\n自 `1.7.0` 起可以通过 `|` 或者换行来分隔多条命令，例如：\n```shell\n/a 1 | /a 2\n/a 3\n```\n\n调用 `ping` 响应数据将包含插件版本号。\n\n## 使用本插件的应用\n- [GrasscutterTools](https://github.com/jie65535/GrasscutterCommandGenerator) —— Windows 客户端工具\n- [JGrasscutterCommand](https://github.com/jie65535/JGrasscutterCommand) —— [Mirai](https://github.com/mamoe/mirai) 插件，在QQ里执行命令\n- [Yunzai-GrasscutterCommand](https://github.com/Zyy-boop/Yunzai-GrasscutterCommand) —— Yunzai-bot插件，在QQ里执行命令\n- 待补充\n\n## 服务端安装\n\n1. 在 [Release](https://github.com/jie65535/gc-opencommand-plugin/releases) 下载 `jar`\n2. 放入 `grasscutter/plugins` 文件夹\n3. 重启 `grasscutter` 即可生效\n\n## 玩家使用流程\n\n1. 在远程工具中填写服务地址，查询插件状态\n2. 填写UID，发送验证码（需要在线）\n3. 将游戏内收到的**4位整数验证码**填入工具校验\n4. 享受便利！\n\n## 控制台连接\n\n1. 首次启动时，会在 `plugins` 目录下生成一个 `opencommand-plugin` 目录，打开并编辑 `config.json`\n2. 设置 `consoleToken` 的值为你的连接秘钥，建议使用至少32字符的长随机字符串。（检测到为空时会自动生成，生成时会在控制台中输出）\n3. 重新启动服务端即可生效配置\n4. 在工具中选择控制台身份，并填写你的 `consoleToken` 即可以控制台身份运行指令\n\n---\n\n## 客户端请求流程\n\n1. `ping` 确认是否支持 `opencommand` 插件\n2. `sendCode` 向指定玩家发送验证码（1分钟内不允许重发），保存返回的 `token`\n3. 使用 `token` 和**4位整数验证码**发送 `verify` 校验\n4. 如果验证通过，可以使用该 `token` 执行 `command` 动作\n\n## 插件构建说明\n\n1. 克隆仓库\n2. 在目录下新建 `lib` 目录\n3. 将 `grasscutter.jar` 放入 `lib` 目录\n4. 执行 `gradle build`\n\n## 多服务器\n### 主服务器 (Dispatch)\n1. 在 `opencommand-plugin` 目录下打开 `config.json`\n2. 修改 `socketPort` 值为一个未被使用的端口\n3. 设置 `socketToken` 多服务器通信密钥，建议使用至少32字符的长随机字符串。\n4. 重新启动服务端即可生效配置\n\n### 子服务器 (Game)\n1. 在 `opencommand-plugin` 目录下打开 `config.json`\n2. 修改 `socketHost` 和 `socketPort` 值为主服务器的地址和端口\n3. 设置 `socketToken` 和主服务器相同的值\n4. 设置 `socketDisplayName` 值为你的服务器名称 (用途请见[下方](https://github.com/jie65535/gc-opencommand-plugin#%E8%8E%B7%E5%8F%96%E5%A4%9A%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%88%97%E8%A1%A8))\n5. 重新启动服务端即可生效配置\n\n---\n\n## `config.json`\n\n```json5\n{\n  // 控制台连接令牌（检测到空时会自动生成）\n  \"consoleToken\": \"\",\n  // 验证码过期时间（秒）\n  \"codeExpirationTime_S\": 60,\n  // 临时令牌过期时间（秒）\n  \"tempTokenExpirationTime_S\": 300,\n  // 授权令牌最后使用过期时间（小时）\n  \"tokenLastUseExpirationTime_H\": 48,\n  // 多服务器通信端口\n  \"socketPort\": 5746,\n  // 多服务器通信密钥\n  \"socketToken\": \"\",\n  // 多服务器Dispatch服务器地址\n  \"socketHost\": \"127.0.0.1\",\n  // 多服务器显示名称\n  \"socketDisplayName\": \"\"\n}\n```\n\n## API `/opencommand/api`\n\n示例\n\n```\nhttps://127.0.0.1/opencommand/api\n```\n\n### Request 请求\n\n```java\npublic final class JsonRequest {\n    public String token = \"\";\n    public String action = \"\";\n    public String server = \"\";\n    public Object data = null;\n}\n```\n\n### Response 响应\n\n```java\npublic final class JsonResponse {\n    public int retcode = 200;\n    public String message = \"Success\";\n    public Object data;\n}\n```\n\n### Actions 动作\n\n#### `测试连接`\n\n##### Request\n\n| 请求参数   | 请求数据   | 类型       |\n|--------|--------|----------|\n| action | `ping` | `String` |\n\n##### Response\n\n| 返回参数    | 返回数据      | 类型       |\n|---------|-----------|----------|\n| retcode | `200`     | `Int`    |\n| message | `Success` | `String` |\n| data    | `null`    | `null`   |\n\n#### `获取在线玩家`\n\n##### Request\n\n| 请求参数   | 请求数据     | 类型       |\n|--------|----------|----------|\n| action | `online` | `String` |\n\n##### Response\n\n| 返回参数    | 返回数据                            | 类型           |\n|---------|---------------------------------|--------------|\n| retcode | `200`                           | `Int`        |\n| message | `Success`                       | `String`     |\n| data    | `{\"count\": 0, playerList\": []}` | `JsonObject` |\n\n#### `发送验证码`\n\n##### Request\n\n| 请求参数   | 请求数据       | 类型       |\n|--------|------------|----------|\n| action | `sendCode` | `String` |\n| data   | `uid`      | `Int`    |\n\n##### Response\n\n| 返回参数    | 返回数据      | 类型       |\n|---------|-----------|----------|\n| retcode | `200`     | `Int`    |\n| message | `Success` | `String` |\n| data    | `token`   | `String` |\n\n#### `验证验证码`\n\n##### Request\n\n| 请求参数   | 请求数据     | 类型       |\n|--------|----------|----------|\n| action | `verify` | `String` |\n| token  | `token`  | `String` |\n| data   | `code`   | `Int`    |\n\n##### Response\n\n成功\n\n| 返回参数    | 返回数据      | 类型       |\n|---------|-----------|----------|\n| retcode | `200`     | `Int`    |\n| message | `Success` | `String` |\n| data    | `null`    | `null`   |\n\n失败\n\n| 返回参数    | 返回数据                  | 类型       |\n|---------|-----------------------|----------|\n| retcode | `400`                 | `Int`    |\n| message | `Verification failed` | `String` |\n| data    | `null`                | `null`   |\n\n#### `执行命令`\n\n##### Request\n\n| 请求参数   | 请求数据      | 类型       |\n|--------|-----------|----------|\n| action | `command` | `String` |\n| token  | `token`   | `String` |\n| data   | `command` | `String` |\n\n##### Response\n\n成功\n\n| 返回参数    | 返回数据             | 类型       |\n|---------|------------------|----------|\n| retcode | `200`            | `Int`    |\n| message | `Success`        | `String` |\n| data    | `Command return` | `String` |\n\n### 执行控制台命令\n\n#### `获取运行模式`\n\n##### Request\n\n| 请求参数   | 请求数据      | 类型       |\n|--------|-----------|----------|\n| action | `runmode` | `String` |\n| token  | `token`   | `String` |\n\n##### Response\n\n成功\n\n| 返回参数    | 返回数据                  | 类型       |\n|---------|-----------------------|----------|\n| retcode | `200`                 | `Int`    |\n| message | `Success`             | `String` |\n| data    | `1 (多服务器) / 0 (单服务器)` | `Int`    |\n\n#### `获取多服务器列表`\n\n##### Request\n\n| 请求参数   | 请求数据     | 类型       |\n|--------|----------|----------|\n| action | `server` | `String` |\n| token  | `token`  | `String` |\n\n##### Response\n\n成功\n\n| 返回参数    | 返回数据      | 类型           |\n|---------|-----------|--------------|\n| retcode | `200`     | `Int`        |\n| message | `Success` | `String`     |\n| data    | `{}`      | `JsonObject` |\n\n```json5\n{\n  \"retcode\": 200,\n  \"message\": \"success\",\n  \"data\": {\n    // 服务器 UUID\n    \"13d82d0d-c7d9-47dd-830c-76588006ef6e\": \"2.8.0 服务器\",\n    \"e6b83224-a761-4023-be57-e054c5bb823a\": \"2.8.0 开发服务器\"\n  }\n}\n```\n\n#### `执行命令`\n\n##### Request\n\n\u003e 如果为单服务器则无需填写服务器 UUID\n\n| 请求参数   | 请求数据      | 类型       |\n|--------|-----------|----------|\n| action | `command` | `String` |\n| token  | `token`   | `String` |\n| server | `UUID`    | `String` |\n| data   | `command` | `String` |\n\n##### Response\n\n成功\n\n| 返回参数    | 返回数据             | 类型       |\n|---------|------------------|----------|\n| retcode | `200`            | `Int`    |\n| message | `Success`        | `String` |\n| data    | `Command return` | `String` |\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjie65535%2Fgc-opencommand-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjie65535%2Fgc-opencommand-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjie65535%2Fgc-opencommand-plugin/lists"}