RE:NODE

Сервер Qbox для FiveM: установка, ресурсы и порядок загрузки

Автор Команда RE:NODE
16 мин чтения


Самый быстрый путь к рабочему серверу Qbox - официальный рецепт txAdmin: запустите FXServer, откройте txAdmin, выберите Popular Recipes, затем QBox Framework, укажите базу данных и дождитесь, пока он скачает около шестидесяти ресурсов и импортирует SQL. В основе всего лежат пять ресурсов - qbx_core, ox_lib, oxmysql, ox_inventory и ox_target - и три требования, которые часто упускают: включённый OneSync, свежая сборка FXServer и база MariaDB, а не MySQL. Всё остальное в этой статье - о том, как эти части связаны между собой, где взять остальные ресурсы Qbox, какие convars меняют поведение ядра и что именно пишет консоль, когда сервер не запускается.

Если вы ещё не выбрали фреймворк, сравнение есть в статье ESX vs QBCore vs Qbox. Здесь предполагается, что выбор уже сделан.

Что нужно Qbox до установки#

Qbox - это форк QBCore, перестроенный на ресурсах Overextended (ox_*). К окружению он требовательнее, чем когда-либо был QBCore, и большинство неудачных первых запусков - проблема окружения, а не самого Qbox.

ТребованиеЧто ожидает Qbox
Сборка FXServerСвежая; qbx_core указывает минимум в манифесте
OneSyncВключён - qbx_core перечисляет /onesync среди зависимостей
Сборка игрыРецепт на момент написания принудительно ставит 3258
Lua5.4 (lua54 'yes' в каждом манифесте Qbox)
База данныхMariaDB 10.9 или новее; MySQL не поддерживается
txAdminНастоятельно рекомендуется для установки

Сборка сервера. В текущем манифесте qbx_core есть зависимость вида /server:10731: FXServer откажется запускать ресурс на любой более старой сборке. Это число растёт по мере того, как Qbox переходит на новые natives, поэтому смотрите манифест скачанного вами релиза, а не число из поста на форуме, включая этот. Если вы отстали, в статье обновление артефактов сервера FiveM описано, как перейти на новую сборку, не сломав всё остальное.

OneSync. Без него Qbox не работает. В зависимости от версии txAdmin он включается либо настройкой на странице настроек FXServer в txAdmin, либо строкой set onesync on в server.cfg; server.cfg из рецепта Qbox такой строки не пишет, так что проверьте, как это устроено у вас. В статье OneSync и слоты игроков объясняется, что он на самом деле меняет и почему от него зависит любой современный фреймворк.

MariaDB, а не MySQL. Именно это удивляет людей больше всего. Руководство по установке Qbox однозначно: минимум - MariaDB 10.9.0, рекомендуется актуальный LTS-релиз, MySQL не поддерживается, а XAMPP использовать нельзя ни в коем случае. oxmysql спокойно подключается к любому из движков, поэтому сервер MySQL обычно переживает первый запуск - проблемы начинаются позже: в SQL, который опирается на поведение MariaDB, в несовпадении collation между таблицами и в том, что в каналах поддержки Qbox вам с такой отладкой никто не поможет. Если база у вас хостинговая и вы не знаете, какой это движок, выполните SELECT VERSION(); в phpMyAdmin. Сервер MariaDB сообщит об этом в строке версии; просто число вроде 8.4.x - это MySQL.

Установка через рецепт txAdmin#

Рецепт - это YAML-файл, который txAdmin выполняет сверху вниз: скачивает репозитории, распаковывает их по папкам, пишет конфиги и импортирует SQL. Рецепт Qbox поддерживает сам проект Qbox, и в актуальном txAdmin он находится в разделе Popular Recipes.

  1. Запустите FXServer с пустой папкой данных. Откроется txAdmin и выдаст PIN для привязки вашей учётной записи Cfx.re.
  2. Выберите Popular Recipes, затем QBox Framework.
  3. Когда попросят, вставьте лицензионный ключ Cfx.re. Ключ ваш, его создают на портале Cfx.re - где его взять, написано в статье сервер FiveM и txAdmin.
  4. Введите данные базы. txAdmin соберёт из них строку подключения и выполнит на этой базе все SQL-файлы рецепта.
  5. Дождитесь окончания, просмотрите сгенерированный server.cfg в редакторе, который покажет txAdmin, и запустите сервер.

