feat(scum): add bounded vehicle spawn adapter

This commit is contained in:
npc0-hue
2026-07-29 16:04:26 +08:00
parent 7ae4dbf0b2
commit daa0f330a4
24 changed files with 314 additions and 23 deletions
@@ -1,4 +1,4 @@
import type { SCUMConfigField, SCUMConfigPatch, SCUMFeatureAvailability, SCUMStateField } from "./contracts.js";
import type { SCUMConfigField, SCUMConfigPatch, SCUMFeatureAvailability, SCUMStateField, SCUMVehicleSpawn, SCUMVehicleSpawnOption } from "./contracts.js";
const stateFieldsByVersion: Record<string, readonly Omit<SCUMStateField, "value" | "editable" | "reason">[]> = {
"0.9.700.90357": [
@@ -16,8 +16,12 @@ export const configurationFieldsByVersion: Record<string, readonly SCUMConfigFie
{ key: "welcome-message", configKey: "WelcomeMessage", label: "欢迎消息", description: "登录成功后由已声明的服务器扩展显示给玩家。", control: "text", defaultValue: "", restartImpact: "none" }
]
};
export const vehicleSpawnCatalogByVersion: Record<string, readonly SCUMVehicleSpawnOption[]> = {
"0.9.700.90357": [{ code: "BPC_Laika_C", label: "Laika" }, { code: "BPC_WolfsWagen_C", label: "WolfsWagen" }]
};
export function configurationCatalog(serverVersion: string): readonly SCUMConfigField[] { return configurationFieldsByVersion[serverVersion] ?? []; }
export function vehicleSpawnCatalog(serverVersion: string): readonly SCUMVehicleSpawnOption[] { return vehicleSpawnCatalogByVersion[serverVersion] ?? []; }
export function stateFieldCatalog(serverVersion: string): readonly Omit<SCUMStateField, "value" | "editable" | "reason">[] { return stateFieldsByVersion[serverVersion] ?? []; }
export function supportsStateField(serverVersion: string, field: string): boolean { return stateFieldCatalog(serverVersion).some((candidate) => candidate.key === field); }
export function featureUnavailable(reason: string): SCUMFeatureAvailability { return { feature: "configuration", available: false, reason }; }
@@ -38,3 +42,8 @@ export function validateStatePatch(serverVersion: string, fields: Array<{ fieldK
for (const field of fields) { const definition = stateFieldCatalog(serverVersion).find((candidate) => candidate.key === field.fieldKey); if (!definition) return `字段 ${field.fieldKey} 未受当前版本支持。`; if (!Number.isFinite(field.before) || !Number.isFinite(field.after) || field.after < definition.minimum || field.after > definition.maximum) return `字段 ${definition.label} 超出允许范围。`; }
return null;
}
export function validateVehicleSpawn(spawn: SCUMVehicleSpawn, serverVersion = "0.9.700.90357"): string | null {
if (!/^[A-Za-z][A-Za-z0-9_]{2,63}$/.test(spawn.vehicleCode)) return "载具代码格式无效。";
if (!vehicleSpawnCatalog(serverVersion).some((candidate) => candidate.code === spawn.vehicleCode)) return "载具代码未在当前版本的受控目录中声明。";
return null;
}