const EventEmitter = require('events'); const io = require('../globals/io'); const { sendAlert } = require('./alertService'); const ALERT_COLOR = '#ff9800'; const { isAdmin, isLockdownAdmin } = require('./roleService'); const { publishEvent } = require('./eventBus'); const MODES = { OPEN: 'open', TURNS: 'turns', ADMIN: 'admin', LOCKDOWN: 'lockdown', }; let currentMode = MODES.ADMIN; const modeEvents = new EventEmitter(); function canChangeMode(socket, nextMode) { if (currentMode === MODES.LOCKDOWN && nextMode !== MODES.LOCKDOWN) { return isLockdownAdmin(socket); } if (nextMode === MODES.LOCKDOWN) { return isAdmin(socket); } return isAdmin(socket); } function setMode(nextMode, socket, options = {}) { if (!Object.values(MODES).includes(nextMode)) { throw new Error(`Unknown mode ${nextMode}`); } const force = Boolean(options.force); if (!force && !canChangeMode(socket, nextMode)) { throw new Error('Not authorized to change mode'); } if (currentMode === nextMode) { return currentMode; } currentMode = nextMode; sendAlert({ color: ALERT_COLOR, title: 'Mode Changed', message: `Server mode set to ${nextMode}`, }); publishEvent({ source: 'modeManager', type: 'mode.changed', payload: { mode: currentMode, by: socket?.data?.user?.username || null }, }); modeEvents.emit('change', currentMode); io.emit('mode', { mode: currentMode }); return currentMode; } function getMode() { return currentMode; } module.exports = { MODES, getMode, setMode, modeEvents, }; io.on('connection', (socket) => { socket.emit('mode', { mode: currentMode }); socket.on('setMode', ({ mode }) => { try { setMode(mode, socket); } catch (err) { sendAlert({ color: ALERT_COLOR, title: 'Mode change failed', message: err.message }); } }); });