import type { SCUMConfigField, SCUMConfigPatch, SCUMFeatureAvailability } from "./contracts.js"; // These are safe fallback allowlists. A Companion schema probe may narrow them // per server, but a game version never enables or disables a feature. export const configurationCatalog: readonly SCUMConfigField[] = [ { 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: "7779", 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: "128", restartImpact: "restart-required" }, { key: "welcome-message", fileKey: "scum-server-settings", configKey: "WelcomeMessage", label: "欢迎消息", description: "登录成功后由已声明的服务器扩展显示给玩家。", control: "text", defaultValue: "", restartImpact: "none" } ]; export function featureUnavailable(reason: string): SCUMFeatureAvailability { return { feature: "configuration", available: false, reason }; } export function validateConfigPatch(patch: SCUMConfigPatch): string | null { if (!patch.idempotencyKey.trim() || !patch.reason.trim() || !patch.changes.length) return "配置修改必须包含原因、幂等键和至少一项变更。"; for (const change of patch.changes) { const field = configurationCatalog.find((candidate) => candidate.key === change.key); if (!field) return `字段 ${change.key} 不在受控目录中。`; if (!change.value.trim()) return `字段 ${field.label} 不能为空。`; if ((field.control === "number" || field.control === "port") && (!Number.isInteger(Number(change.value)) || (field.minimum !== undefined && Number(change.value) < field.minimum) || (field.maximum !== undefined && Number(change.value) > field.maximum))) return `字段 ${field.label} 超出允许范围。`; } return null; }