Рецепт скачивает много всего. На момент написания ресурсы раскладываются так:

code
resources/  [ox]/          ox_lib, oxmysql, ox_target, ox_inventory, ox_doorlock, ox_fuel  [qbx]/         qbx_core, qbx_spawn, qbx_garages, qbx_police, qbx_ambulancejob...  [standalone]/  cfx defaults, illenium-appearance, Renewed-Banking, loadscreen...  [voice]/       pma-voice, mm_radio  [npwd]/        npwd (phone), qbx_npwd  [npwd-apps]/   phone apps  [assets]/      map assets

Кроме того, он пишет в корень сервера пять конфигурационных файлов: server.cfg, permissions.cfg, ox.cfg, voice.cfg и misc.cfg. Разделение сделано намеренно: server.cfg остаётся читаемым, а длинный список настроек ox_inventory и ox_target живёт в ox.cfg.

Импортируемый SQL - это несколько файлов, а не один: базовый qbox.sql, затем qbx_core.sql, затем таблицы транспорта, автосалона, продаж транспорта, травы, гоночных кругов и наркотиков, а также собственный импорт телефона. Это важно, если вы когда-нибудь будете собирать всё вручную: пропустите один файл - и получите ресурс, который чисто запускается, а при первом же обращении игрока выдаёт ER_NO_SUCH_TABLE.

Относитесь к рецепту как к отправной точке. Он ставит работы, ограбления и телефон, которые вам могут быть не нужны, а каждый из них - это то, что нужно обновлять и что может сломаться. Разумный и распространённый приём: дайте рецепту собрать сервер, поиграйте на нём вечер, чтобы увидеть, как выглядит работающий Qbox, а затем сократите папку [qbx] до того, о чём на самом деле ваш сервер.

Основные ресурсы и что делает каждый#

Фреймворк держится на пяти ресурсах. Всё остальное необязательно, а эти - обязательны.

`qbx_core` - сам фреймворк: игроки и персонажи, деньги, работы и банды (со встроенным multijob), очередь подключения, экран выбора персонажа и мост совместимости, который отвечает как qb-core. Его настройки лежат в qbx_core/config/ (client.lua, server.lua, shared.lua), а игровые данные - работы, банды, транспорт, оружие - в qbx_core/shared/. В отличие от QBCore, в Qbox нет объекта ядра. Вы вызываете экспорты напрямую:

server side, written for Qbox
local player = exports.qbx_core:GetPlayer(source)if not player then return endplayer.Functions.AddMoney('bank', 500, 'weekly-wage')

`oxmysql` - мост к базе данных. Он читает mysql_connection_string и даёт всем остальным ресурсам функции запросов. Строка подключения, импорт и работа с медленными запросами описаны в статье базы данных FiveM и oxmysql, так что здесь это не повторяется.

`ox_lib` - общая библиотека: callbacks, уведомления, меню, индикаторы прогресса, зоны, локали. Почти каждый ресурс Qbox подключает её через '@ox_lib/init.lua' в манифесте. Уведомления в Qbox идут через ox_lib, поэтому чтобы подставить собственный ресурс уведомлений, нужно править ox_lib, а не qbx_core.

`ox_inventory` заменяет слотовый инвентарь, который поставлялся с QBCore. Предметы описываются в ox_inventory/data/items.lua, магазины и хранилища - файлами данных рядом, а картинки предметов лежат в ox_inventory/web/images. Ему нужно сообщить, под каким фреймворком он работает, через setr inventory:framework "qbx" - в ox.cfg из рецепта это задано, а собранный вручную сервер, где об этом забыли, получает инвентарь, который не находит ни одного игрока.

`ox_target` - система взаимодействия "третий глаз": зажимаете клавишу, смотрите на объект, получаете варианты действий. Большинство работ Qbox регистрируют свои взаимодействия через неё, так что на сервере без неё полицейские и механики ничего не могут сделать.

