-
-
Notifications
You must be signed in to change notification settings - Fork 0
Beta Features
2.6.1 RIDGE 是预发布版本(GitHub Pre-release,tag v2.6.1_RIDGE,正式发布后可用)。本页的两项功能默认全部关闭;不开开关时行为与稳定版 2.6.0 PEAK 一致(文件沙箱的链接防护除外,见 Security-Model)。
内测功能只在维护者本机做过加载冒烟与无鉴权探测,带鉴权的端到端流程尚未完整测试。请只在测试服打开开关,发现问题请 开 Issue。
键(config.yml) |
默认 | 打开后 |
|---|---|---|
beta_adapted_plugin_actions |
false |
POST /control/adapted/<plugin_id>/<action> 可用;/plugins/adapted 列出 actions
|
beta_file_root_ws |
false |
/control/files/stat、read_chunk、write_chunk 可用(仍需配置 file_root) |
- 升级到 2.6.1 后首次加载,LabAPI 会把两个键以
false写进config.yml。 - 改完必须重启服务器才生效(见 Configuration)。
- 开关关闭时,上述端点一律 404(
内测端点未开启(config: ...: false))。 - 打开任一开关时,启动日志会打一条
[SLDataAPI] 内测功能已开启……警告。 - 两类端点都属于控制面:需
control_enabled: true,HTTP/control/*与 WScall走同一路由(受control_transport互斥约束),鉴权、ACL、审计与其他/control/*一致。
新增 / 涉及的端点默认拒绝,内置 admin、duty 模板以及 all_control_true 都不会自动授予:
| ACL 键 | 覆盖 | 默认 |
|---|---|---|
/control/adapted/ |
全部适配插件动作 | 拒绝 |
/control/adapted/<plugin_id>/ |
单个插件的全部动作 | 未定义(按上一条) |
/control/adapted/<plugin_id>/<action> |
单个动作(精确) | 未定义 |
/control/files/ |
files/list|read|write 与新增的 stat|read_chunk|write_chunk
|
拒绝 |
按 Key 显式放开(apikey.config → keys[].endpoints_override,最长前缀匹配,越具体越优先):
keys:
- id: platform
template: admin
fingerprint: "sha256:..." # 由 sldataapi apikey create 写入,勿手改
endpoints_override:
"/control/adapted/dntof.sample_adapted/": true # 只放开示例插件
"/control/files/": { read: true, write: false } # 文件只读(stat / read_chunk / list / read)- 全部适配插件:
"/control/adapted/": true;在全放开的同时禁掉某个插件:再加"/control/adapted/<id>/": false。 - 读写判定:
files/stat、files/read_chunk(及list、read)算读;files/write_chunk与全部/control/adapted/*一律算写。 - 修改
apikey.config后建议重启服务器。也可以改文件里的endpoint_catalog让 admin 模板默认获得/control/adapted/,但不推荐——按 Key 授权更可控。
在只读发现(GET /plugins/adapted、GET /plugins/<id>/<route>,见 HTTP-API)之外,适配插件可以注册写 / 动作路由,经控制面调用。插件侧用法见 Development-Guide · 适配插件集成。
curl -s -X POST "http://<host>:8081/control/adapted/dntof.sample_adapted/bump" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"by":3}'WS(control_transport: ws):
{"type":"call","reqId":"a1","path":"/control/adapted/dntof.sample_adapted/bump","body":{"by":3}}| 项 | 值 |
|---|---|
| 路径 |
/control/adapted/<plugin_id>/<action>,恰好两段;plugin_id 形如 ^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$,action 形如 ^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$(大小写不敏感匹配) |
| 请求体 | 任意 JSON(空体视为 {}),≤64KB;非 JSON → 400 |
| 执行 | Unity 主线程,超时 3s |
| 每插件动作数 | ≤16 |
| 审计 | 一律按写操作,每次调用写入 control_log(actor = Key id) |
| 插件返回体 | ≤64KB;非 JSON 文本按字符串返回 |
成功(200):
{"success":true,"message":"ok","data":{"plugin_id":"dntof.sample_adapted","action":"bump","result":{"bumps":3}}}result 为插件返回的 JSON;插件返回 null 时为 null。
| 状态 | 场景 |
|---|---|
| 400 | 请求体不是 JSON;路径字符非法;插件抛 AdaptedActionException(默认 400) |
| 4xx | 插件抛 AdaptedActionException(message, statusCode)(仅 400–499 生效,其他值按 400) |
| 403 | Key 未获授权(见上文 ACL) |
| 404 | 开关关闭;路径不是两段;插件未注册;动作不存在 |
| 413 | 请求体或返回体超过 64KB |
| 500 | 插件处理器抛出其他异常 |
| 504 | 主线程派发超时 / 失败 |
失败时 message 为插件或注册表给出的原因(如 by must be 1..100、action not found)。
开关打开时,GET /plugins/adapted 与 get_sl_data.adapted_plugins[*] 每项多一个 actions 字段(动作名数组;内置探测包装 SLPlayer / OmegaWarhead 为 [],且不能追加动作)。开关关闭时该字段整体省略,只读发现的结构不变。
原有 files/list|read|write 本来就能走 WS call,但单条消息有上限(WS 256KB、HTTP 请求体 64KB),而文件读上限 1MB、写上限 512KB,接近上限的配置文件无法一次传完。新增三个端点用分块解决。
共同约束(与原文件端点完全一致):
- 必须配置
file_root(为空 → 404文件端点未启用) - 路径相对
file_root;拒绝..越界、:、符号链接 / junction;禁止 Windows 系统目录、游戏数据目录、SLDataAPI 自身配置目录 - 只允许配置类扩展名:
yml yaml txt json cfg ini conf config xml properties - 参数错误统一 400 + 中文
message - 纯 IO,不派发主线程
请求:{"path":"configs/a.yml"}
文件:
{"path":"configs/a.yml","type":"file","size":1234,"modified":"2026-10-04 01:02:03","protected":false,
"sha256":"<hex>","max_read_bytes":1048576,"max_write_bytes":524288,"max_chunk_bytes":163840}目录:{"path":"configs","type":"dir","size":0,"modified":"...","protected":false,"sha256":null}(protected 为 true 表示受保护目录)。
modified 为 UTC,格式 yyyy-MM-dd HH:mm:ss。文件超过 1MB 时 sha256 为 null。非配置扩展名的文件 → 400。
| 字段 | 说明 |
|---|---|
path |
必填 |
offset |
可选,默认 0;须在 0..size 内 |
length |
可选,默认 65536;上限 163840(160KB),超出按上限截断 |
响应 data:
{"path":"configs/a.yml","size":300000,"offset":0,"length":65536,"next_offset":65536,"eof":false,
"data":"<base64>","sha256":"<整文件 sha256,仅 offset 为 0 时给出,否则 null>"}循环用 next_offset 续读直到 eof: true;拼接后与首块的 sha256 比对。文件 >1MB 拒绝读取。
分块上传会话:
| 字段 | 说明 |
|---|---|
path |
必填;每块都要带,且与会话一致 |
action |
可选:append(默认)/ abort
|
upload_id |
首块省略(服务器新建会话并返回);后续块必填 |
offset |
本块起始字节;必须等于已接收字节数(首块为 0) |
data |
本块内容,base64 |
final |
可选 bool;为 true 时提交写入 |
sha256 |
可选;final 时校验整份内容(hex,大小写不敏感),不符则不写入 |
限制:整份 ≤512KB;会话 120s 无活动过期;每把 Key 最多 2 个未完成会话,全服最多 8 个;会话绑定 Key 与 path。内容必须是合法 UTF-8 文本;提交时先写同目录临时文件再替换(原子写入)。首块就会做完全部写入防线检查,越界或受保护路径立即拒绝。
响应 data:
| 场景 | data |
|---|---|
| 非最后一块 | {"upload_id":"up_<hex>","received":65536,"committed":false} |
final: true |
{"upload_id":"up_...","received":300000,"committed":true,"file":{"path":"...","bytes":300000,"sha256":"<hex>"}} |
action: "abort" |
{"upload_id":"up_...","aborted":true}(只能取消自己 Key 的会话;不存在或已过期时 aborted:false) |
单块大小建议:WS 下 ≤160KB 原始字节(base64 后仍在 256KB 消息上限内);HTTP 下请求体 ≤64KB,单块约 ≤45KB。
审计:write_chunk 每次调用都记入 control_log,但其中的 data 只记录长度(<base64 N chars>),避免撑大日志。stat / read_chunk 是读操作,不记审计。
服务器卸载插件(重启)时,未完成的上传会话全部丢弃。
控制 WS 握手后的 hello 新增 beta,列出当前已开启的内测能力:
{"type":"hello","server":"SLDataAPI","version":"2.6.1","endpoints":"/control/*","beta":["adapted_actions","file_chunks"]}| 值 | 对应开关 |
|---|---|
adapted_actions |
beta_adapted_plugin_actions |
file_chunks |
beta_file_root_ws |
都关闭时为 []。平台可据此决定是否展示相关 UI;file_chunks 只表示开关已开,file_root 是否配置请以 files/stat 的结果为准。协议其余部分见 WS-Control-Protocol。
相关:HTTP-API · Configuration · Security-Model · Development-Guide
SLDataAPI Wiki
- Home
- 接口
- HTTP-API
- WS-Control-Protocol
- Beta-Features(2.6.1 RIDGE 内测)
- Old-HTTP-API(2.5.x 历史)
- 语音
- 运维
- 开发