Персонажи и игроки
Прочитать данные и персонажа загруженного игрока, найти игрока по id персонажа или citizen id, сменить персонажа, переместить офлайн-персонажа, игроки в зоне видимости.
Игрок - это подключённый человек с серверным id (source). Персонаж - один из людей, которыми играет этот игрок; у него есть id в базе данных (charId) и citizen id (citizenid, короткий текст вроде ABC12345). У игрока появляется загруженный персонаж после выбора на экране персонажей. Большинство экспортов здесь до этого отвечают null.
Вызовы экспортов копируют свой ответ, поэтому прочитайте нужное один раз и следите за событиями ai-core (ai-core:playerLoaded, ai-core:playerUnloaded), а не спрашивайте снова. См. События и состояние.
GetPlayerData
Всё, что ai-core хранит для загруженного игрока, одним объектом: персонаж, деньги, работы, дежурство, банды и метаданные. Используйте, когда ресурс стартует поздно и ему один раз нужно полное состояние игрока; для отдельных значений используйте экспорты поменьше ниже.
Сторона: сервер · Ожидание: нет · Библиотека: нет на сервере (getPlayerData из клиентской библиотеки читает те же данные в игре игрока)
GetPlayerData(src: number): AiPlayerData | nulllocal data = exports['ai-core']:GetPlayerData(source) -- table или nilПараметры
Prop
Type
Возвращает
AiPlayerData | null: копия данных игрока (AiPlayerData). null, когда ни у кого с этим серверным id нет загруженного персонажа (не подключён или ещё на экране персонажей). Копия потом не меняется: вызовите снова или следите за событиями, чтобы получить новые значения.
Пример
import { addCommand, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
addCommand("whoami", { help: "Shows your character", restricted: true }, (source) => {
const data = core.GetPlayerData(source);
if (!data?.character) return;
const { firstname, lastname } = data.character;
console.log(`${firstname} ${lastname}: job ${data.job.job} (grade ${data.job.grade}), cash ${data.money.cash ?? 0}`);
});Весь объект копируется при каждом вызове. Никогда не вызывайте его в цикле по всем игрокам или по таймеру: читайте отдельные значения (GetMoney, GetDutyJob) или используйте зеркало online из библиотеки.
GetCharacter
Загруженный персонаж игрока: id в базе данных, citizen id, слот, имена, дата рождения, пол и национальность. Используйте, чтобы показать имя или сохранить что-то по id персонажа.
Сторона: сервер · Ожидание: нет · Библиотека: нет (online.character(source) читает то же из зеркала библиотеки без вызова экспорта)
GetCharacter(src: number): CharacterInfo | nulllocal character = exports['ai-core']:GetCharacter(source) -- table или nilПараметры
Prop
Type
Возвращает
CharacterInfo | null: персонаж (CharacterInfo). null, когда у игрока нет загруженного персонажа.
Пример
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
onClientCallback("myscript:profile", (source) => {
const character = core.GetCharacter(source);
if (!character) return fail("NO_CHARACTER");
return { ok: true, name: `${character.firstname} ${character.lastname}`, citizenid: character.citizenid };
});GetSourceByCharId
Серверный id игрока, который играет персонажем прямо сейчас. Используйте, когда вы сохранили id персонажа (владелец, контакт) и нужно найти этого человека в игре.
Сторона: сервер · Ожидание: нет · Библиотека: нет
GetSourceByCharId(charId: number): number | nulllocal src = exports['ai-core']:GetSourceByCharId(charId) -- number или nilПараметры
Prop
Type
Возвращает
number | null: серверный id игрока. null, когда этим персонажем сейчас никто не играет (офлайн или загружен другой персонаж).
Пример
import { notify, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
/** Tells a house owner that someone rang, when the owner is online. */
export function ringOwner(ownerCharId: number): void {
const owner = core.GetSourceByCharId(ownerCharId);
if (owner !== null) notify(owner, Locale("NOTIFY_DOORBELL"), "info");
}GetSourceByCitizenId
То же, что GetSourceByCharId, но по citizen id. Используйте с данными, которые хранят citizen id (так делает большинство таблиц в стиле ESX / QB).
Сторона: сервер · Ожидание: нет · Библиотека: нет
GetSourceByCitizenId(citizenid: string): number | nulllocal src = exports['ai-core']:GetSourceByCitizenId(citizenid) -- number или nilПараметры
Prop
Type
Возвращает
number | null: серверный id игрока, который играет этим персонажем. null, когда персонаж не загружен.
Пример
import { addCommand, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
addCommand("findcid", {
help: "Finds the player of a citizen id",
params: [{ name: "citizenid", type: "string" }],
restricted: true,
}, (source, args) => {
const target = core.GetSourceByCitizenId(args.citizenid);
console.log(target === null ? "not online" : `server id ${target}`);
});GetLoadedSources
Серверные id всех игроков с загруженным персонажем. Используйте для редкой работы по всему серверу (предупреждение о перезапуске, список для админа).
Сторона: сервер · Ожидание: нет · Библиотека: online.sources() читает то же из зеркала библиотеки
GetLoadedSources(): number[]local sources = exports['ai-core']:GetLoadedSources() -- список чиселПараметры
Нет.
Возвращает
number[]: по серверному id на каждого загруженного игрока, без определённого порядка. Пустой список, когда ни у кого нет загруженного персонажа. Игроков, которые ещё на экране персонажей, в нём нет.
Пример
import { addCommand, notify, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
addCommand("announce", {
help: "Sends a notification to every player",
params: [{ name: "text", type: "longString" }],
restricted: true,
}, (_source, args) => {
for (const target of core.GetLoadedSources())
notify(target, Locale("NOTIFY_ANNOUNCEMENT", args.text), "warning");
});Никогда не вызывайте другой экспорт для каждого id из этого списка на частом пути (GetLoadedSources() + GetDutyJob на каждого игрока каждую секунду). Кто на дежурстве, имена и работы многих игроков берутся из зеркала online в библиотеке; кто рядом - из playersNear.
GetUserId
Id аккаунта подключённого игрока: строка в ai_core_users, которая хранит аккаунт FiveM игрока и всех его персонажей. В отличие от большинства экспортов отвечает и тогда, когда игрок ещё на экране персонажей.
Сторона: сервер · Ожидание: нет · Библиотека: нет
GetUserId(src: number): number | nulllocal userId = exports['ai-core']:GetUserId(source) -- number или nilПараметры
Prop
Type
Возвращает
number | null: id аккаунта. null, когда игрок не подключён или ещё не дошёл до экрана персонажей.
Пример
import { addCommand, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
addCommand("account", {
help: "Shows a player account id",
params: [{ name: "id", type: "playerId" }],
restricted: true,
}, (_source, args) => {
console.log(`account ${core.GetUserId(args.id) ?? "unknown"}`);
});GetFivemId
Id аккаунта FiveM (Cfx.re) игрока. ai-core использует его как ключ аккаунта игрока: игрок без него не может подключиться.
Сторона: сервер · Ожидание: нет · Библиотека: нет
GetFivemId(src: number): string | nulllocal fivemId = exports['ai-core']:GetFivemId(source) -- string или nilПараметры
Prop
Type
Возвращает
string | null: id без префикса fivem: (например, 1234567). null, когда у игрока нет загруженного персонажа.
Пример
import { addCommand, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
addCommand("fivemid", {
help: "Prints the add_principal line for a player",
params: [{ name: "id", type: "playerId" }],
restricted: true,
}, (_source, args) => {
const id = core.GetFivemId(args.id);
if (id) console.log(`add_principal identifier.fivem:${id} group.admin`);
});GetCharacterInfo
Персонаж по id в базе данных, загружен он или нет, с id аккаунта, которому он принадлежит. Используйте, чтобы показать владельца чего-либо, когда этот человек может быть офлайн.
Сторона: сервер · Ожидание: нет (отвечает через done) · Библиотека: нет
GetCharacterInfo(
charId: number,
done: (info: (CharacterInfo & { userId: number }) | null) => void,
): voidexports['ai-core']:GetCharacterInfo(charId, function(info) end) -- info: table или nilПараметры
Prop
Type
Возвращает
Ничего. done получает CharacterInfo с ещё одним полем, userId (id аккаунта), или null для неизвестного или удалённого персонажа, неверного id или неудачного чтения. Если done не функция, вызов ничего не делает.
Пример
import { addCommand, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
addCommand("charinfo", {
help: "Shows a character by id",
params: [{ name: "charId", type: "number" }],
restricted: true,
}, (_source, args) => {
core.GetCharacterInfo(args.charId, (info) => {
if (!info) return console.log("no such character");
console.log(`${info.firstname} ${info.lastname} (${info.citizenid}), account ${info.userId}`);
});
});Сохранённый персонаж держится 5 минут после чтения, поэтому имя, изменённое в админ-панели, может столько же показывать старое значение. Загруженный персонаж всегда отвечает из памяти.
SwitchCharacter
Отправляет игрока обратно на экран персонажей, не выходя с сервера, как выход из персонажа. ai-core сначала сохраняет и выгружает персонажа, затем открывает экран.
Сторона: сервер · Ожидание: нет (выгрузка выполняется после возврата из вызова) · Библиотека: нет
SwitchCharacter(src: number): booleanlocal started = exports['ai-core']:SwitchCharacter(source) -- booleanПараметры
Prop
Type
Возвращает
boolean: true, когда смена началась. false, когда у игрока нет загруженного персонажа.
Пример
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Кнопка «Сменить персонажа» в вашем меню.
onClientCallback("myscript:logout", (source) =>
core.SwitchCharacter(source) ? { ok: true } : fail("NO_CHARACTER"),
);Ваш ресурс получает ai-core:playerUnloaded с причиной "switch", когда персонажа уже нет. Очищайте состояние, привязанное к персонажу, там, а не сразу после этого вызова.
SetOfflinePosition
Перемещает точку появления незагруженного персонажа: в следующий раз, когда этого персонажа выберут, он появится там. Используйте, когда что-то перемещает спящее тело или офлайн-персонажа (тело унесли, игрока отбуксировали).
Сторона: сервер · Ожидание: нет (запись идёт в фоне) · Библиотека: characters.setOfflinePosition
SetOfflinePosition(
charId: number,
position: { x: number; y: number; z: number; heading?: number },
): booleanlocal accepted = exports['ai-core']:SetOfflinePosition(charId, { x = x, y = y, z = z, heading = h })Параметры
Prop
Type
Возвращает
boolean: true, когда перемещение принято; запись в базу данных выполняется, как только не идёт ни загрузка, ни сохранение этого персонажа (ждёт до 30 секунд). false, когда персонаж сейчас загружен, charId не целое число или координата отсутствует или не является конечным числом. Отсутствующий heading сохраняется как 0.
Пример
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
const HOSPITAL = { x: 298.6, y: -584.5, z: 43.3, heading: 70 };
/** A body left in the world too long is moved to the hospital. */
export function sendBodyToHospital(charId: number): void {
if (!core.SetOfflinePosition(charId, HOSPITAL))
console.log(`character ${charId} is online, not moved`);
}Если персонаж загружается, пока запись ждёт, запись пропускается: пед загруженного персонажа находится там, где он на самом деле.
GetPlayersInScope
Игроки в зоне OneSync другого игрока: все, чья игра сейчас стримит этого игрока, примерно в 424 метрах вокруг. ai-core ведёт этот список по событиям зоны FiveM один раз для всех ресурсов, поэтому другим ресурсам никогда не нужно слушать эти события самим.
Сторона: сервер · Ожидание: нет · Библиотека: playersNear(source, radius) и playersNearEntity(entity, radius) строятся на нём и фильтруют по расстоянию
GetPlayersInScope(source: number): number[]local nearby = exports['ai-core']:GetPlayersInScope(source) -- список серверных idПараметры
Prop
Type
Возвращает
number[]: серверные id других игроков в зоне (самого игрока в списке нет). Пустой список для игрока в одиночестве, неизвестного id или значения, которое не является числом.
Пример
import { coordsOf, resourceExport } from "@aicore-fivem/lib/server";
import { distance } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
/** Plays a sound for everyone within 30 m of a player. */
export function playNear(source: number, sound: string): void {
const at = coordsOf(source);
for (const other of [source, ...core.GetPlayersInScope(source)])
if (distance(coordsOf(other), at) <= 30) emitNet("myscript:sound", other, sound);
}