Вокруг этих пяти рецепт добавляет то, что ролевой сервер считает само собой разумеющимся: qbx_spawn для выбора места появления, qbx_vehicles и qbx_garages для личного транспорта, qbx_vehiclekeys, qbx_medical и qbx_ambulancejob, qbx_police, illenium-appearance для одежды, Renewed-Banking и pma-voice для голоса по расстоянию.

Где искать ресурсы Qbox#

Всё официальное находится в организации Qbox-project на GitHub, и каждый официальный ресурс называется с префиксом qbx_. На сайте документации docs.qbox.re для каждого основного ресурса есть страница с его экспортами, событиями и convars.

Три правила избавляют от большей части проблем:

  • Скачивайте релизы, а не зелёную кнопку Code. У ox_lib и ox_inventory веб-интерфейсы написаны на фронтенд-фреймворке, а в исходном дереве готовых файлов нет. В zip-архиве релиза они есть. Сервер, на котором ox_inventory взят из исходников, выводит предупреждение о том, что UI не собран, а игроки открывают инвентарь, которого нет. Документация Qbox также советует для стабильности запускать только релизные версии их ресурсов.
  • Номера версий ниже 1.0.0 означают бету. Qbox говорит об этом прямо. Пользоваться можно, но между минорными версиями ждите ломающих изменений.
  • Архивные репозитории - это завершённые, а не заброшенные. Несколько старых ресурсов Qbox заархивировали, когда их задача переехала в другое место - обычно в qbx_core или в ресурс ox_*. Если руководство советует установить ресурс с архивным репозиторием, проверьте, что его заменило, прежде чем ставить.

Сторонние ресурсы делятся на три группы. Ресурсы, написанные для Qbox, работают так, как вы ожидаете. Ресурсы, написанные для стека Overextended (с поддержкой ox_*), обычно работают, поскольку Qbox построен на нём. Ресурсы, написанные для QBCore, работают через мост - о нём в следующем разделе - с реальными ограничениями.

Найдя ресурс, прочитайте его fxmanifest.lua перед установкой: блок dependencies покажет, что ему нужно, lua54 'yes' - что он современный, а всё, что вызывает os.execute или отправляет HTTP-запросы на неизвестный домен, - повод остановиться. Более подробно о том, почему так стоит делать каждый раз, написано в статье как держать модифицированный сервер чистым.

Порядок ensure и как рецепт запускает ресурсы#

Вот последовательность запуска, которую пишет рецепт Qbox, с сокращёнными комментариями:

server.cfg - from the Qbox recipe
exec voice.cfgexec ox.cfgensure mapmanagerensure chatensure spawnmanagerensure baseeventsensure ox_libensure qbx_coreensure ox_targetensure [ox]ensure [qbx]ensure [standalone]ensure [voice]ensure [assets]ensure [npwd-apps]ensure qbx_npwdensure npwdexec permissions.cfgexec misc.cfg

Две вещи здесь выглядят неправильно, но на самом деле всё верно.

Во-первых, oxmysql нигде не назван перед qbx_core. Это и не нужно: qbx_core объявляет oxmysql и ox_lib в dependencies своего манифеста, а FXServer запускает зависимости ресурса раньше самого ресурса. Явный ensure ox_lib стоит для наглядности; механизм зависимостей справился бы и без него. Поэтому же отсутствующая папка oxmysql приводит к громкому сбою на qbx_core, а не к тихой проблеме позже.

Во-вторых, ensure [ox] выполняется после qbx_core, хотя ox_inventory лежит в этой папке. Так и должно быть: ox_inventory под Qbox нужно, чтобы ядро уже работало и он мог читать игроков и их предметы. ensure папки в скобках запускает все ресурсы внутри неё в порядке, на который не стоит полагаться, поэтому всё, что требует строгого порядка, указывается отдельной строкой перед папкой.

dependencyserver.cfgсначала exec ox.cfgoxmysqlкак зависимостьox_libобщая библиотекаqbx_coreигроки, работы, мостпапка [ox]инвентарь, цель, дверипапка [qbx]работы и функции
Как поднимается сервер Qbox

