Panel-Daten
num, int, bool, str, record, vec4, spec, readRecords und withoutSchemaKey: die data/*.json-Dateien lesen, die das Admin-Panel bearbeitet.
Die Einstellungen deines Skripts liegen in data/*.json-Dateien, die der Serverbetreiber im Admin-Panel von ai-core bearbeitet (siehe Admin-Panel). Das Panel prüft Werte gegen dein schema.ts, aber eine Datei kann trotzdem alt, von Hand bearbeitet sein oder ein Feld vermissen. Die Leser auf dieser Seite lehnen nie ab: Ein fehlender oder falscher Wert ergibt den Fallback, den du übergibst, sodass das Skript immer startet.
Für Werte, die ein Client sendet, nutze stattdessen die strikten Leser unter Aktionen und Client-Eingaben: Diese lehnen einen fehlerhaften Wert ab.
import { num, int, bool, str, record, vec4, spec, readRecords, withoutSchemaKey } from "@aicore-fivem/lib/shared";Lua: Keiner davon hat einen Lua-Zwilling (das Admin-Panel und seine Datendateien gibt es nur in TypeScript).
Wertleser
num
Eine endliche Zahl, auf [min, max] begrenzt, sonst der Fallback.
Seite: Client, Server und NUI · Wartet: nein
num(value: unknown, fallback: number, min?: number, max?: number): numberParameter
Prop
Type
Rückgabewert
number: der Wert, in den Bereich begrenzt, oder fallback (nicht begrenzt).
Beispiel
import { num } from "@aicore-fivem/lib/shared";
num(25, 2.5, 1, 20); // 20 (begrenzt)
num("big", 2.5, 1, 20); // 2.5 (Fallback)int
Wie num, dann auf eine ganze Zahl gerundet.
Seite: Client, Server und NUI · Wartet: nein
int(value: unknown, fallback: number, min?: number, max?: number): numberParameter
Prop
Type
Rückgabewert
number: eine ganze Zahl (der Fallback wird ebenfalls gerundet).
Beispiel
import { int } from "@aicore-fivem/lib/shared";
int(12.6, 10, 0, 100); // 13
int(null, 10, 0, 100); // 10bool
Ein Boolean, sonst der Fallback.
Seite: Client, Server und NUI · Wartet: nein
bool(value: unknown, fallback: boolean): booleanParameter
Prop
Type
Rückgabewert
boolean.
Beispiel
import { bool } from "@aicore-fivem/lib/shared";
bool(true, false); // true
bool("yes", false); // false (Fallback)str
Ein getrimmter, nicht leerer String, auf max Zeichen gekürzt, sonst der Fallback.
Seite: Client, Server und NUI · Wartet: nein
str(value: unknown, fallback: string, max?: number): stringParameter
Prop
Type
Rückgabewert
string.
Beispiel
import { str } from "@aicore-fivem/lib/shared";
str(" City Hall ", "Hall", 48); // "City Hall"
str("", "Hall", 48); // "Hall"record
Der Wert als einfaches Objekt, oder ein leeres Objekt {}. Nutze es, bevor du Felder eines Werts liest, der fehlen kann.
Seite: Client, Server und NUI · Wartet: nein
record(value: unknown): Record<string, unknown>Parameter
Prop
Type
Rückgabewert
value selbst, wenn es ein einfaches Objekt ist, sonst ein neues {} (auch für Arrays und null).
Beispiel
import { num, record } from "@aicore-fivem/lib/shared";
function readCoords(raw: unknown) {
const c = record(raw); // {}, wenn das Feld fehlt
return { x: num(c.x, 0), y: num(c.y, 0), z: num(c.z, 0) };
}vec4
Eine Position mit Heading; jedes fehlende oder falsche Feld kommt aus dem Fallback.
Seite: Client, Server und NUI · Wartet: nein
vec4(value: unknown, fallback: Vec4): Vec4Parameter
Prop
Type
Rückgabewert
Ein neues Vec4.
Beispiel
import { vec4 } from "@aicore-fivem/lib/shared";
vec4({ x: 10, y: 20, z: 30 }, { x: 0, y: 0, z: 0, heading: 90 }); // { x: 10, y: 20, z: 30, heading: 90 }Schema-Helfer
spec
Builder für Zahlenfelder in deinem Panel-schema.ts, damit du nicht dasselbe DataSpec-Objekt von Hand schreibst.
Seite: Client, Server und NUI · Wartet: nein
spec.int(min: number, max: number, optional?: boolean): DataSpec
spec.num(min: number, max: number, optional?: boolean): DataSpecParameter
Prop
Type
Rückgabewert
DataSpec: { type: "number", min, max }, plus integer: true bei spec.int und optional: true, wenn verlangt.
Beispiel
import { spec } from "@aicore-fivem/lib/shared";
import type { PanelSchema } from "@aicore-fivem/shared";
export const schema: PanelSchema = {
title: "ADMIN_TITLE",
icon: "store",
files: {
settings: {
kind: "settings",
sync: "admin",
sections: {
prices: { type: "object", fields: { water: spec.int(0, 1_000_000), tax: spec.num(0, 0.5) } },
},
},
},
tabs: [], // das Panel-Layout (Karten und Felder), siehe Admin-Panel
};withoutSchemaKey
Entfernt den Schlüssel "$schema" aus dem Inhalt einer Datendatei. Der Schlüssel ist nur da, damit Code-Editoren die Datei prüfen können; dein Reader soll ihn nicht sehen.
Seite: Client, Server und NUI · Wartet: nein
withoutSchemaKey(value: unknown): unknownParameter
Prop
Type
Rückgabewert
Eine Kopie ohne $schema, wenn der Wert ein Objekt ist, das ihn hat; sonst value unverändert.
Beispiel
import { withoutSchemaKey } from "@aicore-fivem/lib/shared";
withoutSchemaKey({ $schema: "./schemas/shops.schema.json", legion: { label: "Legion" } });
// { legion: { label: "Legion" } }Records-Dateien
Eine Records-Datei hält viele Einträge nach Schlüssel ({ "legion": {...}, "pillbox": {...} }): Shops, Garagen, Rathäuser. Jeder Eintrag wird von deiner eigenen Reader-Funktion gelesen (RecordReader<T> = (key: string, raw: Record<string, unknown>) => T | null), gebaut aus den Wertlesern oben.
readRecords
Liest eine ganze Records-Datei einmal in eine Map, ein Eintrag pro Schlüssel, über deinen Reader. Einträge, die keine Objekte sind oder für die dein Reader null zurückgibt, werden weggelassen.
Seite: Client, Server und NUI · Wartet: nein
readRecords<T>(raw: unknown, readOne: RecordReader<T>): Map<string, T>Parameter
Prop
Type
Rückgabewert
Map<string, T>: die geparsten Einträge nach Schlüssel.
Beispiel
import { readRecords, str, num, record } from "@aicore-fivem/lib/shared";
type Shop = { label: string; x: number; y: number; z: number };
const readShop = (key: string, v: Record<string, unknown>): Shop => {
const c = record(v.coords);
return { label: str(v.label, key, 48), x: num(c.x, 0), y: num(c.y, 0), z: num(c.z, 0) };
};
const shops = readRecords({ legion: { label: "Legion", coords: { x: 25.7, y: -1347.3, z: 29.5 } } }, readShop);
shops.get("legion"); // { label: "Legion", x: 25.7, y: -1347.3, z: 29.5 }Für eine Panel-Datei nutze lieber panel.records(file, readOne) (Server-AdminPanel) oder world.records(file, readOne) (Client-AdminWorld): Sie geben eine Map zurück, die aktuell bleibt, während der Betreiber bearbeitet, und parsen nur den geänderten Eintrag.
RecordObjects
Hält die Weltobjekte einer Records-Datei (Punkte, Blips, Peds, Zonen) Eintrag für Eintrag im Gleichschritt mit dem Panel: Ein bearbeiteter Eintrag baut nur seine eigenen Objekte neu. Es wird aus @aicore-fivem/lib/shared exportiert und hat keinen Lua-Zwilling. Seine vollständige Referenz (Konstruktor, build-Funktion, rebuild, rebuildAll, Beispiel) steht unter Interaktionspunkte: RecordObjects.
Fahrzeuge
plateOf, normalizePlate, vehicleTypeOfClass, toVehicleProps und toVehicleSetup: Kennzeichen als Schlüssel, Spawn-Typen und Fahrzeug-Aussehen aus nicht vertrauenswürdigen Daten.
Zugriff, Blips und Orts-NPCs
readAccess, isPublic, decideAccess, ACCESS_FIELDS, accessFields, readBlipStyle, BLIP_STYLE_FIELDS, PLACE_PED_SPEC, placePedFields und readPlacePed: die Panel-Teile, die jeder Ort teilt.