AI Core
API başvurusuEvent’ler ve durum

Server event’leri

ai-core’un tetiklediği her server tarafı local event - karakterler, para, meslekler, mesai, çeteler, metadata, tanımlar, eşyalar, ölümler - TypeScript ve Lua’da argümanları ve dinleyicileriyle.

ai-core bu event’leri server’da TriggerEvent ile tetikler (local: diğer server resource’ları duyar, client’lar asla duymaz). Lib’in online aynası ve ESX / QB / vRP köprüleri bunların üstüne kurulmuştur, bu yüzden oyuncuları izlemenin en ucuz yoludur: export çağrısı yok, yoklama yok.

Her event’in handler’ı ai-core değişikliğin ortasındayken senkron çalışır: handler’ları kısa tut ve içlerinde asla bekleme. Beklemen gerekiyorsa (bir veritabanı yazması) bloklamadan başlat.

ai-core:playerLoaded

Bir oyuncunun karakteri yüklendi ve verisi client’ına gönderildi. Karakter yüklemesi başına bir kez tetiklenir, karakter değişiminden sonra da. Doğma seçimi açıkken oyuncu nerede görüneceğini seçmeden önce tetiklenir; seçimin ardından ai-core:playerSpawned gelir.

Taraf: Server · Sabit: CORE.playerLoadedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE, type CharacterInfo } from "@aicore-fivem/shared";

on(CORE.playerLoadedEvent, (src: number, character: CharacterInfo) => {
  console.log(`#${character.id} ${character.firstname} ${character.lastname} loaded (src ${src})`);
});

Resource’un başlamadan önce zaten yüklenmiş karakterler bunu senin için asla tetiklemez. Onları yeniden oynatan lib’in onCharacter({ loaded })’ını (Lua’da aiLib.onCharacter) kullan.

ai-core:playerSpawned

Yüklü karakter dünyaya kondu. ai-core:playerLoaded’dan hemen sonra ya da sunucu seçmelerine izin veriyorsa oyuncu bir doğma noktası seçtikten sonra tetiklenir. Dünyada ped gerektiren şeyler için kullan (bir karşılama mesajı, bir ışınlanma).

Taraf: Server · Sabit: CORE.playerSpawnedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { notify } from "@aicore-fivem/lib/server";
import { CORE } from "@aicore-fivem/shared";
import { Locale } from "common";

on(CORE.playerSpawnedEvent, (src: number, _charId: number) => {
  notify(src, Locale("WELCOME_BACK"), "info");
});

ai-core:playerUnloaded

Bir karakter bırakılıyor: oyuncu sunucudan ayrıldı ya da karakter ekranına döndü. ai-core karakteri bırakmadan önce tetiklenir, bu yüzden ai-core’un export’ları handler’ının içinde onun için hâlâ cevap verir. Oyuncu başına tuttuğun her şeyi burada temizle.

Taraf: Server · Sabit: CORE.playerUnloadedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

const activeJobs = new Map<number, string>();

on(CORE.playerUnloadedEvent, (src: number, _charId: number, reason: "dropped" | "switch") => {
  activeJobs.delete(src);
  console.log(`${src} unloaded (${reason})`);
});

reason = "switch" ile aynı server id bir an sonra başka bir karakter yükleyebilir. Karakter başına verini charId ile anahtarla ya da burada temizle; bir server id’nin tek bir karakteri koruduğunu asla varsayma.

ai-core:moneyChanged

Yüklü bir karakterin bir hesap bakiyesi değişti. Değişiklik uygulandıktan sonra, değişiklik başına bir kez, yalnızca bakiye gerçekten hareket ettiğinde tetiklenir.

Taraf: Server · Sabit: CORE.moneyChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

// Büyük nakit ödemeleri yetkililer için işaretler.
on(CORE.moneyChangedEvent, (src: number, account: string, balance: number, delta: number, reason: string) => {
  if (account === "cash" && delta >= 100_000)
    console.log(`${src} got $${delta} cash (${reason}), now $${balance}`);
});

ai-core:jobsChanged

Yüklü bir karakterin sahip olduğu meslekler listesi değişti: bir meslek eklendi ya da kaldırıldı veya bir rütbe değişti.

Taraf: Server · Sabit: CORE.jobsChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE, type JobMembership } from "@aicore-fivem/shared";

