feat(plugin): gate pages on companion features

This commit is contained in:
npc0-hue
2026-07-29 09:53:39 +08:00
parent 271e1e684f
commit c9494abc48
16 changed files with 300 additions and 61 deletions
@@ -242,6 +242,13 @@
],
"commandRetentionSeconds": 604800,
"maxCommands": 1000,
"features": [
{ "key": "config.manage", "title": "SCUM configuration", "permission": "server.game-client.read", "requiredHandlers": ["config.read", "config.patch"] },
{ "key": "player.intelligence", "title": "SCUM player intelligence", "permission": "server.game-client.read", "requiredHandlers": ["player.lookup"], "requiredEventProducers": ["semantic.events"] },
{ "key": "reward.delivery", "title": "SCUM reward delivery", "permission": "server.game-client.command", "requiredHandlers": ["reward.deliver", "player.notify"] },
{ "key": "state.patch", "title": "SCUM player state patch", "permission": "server.game-client.maintenance", "requiredHandlers": ["game-state.patch"] },
{ "key": "trajectory.collect", "title": "SCUM trajectories", "permission": "server.game-client.read", "requiredEventProducers": ["semantic.events"] }
],
"pages": [
{
"pageKey": "files-config",
@@ -254,7 +261,8 @@
"restart.prepare",
"maintenance.prepare"
],
"snapshotTypes": ["companion.health", "online.sessions", "players", "squads", "vehicles", "flags"]
"snapshotTypes": ["companion.health", "online.sessions", "players", "squads", "vehicles", "flags"],
"featureKeys": ["config.manage", "player.intelligence", "reward.delivery", "state.patch", "trajectory.collect"]
}
],
"companion": {
@@ -303,7 +311,7 @@
"dependencyPolicy": "required",
"approvalRequired": ["disable", "rollback", "retire"]
},
"pages": [{ "key": "files-config", "title": "文件、配置与玩家档案", "path": "/files-config", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.0", "bundleIntegritySha256": "sha256:8a4216107e1d7773d42a7e13b6466fd4fcf6e6bb2dc5f5af398fb7f4ea4f623b", "permissions": ["server.read", "server.files.read", "server.files.write", "server.logs.read", "server.game-client.read", "ai.invoke"], "bridgeActions": ["server.instances.read", "files.request", "logs.query", "ai.invoke"] }],
"pages": [{ "key": "files-config", "title": "文件、配置与玩家档案", "path": "/files-config", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.0", "bundleIntegritySha256": "sha256:8a4216107e1d7773d42a7e13b6466fd4fcf6e6bb2dc5f5af398fb7f4ea4f623b", "permissions": ["server.read", "server.files.read", "server.files.write", "server.logs.read", "server.game-client.read", "server.game-client.command", "server.game-client.maintenance", "ai.invoke"], "bridgeActions": ["server.instances.read", "files.request", "logs.query", "ai.invoke"], "featureKeys": ["config.manage", "player.intelligence", "reward.delivery", "state.patch", "trajectory.collect"] }],
"fileWorkspace": {
"defaultDirectoryKey": "scum-config",
"directories": [{ "key": "scum-config", "label": "服务器配置", "scope": "config" }, { "key": "scum-logs", "label": "日志文件", "scope": "logs" }],
@@ -190,7 +190,8 @@
"bundleVersion": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$" },
"bundleIntegritySha256": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
"permissions": { "type": "array", "items": { "$ref": "#/$defs/pluginPermission" }, "uniqueItems": true },
"bridgeActions": { "type": "array", "items": { "$ref": "#/$defs/bridgeAction" }, "uniqueItems": true }
"bridgeActions": { "type": "array", "items": { "$ref": "#/$defs/bridgeAction" }, "uniqueItems": true },
"featureKeys": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
}
}
},
@@ -262,6 +263,7 @@
"items": { "$ref": "#/$defs/gameClientBridgePageContract" },
"maxItems": 64
},
"features": { "type": "array", "items": { "$ref": "#/$defs/gameClientBridgeFeature" }, "maxItems": 128 },
"companion": { "$ref": "#/$defs/gameClientBridgeCompanion" }
}
},
@@ -337,7 +339,15 @@
"pageKey": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
"commandTypes": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"snapshotTypes": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"queryTemplateKeys": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
"queryTemplateKeys": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"featureKeys": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
}
},
"gameClientBridgeFeature": {
"type": "object", "required": ["key", "title", "permission"], "additionalProperties": false,
"properties": {
"key": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,159}$" }, "title": { "type": "string", "minLength": 1, "maxLength": 80 }, "permission": { "$ref": "#/$defs/pluginPermission" },
"requiredHandlers": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "maxItems": 64 }, "requiredEventProducers": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "maxItems": 64 }
}
},
"productionLifecycleOperation": {
+9
View File
@@ -250,8 +250,11 @@ export interface GameClientBridgePageContract {
commandTypes?: string[];
snapshotTypes?: string[];
queryTemplateKeys?: string[];
featureKeys?: string[];
}
export interface GameClientBridgeFeatureDeclaration { key: string; title: string; permission: PluginPermission; requiredHandlers?: string[]; requiredEventProducers?: string[]; }
export interface GameClientBridgeCompanionDeclaration {
profileKey: string;
configTemplateKey: string;
@@ -275,6 +278,7 @@ export interface GameClientBridgeManifest {
commandRetentionSeconds: number;
maxCommands: number;
pages?: GameClientBridgePageContract[];
features?: GameClientBridgeFeatureDeclaration[];
companion?: GameClientBridgeCompanionDeclaration;
}
@@ -286,14 +290,19 @@ export interface GameClientBridgeProfileStatus {
commandTypes: string[];
snapshotTypes: string[];
queryTemplateKeys: string[];
handlerTypes?: string[];
eventProducerTypes?: string[];
}
export interface GameClientBridgeFeatureAvailability { key: string; available: boolean; reason?: string; }
export interface GameClientBridgeStatus {
serverInstanceId: string;
pluginId: string;
available: boolean;
reason?: string;
profiles: GameClientBridgeProfileStatus[];
features?: GameClientBridgeFeatureAvailability[];
}
export interface GameClientBridgeCommandResult {