AI Core
API-ReferenzLib: Shared und fivem

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.

TypeScript
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

Signatur
num(value: unknown, fallback: number, min?: number, max?: number): number

Parameter

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

Signatur
int(value: unknown, fallback: number, min?: number, max?: number): number

Parameter

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); // 10

bool

Ein Boolean, sonst der Fallback.

Seite: Client, Server und NUI · Wartet: nein

Signatur
bool(value: unknown, fallback: boolean): boolean

Parameter

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

Signatur
str(value: unknown, fallback: string, max?: number): string

Parameter

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

Signatur
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

Signatur
vec4(value: unknown, fallback: Vec4): Vec4

Parameter

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

Signatur
spec.int(min: number, max: number, optional?: boolean): DataSpec
spec.num(min: number, max: number, optional?: boolean): DataSpec

Parameter

Prop

Type

Rückgabewert

DataSpec: { type: "number", min, max }, plus integer: true bei spec.int und optional: true, wenn verlangt.

Beispiel

resource/server/schema.ts
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

Signatur
withoutSchemaKey(value: unknown): unknown

Parameter

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

Signatur
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.

Auf dieser Seite