AI Core
API-ReferenzAI Core: Server-Exports

Charaktere und Spieler

Die Daten und den Charakter eines geladenen Spielers lesen, einen Spieler per Charakter-ID oder Citizen-ID finden, den Charakter wechseln, einen Offline-Charakter versetzen, Spieler in Reichweite.

Ein Spieler ist eine verbundene Person mit einer Server-ID (source). Ein Charakter ist eine der Personen, die dieser Spieler spielt; er hat eine Datenbank-ID (charId) und eine Citizen-ID (citizenid, ein kurzer Text wie ABC12345). Ein Spieler hat einen geladenen Charakter, nachdem er auf dem Charakterbildschirm einen gewählt hat. Die meisten Exports hier antworten vorher mit null.

Export-Aufrufe kopieren ihre Antwort, also lies einmal, was du brauchst, und folge den Events von ai-core (ai-core:playerLoaded, ai-core:playerUnloaded), statt erneut zu fragen. Siehe Events und Zustand.

GetPlayerData

Alles, was ai-core für einen geladenen Spieler hält, in einem Objekt: Charakter, Geld, Jobs, Dienst, Gangs und Metadaten. Nutze es, wenn eine Ressource spät startet und den vollständigen Zustand eines Spielers einmal braucht; für einzelne Werte nutze die kleineren Exports unten.

Seite: Server · Wartet: nein · Lib: keine auf dem Server (getPlayerData der Client-Lib liest dieselben Daten im Spiel des Spielers)

Signature
GetPlayerData(src: number): AiPlayerData | null
Lua
local data = exports['ai-core']:GetPlayerData(source) -- Tabelle oder nil

Parameter

Prop

Type

Rückgabe

AiPlayerData | null: eine Kopie der Daten des Spielers (AiPlayerData). null, wenn niemand mit dieser Server-ID einen geladenen Charakter hat (nicht verbunden oder noch auf dem Charakterbildschirm). Die Kopie ändert sich später nicht: Rufe erneut auf oder folge den Events für neue Werte.

Beispiel

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("whoami", { help: "Shows your character", restricted: true }, (source) => {
  const data = core.GetPlayerData(source);
  if (!data?.character) return;
  const { firstname, lastname } = data.character;
  console.log(`${firstname} ${lastname}: job ${data.job.job} (grade ${data.job.grade}), cash ${data.money.cash ?? 0}`);
});

Das ganze Objekt wird bei jedem Aufruf kopiert. Rufe es nie in einer Schleife über alle Spieler oder in einem Timer auf: Lies einzelne Werte (GetMoney, GetDutyJob) oder nutze den online-Spiegel der Lib.

GetCharacter

Der geladene Charakter eines Spielers: Datenbank-ID, Citizen-ID, Slot, Namen, Geburtsdatum, Geschlecht und Nationalität. Nutze es, um einen Namen anzuzeigen oder etwas nach Charakter-ID zu speichern.

Seite: Server · Wartet: nein · Lib: keine (online.character(source) liest dasselbe aus dem Spiegel der Lib ohne Export-Aufruf)

Signature
GetCharacter(src: number): CharacterInfo | null
Lua
local character = exports['ai-core']:GetCharacter(source) -- Tabelle oder nil

Parameter

Prop

Type

Rückgabe

CharacterInfo | null: der Charakter (CharacterInfo). null, wenn der Spieler keinen geladenen Charakter hat.

Beispiel

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback("myscript:profile", (source) => {
  const character = core.GetCharacter(source);
  if (!character) return fail("NO_CHARACTER");
  return { ok: true, name: `${character.firstname} ${character.lastname}`, citizenid: character.citizenid };
});

GetSourceByCharId

Die Server-ID des Spielers, der gerade einen Charakter spielt. Nutze es, wenn du eine Charakter-ID gespeichert hast (einen Besitzer, einen Kontakt) und diese Person im Spiel erreichen musst.

Seite: Server · Wartet: nein · Lib: keine

Signature
GetSourceByCharId(charId: number): number | null
Lua
local src = exports['ai-core']:GetSourceByCharId(charId) -- Zahl oder nil

Parameter

Prop

Type

Rückgabe

number | null: die Server-ID des Spielers. null, wenn gerade niemand diesen Charakter spielt (offline, oder ein anderer Charakter ist geladen).

Beispiel

