Skip to content

Development Guide

Cursor Agent edited this page Sep 18, 2026 · 4 revisions

开发者指南

面向在 SLDataAPI 仓库贡献功能的开发者。当前 preview 分支:preview/v2.6.0-DevOnly(2.6.0-preview-DevOnly);稳定 main:2.5.4。

可选:发布包 SLDataAPI-DevKit-*.zip 内含 sl-dataapi-dev skill(与本 wiki 同源参考)。


项目结构

目录 命名空间 职责
Plugin.cs SLDataAPI Enable/Disable、事件订阅、服务启动顺序
Config.cs SLDataAPI config.yml 属性(snake_case)
Data/ SLDataAPI.Data HTTP/WS JSON DTO
Control/ SLDataAPI.Control 路由 ControlController、WS WsControlServiceControlAuth(verify_token 与锁定)
Auth/ SLDataAPI.Auth ApiKeyServiceEndpointAclRemoteCommandGuard
Commands/ SLDataAPI.Commands sldataapi / apikey LabAPI 命令(本地 only)
Services/ SLDataAPI.Services HttpServerDataCollectorMainThreadExecutorReportServiceControlLogService
Voice/ SLDataAPI.Voice SPY 转发 + 录音
Map/ SLDataAPI.Map seed/layout/export
Integrations/ SLDataAPI.Integrations EXILED 反射、SLPlayer/OmegaWarhead
Capture/ SLDataAPI.Capture 控制台输出 Harmony 补丁

架构图与线程:Architecture。编译发布:Building


强制约定

1. 事件链保护

LabAPI 事件 handler 必须整体 try/catch,异常 Log.Error 后吞掉,不得抛回游戏。参考 Plugin.OnRoundStarted

2. 主线程派发

var (status, json) = MainThreadExecutor.RunOnMainThread(() =>
{
    // Unity / Mirror API
    return (200, Json(true, "ok", data));
}, out var err);
if (err != null)
    return (400, Json(false, err.Message));

纯文件、ACL、序列化可不派发。超时后设置取消标志,迟到的 action 不得再执行。

3. 错误对外表述

ControlController.Handle 顶层 catch → 500 "内部错误"。不向客户端返回堆栈、绝对路径。

4. 配置 snake_case

C# ReportMaxRecords → YAML report_max_records。单字段错误可能导致整文件回退默认。

5. 版本注释

功能块用注释标版本,例如:

// ===== 举报(v2.5.4 推出)=====

Plugin.Version 为单一真相;README/Wiki 与 release tag 对齐。


添加控制端点(完整流程)

  1. Data/ControlModels.cs:新增请求类(JSON 属性 snake_case)。
  2. ControlController.Handleswitch 注册 path(2.6 用 RA 对齐路径;2.5 维护旧路径直到弃用)。
  3. 实现 XxxAction(string body)Parse<T> → 校验 → MainThreadExecutor(status, Json(...))
  4. 鉴权
    • 2.5:ControlAuth + control_tokenHttpServer / WS 握手)。
    • 2.6:ApiKeyService.TryAuthenticate + EndpointAcl.IsAllowed(path, wantWrite);在 EndpointAcl.DefaultCatalog 登记新 path 的默认 bool。
  5. 写操作判定:若只读/写依赖 body,在 EndpointAcl.IsWriteOperation 补分支(影响 ACL 与审计)。
  6. 审计:侵入性写操作经 ControlLogService(若启用)。
  7. 文档:稳定 HTTP-API;预览 Preview-HTTP-API;各加一条 curl。
  8. WS:无需 duplicate——call.path 与 HTTP 相同即自动兼容。

参考实现:ReportsActionMapFacilityAction

501 占位

未实现 RA 页:Stub501("name") 返回统一占位,便于路径先对齐。

远程命令护栏

RemoteCommandGuard 拦截经控制通道执行的 sldataapi/slda(含点前缀变体)。新增本地管理命令应注册在 Commands/ 并默认拒绝远程。

API Key 确认

create/revokeOperatorConfirmService + ConfirmPanel(全屏 TUI)或退化 [y/N]。勿绕过确认路径。


2.6 ACL 开发注意

  • MergeEffective:admin + all_control_true 仍尊重 endpoint_catalogfalse
  • 前缀键以 / 结尾;voice:/ws 等非 HTTP path 单独键。
  • 单元测试:tests/SLDataAPI.Auth.TestsEndpointAclTestsRemoteCommandGuardTests)。

SSS 游戏内 UI

模式见 Services/ReportService.csUserSettings.ServerSpecific):

控件 用途
SSGroupHeader 分组标题
SSDropdownSetting 下拉(如选被举报人)
SSPlaintextSetting 文本
SSButton + holdTimeSeconds 长按提交

流程:DefinedSettingsSendToAll()ServerOnSettingValueReceived 在主线程按 SettingId 处理。

注意:DefinedSettings 全局单例,与其他插件冲突;勿用 setting 实例引用相等判断用户。


本地测试

2.6 preview(先 sldataapi apikey create):

curl -s -X POST "http://127.0.0.1:8081/control/reports" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{"action":"list"}'

curl -s "http://127.0.0.1:8081/get_sl_data?token=<verify_token>"

2.5 stable

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"}'

WS:2.6 握手带 Bearer;2.5 用 ?key=。见 WS-Control-Protocol

dotnet test tests/SLDataAPI.Auth.Tests

分支与文档

变更类型 分支 Wiki
2.5 行为 main HTTP-APISecurity-Model(control_token 段)
2.6 预览 preview/v2.6.0-DevOnly Preview-HTTP-API、鉴权相关页

勿在稳定文档中写 2.6 路径为默认;README 在 preview 分支应链到 Preview 页。


发布

Building 发布检查清单。Preview 包勿被生产服务器的 auto_update_install 当作稳定版拉取(tag 命名含 preview/dev)。

Clone this wiki locally