Правила для ваших собственных добавлений следуют отсюда. Ресурс, использующий экспорты Qbox, идёт после qbx_core. Ресурс, использующий предметы ox_inventory, идёт после [ox]. Если свои ресурсы вы кладёте в папку вроде [custom], добавьте ensure [custom] в конец списка, после [qbx]. А строка exec ox.cfg должна стоять раньше строк ensure, потому что значения setr считываются при запуске ресурса - convar, заданный после того, как ресурс уже работает, ничего не меняет до следующего перезапуска. Каждая директива файла разобрана в статье server.cfg для FiveM: разбор.

Convars qbx_core#

Qbox вынес многое из того, что раньше было настройками в Lua, в convars, поэтому поведение ядра меняется в server.cfg, а не правкой файлов, которые следующее обновление перезапишет. Вот документированные convars с их значениями по умолчанию:

ConvarПо умолчаниюЧто делает
qbx:enableBridgetrueМост совместимости с qb-core
qbx:enableQueuetrueВстроенная очередь подключения
qbx:max_jobs_per_player1Сколько работ может быть у одного персонажа
qbx:max_gangs_per_player1Сколько банд может быть у одного персонажа
qbx:setjob_replacestrue/setjob заменяет, а не добавляет
qbx:setgang_replacestrue/setgang заменяет, а не добавляет
qbx:cleanPlayerGroupstrueУдаляет недействительные работы из player_groups при старте
qbx:enableVehiclePersistencefalseВозвращает личный транспорт, удалённый сервером
qbx:vehiclePersistenceTypesemifull восстанавливает его и после перезапуска
qbx:bucketLockdownModeinactiveБлокировка сущностей для bucket 0
qbx:acknowledgefalsetrue скрывает в консоли уведомление о документации

Несколько из них заслуживают пары слов.

Multijob. Если поднять qbx:max_jobs_per_player до 3 и выставить qbx:setjob_replaces в false, вы получите multijob без дополнительного ресурса: /setjob добавляет работу, а не затирает текущую, и игрок переключается между ними. Это самая частая причина, по которой в QBCore ставили отдельный скрипт multijob.

`cleanPlayerGroups`. При старте ядро удаляет из player_groups строки, указывающие на работы или банды, которых больше нет в qbx_core/shared/. Это именно то, что нужно после удаления работы, - и неприятный сюрприз, если вы переименовали работу в jobs.lua и рассчитывали, что она останется у всех. Переименовывайте так: добавьте новую работу, переведите людей, затем удалите старую.

Сохранение транспорта. FiveM иногда удаляет сущности, которые удалять не должен, и результат, который замечают игроки, - личная машина, исчезнувшая прямо на ходу. qbx:enableVehiclePersistence возвращает её вместе с параметрами. Рецепт пишет его через setr, а не set, как и qbx:enableBridge, потому что эти значения читает и клиентская сторона. Меняя их, сохраняйте тот же глагол.

`bucketLockdownMode`. Режимы relaxed и strict запрещают клиентам создавать сетевые сущности в стандартном routing bucket, а это основной путь для читов, спамящих объектами. strict ломает любой ресурс, который создаёт сущности с клиента, поэтому сначала проверьте его на тестовой копии.

Помните правило set и sets из любого другого руководства по FiveM: sets публикует значение в списке серверов. Ни одно из этих значений не секретно, но привычка писать set важна из-за одной строки, которая секретна, - mysql_connection_string.

Ресурсы QBCore на Qbox: мост#

Когда qbx:enableBridge включён, qbx_core объявляет provide 'qb-core', поэтому ресурс, указавший qb-core в зависимостях, считается удовлетворённым, а exports['qb-core']:GetCoreObject() возвращает объект, который ведёт себя как объект QBCore. Большинство качественно написанных ресурсов QBCore работают без изменений.

Что мост не переносит:

  • Прямой доступ к таблицам. Ресурс, который сам пишет в колонки players из QBCore вместо использования функций игрока, обходит Qbox и может писать в колонки, устроенные теперь иначе.
  • Код инвентаря. Всё, что вызывает экспорты qb-inventory или ожидает формат предметов QBCore, нужно переписать под ox_inventory.
  • Непубличные внутренности. Ресурсы, которые читают файлы прямо из qb-core/ или опираются на поведение, которое QBCore никогда не документировал, ломаются так, что разбираться в этом утомительно.
  • Скрипты multijob со своими таблицами. Они конфликтуют со встроенным multijob; в документации Qbox сказано, что они могут работать, только если идут через экспорты qbx_core.

