42 lines
1.8 KiB
TypeScript
42 lines
1.8 KiB
TypeScript
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";
|
|
}
|