Agendamento e ciclo de vida
every, onStop, caller, ByResource, Reasons, sleep e waitFor: trabalho periódico, espera, e dados que pertencem ao recurso que os registrou.
import { every, onStop, caller, ByResource, Reasons } from "@aicore-fivem/lib/fivem";
import { sleep, waitFor } from "@aicore-fivem/lib/shared";Trabalho periódico
every
Roda uma função a cada ms milissegundos (0 = a cada frame) a partir do único agendador do seu recurso. Use em vez de setInterval, setTick ou um loop de CreateThread com Wait: todos os jobs de um recurso compartilham um tick, e esse tick só existe enquanto pelo menos um job está ligado, então um recurso ocioso não custa nada no resmon.
Lado: Cliente e servidor · Espera: não
every(ms: number, fn: () => unknown, options?: EveryOptions): Joblocal job = aiLib.every(ms, fn, options) -- job:set(active), job:stop(), job.runningParâmetros
Prop
Type
EveryOptions
Prop
Type
Retorno
Job: um handle para ligar e desligar o job.
Prop
Type
Exemplo
Um job por frame que só roda enquanto tem algo a fazer:
import { every, cache, onCache } from "@aicore-fivem/lib/client";
// Esconde a mira a cada frame, mas só enquanto há uma arma na mão.
const hideCrosshair = every(0, () => HideHudComponentThisFrame(14), {
active: cache.weapon !== false,
name: "hide crosshair",
});
onCache("weapon", (weapon) => hideCrosshair.set(weapon !== false));Um job nunca deve esperar: nada de Wait em Lua, nada de uma cadeia longa de await que você espera que termine antes da próxima execução em TypeScript. Em Lua um Wait dentro de um job segura todos os outros jobs do recurso; para isso, inicie uma thread a partir do job. Um job que falha é registrado em log no máximo uma vez a cada 10 segundos (os erros no meio são somados na linha seguinte).
Espera
sleep
Espera ms milissegundos.
Lado: Cliente, servidor e NUI · Espera: sim (Promise)
sleep(ms: number): Promise<void>Lua: sem equivalente; use Wait(ms) dentro de uma thread.
Parâmetros
Prop
Type
Retorno
Promise<void> que resolve depois de ms milissegundos.
Exemplo
import { sleep } from "@aicore-fivem/lib/shared";
import { fadeOut, fadeIn } from "@aicore-fivem/lib/client";
async function blink(): Promise<void> {
await fadeOut(300);
await sleep(1000);
await fadeIn(300);
}waitFor
Verifica uma condição até ela dar um valor, depois retorna esse valor. Use para esperar algo que o jogo faz no próprio tempo: uma entidade existir, um modelo carregar, um valor chegar.
Lado: Cliente, servidor e NUI · Espera: sim (Promise em TypeScript, pausa a thread em Lua)
waitFor<T>(check: () => T | undefined, timeoutMs?: number | false, intervalMs?: number): Promise<T>local value = aiLib.waitFor(check, timeout, interval) -- valor, ou nil depois do timeout; chame dentro de uma threadParâmetros
Prop
Type
Retorno
TypeScript: Promise<T> que resolve com o primeiro valor diferente de undefined que check retornou. Ela rejeita com Error("waitFor timed out after <ms> ms") depois do timeout.
Lua: o valor, ou nil depois do timeout (não lança erro).
Exemplo
import { waitFor } from "@aicore-fivem/lib/shared";
async function vehicleFromNet(netId: number): Promise<number | null> {
try {
return await waitFor(() => {
const vehicle = NetworkGetEntityFromNetworkId(netId);
return DoesEntityExist(vehicle) ? vehicle : undefined;
}, 5000);
} catch {
return null; // não foi transmitido em 5 segundos
}
}Em TypeScript, sempre trate a rejeição (try / catch ou .catch()), ou passe false como timeout. Em Lua, waitFor só funciona dentro de uma thread.
Ciclo de vida do recurso
onStop
Roda uma função quando o seu recurso para (no lado em que o código roda). Use para apagar o que natives criaram e nada mais remove: entidades que você spawnou, câmeras, um foco de NUI.
Lado: Cliente e servidor · Espera: não
onStop(fn: () => void): voidLua: sem equivalente; use AddEventHandler('onResourceStop', function(name) if name == GetCurrentResourceName() then ... end end).
Parâmetros
Prop
Type
Retorno
void.
Exemplo
import { onStop } from "@aicore-fivem/lib/server";
const spawned = new Set<number>();
onStop(() => {
for (const entity of spawned) if (DoesEntityExist(entity)) DeleteEntity(entity);
});Todos os onStop, ByResource e Reasons de um recurso compartilham um listener de parada, então adicionar muitos não custa nada a mais.
caller
O nome do recurso que chamou o export que está rodando agora. Dentro do seu próprio código (fora de uma chamada de export) é o nome do seu recurso.
Lado: Cliente e servidor · Espera: não
caller(): stringLua: sem equivalente; use GetInvokingResource() or GetCurrentResourceName().
Retorno
string: o nome do recurso que chama, ou o nome deste recurso quando nenhum outro recurso está chamando.
Exemplo
import { registerExport, caller } from "@aicore-fivem/lib/server";
registerExport("Ping", () => {
console.log(`${caller()} asked for a ping`);
return true;
});ByResource
Um mapa cujas entradas pertencem ao recurso que as definiu. Quando esse recurso para, as entradas dele são removidas na hora (e onDrop roda para cada uma). Use para coisas que outros recursos registram pelos seus exports: hooks, prompts, itens, entradas de menu.
Lado: Cliente e servidor · Espera: não
new ByResource<K, V>(options?: { onDrop?: (resource: string, key: K, value: V) => void })Lua: sem equivalente.
Parâmetros
Prop
Type
Métodos
Prop
Type
Exemplo
import { ByResource, registerExport } from "@aicore-fivem/lib/server";
import { readText } from "@aicore-fivem/lib/shared";
type Hook = (source: number, text: string) => boolean;
const hooks = new ByResource<string, Hook>({
onDrop: (resource, id) => console.log(`${resource} stopped: hook ${id} removed`),
});
// Outro recurso: exports["my-chat"].AddHook("swear-filter", (source, text) => ...)
registerExport("AddHook", (id: unknown, hook: unknown) => {
const name = readText(id, 64);
if (name === null || typeof hook !== "function") return false;
hooks.set(name, hook as Hook); // owner = o recurso que chama AddHook
return true;
});
export function allowed(source: number, text: string): boolean {
for (const hook of hooks.values()) if (!hook(source, text)) return false;
return true;
}Reasons
Um interruptor que fica ligado enquanto pelo menos um motivo está definido. Cada recurso define os próprios motivos nomeados, e os motivos de um recurso que para são limpos. Use para "esconder o HUD", "pausar a sincronização", "bloquear o menu": vários scripts podem pedir ao mesmo tempo, e o estado só volta quando o último solta.
Lado: Cliente e servidor · Espera: não
new Reasons()Lua: sem equivalente.
Métodos
Prop
Type
Exemplo
import { Reasons, registerExport } from "@aicore-fivem/lib/client";
import { readText } from "@aicore-fivem/lib/shared";
const hidden = new Reasons();
hidden.onChange((any) => SendNUIMessage({ action: "visible", value: !any }));
// Outros recursos: exports["my-hud"].Hide("cutscene") e exports["my-hud"].Show("cutscene")
registerExport("Hide", (reason: unknown) => {
const name = readText(reason, 64);
if (name !== null) hidden.set(name, true);
});
registerExport("Show", (reason: unknown) => {
const name = readText(reason, 64);
if (name !== null) hidden.set(name, false);
});Exports entre recursos
registerExport, resourceExport, optionalExport, callExport, provideExport e isResourceStarted: oferecer e chamar exports a partir de TypeScript.
State bags
EntityState, PlayerState, GlobalKey, GlobalGroup e os parsers stateNumber, stateBoolean, stateString: ler valores replicados da memória.