Установка
Десять минут, и большая часть этого времени — ожидание запуска сервера. Здесь нет SQL-файла для импорта и нет второй программы, которую нужно запускать отдельно: таблицы создаются сами при первом запуске ресурса.
Каждый шаг ниже заканчивается пунктом как понять, что всё сработало, поэтому вам не придётся идти дальше наугад.
Перед началом
Заголовок раздела «Перед началом»| Что вам нужно | Зачем |
|---|---|
| oxmysql, запущенный | Всё, что помнит телефон, хранится в вашей базе данных |
| ESX, QBCore, QBox или fmLib | Определяется автоматически; указывать вручную не нужно |
| Сервер FiveM за последние пару лет | Веб-часть телефона использует встроенный в сервер Node |
Больше ничего. Никакого npm, никакой сборки (build), никакого отдельного веб-сервера.
1. Поместите папку на место
Заголовок раздела «1. Поместите папку на место»Закиньте mic_phone в папку resources — аккуратнее всего положить его внутрь папки в квадратных скобках:
resources/[mic]/mic_phone/Оставьте папке имя mic_phone. Ничего не сломается, если вы переименуете её, но веб-адрес телефона формируется из имени папки, поэтому всё, что написано о нём в документации, тоже изменится.
2. Запустите его после зависимостей
Заголовок раздела «2. Запустите его после зависимостей»В server.cfg, ниже oxmysql и ниже вашего фреймворка:
ensure oxmysqlensure es_extended # or qb-core / qbx_coreensure mic_phoneВсё сработало, когда консоль при запуске пишет:
[mic_phone] web: door B listening on http://0.0.0.0:30125 · door A at /mic_phone/web/ on the game portЕсли вместо этого вы видите красную строку с ошибкой фреймворка, запускайте mic_phone после вашего фреймворка — почти всегда причина именно в этом.
3. База данных — ничего делать не нужно
Заголовок раздела «3. База данных — ничего делать не нужно»При первом запуске ресурс читает sql/schema.sql и создаёт все недостающие таблицы. В консоли промелькнёт ряд строк CREATE TABLE IF NOT EXISTS mic_phone_…. На этом всё.
Всё сработало, когда эти строки появились один раз и больше не появляются при следующих запусках.
4. Дайте игрокам то, что можно открыть
Заголовок раздела «4. Дайте игрокам то, что можно открыть»Из коробки телефону требуется предмет инвентаря под названием phone:
-- shared/config.luaConfig.Open = { RequireItem = true, Item = 'phone', ...}В большинстве сборок ESX и QB этот предмет уже есть. Пользователям ox_inventory: добавьте его в свой список предметов, если его там нет. Просто тестируете? Установите RequireItem = false и полностью пропустите этот шаг.
Всё сработало, когда вы заходите на сервер, берёте предмет в инвентарь, и клавиша F1 открывает телефон. Команда /phone делает то же самое, а клавиша T раскладывает открытый телефон в планшет.
5. Настройки только для сервера
Заголовок раздела «5. Настройки только для сервера»Скопируйте пример файла и заполните то, что вам нужно:
shared/server_config.example.lua → shared/server_config.luaЭтот файл загружается только как серверный скрипт, поэтому ни одна строчка из него никогда не попадёт к игроку. В нём хранятся две вещи:
Фото, видео и голосовые сообщения. Укажите медиа-токен Fivemanage в ServerConfig.Media.Token (или в convar FIVEMANAGE_MEDIA_API_KEY), и телефон будет сам загружать файлы, сохраняя в базе только полученную ссылку. Вебхук Discord работает как запасной вариант.
Если не указано ни то, ни другое, параметр
FallbackToDataUrlсохраняет файлы прямо внутри вашей базы данных. Это нормально для тестов, но тяжело для продакшена — несколько секунд голоса весят десятки килобайт в каждой затронутой строке. Укажите токен или отключите эту опцию, чтобы загрузка файлов явно выдавала ошибку.
Вебхуки Discord. По одному URL на каждый тип события или Default для перехвата всего. Единственный вебхук, который стоит настроить, даже если вы пропустите остальные — это Server: только он сообщает о состоянии сервера, а не об игроках (например, если сменился адрес или не продлился сертификат).
Телефон работает. Всё, что описано ниже, не является обязательным.
Опционально: телефон на реальном смартфоне
Заголовок раздела «Опционально: телефон на реальном смартфоне»Игроки могут носить телефон своего персонажа на собственном мобильном устройстве. Эта функция уже включена: раздел Настройки › Привязанные устройства в игровом телефоне показывает QR-код — игрок сканирует его и вводит шесть показанных цифр обратно в игру. После этого устройство действует от лица этого персонажа.
По обычному HTTP это уже даёт доступ к сообщениям, почте, контактам, гаражу, недвижимости и всему остальному. Но самое лучшее — это то, что браузер не разрешает делать на незащищённой странице:
| Обычный HTTP | HTTPS | |
|---|---|---|
| Сообщения, почта, гараж и всё остальное | да | да |
| Уведомления при закрытом приложении | нет | да |
| Звонки | нет | да |
| Микрофон для голосовых сообщений | нет | да |
| Установка как приложение с собственной иконкой | нет | да |
Получение HTTPS без установки сторонних программ
Заголовок раздела «Получение HTTPS без установки сторонних программ»Этот ресурс умеет сам получать и продлевать свой сертификат. Направьте доменное имя на ваш сервер, откройте два порта и заполните три строки:
-- shared/server_config.lua (server-only: this file is never sent to a client)ServerConfig.Web = { Url = 'https://phone.yourserver.com/', Https = { Enabled = true, Names = { 'phone.yourserver.com' }, },}- Доменное имя. На VPS это одна A-запись, указывающая на его IP-адрес. Нет домена? На
duckdns.orgможно бесплатно получить его за минуту. - Порт 80 и порт 443, открытые в брандмауэре (файрволе). Порт 80 открывается только на время запроса сертификата и закрывается сразу после получения ответа.
Всё сработало, когда консоль пишет:
https: asking for phone.yourserver.comhttps: port 80 open for the challengehttps: challenge port closedhttps: certificate in hand, good until 2027-01-31https: listening on https://phone.yourserver.com/Если порт 443 занят — некоторые роутеры оставляют его для собственной панели управления — используйте другой порт: укажите Port = 8443, пробросьте 8443 и напишите Url = 'https://phone.yourserver.com:8443/'. Только проверка (challenge) обязана проходить через порт 80; сам сертификат привязан к имени домена, а не к порту, поэтому всё продолжит работать.
В файле docs/HTTPS.md описаны остальные случаи: работа за прокси Cfx.re, за вашим собственным обратным прокси (reverse proxy) или на хостинге, который не выделяет дополнительные порты.
Если что-то пошло не так
Заголовок раздела «Если что-то пошло не так»phonehttps check — спрашивает у тестового сервера центра сертификации, может ли он достучаться до вашей машины. Запускайте эту команду первой, если сертификат не приходит: она позволяет отделить проблему с вашим файрволом от проблемы с этим ресурсом.
phonehttps — показывает текущий статус сертификата и дату его продления.
phoneduck — показывает статус доменного имени (если сервер сам поддерживает привязку своего имени DuckDNS к своему IP) и время последнего обновления. Команда phoneduck now отправляет текущий адрес и выводит ответ DuckDNS — это лучший способ сразу узнать о неправильном токене, не дожидаясь смены IP-адреса.
| Что вы видите | В чём причина |
|---|---|
| Телефон не открывается | Нет предмета phone, либо включён RequireItem, а у игрока нет телефона с собой |
| QR-код ведёт на недоступный адрес | Укажите ServerConfig.Web.Url вручную; автоопределение не видит проброс изменённого порта за роутером |
| Сертификата нет, а в логах ошибка проверки (challenge) | Порт 80 не доходит до этой машины. Проверьте проброс портов и брандмауэр именно в таком порядке |
| Фотографии огромные / база данных быстро разрастается | Не указан медиа-токен, и FallbackToDataUrl сохраняет файлы прямо в базу данных |
| В звонках между двумя игроками тишина | Голос стоит в режиме auto и не нашёл голосовой ресурс; укажите свой в Config.Bridge.voice |
Перед открытием вашего города
Заголовок раздела «Перед открытием вашего города»shared/server_config.lua— только ваш. Никогда не делитесь им и не публикуйте его в открытых репозиториях: в нём хранятся ваш медиа-токен и URL-адреса вебхуков.- Направьте вебхук
Serverв канал, который вы читаете. Именно он сообщит, если веб-доступ к телефону перестанет работать, и это единственное предупреждение, которое вы получите до того, как вам напишут игроки. - Выключите
Config.Debug, если включали его: он выводит в консоль каждое решение моста (bridge). - Раздел Безопасность стоит десяти минут чтения, если вы держите публичный сервер: там описано, что этот ресурс предполагает о подключающихся людях и какие правила соблюдает, чтобы модифицированный клиент не смог выйти за пределы своего персонажа.