on(CORE.jobsChangedEvent, (src: number, jobs: JobMembership[]) => {
  const police = jobs.find((m) => m.job === "police");
  console.log(police ? `${src} is police grade ${police.grade}` : `${src} is not police`);
});

ai-core:dutyChanged

Yüklü bir karakter bir meslekte mesaiye girdi ya da mesaiden çıktı. Bir oyuncu aynı anda en fazla bir meslekte mesaidedir.

Taraf: Server · Sabit: CORE.dutyChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

on(CORE.dutyChangedEvent, (src: number, job: string | null) => {
  console.log(job ? `${src} on duty: ${job}` : `${src} off duty`);
});

Bir meslekte kaç oyuncunun mesaide olduğunu öğrenmek için bu event’leri kendin saymak yerine GlobalState ai:duty:<job>’ı oku (bkz. State bag’ler).

ai-core:gangsChanged

Yüklü bir karakterin ait olduğu çeteler listesi değişti: bir çete eklendi ya da kaldırıldı veya bir rütbe değişti.

Taraf: Server · Sabit: CORE.gangsChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE, type GangMembership } from "@aicore-fivem/shared";

on(CORE.gangsChangedEvent, (src: number, gangs: GangMembership[]) => {
  console.log(`${src} is in ${gangs.length} gang(s)`);
});

ai-core:activeGangChanged

Yüklü bir karakter adına hareket ettiği çeteyi değiştirdi ya da artık hiçbiri adına hareket etmiyor.

Taraf: Server · Sabit: CORE.activeGangChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

on(CORE.activeGangChangedEvent, (src: number, gang: string | null) => {
  console.log(`${src} now acts for ${gang ?? "no gang"}`);
});

ai-core:metaChanged

Yüklü bir karakterin bir metadata değeri değişti. Metadata, karakterle birlikte saklanan serbest bir anahtar / değer çantasıdır; ESX / QB köprüleri framework metadata’sını (açlık, susuzluk, stres, isdead...) orada tutar.

Taraf: Server · Sabit: CORE.metaChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

on(CORE.metaChangedEvent, (src: number, key: string, value: unknown) => {
  if (key === "stress" && typeof value === "number" && value >= 90)
    console.log(`${src} is very stressed`);
});

ai-core:definitionsChanged

Admin panelinde bir meslek ya da çete eklendi, değiştirildi veya silindi. Değişen her meslek ya da çete için bir kez tetiklenir.

Taraf: Server · Sabit: CORE.definitionsChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

const labelCache = new Map<string, string>();

// Panel o mesleği değiştirdiğinde önbellekteki bir etiketi at.
on(CORE.definitionsChangedEvent, (file: "jobs" | "gangs", name: string) => {
  if (file === "jobs") labelCache.delete(name);
});

ai-core:characterScreen

Bir oyuncunun karakter ekranı yükleniyor (katıldıktan ya da ona döndükten sonra). ai-core kartların görünümlerini kendisi okur; bir kıyafet script’i kartlara portre çizmek için dinler.

Taraf: Server · Sabit: CORE.characterScreenEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

on(CORE.characterScreenEvent, (src: number, charIds: number[]) => {
  console.log(`${src} sees ${charIds.length} character card(s)`);
});

ai-core:inventoryChanged

ai-core’un envanter katmanının arkasındaki envanter değişti: seçilen envanter başladı ya da durdu veya sahibi panelde başka birini seçti. Eski envanterden önbelleğe aldığın her şeyi at (eşya etiketleri, tanımlar).

Taraf: Server · Sabit: CORE.inventoryChangedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { CORE } from "@aicore-fivem/shared";

let itemLabels: Record<string, string> | null = null;

on(CORE.inventoryChangedEvent, (resource: string | null) => {
  itemLabels = null; // bir sonraki kullanımda yeni envanterden tekrar oku
  console.log(`inventory is now ${resource ?? "none"}`);
});

ai-core:itemUsed

Bir oyuncu bir eşya kullandı. Eşyanın verdiği ihtiyaçları (açlık, susuzluk, stres) taşır, böylece bir HUD ya da ihtiyaç script’i envanteri bilmeden onları uygular. ai-hud bunu dinler.

