Remove manual runtime controls from server detail

This commit is contained in:
npc0-hue
2026-08-10 12:23:17 +08:00
parent b789925ae5
commit fbd24b6a44
24 changed files with 272 additions and 1361 deletions
@@ -22,6 +22,8 @@ export type SCUMFileReadSnapshot = {
};
export type SCUMPageContext = {
pageKey?: string;
pageTitle?: string;
serverInstanceId?: string;
permissions: string[];
availability: { available: boolean; reason?: string };
@@ -45,6 +47,7 @@ type DiffLine = { kind: "same" | "added" | "removed"; text: string };
export function renderSCUMFeaturePage(react: ReactLike, input: SCUMPageContext) {
const e = react.createElement;
if (input.pageKey && input.pageKey !== "files-config") return renderSCUMFeatureSurface(e, input);
const workspace = normalizeWorkspace(input.workspace);
const [selectedDirectoryKey, setSelectedDirectoryKey] = usePluginState(react, workspace.defaultDirectoryKey);
const effectiveDirectoryKey = workspace.directories.some((directory) => directory.key === selectedDirectoryKey) ? selectedDirectoryKey : workspace.defaultDirectoryKey;
@@ -199,6 +202,34 @@ export function renderSCUMFeaturePage(react: ReactLike, input: SCUMPageContext)
);
}
function renderSCUMFeatureSurface(e: ReactLike["createElement"], input: SCUMPageContext) {
const meta = scumSurfaceMeta(input.pageKey ?? "");
const featureRows = (input.featureAvailability ?? [])
.filter((feature) => meta.features.includes(feature.key))
.map((feature) => e("div", { key: feature.key, className: "console-row" }, e("span", null, feature.key), e("strong", null, feature.available ? "可用" : feature.reason ?? "等待 Companion")));
return e("section", { className: "console-panel", "aria-label": input.pageTitle ?? meta.title },
e("div", { className: "panel-header" },
e("div", null, e("h2", null, input.pageTitle ?? meta.title), e("p", { className: "provider-id" }, meta.summary)),
e("span", { className: "page-status" }, input.availability.available ? "Companion 在线" : input.availability.reason ?? "等待 Companion")
),
e("div", { className: "console-row-list" },
e("div", { className: "console-row" }, e("span", null, "服务器"), e("strong", null, input.serverInstanceId ?? "未绑定")),
e("div", { className: "console-row" }, e("span", null, "权限"), e("strong", null, input.permissions.join(" / ") || "未声明")),
featureRows.length ? featureRows : e("div", { className: "console-row" }, e("span", null, "插件能力"), e("strong", null, meta.features.join(" / ") || "由插件声明"))
)
);
}
function scumSurfaceMeta(pageKey: string): { title: string; summary: string; features: string[] } {
switch (pageKey) {
case "players": return { title: "用户管理", summary: "玩家查询、在线状态、维护窗口和状态修正由 SCUM 插件 Companion 提供。", features: ["player.intelligence", "state.patch"] };
case "squads": return { title: "队伍管理", summary: "队伍列表、成员关系和风险上下文来自插件声明的 squads 快照。", features: ["player.intelligence"] };
case "live-map": return { title: "实时地图", summary: "玩家、载具和轨迹采样由插件事件流驱动。", features: ["trajectory.collect", "vehicle.spawn"] };
case "gifts": return { title: "礼包管理", summary: "礼包目录、发放和玩家通知通过受保护插件命令执行。", features: ["reward.delivery"] };
default: return { title: "SCUM 插件页面", summary: "该页面由 SCUM 插件声明。", features: [] };
}
}
function navigationPane(e: ReactLike["createElement"], workspace: NormalizedWorkspace, directoryKey: string, directoryFiles: readonly SCUMLogicalFile[], selectedFileKey: string | undefined, refreshState: WorkspaceRefreshState, canRefreshWorkspace: boolean, onDirectoryChange: (directoryKey: string) => void, onFileSelect: (file: SCUMLogicalFile) => void, onRefreshWorkspace: () => void) {
const activeDirectory = workspace.directories.find((directory) => directory.key === directoryKey);
const selectedFile = directoryFiles.find((file) => file.key === selectedFileKey) ?? directoryFiles[0];
@@ -373,7 +373,13 @@
"dependencyPolicy": "required",
"approvalRequired": ["disable", "rollback", "retire"]
},
"pages": [{ "key": "files-config", "title": "文件管理", "path": "/files-config", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.3", "bundleIntegritySha256": "sha256:797c4e303c102f0316e71e4e5bda50a6ca96506a7cb368a42ecf858b236609b2", "permissions": ["server.read", "server.files.read", "server.files.write", "server.logs.read"], "bridgeActions": ["server.instances.read", "files.request", "logs.query"], "featureKeys": ["config.manage"] }],
"pages": [
{ "key": "files-config", "title": "文件管理", "path": "/files-config", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.3", "bundleIntegritySha256": "sha256:797c4e303c102f0316e71e4e5bda50a6ca96506a7cb368a42ecf858b236609b2", "permissions": ["server.read", "server.files.read", "server.files.write", "server.logs.read"], "bridgeActions": ["server.instances.read", "files.request", "logs.query"], "featureKeys": ["config.manage"] },
{ "key": "players", "title": "用户管理", "path": "/players", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.3", "bundleIntegritySha256": "sha256:797c4e303c102f0316e71e4e5bda50a6ca96506a7cb368a42ecf858b236609b2", "permissions": ["server.read", "server.game-client.read", "server.game-client.command"], "bridgeActions": ["server.instances.read"], "featureKeys": ["player.intelligence", "state.patch"] },
{ "key": "squads", "title": "队伍管理", "path": "/squads", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.3", "bundleIntegritySha256": "sha256:797c4e303c102f0316e71e4e5bda50a6ca96506a7cb368a42ecf858b236609b2", "permissions": ["server.read", "server.game-client.read"], "bridgeActions": ["server.instances.read"], "featureKeys": ["player.intelligence"] },
{ "key": "live-map", "title": "实时地图", "path": "/live-map", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.3", "bundleIntegritySha256": "sha256:797c4e303c102f0316e71e4e5bda50a6ca96506a7cb368a42ecf858b236609b2", "permissions": ["server.read", "server.game-client.read"], "bridgeActions": ["server.instances.read"], "featureKeys": ["trajectory.collect"] },
{ "key": "gifts", "title": "礼包管理", "path": "/gifts", "bundleKey": "scum-server-plugin", "bundleVersion": "1.0.3", "bundleIntegritySha256": "sha256:797c4e303c102f0316e71e4e5bda50a6ca96506a7cb368a42ecf858b236609b2", "permissions": ["server.read", "server.game-client.read", "server.game-client.command"], "bridgeActions": ["server.instances.read"], "featureKeys": ["reward.delivery"] }
],
"fileWorkspace": {
"defaultDirectoryKey": "scum-config",
"directories": [{ "key": "scum-config", "label": "服务器配置", "scope": "config" }, { "key": "scum-logs", "label": "日志文件", "scope": "logs" }],
@@ -3,4 +3,4 @@ import type { SCUMFeatureWorkspace } from "../features/contracts.js";
export const pluginPageBundle = { key: "scum-server-plugin", version: "1.0.3", integritySha256: "sha256:797c4e303c102f0316e71e4e5bda50a6ca96506a7cb368a42ecf858b236609b2" };
export function renderPluginPage(react: any, input: any) { return renderSCUMFeaturePage(react, { serverInstanceId: input.context.serverInstanceId, permissions: input.context.permissions, availability: input.availability, featureAvailability: input.availability.features, workspace: input.workspace as SCUMFeatureWorkspace | undefined, workspaceActions: input.workspaceActions }); }
export function renderPluginPage(react: any, input: any) { return renderSCUMFeaturePage(react, { pageKey: input.page?.key ?? "files-config", pageTitle: input.page?.title ?? "文件管理", serverInstanceId: input.context.serverInstanceId, permissions: input.context.permissions, availability: input.availability, featureAvailability: input.availability.features, workspace: input.workspace as SCUMFeatureWorkspace | undefined, workspaceActions: input.workspaceActions }); }