import { notify, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";

const core = resourceExport("ai-core");

/** Teilt einem Hausbesitzer mit, dass jemand geklingelt hat, wenn der Besitzer online ist. */
export function ringOwner(ownerCharId: number): void {
  const owner = core.GetSourceByCharId(ownerCharId);
  if (owner !== null) notify(owner, Locale("NOTIFY_DOORBELL"), "info");
}

GetSourceByCitizenId

Dasselbe wie GetSourceByCharId, per Citizen-ID. Nutze es mit Daten, die Citizen-IDs speichern (die meisten Tabellen im ESX- / QB-Stil tun das).

Seite: Server · Wartet: nein · Lib: keine

Signature
GetSourceByCitizenId(citizenid: string): number | null
Lua
local src = exports['ai-core']:GetSourceByCitizenId(citizenid) -- Zahl oder nil

Parameter

Prop

Type

Rückgabe

number | null: die Server-ID des Spielers, der diesen Charakter spielt. null, wenn der Charakter nicht geladen ist.

Beispiel

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("findcid", {
  help: "Finds the player of a citizen id",
  params: [{ name: "citizenid", type: "string" }],
  restricted: true,
}, (source, args) => {
  const target = core.GetSourceByCitizenId(args.citizenid);
  console.log(target === null ? "not online" : `server id ${target}`);
});

GetLoadedSources

Die Server-IDs aller Spieler, die einen geladenen Charakter haben. Nutze es für seltene Arbeit über den ganzen Server (eine Neustartwarnung, eine Admin-Liste).

Seite: Server · Wartet: nein · Lib: online.sources() liest dasselbe aus dem Spiegel der Lib

Signature
GetLoadedSources(): number[]
Lua
local sources = exports['ai-core']:GetLoadedSources() -- Liste von Zahlen

Parameter

Keine.

Rückgabe

number[]: eine Server-ID pro geladenem Spieler, in keiner festen Reihenfolge. Eine leere Liste, wenn niemand einen Charakter geladen hat. Spieler, die noch auf dem Charakterbildschirm sind, sind nicht enthalten.

Beispiel

import { addCommand, notify, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";

const core = resourceExport("ai-core");

addCommand("announce", {
  help: "Sends a notification to every player",
  params: [{ name: "text", type: "longString" }],
  restricted: true,
}, (_source, args) => {
  for (const target of core.GetLoadedSources())
    notify(target, Locale("NOTIFY_ANNOUNCEMENT", args.text), "warning");
});

Rufe auf einem häufigen Pfad nie einen weiteren Export für jede ID dieser Liste auf (GetLoadedSources() + GetDutyJob pro Spieler jede Sekunde). Wer im Dienst ist, Namen und Jobs vieler Spieler kommen aus dem online-Spiegel der Lib; wer in der Nähe ist, aus playersNear.

GetUserId

Die Account-ID eines verbundenen Spielers: die Zeile in ai_core_users, die den FiveM-Account des Spielers und jeden seiner Charaktere hält. Anders als die meisten Exports antwortet es auch, während der Spieler noch auf dem Charakterbildschirm ist.

Seite: Server · Wartet: nein · Lib: keine

Signature
GetUserId(src: number): number | null
Lua
local userId = exports['ai-core']:GetUserId(source) -- Zahl oder nil

Parameter

Prop

Type

Rückgabe

number | null: die Account-ID. null, wenn der Spieler nicht verbunden ist oder den Charakterbildschirm noch nicht erreicht hat.

Beispiel

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("account", {
  help: "Shows a player account id",
  params: [{ name: "id", type: "playerId" }],
  restricted: true,
}, (_source, args) => {
  console.log(`account ${core.GetUserId(args.id) ?? "unknown"}`);
});

GetFivemId

Die FiveM-Account-ID (Cfx.re) des Spielers. ai-core nutzt sie als Schlüssel des Accounts des Spielers: Ein Spieler ohne sie kann sich nicht verbinden.

Seite: Server · Wartet: nein · Lib: keine

Signature
GetFivemId(src: number): string | null
Lua
local fivemId = exports['ai-core']:GetFivemId(source) -- String oder nil

Parameter

Prop

Type

Rückgabe

string | null: die ID ohne das Präfix fivem: (zum Beispiel 1234567). null, wenn der Spieler keinen geladenen Charakter hat.

Beispiel

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("fivemid", {
  help: "Prints the add_principal line for a player",
  params: [{ name: "id", type: "playerId" }],
  restricted: true,
}, (_source, args) => {
  const id = core.GetFivemId(args.id);
  if (id) console.log(`add_principal identifier.fivem:${id} group.admin`);
});

GetCharacterInfo

Ein Charakter per Datenbank-ID, geladen oder nicht, mit der ID des Accounts, zu dem er gehört. Nutze es, um zu zeigen, wem etwas gehört, wenn diese Person offline sein kann.

Seite: Server · Wartet: nein (antwortet über done) · Lib: keine

Signature
GetCharacterInfo(
  charId: number,
  done: (info: (CharacterInfo & { userId: number }) | null) => void,
): void
Lua
exports['ai-core']:GetCharacterInfo(charId, function(info) end) -- info: Tabelle oder nil

Parameter

Prop

Type

Rückgabe

Nichts. done erhält ein CharacterInfo mit einem zusätzlichen Feld, userId (die Account-ID), oder null für einen unbekannten oder gelöschten Charakter, eine falsche ID oder einen fehlgeschlagenen Lesevorgang. Ohne eine Funktion als done tut der Aufruf nichts.

Beispiel

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("charinfo", {
  help: "Shows a character by id",
  params: [{ name: "charId", type: "number" }],
  restricted: true,
}, (_source, args) => {
  core.GetCharacterInfo(args.charId, (info) => {
    if (!info) return console.log("no such character");
    console.log(`${info.firstname} ${info.lastname} (${info.citizenid}), account ${info.userId}`);
  });
});

Ein gespeicherter Charakter wird nach dem Lesen 5 Minuten lang vorgehalten, sodass ein im Admin-Panel geänderter Name so lange den alten Wert zeigen kann. Ein geladener Charakter antwortet immer aus dem Speicher.

SwitchCharacter

Schickt einen Spieler zurück zum Charakterbildschirm, ohne den Server zu verlassen, wie ein Logout. ai-core speichert und entlädt den Charakter zuerst und öffnet dann den Bildschirm.

Seite: Server · Wartet: nein (das Entladen läuft, nachdem der Aufruf zurückkehrt) · Lib: keine

Signature
SwitchCharacter(src: number): boolean
Lua
local started = exports['ai-core']:SwitchCharacter(source) -- boolean

Parameter

Prop

Type

Rückgabe

boolean: true, wenn der Wechsel gestartet ist. false, wenn der Spieler keinen geladenen Charakter hat.

Beispiel

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

// Ein Button „Charakter wechseln“ in deinem Menü.
onClientCallback("myscript:logout", (source) =>
  core.SwitchCharacter(source) ? { ok: true } : fail("NO_CHARACTER"),
);

Deine Ressource hört ai-core:playerUnloaded mit dem Grund "switch", wenn der Charakter weg ist. Räume den Zustand pro Charakter dort auf, nicht direkt nach diesem Aufruf.

SetOfflinePosition

Verschiebt den Spawnpunkt eines Charakters, der nicht geladen ist: Wenn dieser Charakter das nächste Mal gewählt wird, erscheint er dort. Nutze es, wenn etwas einen schlafenden Körper oder einen Offline-Charakter bewegt (ein weggetragener Körper, ein abgeschleppter Spieler).

Seite: Server · Wartet: nein (das Schreiben folgt im Hintergrund) · Lib: characters.setOfflinePosition

Signature
SetOfflinePosition(
  charId: number,
  position: { x: number; y: number; z: number; heading?: number },
): boolean
Lua
local accepted = exports['ai-core']:SetOfflinePosition(charId, { x = x, y = y, z = z, heading = h })

Parameter

Prop

Type

Rückgabe

boolean: true, wenn die Verschiebung angenommen wurde; das Schreiben in die Datenbank folgt, sobald kein Laden oder Speichern dieses Charakters läuft (es wartet bis zu 30 Sekunden). false, wenn der Charakter gerade geladen ist, charId keine ganze Zahl ist oder eine Koordinate fehlt oder keine endliche Zahl ist. Ein fehlendes heading wird als 0 gespeichert.

Beispiel

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");
const HOSPITAL = { x: 298.6, y: -584.5, z: 43.3, heading: 70 };

/** Ein Körper, der zu lange in der Welt liegt, wird ins Krankenhaus gebracht. */
export function sendBodyToHospital(charId: number): void {
  if (!core.SetOfflinePosition(charId, HOSPITAL))
    console.log(`character ${charId} is online, not moved`);
}

Wird der Charakter geladen, während das Schreiben wartet, wird das Schreiben übersprungen: Der Ped eines geladenen Charakters ist dort, wo er wirklich ist.

GetPlayersInScope

Die Spieler im OneSync-Scope eines anderen Spielers: alle, deren Spiel diesen Spieler gerade streamt, etwa 424 Meter im Umkreis. ai-core führt diese Liste einmal für jede Ressource aus den Scope-Events von FiveM, sodass andere Ressourcen nie selbst auf diese Events hören.

Seite: Server · Wartet: nein · Lib: playersNear(source, radius) und playersNearEntity(entity, radius) bauen darauf auf und filtern nach Entfernung

Signature
GetPlayersInScope(source: number): number[]
Lua
local nearby = exports['ai-core']:GetPlayersInScope(source) -- Liste von Server-IDs

Parameter

Prop

Type

Rückgabe

number[]: die Server-IDs der anderen Spieler im Scope (der Spieler selbst ist nicht in der Liste). Eine leere Liste für einen Spieler allein, eine unbekannte ID oder einen Wert, der keine Zahl ist.

Beispiel

import { coordsOf, resourceExport } from "@aicore-fivem/lib/server";
import { distance } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

/** Spielt einen Sound für alle im Umkreis von 30 m um einen Spieler. */
export function playNear(source: number, sound: string): void {
  const at = coordsOf(source);
  for (const other of [source, ...core.GetPlayersInScope(source)])
    if (distance(coordsOf(other), at) <= 30) emitNet("myscript:sound", other, sound);
}

Auf dieser Seite