/
docNemo
/
hex-map-editor
Обзор
Документация
Войти
/
docNemo
/
hex-map-editor
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
5
CI/CD
Аналитика
Безопасность
main
src/foundry/refresh-socket.ts
65 строк
3 KB
docNemo
fix(sync): объявить использование сокета в манифесте
03 авг 2026, 14:08
03 авг 2026, 14:08
abe976f
Код
Авторство
О чём код?
import { MODULE_ID } from '@core/constants'; import { logger } from '@core/log'; /** * Принудительная рассылка карты клиентам. * * Обычные правки доходят сами: карта лежит во флагах сцены, и её изменение * порождает `updateScene`. Но заставить это событие возникнуть на ровном месте * нельзя — ЗАМЕРЕНО на Foundry 14.365: * * ``` * setFlag тем же значением → события НЕТ * update({...}, { diff: false }) → события НЕТ * update({...}, { diff: false, recursive: false }) → события НЕТ * setFlag другим значением → событие есть * ``` * * То есть `diff: false` на флаги не действует, и кнопка «разослать заново», * переписывающая карту тем же значением, не делала ровно ничего. * * Поэтому рассылка идёт сокетом. Так честнее и по существу: обновить нужно * не данные — они и так верны, — а клиентов, которые от них отстали. Лишней * записи в базу мира при этом не происходит вовсе. */ /** * Канал модуля. * * ОБЯЗАТЕЛЬНО требует `"socket": true` в module.json. Без этого поля сервер * молча не пересылает сообщения: `emit` отрабатывает без ошибки, подписчик на * другом клиенте зарегистрирован, но не получает ничего. ЗАМЕРЕНО на 14.365 — * ровно так это и выглядело, пока поле не добавили. */ const CHANNEL = `module.${MODULE_ID}`; interface RefreshMessage { type: 'refresh'; sceneId: string; } function isRefresh(data: unknown): data is RefreshMessage { if (data === null || typeof data !== 'object') return false; const message = data as Partial<RefreshMessage>; return message.type === 'refresh' && typeof message.sceneId === 'string'; } /** * Подписывается на просьбы перечитать карту. * * Отправитель своё же сообщение не получает — это поведение сокета Foundry, * а не упущение: у того, кто нажал кнопку, карта и так свежая. */ export function listenForRefresh(reload: () => void): void { game.socket?.on(CHANNEL, (data: unknown) => { if (!isRefresh(data)) return; if (data.sceneId !== canvas.scene?.id) return; logger.debug('Получена просьба перечитать карту.'); reload(); }); } /** Просит остальных клиентов перечитать карту текущей сцены. */ export function broadcastRefresh(sceneId: string): void { game.socket?.emit(CHANNEL, { type: 'refresh', sceneId } satisfies RefreshMessage); }