Repository navigation
Development Guide
面向在 SLDataAPI 仓库贡献功能的开发者。
main 当前版本:2.6.1 RIDGE(预发布,tag v2.6.1_RIDGE,正式发布后可用);稳定版 2.6.0 PEAK(tag v2.6.0_PEAK)。
DevKit:Release 附件 SLDataAPI-DevKit-v2.6.1_RIDGE.zip(含内测端点清单;2.6.1 Release 发布后可下载)或 SLDataAPI-DevKit-v2.6.0_PEAK.zip(sl-dataapi-dev skill + 冒烟脚本)。
| 目录 | 命名空间 | 职责 |
|---|---|---|
Plugin.cs |
SLDataAPI |
Enable/Disable、事件订阅、服务启动顺序 |
Config.cs |
SLDataAPI |
config.yml 属性(snake_case) |
Data/ |
SLDataAPI.Data |
HTTP/WS JSON DTO |
Control/ |
SLDataAPI.Control |
路由 ControlController、WS WsControlService、ControlAuth
|
Auth/ |
SLDataAPI.Auth |
ApiKeyService、EndpointAcl、RemoteCommandGuard
|
Commands/ |
SLDataAPI.Commands |
sldataapi / apikey(本地 only) |
Services/ |
SLDataAPI.Services |
HttpServer、DataCollector、MainThreadExecutor、ReportService、ControlLogService、WebDavUploader、UpdateChecker… |
Voice/ |
SLDataAPI.Voice |
SPY 转发 + 录音 |
Map/ |
SLDataAPI.Map |
seed/layout/export |
Integrations/ |
SLDataAPI.Integrations |
EXILED 反射、第三方插件探测、PluginEndpointRegistry(适配插件注册表) |
Capture/ |
SLDataAPI.Capture |
控制台输出 Harmony 补丁 |
examples/AdaptedPluginSample/ |
— | 适配插件注册示例 |
架构:Architecture。编译发布:Building。
LabAPI 事件 handler 必须整体 try/catch,异常 Log.Error 后吞掉,不得抛回游戏。参考 Plugin.OnRoundStarted。
var result = MainThreadExecutor.RunOnMainThread(() =>
{
// Unity / Mirror API
return (200, Json(true, "ok", data));
}, out Exception err);
if (err != null)
return (400, Json(false, err.Message));纯文件、鉴权校验、序列化可不派发。超时后设置取消标志,迟到的 action 不得再执行。
ControlController.Handle 顶层 catch → 500 "内部错误"。不向客户端返回堆栈、绝对路径。
C# ReportMaxRecords → YAML report_max_records。单字段错误可能导致整文件回退默认。
功能块用注释标版本,例如:
// ===== 举报(v2.5.4 推出)=====Plugin.Version 为单一真相(2.6.1 · RIDGE);SLDataAPI.csproj 的 Version / InformationalVersion、README / Wiki / Release tag 对齐。新功能注释写成「v2.6.1 推出,代号 RIDGE」。新文件顶部加 SPDX 头:
// SPDX-License-Identifier: GPL-3.0-only
// Copyright (C) 2026 DNT_OF (https://github.com/DNTOF/SLDataAPI)-
Data/ControlModels.cs:新增请求类(JSON 属性 snake_case)。 -
ControlController.Handle:switch注册 path(RA 对齐路径)。 -
实现
XxxAction(string body):Parse<T>→ 校验 →MainThreadExecutor→(status, Json(...))。 -
鉴权:
ApiKeyService.TryAuthenticate(Bearer /X-SLDataAPI-Key)+EndpointAcl。 -
审计:侵入性写操作经
ControlLogService(若启用)。 - 文档:更新 HTTP-API;历史对照仍见 Old-HTTP-API。
-
WS:无需 duplicate——
call.path与 HTTP 相同即自动兼容。
参考:ReportsAction、MapFacilityAction、broadcast / staffchat。
未实现:Stub501("name")。当前仍为 501:/control/player/inventory、/control/dummies。
已实现:/control/broadcast、/control/staffchat。
RemoteCommandGuard 拦截经控制通道执行的 sldataapi/slda。新增本地管理命令应注册在 Commands/ 并默认拒绝远程。
第三方 LabAPI 插件引用 SLDataAPI.dll(编译期引用即可,部署时与 SLDataAPI 同放 LabAPI/plugins/global/),在 Enable 里注册、Disable 里注销。完整示例见仓库 examples/AdaptedPluginSample。
bool ok = PluginEndpointRegistry.TryRegister(
id: "dntof.sample_adapted", // ^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$,建议反向域名
name: "Adapted Plugin Sample",
version: Version.ToString(),
capabilities: new[] { "sample.hello" }, // ≤32
statusCallback: () => JsonConvert.SerializeObject(new { ok = true }), // ≤4KB
routes: new List<AdaptedRoute> // ≤16;GET /plugins/<id>/<route>
{
new AdaptedRoute { Path = "hello", Handler = _ => "{\"ok\":true}" },
},
out string error);先 TryRegister,再调用 TryRegisterActions 追加动作(每次调用替换该插件此前的全部动作;每插件 ≤16)。动作经控制面 POST /control/adapted/<id>/<action> 调用,只有服务器打开 beta_adapted_plugin_actions 且调用方 Key 显式获得 /control/adapted/ 授权时才可达(见 Beta-Features)。
为兼容旧版 SLDataAPI(没有 TryRegisterActions),把调用隔离在单独的方法里并标 NoInlining,捕获 MissingMethodException / TypeLoadException 后退回只读:
using System.Runtime.CompilerServices;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SLDataAPI.Integrations;
private static int _bumps;
public override void Enable()
{
// ……先 TryRegister(见上)……
try { RegisterActions(); }
catch (MissingMethodException) { Logger.Info("SLDataAPI 版本过旧,仅只读"); }
catch (TypeLoadException) { Logger.Info("SLDataAPI 版本过旧,仅只读"); }
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void RegisterActions()
{
bool ok = PluginEndpointRegistry.TryRegisterActions("dntof.sample_adapted", new List<AdaptedAction>
{
new AdaptedAction
{
Path = "echo", // ^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$
Description = "原样返回请求体与调用方信息",
Handler = req => JsonConvert.SerializeObject(new
{
echo = JToken.Parse(req.BodyJson), // 空请求体时为 "{}"
actor = req.Actor, // 调用方 API Key 的 id
transport = req.Transport, // "http" 或 "ws"
}),
},
new AdaptedAction
{
Path = "bump",
Description = "计数器 +by(1..100)",
Handler = req =>
{
int by = 1;
try
{
var body = JObject.Parse(req.BodyJson);
if (body["by"] != null) by = (int)body["by"]!;
}
catch (Exception) { throw new AdaptedActionException("body must be {\"by\": <int>}"); }
if (by < 1 || by > 100)
throw new AdaptedActionException("by must be 1..100"); // → 400;可传第二个参数指定 4xx
return JsonConvert.SerializeObject(new { bumps = Interlocked.Add(ref _bumps, by) });
},
},
}, out string error);
if (!ok) Logger.Warn($"action register failed: {error}");
}
public override void Disable() => PluginEndpointRegistry.Unregister("dntof.sample_adapted");要点:
- 处理器在 Unity 主线程执行,超时 3s;不要做阻塞 IO 或长计算。
- 请求体(
BodyJson)与返回值各 ≤64KB;返回 JSON 字符串,返回null表示无返回体;非 JSON 文本会被当作字符串。 - 要以特定状态码拒绝时抛
AdaptedActionException(message, statusCode)(400–499,默认 400);其他异常一律 500action handler error,堆栈不会回给客户端。 - 每次调用都会写入
control_log;插件可以用req.Actor做自己的二次授权或记录。 - 内置包装 id(
dntof.sl_player、dntof.omega_warhead)不能追加动作。 - 适配插件可能先于 SLDataAPI 启用;动作是否对外由 SLDataAPI 运行时判断开关,注册时机不受影响。
模式见 Services/ReportService.cs(UserSettings.ServerSpecific):
| 控件 | 用途 |
|---|---|
SSGroupHeader |
分组标题 |
SSDropdownSetting |
下拉 |
SSPlaintextSetting |
文本 |
SSButton + holdTimeSeconds
|
长按提交 |
流程:DefinedSettings → SendToAll();ServerOnSettingValueReceived 在主线程按 SettingId 处理。
注意:DefinedSettings 全局单例,与其他插件可能冲突。
先本地执行 sldataapi apikey create <id> admin,再:
curl -s -X POST "http://127.0.0.1:8081/control/broadcast" \
-H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" \
-d '{"message":"ping","duration_seconds":5}'
curl -s "http://127.0.0.1:8081/get_sl_data" \
-H "Authorization: Bearer <verify_token>"DevKit 冒烟:
.\scripts\Test-ControlEndpoints.ps1 -BaseUrl http://127.0.0.1:8081 `
-VerifyToken "<verify_token>" -ApiKey "<admin_key>"仅对自有服务器;勿把真实密钥写进脚本。
dotnet test tests/SLDataAPI.Auth.Tests
dotnet test tests/SLDataAPI.Update.Tests
dotnet test tests/SLDataAPI.WebDav.TestsWS:握手带 Bearer。见 WS-Control-Protocol。
| 内容 | 页面 |
|---|---|
| 现行 HTTP / 控制 | HTTP-API |
| 内测功能(2.6.1) | Beta-Features |
| 安全 / 配置 / 构建 | Security-Model · Configuration · Building |
| 历史 2.5 对照 | Old-HTTP-API |
见 Building。正式 Release 请用带 key.snk 的本机构建并核对公钥令牌后再上传附件。DevKit zip 与 DLL 一并挂到对应 tag。
SLDataAPI Wiki
- Home
- 接口
- HTTP-API
- WS-Control-Protocol
- Beta-Features(2.6.1 RIDGE 内测)
- Old-HTTP-API(2.5.x 历史)
- 语音
- 运维
- 开发