Akcje i wejście z klienta
fail, isActionOk, replyError i ścisłe czytniki readInt, readFinite, readId, readText, readVec3, readVec4, oneArg, asArgs, isRecord.
Wszystko, co wysyła klient, może zostać podrobione przez oszusta: ujemna kwota, ułamek tam, gdzie oczekujesz liczby całkowitej, string o rozmiarze 10 MB, obiekt zamiast liczby. Ścisłe czytniki z tej strony zamieniają jedną surową wartość w sprawdzoną wartość albo w null, żeby ją odrzucić. Nigdy nie zastępują złej wartości domyślną (to robią czytniki danych panelu, dla plików edytowanych przez właściciela serwera).
Każda akcja serwera odpowiada ActionResult: { ok: true } albo odmową z kluczem tłumaczenia.
import { fail, isActionOk, replyError, readInt, readFinite, readId, readText, readVec3, readVec4, oneArg, asArgs, isRecord } from "@aicore-fivem/lib/shared";Gdzie trafiają czytniki: do opcji args w onClientCallback i onClientEvent (zobacz Wejście z klienta). Parser dostaje surowe argumenty jako tablicę i zwraca sprawdzone jako tablicę albo null, żeby odrzucić wywołanie, zanim zadziała twój handler.
Wyniki akcji
fail
Buduje odmowę: { ok: false, error }. Zwróć ją z handlera akcji; callAction klienta pokazuje przetłumaczony tekst error jako powiadomienie o błędzie.
Strona: Klient, serwer i NUI · Czeka: nie
fail(error: string): { ok: false; error: string }return aiLib.fail('NOT_ENOUGH_MONEY') -- { ok = false, error = 'NOT_ENOUGH_MONEY' }Parametry
Prop
Type
Zwracana wartość
{ ok: false, error: string }, co pasuje do każdego ActionResult.
Przykład
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, oneArg, readInt, type ActionResult } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
onClientCallback(
"my-shop:buyWater",
{ args: oneArg((v) => readInt(v, 1, 10)), lock: true },
(source, count): ActionResult => {
if (!core.CanCarryItem(source, "water", count)) return fail("NO_SPACE");
if (!core.RemoveMoney(source, "cash", count * 5, "Water")) return fail("NOT_ENOUGH_MONEY");
core.AddItem(source, "water", count);
return { ok: true };
},
);Na kliencie callAction("my-shop:buyWater", [2], { fallback: "BUY_FAILED" }) (Lua aiLib.callAction) pokazuje odmowę za ciebie. Zobacz Rozmowa z serwerem.
isActionOk
Sprawdza, czy odpowiedź to udany ActionResult (ok === true). Używaj jej, gdy czytasz odpowiedź ręcznie zamiast przez callAction.
Strona: Klient, serwer i NUI · Czeka: nie
isActionOk(reply: unknown): reply is { ok: true } & Record<string, unknown>Lua: brak odpowiednika; sprawdź type(reply) == 'table' and reply.ok == true.
Parametry
Prop
Type
Zwracana wartość
true, gdy reply jest obiektem z ok: true. Dodatkowe pola nie są sprawdzane: parsuj te, które czytasz.
Przykład
import { triggerServerCallback } from "@aicore-fivem/lib/client";
import { isActionOk, readId } from "@aicore-fivem/lib/shared";
/** Asks the server to create a garage; answers its new id, or null. */
async function createGarage(name: string): Promise<number | null> {
const reply = await triggerServerCallback("my-garage:create", [name]).catch(() => null);
if (!isActionOk(reply)) return null;
return readId(reply.id); // dodatkowe pole: sprawdź je jak każde inne wejście
}replyError
Klucz tłumaczenia odrzuconej odpowiedzi: jej error albo fallback, gdy odpowiedzi brak lub jest zniekształcona. null, gdy odpowiedź jest ok.
Strona: Klient, serwer i NUI · Czeka: nie
replyError(reply: unknown, fallback: string): string | nullLua: brak odpowiednika.
Parametry
Prop
Type
Zwracana wartość
null dla odpowiedzi ok. W przeciwnym razie error odpowiedzi, gdy jest niepustym stringiem, a jeśli nie, fallback.
Przykład
import { triggerServerCallback, notify, loadLocaleTexts } from "@aicore-fivem/lib/client";
import { replyError } from "@aicore-fivem/lib/shared";
const texts = loadLocaleTexts();
async function buyWater(): Promise<boolean> {
const reply = await triggerServerCallback("my-shop:buy", ["water"]).catch(() => null);
const error = replyError(reply, "BUY_FAILED");
if (error !== null) notify(texts[error] ?? error, "error");
return error === null;
}Ścisłe czytniki
readFinite
Skończona liczba, w przeciwnym razie null. NaN, Infinity, tekst i wszystko inne są odrzucane.
Strona: Klient, serwer i NUI · Czeka: nie
readFinite(value: unknown): number | nullLua: brak odpowiednika; sprawdź type(value) == 'number' and value == value and value ~= math.huge and value ~= -math.huge.
Parametry
Prop
Type
Zwracana wartość
Liczba albo null.
Przykład
import { readFinite } from "@aicore-fivem/lib/shared";
readFinite(12.5); // 12.5
readFinite(NaN); // null
readFinite("12"); // nullreadInt
Liczba całkowita od min do max (obie włącznie), w przeciwnym razie null. Ułamki, NaN, Infinity, tekst i wartości spoza zakresu są odrzucane. Używaj jej dla liczebności, kwot, slotów, indeksów.
Strona: Klient, serwer i NUI · Czeka: nie
readInt(value: unknown, min: number, max: number): number | nullLua: brak odpowiednika; sprawdź math.type(value) == 'integer' and value >= min and value <= max.
Parametry
Prop
Type
Zwracana wartość
Liczba albo null.
Przykład
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readInt, readText } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
const prices = new Map<string, number>([["water", 5], ["bread", 3]]);
onClientCallback(
"my-shop:buy",
{
args: ([rawItem, rawCount]) => {
const item = readText(rawItem, 64);
const count = readInt(rawCount, 1, 50);
return item !== null && count !== null ? [item, count] : null;
},
lock: true,
},
(source, item, count) => {
const price = prices.get(item); // tylko przedmioty, które sprzedaje ten sklep
if (price === undefined) return fail("UNKNOWN_ITEM");
if (!core.CanCarryItem(source, item, count)) return fail("NO_SPACE");
if (!core.RemoveMoney(source, "cash", price * count, "Shop")) return fail("NOT_ENOUGH_MONEY");
core.AddItem(source, item, count);
return { ok: true };
},
);readId
Dodatnia 32-bitowa liczba całkowita (od 1 do 2 147 483 647), w przeciwnym razie null. Używaj jej dla id rekordów, tokenów i id sieciowych wysyłanych przez klienta.
Strona: Klient, serwer i NUI · Czeka: nie
readId(value: unknown): number | nullLua: brak odpowiednika; sprawdź math.type(value) == 'integer' and value > 0 and value <= 2147483647.
Parametry
Prop
Type
Zwracana wartość
Id albo null.
Przykład
import { onClientCallback, vehicleFromNet } from "@aicore-fivem/lib/server";
import { oneArg, readId, fail } from "@aicore-fivem/lib/shared";
onClientCallback("my-tow:attach", { args: oneArg(readId) }, (source, netId) => {
const vehicle = vehicleFromNet(netId);
if (vehicle === 0) return fail("NO_VEHICLE");
return { ok: true };
});Prawidłowe id to jeszcze nie prawidłowy cel. Zawsze sprawdzaj, czy rekord lub encja istnieje, czy gracz może z niej korzystać i czy jest blisko niej.
readText
Przycięty, niepusty string skrócony do max znaków, w przeciwnym razie null. Używaj go dla nazw, nazw przedmiotów, notatek, tekstu wyszukiwania.
Strona: Klient, serwer i NUI · Czeka: nie
readText(value: unknown, max: number): string | nullLua: brak odpowiednika; sprawdź type(value) == 'string', potem go przytnij i skróć (value:sub(1, max)).
Parametry
Prop
Type
Zwracana wartość
Przycięty tekst (najwyżej max znaków) albo null, gdy nie jest stringiem albo jest pusty po przycięciu.
Przykład
import { readText } from "@aicore-fivem/lib/shared";
readText(" Hello ", 64); // "Hello"
readText(" ", 64); // null
readText(42, 64); // nullreadVec3
Punkt z wejścia klienta albo eksportu, każda współrzędna skończona, w przeciwnym razie null. Przyjmuje obiekt { x, y, z } i wektor Lua, który dociera do TypeScript jako tablica [x, y, z].
Strona: Klient, serwer i NUI · Czeka: nie
readVec3(value: unknown): { x: number; y: number; z: number } | nullLua: brak odpowiednika; kod Lua czyta value.x, value.y, value.z (działa dla wektorów i tabel).
Parametry
Prop
Type
Zwracana wartość
Nowy obiekt Vec3 albo null.
Przykład
import { registerExport } from "@aicore-fivem/lib/server";
import { readVec3, type Vec3 } from "@aicore-fivem/lib/shared";
const markers: Vec3[] = [];
// Działa dla exports["my-markers"].AddMarker(vector3(1, 2, 3)) z Lua i AddMarker({ x: 1, y: 2, z: 3 }) z TypeScript.
registerExport("AddMarker", (raw: unknown) => {
const point = readVec3(raw);
if (!point) return false;
markers.push(point);
return true;
});readVec4
Punkt z kierunkiem, w przeciwnym razie null. Przyjmuje { x, y, z, heading }, { x, y, z, w } i vector4 z Lua ([x, y, z, w]). Brakujący kierunek czyta się jako 0.
Strona: Klient, serwer i NUI · Czeka: nie
readVec4(value: unknown): { x: number; y: number; z: number; heading: number } | nullLua: brak odpowiednika.
Parametry
Prop
Type
Zwracana wartość
Nowy obiekt Vec4 (heading 0, gdy nie podano) albo null, gdy współrzędna lub podany kierunek nie jest skończoną liczbą.
Przykład
import { readVec4 } from "@aicore-fivem/lib/shared";
readVec4({ x: 1, y: 2, z: 3, w: 90 }); // { x: 1, y: 2, z: 3, heading: 90 }
readVec4([1, 2, 3]); // { x: 1, y: 2, z: 3, heading: 0 }
readVec4({ x: 1, y: 2 }); // nulloneArg
Zamienia czytnik w parser args dla callbacka albo zdarzenia, które przyjmuje dokładnie jedną wartość: { args: oneArg(readId) }.
Strona: Klient, serwer i NUI · Czeka: nie
oneArg<T>(read: (value: unknown) => T | null): (args: unknown[]) => [T] | nullLua: brak odpowiednika.
Parametry
Prop
Type
Zwracana wartość
Parser, który zwraca [value] albo null (odrzuca wywołanie), gdy read zwrócił null.
Przykład
import { onClientCallback } from "@aicore-fivem/lib/server";
import { oneArg, readText } from "@aicore-fivem/lib/shared";
const notes = new Map<number, string>();
onClientCallback("my-notes:save", { args: oneArg((v) => readText(v, 500)) }, (source, text) => {
notes.set(source, text);
return { ok: true };
});asArgs
Opakowuje jedną już sparsowaną wartość jako wynik args: [value] albo null, gdy wartość to null. Używaj jej, gdy twoja własna funkcja sprawdzająca zwraca wartość albo null.
Strona: Klient, serwer i NUI · Czeka: nie
asArgs<T>(value: T | null): [T] | nullLua: brak odpowiednika.
Parametry
Prop
Type
Zwracana wartość
[value] albo null.
Przykład
import { onClientCallback } from "@aicore-fivem/lib/server";
import { asArgs, toVehicleSetup, type VehicleSetup } from "@aicore-fivem/lib/shared";
const previews = new Map<number, VehicleSetup>();
onClientCallback("my-shop:preview", { args: ([raw]) => asArgs(toVehicleSetup(raw)) }, (source, setup) => {
previews.set(source, setup);
return { ok: true };
});isRecord
Sprawdza, czy wartość jest zwykłym obiektem (nie null, nie tablicą).
Strona: Klient, serwer i NUI · Czeka: nie
isRecord(value: unknown): value is Record<string, unknown>Lua: brak odpowiednika; sprawdź type(value) == 'table'.
Parametry
Prop
Type
Zwracana wartość
true dla obiektu jak { a: 1 }. false dla null, tablic, liczb, stringów.
Przykład
import { isRecord, readText } from "@aicore-fivem/lib/shared";
function readNote(raw: unknown): { title: string } | null {
if (!isRecord(raw)) return null;
const title = readText(raw.title, 80);
return title === null ? null : { title };
}