feat(scum): add file config workbench
This commit is contained in:
@@ -281,7 +281,7 @@
|
||||
"maxCommands": 1000,
|
||||
"pages": [
|
||||
{
|
||||
"pageKey": "operations",
|
||||
"pageKey": "files-config",
|
||||
"commandTypes": [
|
||||
"announcement.send",
|
||||
"companion.diagnostics",
|
||||
@@ -347,89 +347,13 @@
|
||||
"dependencyPolicy": "required",
|
||||
"approvalRequired": ["disable", "rollback", "retire"]
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"key": "overview",
|
||||
"title": "SCUM 概览",
|
||||
"path": "/overview",
|
||||
"permissions": [
|
||||
"server.read",
|
||||
"server.lifecycle"
|
||||
],
|
||||
"bridgeActions": [
|
||||
"server.instances.read",
|
||||
"jobs.dispatch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "operations",
|
||||
"title": "SCUM 运维",
|
||||
"path": "/operations",
|
||||
"permissions": [
|
||||
"server.read",
|
||||
"server.game-client.read",
|
||||
"server.game-client.command",
|
||||
"server.game-client.maintenance",
|
||||
"server.client-manager.manage",
|
||||
"server.logs.read",
|
||||
"server.remote.access"
|
||||
],
|
||||
"bridgeActions": [
|
||||
"server.instances.read",
|
||||
"jobs.dispatch",
|
||||
"client-manager.request",
|
||||
"logs.query",
|
||||
"remote.access.request"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "config",
|
||||
"title": "SCUM 配置",
|
||||
"path": "/config",
|
||||
"permissions": [
|
||||
"server.files.read",
|
||||
"server.files.write",
|
||||
"ai.invoke"
|
||||
],
|
||||
"bridgeActions": [
|
||||
"files.request",
|
||||
"ai.invoke"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "logs",
|
||||
"title": "SCUM 日志",
|
||||
"path": "/logs",
|
||||
"permissions": [
|
||||
"server.logs.read",
|
||||
"server.artifacts.read",
|
||||
"server.remote.access",
|
||||
"ai.invoke"
|
||||
],
|
||||
"bridgeActions": [
|
||||
"logs.query",
|
||||
"artifacts.open",
|
||||
"remote.access.request",
|
||||
"ai.invoke"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "remote",
|
||||
"title": "SCUM 远程",
|
||||
"path": "/remote",
|
||||
"permissions": [
|
||||
"server.remote.access",
|
||||
"server.files.read",
|
||||
"server.files.write",
|
||||
"server.lifecycle"
|
||||
],
|
||||
"bridgeActions": [
|
||||
"remote.access.request",
|
||||
"files.request",
|
||||
"jobs.dispatch"
|
||||
]
|
||||
}
|
||||
],
|
||||
"pages": [{ "key": "files-config", "title": "文件与配置", "path": "/files-config", "permissions": ["server.read", "server.files.read", "server.files.write", "server.logs.read", "server.game-client.read", "server.remote.access", "ai.invoke"], "bridgeActions": ["server.instances.read", "files.request", "logs.query", "remote.access.request", "ai.invoke"] }],
|
||||
"fileWorkspace": {
|
||||
"defaultDirectoryKey": "scum-config",
|
||||
"directories": [{ "key": "scum-config", "label": "服务器配置", "scope": "config" }, { "key": "scum-logs", "label": "日志文件", "scope": "logs" }],
|
||||
"files": [{ "key": "scum-server-settings", "directoryKey": "scum-config", "label": "ServerSettings.ini", "kind": "config", "editable": true }, { "key": "scum-server-log", "directoryKey": "scum-logs", "label": "SCUM Server.log", "kind": "log", "streamKey": "scum.server" }, { "key": "scum-chat-log", "directoryKey": "scum-logs", "label": "SCUM Chat.log", "kind": "log", "streamKey": "scum.chat" }],
|
||||
"configFields": [{ "key": "server-name", "fileKey": "scum-server-settings", "configKey": "ServerName", "label": "服务器名称", "description": "显示在服务器浏览器与玩家连接界面。", "control": "text", "defaultValue": "SCUM Server", "restartImpact": "restart-required" }, { "key": "game-port", "fileKey": "scum-server-settings", "configKey": "GamePort", "label": "游戏端口", "description": "玩家连接所使用的游戏端口。", "control": "port", "minimum": 1, "maximum": 65535, "defaultValue": "7777", "restartImpact": "restart-required" }, { "key": "query-port", "fileKey": "scum-server-settings", "configKey": "QueryPort", "label": "查询和状态发现端口。", "description": "服务器查询和状态发现所使用的端口。", "control": "port", "minimum": 1, "maximum": 65535, "defaultValue": "27015", "restartImpact": "restart-required" }, { "key": "max-players", "fileKey": "scum-server-settings", "configKey": "MaxPlayers", "label": "最大玩家数", "description": "允许同时进入服务器的玩家上限。", "control": "number", "minimum": 1, "maximum": 128, "defaultValue": "64", "restartImpact": "restart-required" }]
|
||||
},
|
||||
"ai": {
|
||||
"purposes": [
|
||||
"config.suggest",
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"fileWorkspace": { "type": "object", "required": ["defaultDirectoryKey", "directories", "files", "configFields"], "additionalProperties": false, "properties": { "defaultDirectoryKey": { "$ref": "#/$defs/logicalKey" }, "directories": { "type": "array", "items": { "$ref": "#/$defs/pluginLogicalDirectory" } }, "files": { "type": "array", "items": { "$ref": "#/$defs/pluginLogicalFile" } }, "configFields": { "type": "array", "items": { "$ref": "#/$defs/pluginConfigField" } } } },
|
||||
"ai": {
|
||||
"type": "object",
|
||||
"required": ["mediation", "configWritePolicy"],
|
||||
@@ -202,6 +203,9 @@
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"pluginLogicalDirectory": { "type": "object", "required": ["key", "label", "scope"], "additionalProperties": false, "properties": { "key": { "$ref": "#/$defs/logicalKey" }, "label": { "type": "string", "minLength": 1, "maxLength": 60 }, "scope": { "enum": ["config", "logs"] } } },
|
||||
"pluginLogicalFile": { "type": "object", "required": ["key", "directoryKey", "label", "kind"], "additionalProperties": false, "properties": { "key": { "$ref": "#/$defs/logicalKey" }, "directoryKey": { "$ref": "#/$defs/logicalKey" }, "label": { "type": "string", "minLength": 1, "maxLength": 80 }, "kind": { "enum": ["config", "log"] }, "streamKey": { "$ref": "#/$defs/logicalKey" }, "editable": { "type": "boolean" } } },
|
||||
"pluginConfigField": { "type": "object", "required": ["key", "fileKey", "configKey", "label", "description", "control", "restartImpact"], "additionalProperties": false, "properties": { "key": { "$ref": "#/$defs/logicalKey" }, "fileKey": { "$ref": "#/$defs/logicalKey" }, "configKey": { "type": "string", "pattern": "^[A-Za-z][A-Za-z0-9_.-]*$", "maxLength": 120 }, "label": { "type": "string", "minLength": 1, "maxLength": 80 }, "description": { "type": "string", "minLength": 1, "maxLength": 240 }, "control": { "enum": ["text", "number", "boolean", "port"] }, "minimum": { "type": "integer", "minimum": 0, "maximum": 65535 }, "maximum": { "type": "integer", "minimum": 0, "maximum": 65535 }, "defaultValue": { "type": "string", "maxLength": 120 }, "restartImpact": { "enum": ["none", "restart-required"] } } },
|
||||
"pluginCreateField": {
|
||||
"type": "object",
|
||||
"required": ["key", "label", "type"],
|
||||
|
||||
@@ -470,8 +470,8 @@ describe("plugin manifest validation", () => {
|
||||
"maintenance.prepare"
|
||||
]));
|
||||
expect(manifest.gameClientBridge.snapshots.map((snapshot) => snapshot.type)).toEqual(expect.arrayContaining(["companion.health", "online.sessions", "players", "squads", "vehicles", "flags"]));
|
||||
expect(manifest.gameClientBridge.pages.map((page) => page.pageKey)).toContain("operations");
|
||||
expect(manifest.gameClientBridge.pages.find((page) => page.pageKey === "operations")?.commandTypes).toEqual(expect.arrayContaining([
|
||||
expect(manifest.gameClientBridge.pages.map((page) => page.pageKey)).toContain("files-config");
|
||||
expect(manifest.gameClientBridge.pages.find((page) => page.pageKey === "files-config")?.commandTypes).toEqual(expect.arrayContaining([
|
||||
"announcement.send",
|
||||
"companion.diagnostics",
|
||||
"player.lookup",
|
||||
@@ -480,7 +480,7 @@ describe("plugin manifest validation", () => {
|
||||
"restart.prepare",
|
||||
"maintenance.prepare"
|
||||
]));
|
||||
expect(manifest.pages.map((page) => page.key)).toContain("operations");
|
||||
expect(manifest.pages.map((page) => page.key)).toContain("files-config");
|
||||
expect(manifest.runtimeProfiles?.lifecycleProfiles?.find((profile) => profile.key === "scum-client")?.capabilities).not.toContain("remote.run.rcon.command");
|
||||
expect(manifest.runtimeProfiles?.logSources?.map((source) => source.key)).toEqual(expect.arrayContaining(["scum-chat-events", "scum-server-events", "scum-client-events"]));
|
||||
});
|
||||
@@ -587,7 +587,7 @@ describe("plugin manifest validation", () => {
|
||||
}
|
||||
}
|
||||
|
||||
const operationsPage = manifest.gameClientBridge.pages.find((page) => page.pageKey === "operations");
|
||||
const operationsPage = manifest.gameClientBridge.pages.find((page) => page.pageKey === "files-config");
|
||||
expect(operationsPage?.snapshotTypes).toEqual(expect.arrayContaining(expectedTypes));
|
||||
});
|
||||
|
||||
@@ -663,8 +663,8 @@ describe("plugin manifest validation", () => {
|
||||
}
|
||||
}
|
||||
|
||||
const operationsPage = manifest.gameClientBridge.pages.find((page) => page.pageKey === "operations");
|
||||
const operationsPluginPage = manifest.pages.find((page) => page.key === "operations");
|
||||
const operationsPage = manifest.gameClientBridge.pages.find((page) => page.pageKey === "files-config");
|
||||
const operationsPluginPage = manifest.pages.find((page) => page.key === "files-config");
|
||||
expect(operationsPage?.queryTemplateKeys).toEqual(expect.arrayContaining(expectedKeys));
|
||||
expect(operationsPluginPage?.permissions).toEqual(expect.arrayContaining(["server.game-client.read", "server.remote.access"]));
|
||||
expect(operationsPluginPage?.bridgeActions).toContain("remote.access.request");
|
||||
|
||||
Reference in New Issue
Block a user