Taraf: Server · Sabit: CORE.itemUsedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/needs.ts
import { CORE } from "@aicore-fivem/shared";

on(CORE.itemUsedEvent, (src: number, name: string, status: Record<string, number> | null) => {
  if (!status) return;
  for (const [need, amount] of Object.entries(status))
    console.log(`${src} used ${name}: ${need} ${amount > 0 ? "+" : ""}${amount}`);
});

Bugün eşya kullanımlarını ai-core’a yalnızca ai-inventory bildirir: başka bir envanterle bu event tetiklenmez. Bir envanterin kendi kullanım event’ini değil bu event’i dinle, böylece script’in envanter ai-inventory iken çalışır ve başkaları eklendiğinde de çalışmaya devam eder.

ai-core:playerDied

Yüklü karakteri olan bir oyuncu öldü. ai-core bunu FXServer’ın kendi ped ölüm raporundan alır (FXServer 38039 ya da daha yeni), bu yüzden hiçbir client’a güvenilmez.

Taraf: Server · Sabit: CORE.playerDiedEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/killfeed.ts
import { CORE } from "@aicore-fivem/shared";

on(CORE.playerDiedEvent, (src: number, killer: number | null, weaponHash: number) => {
  if (killer !== null && killer !== src)
    console.log(`${GetPlayerName(String(killer))} killed ${GetPlayerName(String(src))} (weapon ${weaponHash})`);
});

Bu, ölüm script’inin "yerde" durumu değil, oyunun ölümüdür: bir ölüm script’i yerdeki bir oyuncuyu canlandırmak için canlı tutabilir. "Bu oyuncu yerde mi" için server lib’inin medical’ını ya da ai-core’un server sağlık export’larını kullan.

ai-core:vrp:config

Sunucu sahibi ai-core’un panelinde vRP eşlemesini değiştirdi ("vRP scripts" sekmesi). ai-core’un vRP köprüsü bunu dinler; yalnızca vRP eşlemesini kendin okuyorsan ihtiyacın olur.

Taraf: Server · Sabit: VRP.configEvent

Argümanlar

Prop

Type

Dinleyici

resource/server/index.ts
import { VRP, type VrpConfig } from "@aicore-fivem/shared";

on(VRP.configEvent, (config: VrpConfig) => {
  console.log(`${config.permissions.length} vRP permission rule(s)`);
});

Diğer ai-* script’lerinin event’leri

Bunları ai-core değil ai-* script’leri tetikler, ama birçok resource onları dinler. Tam başvuruları her script’in developer sayfasındadır.

ai-vehicles:owners

Bellekteki sahipli araçların sahipleri değişti (bir karakter garajıyla yüklendi, bir araç satın alındı, satıldı ya da silindi). Server tick’i başına en fazla bir kez, o tick’in her değişikliğiyle tetiklenir. Anahtar script’leri her seferinde ai-vehicles’a sormadan plakadan sahibe bir harita tutmak için bunu kullanır.

Taraf: Server · Sabit: VEHICLES_EVENTS.owners

Argümanlar

Prop

Type

Dinleyici

resource/server/owners.ts
import { resourceExport } from "@aicore-fivem/lib/server";
import { VEHICLES_EVENTS } from "@aicore-fivem/shared";

const owners = new Map<string, string>();

// Tam listeden başla, sonra değişiklikleri izle.
for (const [plate, type, id] of resourceExport("ai-vehicles").GetPlateOwners()) owners.set(plate, `${type}:${id}`);

on(VEHICLES_EVENTS.owners, (puts: Array<[string, string, string]>, removes: string[]) => {
  for (const [plate, type, id] of puts) owners.set(plate, `${type}:${id}`);
  for (const plate of removes) owners.delete(plate);
});

chatMessage

ai-chat, bir oyuncunun mesajını iletmeden önce klasik FiveM chatMessage event’ini tetikler. Handler’ında CancelEvent() çağırmak mesajı atar.

Taraf: Server · Sabit: yok (FiveM’in kendi adı)

Argümanlar

Prop

Type

Dinleyici

resource/server/filter.ts
on("chatMessage", (source: number, _author: string, text: string) => {
  if (text.toLowerCase().includes("discord.gg")) {
    CancelEvent();
    console.log(`blocked an invite link from ${source}`);
  }
});

Bu sayfada