AI Core
Справочник APIAI Core: серверные экспорты

Счета

Отправлять счета (штрафы, оплата услуг, счета от игроков), получать список открытых счетов игрока и оплачивать их через тот скрипт счетов, который работает, или через собственные счета ai-core.

Счета идут через ai-core, а не через собственные экспорты или события скрипта счетов. ai-core отправляет каждый счёт активному скрипту счетов: тому, что выбран в настройке панели Billing script, или первому запущенному. Если такого нет, счёт принимают собственные счета ai-core: игрок видит на экране список открытых счетов, а деньги перемещаются, когда он платит. Счёт никогда не пропадает впустую.

Счёт приходит от работы (платёж получает счёт bank этой работы: полицейские штрафы, оплата механику) или от игрока (платёж получает этот игрок).

Собственные счета ai-core вкратце: открытые счета хранятся по персонажам (в том числе офлайн), не более 20 открытых счетов на персонажа, а оплата списывает деньги с bank, затем с cash в одной транзакции с удалением счёта.

GetBillingSystem

Куда идут счета.

Сторона: сервер · Ожидание: нет · Библиотека: billing.provider()

Сигнатура
GetBillingSystem(): string | null
Lua
local system = exports['ai-core']:GetBillingSystem() -- 'ai-core' или имя скрипта

Параметры

Нет.

Возвращает

string | null: имя ресурса скрипта счетов или "ai-core" для собственных счетов ai-core. Поскольку собственные счета ai-core доступны всегда, на практике это не null.

Пример

import { resourceExport } from "@aicore-fivem/lib/server";

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

/** Bills to offline characters only work with ai-core's own bills. */
export function canBillOffline(): boolean {
  return core.GetBillingSystem() === "ai-core";
}

SendBill

Отправляет игроку счёт.

Сторона: сервер · Ожидание: нет · Библиотека: billing.send

Сигнатура
SendBill(bill: BillRequest): boolean
Lua
local sent = exports['ai-core']:SendBill({ to = target, amount = 250, label = 'Speeding', from = source, job = 'police' })

Параметры

Prop

Type

BillRequest

Prop

Type

См. BillRequest.

Возвращает

boolean: true, когда счёт отправлен. false, когда:

  • счёт недопустим: указаны оба или ни одного из to / toCitizenid, нет label, amount не целое число от 1 до 10 000 000, нет ни job, ни from или from совпадает с получателем;
  • from указан, но у него нет загруженного персонажа, или job не существует;
  • получатель офлайн, а счета идут в скрипт счетов (только собственные счета ai-core доходят до офлайн-персонажей);
  • скрипт счетов отказал или у получателя уже 20 открытых счетов в собственных счетах ai-core.

Офлайн-счёт в собственных счетах ai-core отвечает true, как только он допустим; база данных всё ещё может его отклонить (неизвестный citizen id, 20 открытых счетов), и это записывается в лог.

Пример

import { onClientCallback, coordsOf, isNear, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readId, readInt } from "@aicore-fivem/lib/shared";
import { Locale } from "common";

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

// Офицер штрафует игрока перед собой; деньги получает счёт полиции.
onClientCallback(
  "myscript:fine",
  {
    args: ([target, amount]) => {
      const t = readId(target);
      const a = readInt(amount, 1, 50_000);
      return t === null || a === null ? null : [t, a];
    },
  },
  (source, target, amount) => {
    if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
    if (!isNear(target, coordsOf(source), 3)) return fail("TOO_FAR");
    const sent = core.SendBill({ to: target, amount, label: Locale("BILL_FINE"), from: source, job: "police" });
    return sent ? { ok: true } : fail("BILL_FAILED");
  },
);

Никогда не забирайте деньги у цели сами как «принудительный счёт» (TransferMoney с её счёта): счёт - это выбор игрока, платить или нет.

GetUnpaidBills

Открытые (неоплаченные) счета игрока.

Сторона: сервер · Ожидание: нет (отвечает через done) · Библиотека: billing.unpaid(source) возвращает Promise

Сигнатура
GetUnpaidBills(source: number, done: (bills: UnpaidBill[] | null) => void): void
Lua
exports['ai-core']:GetUnpaidBills(source, function(bills) end) -- список или nil

Параметры

Prop

Type

Возвращает

Ничего. done получает по записи на каждый открытый счёт с id (id в скрипте счетов), label, amount (сколько ещё должен) и sender (название работы или имя игрока) (UnpaidBill) или null, когда у игрока нет загруженного персонажа или скрипт счетов не умеет перечислять счета. Если done не функция, вызов ничего не делает.

Пример

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

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

// Стойка в мэрии показывает, сколько игрок должен.
onClientCallback("myscript:myBills", async (source) => {
  const bills = await new Promise<UnpaidBill[] | null>((resolve) => core.GetUnpaidBills(source, resolve));
  if (!bills) return fail("BILLS_UNAVAILABLE");
  return { ok: true, bills, total: bills.reduce((sum, b) => sum + b.amount, 0) };
});

PayBill

Игрок оплачивает один из своих открытых счетов.

Сторона: сервер · Ожидание: нет · Библиотека: billing.pay

Сигнатура
PayBill(source: number, id: string): boolean
Lua
local paid = exports['ai-core']:PayBill(source, billId)

Параметры

Prop

Type

Возвращает

boolean: true, когда счёт оплачен. false, когда у игрока нет загруженного персонажа, счёт не его или уже исчез, он не может его оплатить, скрипт счетов отказал или принимает платежи только на собственном экране. В собственных счетах ai-core для личного счёта также нужно, чтобы выставивший был в сети (деньги идут на его банковский счёт).

Пример

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

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

onClientCallback(
  "myscript:payBill",
  { args: ([id]) => { const v = readText(id, 64); return v ? [v] : null; }, lock: true },
  (source, id) => (core.PayBill(source, id) ? { ok: true } : fail("BILL_NOT_PAID")),
);

На этой странице