Привет! Я делаю многопользовательскую настольную игру на vue, используя сокеты. У меня есть функция случайного распределения ролей. Но вот проблема, когда игроки нажимают кнопку готов, у каждого клиента происходит проверка на то все ли готовы и вызывается функция запуска игры и раздачи ролей и у каждого сокета роли раздаются по своему, а мне нужно, чтобы роли мешались у всех единым образом. Наверное мне стоит сделать проверку готовности прямо на сервере, да?
const { RESOURCES, initResources } = require('./data/resources.js');
const WebSocket = require('ws');
const os = require('os');

function broadcast(data) {
  wss.clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify(data));
    }
  });
}

function getLocalIp() {
  const interfaces = os.networkInterfaces();
  for (const name of Object.keys(interfaces)) {
    for (const net of interfaces[name]) {
      // Пропускаем внутренние и не-IPv4 интерфейсы
      if (net.family === 'IPv4' && !net.internal) {
        return net.address;
      }
    }
  }
  return 'localhost'; // Fallback
}
const LOCAL_IP = getLocalIp();
const WS_PORT = 8080;

const wss = new WebSocket.Server({ host: '0.0.0.0', port: WS_PORT });

const roles = ['lady', 'sir', 'captain', 'fmate', 'frenchy', 'kid'];

let player = {
  nickname: '',
  role: '',
  friend: '',
  foe: '',
}

let gameState = {
  isGameStarted: false,
  round: 0,
  phase: 'init',
  players: [],
  resources: initResources,
  threats: [],
  turn: {
    currentPlayerId: 0,
    phase: ''
  },
  gameStatus: ''
}

const games = new Map();
wss.on('connection', (ws) => {
  ws.player = player;
  ws.isPlaying = false;

  ws.send(JSON.stringify({
    type: 'FULL_STATE_UPDATE',
    state: gameState,
  }))

  function broadcastPlayerStats() {
    const playerCount = Array.from(wss.clients).filter(
      client => client.isPlaying && client.readyState === WebSocket.OPEN
    ).length;
    const totalCount = Array.from(wss.clients).filter(
      client => client.readyState === WebSocket.OPEN
    ).length;

    broadcast({
      command: 'player_stats',
      playerCount,
      totalCount,
    });
  }

  function broadcastState() {
    broadcast({
      type: 'FULL_STATE_UPDATE',
      state: gameState
    });
  }

  function onPlay() {
    if (!ws.isPlaying) {
      ws.isPlaying = true;
      broadcastPlayerStats();

      console.log(`Player ready. Ready players: ${Array.from(wss.clients).filter(
        client => client.isPlaying && client.readyState === WebSocket.OPEN
      ).length}`);

      //gameState.players.push(ws.player);
    }
  }

  function onChatMessage(msg) {
    broadcast({
      command: 'chat_message',
      text: msg.text,
      nickname: msg.nickname,
    });
  }

  function onInitRoles() {
    const players = Array.from(wss.clients).filter(client =>
      client.isPlaying && client.readyState === WebSocket.OPEN
    );

    if (players.length > roles.length) {
      ws.send(JSON.stringify({ error: 'Not enough roles for all players' }));
      return;
    }

    const shuffledRoles = [...roles].sort(() => Math.random() - 0.5).slice(players.length);
    const foeRoles = [...shuffledRoles].sort(() => Math.random() - 0.5);//.slice(players.length);
    const friendRoles = [...shuffledRoles].sort(() => Math.random() - 0.5);//.slice(players.length);
    console.log(`shuffledRoles: ${shuffledRoles}`);
    console.log(`foeRoles: ${foeRoles}`);
    console.log(`friendRoles: ${friendRoles}`);


    gameState.players = players.map((client, index) => ({
      role: shuffledRoles[index],
      foe: foeRoles[index],
      friend: friendRoles[index],
      id: index
    }));

    broadcastState();


    /// Sending index to every user
    Array.from(wss.clients).forEach((client, index) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify({command:'get_id', id: index}));
      }
    });
    return { success: true };
  }

  // function onGameIsStarted() {
  //   gameState.gameStatus = true;

  //   broadcast(JSON.stringify({command: 'game_is_started', gameState}))
  // }

  function startGame() {
    gameState.isGameStarted = true;
    gameState.gameStatus = 'playing';
    broadcastState();
  }

  ws.on('message', (message) => {
    let msg;
    try {
      msg = JSON.parse(message);
    } catch (e) {
      ws.send(JSON.stringify({ error: 'Invalid message format, must be JSON' }));
      return;
    }

    switch (msg.command) {
      case 'play':
        onPlay();
        break;

      case 'init_roles':
        onInitRoles();
        break;

      case 'start_game':
        startGame();
        break;

      case 'chat_message':
        onChatMessage(msg);
        break;

      default:
        ws.send(JSON.stringify({ error: 'Unknown command' }));
    }
  });

  ws.on('close', () => {
    if (ws.isPlaying) {
      ws.isPlaying = false;
      broadcastPlayerStats();

      console.log(`Player left. Ready players: ${Array.from(wss.clients).filter(
        client => client.isPlaying && client.readyState === WebSocket.OPEN
      ).length}`);
    }
  });
});

console.log(`WebSocket server is running on:
  Local: ws://localhost:${WS_PORT}
  Network: ws://${LOCAL_IP}:${WS_PORT}`);