import type { GameClientBridgeQueueRequest } from "../api/types"; export const scumManagementRCONProfileKey = "scum-client-manager"; export const scumManagementRCONCommandType = "management.rcon.request"; const maxManagementCommandBytes = 8192; const managementCommandTtlMs = 120_000; export function scumManagementRCONCommandRequest(serverInstanceId: string, command: string, sequence = Date.now()): GameClientBridgeQueueRequest { const stamp = Math.max(0, Math.floor(sequence)); return { profileKey: scumManagementRCONProfileKey, commandType: scumManagementRCONCommandType, payload: { requestText: normalizeSCUMManagementCommand(command, "管理指令") }, idempotencyKey: `web:scum-rcon:${safeBridgeIdentifierPart(serverInstanceId)}:${stamp}`, priority: 20, expiresAt: new Date(stamp + managementCommandTtlMs).toISOString() }; } export function scumAnnouncementCommand(message: string): string { return `#Announce ${validateSCUMManagementRCONText(message, "公告内容")}`; } export function validateSCUMManagementRCONText(value: string, label: string): string { const normalized = value.trim(); if (!normalized || new TextEncoder().encode(normalized).byteLength > maxManagementCommandBytes || /[\u0000\r\n]/.test(normalized)) { throw new Error(`${label}必须是受限的单行文本。`); } return normalized; } function normalizeSCUMManagementCommand(value: string, label: string): string { const normalized = validateSCUMManagementRCONText(value, label); return normalized.startsWith("#") ? normalized : `#${normalized}`; } function safeBridgeIdentifierPart(value: string): string { const normalized = value.trim().replace(/[^A-Za-z0-9._:-]+/g, "-").replace(/^[^A-Za-z0-9]+|[^A-Za-z0-9]+$/g, "").slice(0, 96); return normalized || "server"; }