-
-
Notifications
You must be signed in to change notification settings - Fork 0
Development Guide
面向在 SLDataAPI 代码库上开发新功能的开发者。项目为 LabAPI 原生插件(C# / .NET Framework 4.8),当前版本 v2.5.4,开发代号 GIS,GNSS,RS!。
💡 开发辅助:本项目同时提供
sl-dataapi-dev开发 skill(SKILL.md + references/),内容与本页同源,随SLDataAPI-DevKit-v2.5.4.zip发布包分发。
| 目录 | 命名空间 | 内容 |
|---|---|---|
Plugin.cs |
SLDataAPI |
入口:Enable/Disable、LabAPI 事件订阅、服务编排 |
Config.cs |
SLDataAPI |
配置类(snake_case,LabAPI 自动加载) |
Log.cs |
SLDataAPI |
日志门面:Log.Info/Warn/Error/Debug
|
Data/ |
SLDataAPI.Data |
DTO:Models.cs(数据快照)、ControlModels.cs(控制请求体) |
Control/ |
SLDataAPI.Control |
ControlController(路由+业务)、WsControlService(WS 长连接)、ControlAuth(鉴权) |
Services/ |
SLDataAPI.Services |
HttpServer、DataCollector、MainThreadExecutor、FileService、ReportService 等 |
Voice/ |
SLDataAPI.Voice |
VoiceService(语音转发 SPY)、VoiceRecorder(录音取证) |
Map/ |
SLDataAPI.Map |
地图布局采集与导出 |
Integrations/ |
SLDataAPI.Integrations |
EXILED 互操作反射桥 + 第三方插件探测 |
Capture/ |
SLDataAPI.Capture |
Harmony 补丁:控制台输出捕获 |
LabAPI 事件分发是裸调用——handler 里的任何异常都会传播回游戏主流程(回合初始化中断、玩家状态错乱)。所有 LabAPI 事件 handler 必须整体 try/catch,异常 Log.Error 后吞掉。范例:Plugin.OnRoundStarted。
所有触碰游戏 / Mirror 网络状态的操作必须经 MainThreadExecutor 派发到主线程:
var (status, json) = MainThreadExecutor.RunOnMainThread(() =>
{
// 游戏 API 只能在这里调用
return (200, Json(true, "ok", data));
}, out var err);
if (err != null)
return (400, Json(false, err.Message));超时(默认 5s)后置取消标志,迟到的 action 跳过执行——防止"报超时但实际执行"导致的重试双重执行。纯文件/序列化操作不需要派发。
错误响应不得包含服务器路径等敏感信息;细节只进服务器日志。ControlController.Handle 顶层兜底统一 500 "内部错误"。
LabAPI 用 UnderscoredNamingConvention:C# 属性 ReportMaxRecords → 配置键 report_max_records。错误键名被静默忽略;任何一个值结构错误会导致整个文件回退默认值(启动日志会打 YamlDotNet 精确错误含行号)。
- 版本号:
Plugin.cs的Version属性 - 每个功能区块注释标注推出/更新历史(含 preview 与 patch 版本):
// ===== 功能名(vX.Y.Z 推出,代号 XXX;vX.Y.Z-Patch 加固,代号 YYY)===== - 历史代号:SPY(v2.3)、Yagami Light(v2.5.0/2.5.1)、Bay of Pigs Invasion(v2.5.2/2.5.3)、Apollo 11's Tapes(v2.5.3)、FI-STM(v2.5.3-Patch)、ENIGMA(v2.5.4-preview)、GIS,GNSS,RS!(v2.5.4)
-
Data/ControlModels.cs加请求类(snake_case 属性,范例ReportRequest) -
ControlController.Handle的 switch 注册:"/control/xxx" => XxxAction(body), - 端点方法
private static (int, string) XxxAction(string body):Parse<T>反序列化 → 校验必填(400 明确 message)→ 游戏操作主线程派发 →(200, Json(true, "ok", data)) - 鉴权由
ControlAuth统一处理,端点内不用管 token;WS call 的 path 与 HTTP 完全一致,自动兼容 - README「控制接口」端点表 + 本 wiki
HTTP-API.md同步 - 端点区块注释标注推出版本/代号
完整范例:/control/reports(ReportsAction)。
模式见 Services/ReportService.cs(举报功能),命名空间 UserSettings.ServerSpecific:
- 控件:
SSGroupHeader(label)/SSDropdownSetting(id, label, options, defaultIndex)/SSPlaintextSetting(id, label, placeholder, characterLimit)/SSButton(id, label, text, holdTimeSeconds)(长按按钮) - 下发:
ServerSpecificSettingsSync.DefinedSettings = ...; SendToAll(); - 交互:
ServerOnSettingValueReceived += (hub, setting)(主线程),按setting.SettingId分流 - 读值:
GetSettingOfUser<T>(hub, id);热更新:dropdown.SendDropdownUpdate(...)/button.SendButtonUpdate(...) - 坑:
DefinedSettings全局单例(其他插件设置会覆盖);事件回调的 setting 实例与定义实例不保证同一引用(勿用引用比较过滤);SSS 面板开着时 HUD hint 被菜单挡住(面板内反馈用按钮文本)
详细 API 签名见项目 skill 的 references/sss-api.md。
dotnet build -c Release
# 产物:bin/Release/net48/SLDataAPI.dll- 编译期引用本机游戏程序集:
SCPSL_DIR(游戏 Managed 目录)/LABAPI_DIR,其他机器用-p:覆盖 -
key.snk存在时自动强名称签名(公钥令牌3ec73bb20070fa9c);key.snk 不入库 - 部署:
LabAPI/plugins/global/,重启服务器生效;配置:LabAPI/configs/<端口>/SLDataAPI/config.yml
# 控制端点
curl -s -X POST "http://127.0.0.1:8081/control/reports" \
-H "X-Control-Token: <control_token>" -H "Content-Type: application/json" \
-d '{"action":"list"}'
# 数据接口
curl -s "http://127.0.0.1:8081/get_sl_data?token=<verify_token>"WS 控制:ws://127.0.0.1:8081/control?key=<control_token>(control_transport: ws 模式);语音 WS:端口 8082。