Files
browser/platform_web/schemas/scumManagementRcon.ts
T

41 lines
1.6 KiB
TypeScript

import type { SourceRCONCommandRequest } from "../api/types";
const maxManagementCommandBytes = 8192;
export function scumSourceRCONCommandRequest(serverInstanceId: string, command: string, sequence = Date.now()): SourceRCONCommandRequest {
const stamp = Math.max(0, Math.floor(sequence));
return {
kind: "command",
command: normalizeSCUMManagementCommand(command, "管理指令"),
idempotencyKey: `web:scum-rcon:${safeBridgeIdentifierPart(serverInstanceId)}:${stamp}`,
};
}
export function scumSourceRCONChatRequest(serverInstanceId: string, message: string, sequence = Date.now()): SourceRCONCommandRequest {
const stamp = Math.max(0, Math.floor(sequence));
return {
kind: "chat",
chatType: 4,
message: validateSCUMManagementRCONText(message, "聊天内容"),
idempotencyKey: `web:scum-rcon-chat:${safeBridgeIdentifierPart(serverInstanceId)}:${stamp}`
};
}
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";
}