Ghost
Обзор
В сети из нескольких бэкенд-серверов два игрока, находящиеся на одной карте на разных серверах, не могут видеть друг друга. Ghost решает это визуально: каждый сервер публикует через Redis позицию, поворот и скин своих игроков, а другие серверы рисуют их как призраков в форме игроков с помощью пакетов. В мир ничего не добавляется, у призрака нет серверной сущности, поэтому его нельзя ударить, толкнуть или выбрать целью.
Каждый игрок сам решает, видит ли он призраков. Выбор хранится в факте TypeWriter, поэтому переживает перезапуски и следует за игроком с сервера на сервер. Призраки появляются только между серверами, у которых в конфигурации MySQL указан одинаковый redis.group-id, а сервер никогда не рисует собственных игроков как призраков.
Возможности
- Призраки между серверами — игроки других бэкенд-серверов появляются со своим скином, позицией и поворотом.
- Отрисовка только пакетами — построено на PacketEvents, серверные сущности не создаются.
- Совместимость с Folia — каждый захват и каждая отрисовка выполняются в планировщике соответствующего игрока.
- Переключатель видимости —
/ghost toggle, действие TypeWriter или кнопка меню включают и отключают призраков для каждого игрока. - Постоянный выбор — настройка хранится в сохраняемом факте, общем для серверов.
- Метка сервера — настраиваемый суффикс вроде
[survival-2]показывает, откуда пришёл призрак. - Ограничения — расстояние обзора, максимум призраков на зрителя, частота обновления и фильтрация миров удерживают нагрузку в рамках.
- Именные таблички — если установлен UiCore, призраки получают табличку над головой.
- Плейсхолдеры — видимость и число призраков для текста MiniMessage.
Установка
- Установите PacketEvents на каждый сервер.
- Установите расширение MySQL и включите Redis (или Valkey) на каждом сервере. Задайте каждому серверу уникальный
redis.server-nameи одинаковыйredis.group-id. У Ghost нет собственных настроек Redis. - Поместите JAR-файл Ghost в
plugins/Typewriter/extensions/и перезапустите сервер. Файлplugins/Typewriter/ghost_player/config.ymlсоздаётся при первом запуске. - Выдайте право
typewriter.ghost.useигрокам, которые могут использовать/ghost. Без плагина прав это могут только операторы. - По желанию: установите UiCore, чтобы рисовать таблички над призраками.
Начало работы
Позвольте игрокам переключать призраков из меню или у NPC квеста:
- В веб-панели TypeWriter откройте страницу и добавьте запись-факт Ghost Visibility Fact. Оставьте её
idпо умолчанию,ghost_visibility_fact: расширение читает и записывает факт по этому идентификатору. - Добавьте действие Ghost Toggle Visibility в последовательность или на предмет меню. Заполните
showMessageиhideMessageтекстом MiniMessage или оставьте их пустыми, чтобы использовались сообщения по умолчанию. - По желанию добавьте критерий на факт Ghost Visibility (значение
1означает видимо,0— скрыто), чтобы показывать в меню другой значок. - Опубликуйте и зайдите на два сервера одной группы. Каждый игрок увидит другого как призрака с суффиксом сервера.
Сервер игнорирует собственные рассылки. Чтобы проверить, запустите два сервера с одинаковым redis.group-id и разными redis.server-name и находитесь в мирах, которые могут совпасть (см. ниже).
Как это работает
Каждый сервер публикует снимок каждого локального игрока с заданной частотой, а также сигнал активности, чтобы бездействующие игроки не исчезали. Призрак исчезает, когда его владелец выходит или когда в течение timeout-millis не приходит обновление. Каждое сообщение несёт идентификатор сессии и порядковый номер, поэтому запоздавшие или дублированные сообщения игнорируются.
Призрак рисуется для зрителя, когда у зрителя включены призраки, миры совместимы, призрак находится в пределах view-distance, а у зрителя меньше max-ghosts-per-viewer призраков, начиная с ближайших.
Конфигурация
Файл — plugins/Typewriter/ghost_player/config.yml. Его schema-version должен быть 1 или 2.
schema-version: 2
settings:
update-rate: 4
server-suffix: " <gray>[%server%]</gray>"
team-prefix: "Ghosts"
view-distance: 64.0
max-ghosts-per-viewer: 128
timeout-millis: 10000
allowed-worlds:
- "world"
- "dungeon_"
- "hub"
messages:
no-permission: "<red>You do not have permission to use ghost visibility."
players-only: "<red>This command can only be used by a player."
enabled: "<green>Ghost visibility enabled."
disabled: "<yellow>Ghost visibility disabled."
usage: "<gray>Usage: <white>/ghost toggle"
command:
permission: "typewriter.ghost.use"
| Ключ | Значение |
|---|---|
settings.update-rate | Тики между захватами позиции. Ограничивается диапазоном от 1 до 20. |
settings.server-suffix | Текст MiniMessage, добавляемый после имени призрака. %server% заменяется названием сервера-источника. |
settings.team-prefix | Префикс команды скорборда, показываемой для каждого сервера-источника. |
settings.view-distance | Максимальное расстояние в блоках, от 0 до 256. 0 отключает ограничение расстояния. |
settings.max-ghosts-per-viewer | Число призраков, рисуемых на зрителя, от 0 до 2000. 0 не показывает ни одного. |
settings.timeout-millis | Задержка без обновления, после которой призрак удаляется, от 2000 до 120000. |
settings.allowed-worlds | Шаблоны названий миров, считающихся одной и той же картой на разных серверах. До 64 элементов. |
messages.* | Тексты MiniMessage, используемые /ghost. |
command.permission | Право, требуемое для /ghost. |
Миры. Призрак виден, когда зритель и призрак находятся в мирах с одинаковым названием или когда оба названия миров содержат один и тот же шаблон из allowed-worlds (например, dungeon_ соответствует dungeon_1 и dungeon_2). Расстояние можно измерить только внутри одного мира, поэтому при view-distance больше 0 призраки из мира с другим названием скрываются. Задайте view-distance равным 0, если полагаетесь на сопоставление по шаблону.
Подключение к Redis, название сервера и идентификатор группы читаются из конфигурации MySQL. Файл читается один раз при запуске: перезапустите сервер после его редактирования.
Команды
| Команда | Описание |
|---|---|
/ghost toggle | Включить или отключить видимость призраков для себя. |
Псевдонимы: /ghosts, /ghostplayer. Только для игроков. Право — command.permission, по умолчанию typewriter.ghost.use.
Права
| Право | Что даёт |
|---|---|
typewriter.ghost.use | /ghost toggle. Название можно изменить через command.permission. Право не зарегистрировано со значением по умолчанию, поэтому его нужно выдавать. |
Действие Ghost Toggle Visibility это право не проверяет.
Плейсхолдеры
Теги MiniPlaceholders для текста MiniMessage. PlaceholderAPI не поддерживается.
| Плейсхолдер | Возвращает |
|---|---|
<ghost_visibility> | true, когда игрок видит призраков, иначе false. |
<ghost_visible> | 1, когда игрок видит призраков, иначе 0. |
<ghost_count> | Число удалённых призраков, известных этому серверу в данный момент. |
Записи
Записей: 2, сгенерированы из исходного кода расширения.
Действия1
- Ghost Toggle VisibilityToggle Ghost Visibility
Факты1
- Ghost Visibility FactGhost Visibility
Устранение неполадок
Призраки не появляются. Проверьте по порядку: оба сервера используют один и тот же непустой redis.group-id и разные значения redis.server-name, Redis подключён (иначе в логе пишется «BTC RedisService is not connected; Ghost updates will remain inactive»), у зрителя включены призраки, а два игрока находятся в совместимых мирах (одинаковое название мира или общий шаблон из allowed-worlds при view-distance: 0).
Игроки с того же сервера никогда не отображаются как призраки. Так и должно быть: сервер игнорирует сообщения, которые сам опубликовал.
Расширение не запускается с «Unsupported Ghost custom config schema». schema-version в ghost_player/config.yml вне диапазона 1..2. Задайте 2.
Расширение не запускается из-за ошибки с названием сервера. redis.server-name в конфигурации MySQL должен содержать только буквы, цифры, ., _ или -, длиной до 64 символов.
/ghost сообщает, что у вас нет права. У права нет значения по умолчанию. Выдайте typewriter.ghost.use (или право, заданное в command.permission) через ваш плагин прав.
Призраки исчезают через несколько секунд. В течение timeout-millis не пришло обновление. Проверьте задержку Redis и что сервер-источник запускает Ghost с тем же redis.group-id.
У призраков нет таблички. Таблички приходят из UiCore. Установите его на сервере зрителя. Без него показывается только суффикс сервера в имени.