Экспорты между ресурсами
registerExport, resourceExport, optionalExport, callExport, provideExport и isResourceStarted: как предлагать и вызывать экспорты из TypeScript.
Экспорт это функция, которую предлагает один ресурс и вызывают другие ресурсы (exports["ai-core"].GetMoney(...)). Эти помощники регистрируют экспорты в обоих стилях имён, дают типизированный доступ к другим ресурсам и позволяют вашему коду пережить ресурс, который не запущен.
import { registerExport, resourceExport, optionalExport, callExport, provideExport, isResourceStarted } from "@aicore-fivem/lib/fivem";
// В файле клиента или сервера те же имена есть и в "@aicore-fivem/lib/client" или "@aicore-fivem/lib/server".Правила для каждого экспорта: он синхронный и возвращает небольшие значения. Promise не пересекает границу ресурса: когда значению нужно время, экспорт принимает колбэк (done). На горячем пути (каждый кадр, каждую секунду) зеркалируйте данные из событий, а не вызывайте экспорт каждый раз.
registerExport
Предлагает функцию другим ресурсам под именем name, а также под тем же именем с изменённым регистром первой буквы (GetPrice и getPrice), чтобы её находили скрипты, написанные в любом стиле. Используйте её вместо exports(name, fn) из FiveM.
Сторона: Клиент и сервер · Ждёт: нет
registerExport(name: string, handler: (...args: any[]) => unknown): voidLua: аналога нет; используйте собственный exports('GetPrice', function(...) end) из FiveM.
Параметры
Prop
Type
Возвращает
void.
Пример
import { registerExport } from "@aicore-fivem/lib/server";
import { readText } from "@aicore-fivem/lib/shared";
const prices = new Map<string, number>([["water", 5], ["bread", 3]]);
// Другие ресурсы: exports["my-shop"].GetPrice("water") или exports["my-shop"].getPrice("water")
registerExport("GetPrice", (item: unknown) => {
const name = readText(item, 64);
return name === null ? null : (prices.get(name) ?? null);
});Имя, которое вы регистрируете сами, всегда важнее двойника. Регистрация getPrice после GetPrice заменяет двойника вашим собственным обработчиком getPrice.
resourceExport
Типизированный доступ к экспортам другого ресурса. Типы берутся из CitizenExports в @aicore-fivem/shared (ai-core, ai-lib, ai-target, ai-vehicles, ai-inventory и другие скрипты ai-* с экспортами), поэтому ваш редактор знает каждый экспорт, его аргументы и тип результата.
Сторона: Клиент и сервер · Ждёт: нет
resourceExport<K extends keyof CitizenExports & string>(resource: K): CitizenExports[K]Lua: аналога нет; используйте exports['ai-core']:GetMoney(source, 'cash').
Параметры
Prop
Type
Возвращает
Объект экспортов ресурса. Вызов метода вызывает экспорт.
Пример
import { resourceExport } from "@aicore-fivem/lib/server";
// Один дескриптор на файл, в начале.
const core = resourceExport("ai-core");
export function payBonus(source: number): boolean {
return core.AddMoney(source, "bank", 500, "Bonus");
}Дескриптор не проверяет, запущен ли ресурс. Вызов экспорта остановленного ресурса выбрасывает ошибку. Для ресурса, которого может не быть, используйте optionalExport.
optionalExport
Те же типизированные экспорты, что и у resourceExport, но null, пока ресурс не запущен. Используйте для необязательной зависимости: ваш скрипт продолжает работать, когда на сервере нет этого ресурса.
Сторона: Клиент и сервер · Ждёт: нет
optionalExport<K extends keyof CitizenExports & string>(resource: K): CitizenExports[K] | nullLua: аналога нет; перед вызовом проверьте GetResourceState('ai-vehicles') == 'started'.
Параметры
Prop
Type
Возвращает
Объект экспортов, пока ресурс запущен, иначе null.
Пример
import { optionalExport } from "@aicore-fivem/lib/server";
function plateOfVehicleId(vehicleId: number): string | null {
// Спрашивайте каждый раз: ai-vehicles может запуститься или остановиться во время работы сервера.
return optionalExport("ai-vehicles")?.GetVehicle(vehicleId)?.plate ?? null;
}Вызывайте optionalExport в тот момент, когда он нужен, а не один раз в начале файла: дескриптор, полученный, пока ресурс был остановлен, так и останется null.
callExport
Вызывает экспорт ресурса, у которого нет типов в CitizenExports (сторонний скрипт). Результат имеет тип unknown: проверьте его форму перед использованием.
Сторона: Клиент и сервер · Ждёт: нет
callExport(resource: string, name: string, ...args: unknown[]): unknownLua: аналога нет; используйте exports[resource][name](nil, ...) или exports[resource]:Name(...).
Параметры
Prop
Type
Возвращает
unknown: то, что вернул экспорт.
Пример
import { callExport, isResourceStarted } from "@aicore-fivem/lib/client";
function otherHudVisible(): boolean {
if (!isResourceStarted("some-hud")) return true;
const visible = callExport("some-hud", "IsVisible");
return typeof visible === "boolean" ? visible : true;
}Выбрасывает Error("<resource> has no export <name>"), если у ресурса нет такого экспорта (и когда он остановлен). Сначала проверьте isResourceStarted или оберните вызов в try / catch.
provideExport
Отвечает на exports["<resource>"].<name> для имени ресурса, которое ваш ресурс замещает через provide в своём fxmanifest.lua. provide в FiveM создаёт имя (поэтому строки dependency проходят), но не пересылает его экспорты; этот помощник отвечает на один экспорт этого имени. ai-banking использует его, чтобы отвечать на вызовы qb-banking и Renewed-Banking.
Сторона: Клиент и сервер · Ждёт: нет
provideExport(resource: string, name: string, fn: (...args: any[]) => unknown): voidLua: аналога нет.
Параметры
Prop
Type
Возвращает
void.
Пример
provide 'old-banking'import { provideExport, resourceExport } from "@aicore-fivem/lib/server";
import { readText } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Скрипты, написанные для old-banking, продолжают работать: exports["old-banking"].GetAccountBalance("police")
provideExport("old-banking", "GetAccountBalance", (job: unknown) => {
const name = readText(job, 32);
return name === null ? 0 : (core.GetSharedMoney("job", name, "bank") ?? 0);
});Регистрируйте его при старте ресурса, а не позже: скрипт, который вызовет экспорт до появления вашего обработчика, получит ошибку. Используйте также registerExport, если на ту же функцию должно отвечать и ваше собственное имя.
isResourceStarted
Запущен ли ресурс прямо сейчас (его состояние "started").
Сторона: Клиент и сервер · Ждёт: нет
isResourceStarted(resource: string): booleanLua: аналога нет; используйте GetResourceState(resource) == 'started'.
Параметры
Prop
Type
Возвращает
true, пока ресурс запущен. false, когда он остановлен, запускается, останавливается или не установлен.
Пример
import { isResourceStarted } from "@aicore-fivem/lib/server";
if (!isResourceStarted("ai-inventory")) console.warn("ai-inventory is not running: shop items will not work.");Lib: общее и fivem
@aicore-fivem/lib/shared и /fivem: помощники, которые работают на обеих сторонах, для чего нужна каждая точка входа, и все тематические страницы.
Планирование и жизненный цикл
every, onStop, caller, ByResource, Reasons, sleep и waitFor: периодическая работа, ожидание и данные, принадлежащие ресурсу, который их зарегистрировал.