AI Core
Dokumentacja APIAI Core: eksporty serwerowe

Postacie i gracze

Odczytaj dane i postać wczytanego gracza, znajdź gracza po id postaci lub citizen id, zmień postać, przenieś postać offline, gracze w zasięgu.

Gracz to połączona osoba z id serwera (source). Postać to jedna z osób, którymi gra ten gracz; ma id w bazie danych (charId) i citizen id (citizenid, krótki tekst, taki jak ABC12345). Gracz ma wczytaną postać po wybraniu jej na ekranie postaci. Większość eksportów tutaj odpowiada przed tym null.

Wywołania eksportów kopiują swoją odpowiedź, więc odczytaj to, czego potrzebujesz, raz i śledź zdarzenia ai-core (ai-core:playerLoaded, ai-core:playerUnloaded) zamiast pytać ponownie. Zobacz Zdarzenia i stan.

GetPlayerData

Wszystko, co ai-core trzyma dla wczytanego gracza, w jednym obiekcie: postać, pieniądze, prace, służba, gangi i metadane. Używaj tego, gdy zasób startuje późno i raz potrzebuje pełnego stanu gracza; dla pojedynczych wartości używaj mniejszych eksportów poniżej.

Strona: Serwer · Czeka: nie · Lib: brak na serwerze (getPlayerData z klienckiego liba czyta te same dane w grze gracza)

Sygnatura
GetPlayerData(src: number): AiPlayerData | null
Lua
local data = exports['ai-core']:GetPlayerData(source) -- table lub nil

Parametry

Prop

Type

Zwraca

AiPlayerData | null: kopia danych gracza (AiPlayerData). null, gdy nikt z tym id serwera nie ma wczytanej postaci (niepołączony albo jeszcze na ekranie postaci). Kopia nie zmienia się później: wywołaj ponownie albo śledź zdarzenia, aby dostać nowe wartości.

Przykład

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}`);
});

Cały obiekt jest kopiowany przy każdym wywołaniu. Nigdy nie wywołuj tego w pętli po wszystkich graczach ani na timerze: czytaj pojedyncze wartości (GetMoney, GetDutyJob) albo używaj lustra online liba.

GetCharacter

Wczytana postać gracza: id w bazie danych, citizen id, slot, imię i nazwisko, data urodzenia, płeć i narodowość. Używaj tego, aby pokazać imię albo zapisać coś według id postaci.

Strona: Serwer · Czeka: nie · Lib: brak (online.character(source) czyta to samo z lustra liba bez wywołania eksportu)

Sygnatura
GetCharacter(src: number): CharacterInfo | null
Lua
local character = exports['ai-core']:GetCharacter(source) -- table lub nil

Parametry

Prop

Type

Zwraca

CharacterInfo | null: postać (CharacterInfo). null, gdy gracz nie ma wczytanej postaci.

Przykład

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

Id serwera gracza, który teraz gra daną postacią. Używaj tego, gdy zapisałeś id postaci (właściciel, kontakt) i musisz dotrzeć do tej osoby w grze.

Strona: Serwer · Czeka: nie · Lib: brak

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

Parametry

Prop

Type

Zwraca

number | null: id serwera gracza. null, gdy nikt teraz nie gra tą postacią (offline albo wczytana jest inna postać).

Przykład

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

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

/** Tells a house owner that someone rang, when the owner is online. */
export function ringOwner(ownerCharId: number): void {
  const owner = core.GetSourceByCharId(ownerCharId);
  if (owner !== null) notify(owner, Locale("NOTIFY_DOORBELL"), "info");
}

GetSourceByCitizenId

To samo co GetSourceByCharId, ale według citizen id. Używaj tego z danymi, które zapisują citizen id (robi to większość tabel w stylu ESX / QB).

Strona: Serwer · Czeka: nie · Lib: brak

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

Parametry

Prop

Type

Zwraca

number | null: id serwera gracza grającego tą postacią. null, gdy postać nie jest wczytana.

Przykład

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

Id serwera każdego gracza, który ma wczytaną postać. Używaj tego do rzadkiej pracy na całym serwerze (ostrzeżenie o restarcie, lista dla administratora).

Strona: Serwer · Czeka: nie · Lib: online.sources() czyta to samo z lustra liba

Sygnatura
GetLoadedSources(): number[]
Lua
local sources = exports['ai-core']:GetLoadedSources() -- lista liczb

Parametry

Brak.

Zwraca

number[]: jedno id serwera na wczytanego gracza, bez ustalonej kolejności. Pusta lista, gdy nikt nie ma wczytanej postaci. Gracze, którzy są jeszcze na ekranie postaci, nie są w niej.

Przykład

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");
});

Nigdy nie wywołuj innego eksportu dla każdego id z tej listy na częstej ścieżce (GetLoadedSources() + GetDutyJob dla każdego gracza co sekundę). Kto jest na służbie, imiona i prace wielu graczy pochodzą z lustra online liba; kto jest w pobliżu, z playersNear.

GetUserId

Id konta połączonego gracza: wiersz w ai_core_users, który trzyma konto FiveM gracza i każdą jego postać. W odróżnieniu od większości eksportów odpowiada też, gdy gracz jest jeszcze na ekranie postaci.

Strona: Serwer · Czeka: nie · Lib: brak

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

Parametry

Prop

Type

Zwraca

number | null: id konta. null, gdy gracz nie jest połączony albo jeszcze nie dotarł do ekranu postaci.

Przykład

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

Id konta FiveM (Cfx.re) gracza. ai-core używa go jako klucza konta gracza: gracz bez niego nie może się połączyć.

Strona: Serwer · Czeka: nie · Lib: brak

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

Parametry

Prop

Type

Zwraca

string | null: id bez prefiksu fivem: (na przykład 1234567). null, gdy gracz nie ma wczytanej postaci.

Przykład

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

Postać według id w bazie danych, wczytana lub nie, z id konta, do którego należy. Używaj tego, aby pokazać, kto jest właścicielem czegoś, gdy ta osoba może być offline.

Strona: Serwer · Czeka: nie (odpowiada przez done) · Lib: brak

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

Parametry

Prop

Type

Zwraca

Nic. done dostaje CharacterInfo z jednym polem więcej, userId (id konta), albo null dla nieznanej lub usuniętej postaci, złego id albo nieudanego odczytu. Bez funkcji jako done wywołanie nic nie robi.

Przykład

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}`);
  });
});

