Discord на сервере FiveM выполняет две разные задачи, и всё становится проще, когда перестаёшь считать их одной. Вайтлист решает, кто может подключиться: txAdmin делает это сам, по участию в сервере Discord или по роли, без установки чего-либо ещё. Права решают, что может делать подключившийся игрок: это значит превращать роли Discord в группы ACE через add_principal identifier.discord:<id> group.<name> при входе - готовым ресурсом или сорока строками собственного кода. Обеим задачам нужен бот Discord на вашем сервере, и обе зависят от идентификатора Discord игрока, который существует, только если при запуске FiveM работает настольное приложение Discord. В этом руководстве мы настроим бота, вайтлист в txAdmin, сопоставление ролей с ACE и разберём неполадки, с которыми вы столкнётесь в первую неделю.
Как части складываются вместе#
Когда игрок подключается, FXServer собирает его идентификаторы - license, discord, fivem, xbl, live, IP и steam, если вы задали ключ Steam Web API. Идентификатор discord - это ID пользователя Discord, и он присутствует, только если при запуске FiveM был запущен настольный клиент Discord с выполненным входом. Discord во вкладке браузера не считается.
На шаге вайтлиста через вашего бота у Discord спрашивается, состоит ли этот пользователь на вашем сервере и какие у него роли, после чего подключение принимается или отклоняется. На шаге прав те же роли используются, чтобы добавить идентификатор Discord игрока в группы ACE, и тогда IsPlayerAceAllowed и команды, ограниченные через ACE, его видят. Первое делает txAdmin. Второе - это ресурс, потому что собственный список админов txAdmin управляет его веб-панелью и внутриигровым меню, а не ACE.
Создание бота Discord#
Обоим шагам нужен аккаунт бота на вашем сервере Discord. Ему не обязательно постоянно быть онлайн отдельной программой - txAdmin и ресурс прав используют его токен для запросов.
- Откройте Discord Developer Portal, создайте New Application и добавьте к нему Bot.
- Скопируйте токен бота. Обращайтесь с ним как с паролем: любой, у кого он есть, управляет ботом и может читать список участников вашего сервера.
- На странице Bot включите Server Members Intent. От него зависят запросы участников и ролей, и если о нём забыть, вайтлист чаще всего отклоняет всех подряд.
- В разделе OAuth2 сгенерируйте ссылку-приглашение со scope
botи пригласите бота на свой сервер. Для чтения участников и ролей особые права ему не нужны. - В Discord включите режим разработчика (User Settings, Advanced). Щёлкните правой кнопкой по своему серверу и выберите Copy Server ID, затем щёлкните правой кнопкой по каждой нужной роли и выберите Copy Role ID.
Теперь у вас есть токен, ID сервера и список ID ролей. Храните токен только в одном месте. Если кладёте его в server.cfg, используйте set, а не sets или setr: sets публикует значение в списке серверов, откуда его утащат. Как не допустить его попадания на скриншоты и в репозитории, описано в статье о переменных окружения и секретах.
Вайтлист через txAdmin#
У txAdmin есть встроенный вайтлист и встроенная интеграция с ботом Discord, так что для самих «ворот» ресурс не нужен.
- В txAdmin откройте Settings и вкладку Discord. Включите бота, вставьте токен и ID сервера и сохраните. txAdmin подключится и сообщит, видит ли он сервер.
- Откройте настройку вайтлиста (в актуальных версиях она в Settings, Player Manager) и выберите режим.
| Режим | Кто может войти |
|---|---|
| Disabled | Все, кто не забанен |
| Admin-only | Только админы txAdmin; полезно на время обслуживания |
| Discord server member | Любой участник вашего сервера Discord |
| Discord server roles | Участники, у которых есть хотя бы одна из указанных ролей |
| Approved license | Игроки, которых админ одобрил по одному |
Точные названия немного меняются от версии к версии txAdmin, но эти пять вариантов поведения стабильны.
Discord server roles - то, что нужно большинству ролевых серверов: кандидаты заходят в Discord, проходят заявку, получают роль «Whitelisted» и с этого момента могут подключаться. Снятие роли лишает доступа при следующем подключении. Вставляйте ID ролей, а не названия: названия можно продублировать и переименовать, ID - нельзя.
Approved license подходит небольшому приватному серверу без процесса в Discord. Отклонённому игроку показывается короткий ID запроса; админ одобряет его на странице вайтлиста в txAdmin или командой вайтлиста бота в Discord, и игрок может войти.
Сообщение об отказе настраивается. Пусть оно точно говорит игрокам, что делать, - «Join discord.gg/yourserver and complete the application», - и что проверить, если они уверены, что в вайтлисте: открыто ли приложение Discord и тот ли это аккаунт. Одно это предложение экономит десятки обращений в поддержку.
Роли Discord в права ACE#
Вайтлист пускает людей внутрь. Чтобы дать роли Discord полномочия в игре - админские команды, меню персонала, донатную машину, - нужны principals ACE. Механизм тот же, что описан в статье о server.cfg в FiveM: группы содержат aces, а principal связывает идентификатор игрока с группой.
add_ace group.admin command allowadd_ace group.admin command.quit denyadd_ace group.mod command.kick allowadd_principal group.admin group.modСтатические строки вроде add_principal identifier.discord:216735154273419264 group.admin работают, но не следуют за изменениями ролей в Discord. А ресурс, который добавляет principals при подключении игрока на основе его текущих ролей, - следует.
Самый известный готовый вариант - пара ресурсов от Badger: Badger_Discord_API, который общается с Discord, и DiscordAcePerms, который при подключении сопоставляет ID ролей с группами. Они широко используются и хорошо документированы; формат конфига смотрите в их собственном README, потому что он менялся от версии к версии.
Если вы предпочитаете точно знать, что у вас работает, задача достаточно мала, чтобы написать её самому:
local GUILD = GetConvar("discord_guild_id", "")local TOKEN = GetConvar("discord_bot_token", "")-- Discord role ID -> ACE grouplocal ROLE_GROUPS = { ["111111111111111111"] = "group.admin", ["222222222222222222"] = "group.mod", ["333333333333333333"] = "group.donor",}local function discordId(src) local id = GetPlayerIdentifierByType(src, "discord") return id and id:gsub("discord:", "")endAddEventHandler("playerConnecting", function(name, setKickReason, deferrals) local src = source deferrals.defer() Wait(0) deferrals.update("Checking your Discord roles...") local id = discordId(src) if not id then deferrals.done("Open the Discord desktop app, then restart FiveM.") return end local url = ("https://discord.com/api/v10/guilds/%s/members/%s"):format(GUILD, id) PerformHttpRequest(url, function(status, body) if status == 200 then local member = json.decode(body) for _, group in pairs(ROLE_GROUPS) do ExecuteCommand(("remove_principal identifier.discord:%s %s"):format(id, group)) end for _, role in ipairs(member.roles or {}) do local group = ROLE_GROUPS[role] if group then ExecuteCommand(("add_principal identifier.discord:%s %s"):format(id, group)) end end end deferrals.done() end, "GET", "", { Authorization = "Bot " .. TOKEN })end)И в server.cfg:
set discord_guild_id "123456789012345678"set discord_bot_token "your-bot-token"add_ace resource.discord_perms command.add_principal allowadd_ace resource.discord_perms command.remove_principal allowensure discord_permsДве строки add_ace resource. важны. Ресурс не может выполнить add_principal через ExecuteCommand, если ему не выдали право на эту команду, и без них скрипт работает, не выводит ничего полезного, а группу не получает никто.
Моменты в коде, которые стоит понять, а не просто скопировать:
- `deferrals.defer()`, затем `Wait(0)`. Отложенное подключение удерживает соединение, пока вы выполняете асинхронную работу; ожидание обязательно перед вызовом
updateилиdone. - Удаление перед добавлением. Principals привязаны к идентификатору и живут до перезапуска сервера, поэтому игрок, потерявший роль в Discord, сохранит группу, если её не удалить. Цикл сначала очищает все сопоставленные группы.
- Здесь входит и не участник. Этот ресурс только сопоставляет права. Отклонять не-участников - задача txAdmin; если делать это в двух местах, отлаживать придётся тоже два места.
- `GetPlayerIdentifierByType` доступна в актуальных сборках сервера. На очень старых вместо неё перебирайте
GetPlayerIdentifiers(src).
Права фреймворка - это третья система#
ACE - система прав FiveM, но фреймворки накладывают поверх свою, и связаны они с ней по-разному.
- QBCore использует ACE напрямую. Его уровни прав - это группы ACE вроде
qbcore.god,qbcore.adminиqbcore.mod, так что роль Discord, сопоставленная сqbcore.admin, работает с админскими проверками QBCore. Точные названия смотрите вconfig.luaвашей версии. - ESX хранит в своей базе данных значение
groupдля каждого игрока (user,adminи так далее) и проверяет именно его. Сопоставление роли Discord с группой ACE не меняет группу ESX; нужен ресурс, который задаёт её через фреймворк, или задавать её вручную. - Qbox следует подходу QBCore и опирается на ACE.
Прежде чем сопоставлять роли, решите, к какой из трёх систем относится каждое право, и запишите это. «Почему модератор может открыть админ-меню, но не может никого кикнуть?» - это почти всегда одна система, которая разрешает, и другая, которая отказывает. Сторона фреймворков описана в статье о сравнении фреймворков FiveM.
Админы txAdmin и Discord#
txAdmin ведёт собственные аккаунты админов с собственными правами - кто может кикать, банить, перезапускать, редактировать конфиг, пользоваться внутриигровым меню. Эти аккаунты можно связать с ID в Discord и идентификатором FiveM, чтобы внутриигровое меню их узнавало, но статус админа txAdmin и группы ACE остаются раздельными. Старшему модератору обычно нужно и то, и другое: аккаунт txAdmin с правами на управление игроками и роль Discord, сопоставленная с group.mod, для команд в игре.
Держите оба списка короткими. Каждый, кто может банить, может и разбанить; каждый, у кого есть права на конфиг, может прочитать пароль от вашей базы данных. То же рассуждение применимо к панели, где статья о субпользователях и минимальных привилегиях объясняет, зачем существует доступ только к консоли и только к файлам. На RE:NODE субпользователям можно дать ровно это - только консоль, только файлы, без доступа к оплате, - а доступ можно ограничить по времени, что удобно для разработчика, которого вы пускаете на неделю.
Процесс заявок вокруг вайтлиста#
Технический вайтлист - простая половина. Процесс, который решает, кто получает роль, - вот что делает сервер с вайтлистом достойным того, чтобы на него заходить, и его стоит продумать осознанно.
- Одна роль для доступа, отдельные роли для прав. «Whitelisted» позволяет подключаться. «Police», «EMS» и «Staff» дают что-то в игре. Если их смешать - например, позволить роли полиции также давать доступ, - то исключение человека из полиции заодно закроет ему вход на сервер.
- Канал или форма для заявок. Большинство серверов используют бота-форму в Discord или форму на сайте. Спрашивайте то, на основании чего вы действительно принимаете решение: возраст, часовой пояс, опыт в ролевой игре, короткую концепцию персонажа. Длинные эссе отсеивают как плохих игроков, так и хороших.
- Кто может выдавать роль. Ограничьте управление ролями в Discord теми, кто рассматривает заявки. Любой, кто может выдать «Whitelisted», контролирует дверь вашего сервера, а любой, кто может выдать «Staff», контролирует всё, что за ней.
- Лишение доступа. Снимайте роль при банах, которые должны действовать дольше внутриигрового бана, и у игроков, покинувших ваш Discord. С вайтлистом по ролям выход с сервера Discord автоматически лишает доступа при следующем подключении.
- Неактивные игроки. Некоторые серверы снимают роль вайтлиста после месяцев неактивности, чтобы сообщество оставалось актуальным. Предупредите игроков, прежде чем это делать.
Запишите правила и закрепите их в канале заявок. Человеческая сторона этого, включая апелляции, подробнее разобрана в статье о правилах сервера, модерации и персонале.
Rate limits и надёжность#
Discord ограничивает частоту запросов ботов. Один запрос на каждого подключающегося игрока - это с запасом в пределах лимитов для любого обычного сервера, даже во время рестарта, когда шестьдесят человек переподключаются за две минуты. Проблемы возникают, когда роли проверяют повторно, пока игроки онлайн, - при каждой команде, каждую минуту, при каждой смене работы. Запрашивайте роли при подключении, кэшируйте их на сессию и обновляйте только по запросу.
Если Discord не отвечает, решите, что должно происходить. Код выше пускает игрока без групп - для прав это безопасный вариант отказа. Для вайтлиста компромисс обратный: открытый отказ пускает кого угодно во время сбоя Discord, закрытый не пускает никого. txAdmin отказывает закрыто, что для вайтлиста правильно, - и именно поэтому так важен запасной режим Admin-only.
Устранение неполадок#
Вайтлист по ролям отклоняет всех. Server Members Intent выключен, бота нет на сервере или неверный ID сервера. Страница настроек Discord в txAdmin сообщает, видит ли бот сервер.
Одного игрока отклоняет, хотя роль у него есть. Его приложение Discord не было запущено при старте FiveM, он вошёл в другой аккаунт Discord или аккаунт на сервере не тот, что привязан в клиенте. Попросите его закрыть FiveM, открыть Discord и начать заново.
Роли сопоставляются, но команды всё равно отклоняются. У ресурса нет строки add_ace resource.<name> command.add_principal allow, или у группы нет aces на эту команду.
Удалённый персонал сохраняет полномочия. Principals живут до рестарта. Удаляйте перед добавлением, как показано выше, или перезапустите сервер.
Права работают в игре, но не в txAdmin. Это разные системы. Дайте человеку ещё и аккаунт txAdmin.
FAQ#
Нужно ли игрокам держать Discord открытым, чтобы зайти на сервер с Discord-вайтлистом?
Да. Идентификатор Discord берётся из настольного приложения Discord, запущенного при старте FiveM. Без него проверять нечего, и вайтлист по ролям отклоняет подключение.
Можно ли сделать вайтлист без установки ресурса?
Да. Вайтлист txAdmin напрямую поддерживает участие в сервере Discord и роли Discord, как только настроен его бот Discord. Ресурсы нужны только для того, чтобы превращать роли в права ACE в игре.
Зачем использовать ID ролей, а не их названия?
Названия может изменить или продублировать любой, у кого есть право управлять ролями, и это незаметно поменяет, кто может войти. ID неизменны всё время существования роли.
Делает ли админка в txAdmin человека админом в игре?
С точки зрения ACE - нет. Админы txAdmin могут пользоваться собственным меню и панелью txAdmin, но группы ACE и группы фреймворка - отдельные, и каждую нужно выдавать по отдельности.
Что будет, если утечёт токен бота?
Немедленно сбросьте его в Developer Portal и обновите везде, где он хранится. Утёкший токен позволяет кому угодно действовать от имени бота и читать список участников вашего сервера.




Комментарии
Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.