Предметы - единственное место, где мост работает в обе стороны. Предмет, добавленный в qbx_core/shared/items.lua, автоматически передаётся в ox_inventory, и портированные ресурсы QBCore остаются довольны. Но поведение предмета, для которого нужны клиентские или серверные экспорты, например использование предмета, по-прежнему нужно вручную описывать в ox_inventory/data/items.lua. Для нового предмета, которым пользуются только ресурсы с поддержкой Qbox, определите его сразу в ox_inventory и вовсе обойдитесь без items.lua.

Админы и права#

В permissions.cfg из рецепта лежит настройка ACE. Во время установки txAdmin записывает туда ваш идентификатор как главного администратора, строкой вида add_principal identifier.fivem:1234567 group.admin. Админские команды Qbox - /setjob, /setgang и остальные - это ограниченные команды, которые проверяются по группам ACE, поэтому каждому, кто должен ими пользоваться, нужна строка principal. Файл читается, когда server.cfg его выполняет, поэтому после правки перезапустите сервер или выполните exec permissions.cfg в живой консоли.

Держите список админов в permissions.cfg и больше нигде. Право, выданное из Lua какого-то ресурса, не видно при проверке файла, и именно так действует ресурс с бэкдором. Как привязать эти группы к ролям Discord, не вводя идентификаторы вручную, описано в статье права Discord и whitelist для FiveM.

Частые ошибки запуска и что они значат#

Читайте консоль с начала, а не с конца. Первая красная строка обычно и есть причина, а следующие полсотни - это ресурсы, которые упали из-за неё. Общий метод описан в статье как читать консоль.

`qbx_core` отказывается запускаться из-за неудовлетворённой зависимости `/onesync` или `/server:`. OneSync выключен, либо сборка FXServer старше, чем требует манифест. Включите OneSync в настройках txAdmin или обновите артефакты. Правка qbx_core здесь не поможет, сколько ни правь.

"No such export GetCoreObject in resource qbx_core". Ресурс QBCore просит у qbx_core объект ядра, которого в Qbox нет. Исправлять нужно сам ресурс: он должен вызывать exports['qb-core']:GetCoreObject(), на что отвечает мост. Заодно проверьте, что мост не выключен.

"This resource is still using the deprecated qbx_core utils". Это предупреждение, а не ошибка. Названный ресурс - старый релиз; скачайте его последнюю версию.

Игроки зависают на экране загрузки. На стандартной установке это почти всегда значит, что выбор персонажа так и не закрывает экран загрузки, обычно после замены встроенного multicharacter. Либо задайте в server.cfg значение false для loadscreen:externalShutdown, либо пусть ваш ресурс персонажей вызывает ShutdownLoadingScreen() и ShutdownLoadingScreenNui(). Если вы ничего не заменяли, поищите выше в консоли ресурс, который не запустился, - сбой qbx_spawn или oxmysql даёт тот же симптом.

"Can't create table ... (Foreign Key Constraint is incorrectly formed)". Несовпадение collation между создаваемой таблицей и той, на которую она ссылается; часто бывает, когда SQL разных ресурсов написан с разными значениями по умолчанию, а на MySQL - ещё чаще. Решение Qbox: завершать операторы CREATE TABLE явным указанием набора символов и collation, затем удалить таблицу и создать заново:

sql
CREATE TABLE IF NOT EXISTS example_table (  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,  citizenid VARCHAR(50) NOT NULL) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

"SCRIPT ERROR: failed to load model". Модель не загрузилась за отведённое время, обычно на медленном клиенте. Если ошибка исходит от qbx_core, увеличьте loadingModelsTimeout в qbx_core/config/client.lua.