Zapisana postać jest trzymana przez 5 minut po odczycie, więc imię zmienione w panelu administratora może tak długo pokazywać starą wartość. Wczytana postać zawsze odpowiada z pamięci.

SwitchCharacter

Wysyła gracza z powrotem na ekran postaci bez opuszczania serwera, jak wylogowanie. ai-core najpierw zapisuje i zwalnia postać, potem otwiera ekran.

Strona: Serwer · Czeka: nie (zwolnienie postaci odbywa się po powrocie z wywołania) · Lib: brak

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

Parametry

Prop

Type

Zwraca

boolean: true, gdy zmiana się rozpoczęła. false, gdy gracz nie ma wczytanej postaci.

Przykład

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

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

// Przycisk "Zmień postać" w twoim menu.
onClientCallback("myscript:logout", (source) =>
  core.SwitchCharacter(source) ? { ok: true } : fail("NO_CHARACTER"),
);

Twój zasób słyszy ai-core:playerUnloaded z powodem "switch", gdy postaci już nie ma. Tam sprzątaj stan per postać, nie zaraz po tym wywołaniu.

SetOfflinePosition

Przenosi miejsce pojawienia się postaci, która nie jest wczytana: następnym razem, gdy ta postać zostanie wybrana, pojawi się tam. Używaj tego, gdy coś przenosi śpiące ciało lub postać offline (wyniesione ciało, odholowany gracz).

Strona: Serwer · Czeka: nie (zapis następuje w tle) · Lib: characters.setOfflinePosition

Sygnatura
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 })

Parametry

Prop

Type

Zwraca

boolean: true, gdy przeniesienie zostało przyjęte; zapis do bazy danych następuje, gdy nie trwa żadne wczytywanie ani zapis tej postaci (czeka do 30 sekund). false, gdy postać jest teraz wczytana, charId nie jest liczbą całkowitą albo brakuje współrzędnej lub nie jest skończoną liczbą. Brakujący heading jest zapisywany jako 0.

Przykład

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 };

/** A body left in the world too long is moved to the hospital. */
export function sendBodyToHospital(charId: number): void {
  if (!core.SetOfflinePosition(charId, HOSPITAL))
    console.log(`character ${charId} is online, not moved`);
}

Jeśli postać zostanie wczytana, gdy zapis czeka, zapis jest pomijany: ped wczytanej postaci jest tam, gdzie naprawdę jest.

GetPlayersInScope

Gracze w zasięgu OneSync innego gracza: każdy, czyja gra obecnie streamuje tego gracza, około 424 metrów wokół. ai-core prowadzi tę listę ze zdarzeń zasięgu FiveM raz dla każdego zasobu, więc inne zasoby nigdy same nie nasłuchują tych zdarzeń.

Strona: Serwer · Czeka: nie · Lib: playersNear(source, radius) i playersNearEntity(entity, radius) bazują na tym i filtrują według odległości

Sygnatura
GetPlayersInScope(source: number): number[]
Lua
local nearby = exports['ai-core']:GetPlayersInScope(source) -- lista id serwera

Parametry

Prop

Type

Zwraca

number[]: id serwera pozostałych graczy w zasięgu (sam gracz nie jest na liście). Pusta lista dla samotnego gracza, nieznanego id albo wartości, która nie jest liczbą.

Przykład

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

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

/** Plays a sound for everyone within 30 m of a player. */
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);
}

Na tej stronie