Инвентарь открывается пустым или не открывается вовсе. Либо ox_inventory взят из исходников без собранного UI, либо inventory:framework не равен qbx, потому что ox.cfg так и не выполнился. Проверьте, что exec ox.cfg стоит выше строк ensure.

`ER_NO_SUCH_TABLE` в одной из функций. Один из SQL-файлов рецепта не был импортирован. Найдите .sql файл ресурса и импортируйте его через phpMyAdmin - большие файлы разобраны в руководстве по импорту в phpMyAdmin - предварительно прочитав его первые строки на предмет DROP TABLE.

Qbox на хостинге#

На RE:NODE для сервера FiveM доступен txAdmin, поэтому описанная выше схема с рецептом работает как написано: сервер стартует в txAdmin, вы привязываете учётную запись Cfx.re и вставляете собственный лицензионный ключ. В тариф входит слот базы данных, создаваемый из панели со сгенерированными хостом, пользователем и паролем, и кнопка Open in phpMyAdmin, которая входит по одноразовому токену. Панель не называет движок, стоящий за этим слотом, поэтому выполните SELECT VERSION(); до того, как свяжетесь с Qbox, и если это не MariaDB, решите трезво, готовы ли вы жить с неподдерживаемой базой.

Файловый менеджер распаковывает zip-архивы релизов на месте - так вы заменяете ресурс более новым релизом без локальной копии сервера, а SFTP справляется с массовой загрузкой, например целой папки [qbx]. Ограничение тарифа - память: полный рецепт с телефоном, ассетами карты и всеми работами тяжелее урезанного списка, так что перед выбором тарифа стоит прочитать сколько RAM нужно серверу FiveM. Если сервер упирается в лимит, он останавливается и запускается заново с чистого листа, а не уходит в swap, поэтому сервер, который постоянно перезапускается под нагрузкой, - это вопрос размера, который нужно разбирать с помощью resmon и монитора txAdmin, а не загадка.

Перед обновлением любого ресурса Qbox сделайте backup и экспортируйте базу данных. Релизы Qbox меняют схемы охотнее, чем это делал QBCore, и тестовый сервер с копией базы - см. тестовая и рабочая среда на одном аккаунте - это место, где обновление должно сначала встретиться с вашим списком ресурсов.

FAQ#

Совместим ли Qbox со скриптами QBCore?

В основном да. Мост отвечает как qb-core и обрабатывает его документированные экспорты и события. Скрипты, которые напрямую трогают таблицы QBCore, используют старый инвентарь или опираются на недокументированные внутренности, требуют доработки. Проверяйте каждый, а не предполагайте.

Обязательно ли использовать рецепт txAdmin?

Нет, но это самый быстрый путь к заведомо рабочей отправной точке. Вручную вам понадобятся пять основных ресурсов из их релизов, SQL из qbx_core и каждого функционального ресурса, ox.cfg или эквивалентные строки setr, включённый OneSync и порядок ensure, показанный выше.

Можно ли удалять ресурсы, которые поставил рецепт?

Да. Удалите папку и, если ресурс был назван в отдельной строке ensure, уберите и её. Сначала проверьте, что ни один другой ресурс не указывает его в dependencies своего манифеста. Основную пятёрку не трогайте и будьте осторожны со всем, что входит в создание персонажа, - выбор места появления и одежда, - потому что их удаление проявляется тем, что игроки не могут завершить создание персонажа.

Где добавить новую работу?

В qbx_core/shared/jobs.lua, как запись таблицы с её рангами, после чего нужен перезапуск. Затем ресурс работы даёт ей занятие. Игроков назначают командой /setjob, которая добавляет или заменяет в зависимости от qbx:setjob_replaces.

Почему Qbox настаивает на MariaDB?

В документации MariaDB 10.9 названа минимумом, а MySQL заявлена как неподдерживаемая, поэтому его SQL и поддержка написаны под MariaDB. Сервер MySQL на практике часто работает, но проблемы на нём придётся решать самостоятельно.

Сколько игроков вмещает сервер Qbox?

Это зависит от OneSync и вашего уровня лицензии, а не от Qbox. Сам фреймворк почти ничего не стоит на каждый tick; аппаратные требования определяют список ресурсов, который вы на нём строите, и стримируемые ассеты.