Source: models/Lobby.js

const { v4: uuidv4 } = require('uuid')
const WebSocket = require('ws')
/**
 * Class representing a Lobby.
 * A Lobby is where all the rooms and the players' connections are stored 
 * Think of a Lobby as the place where all the players hangout before they are matched to a room
 *
 */
class Lobby {
    /**
     * @constructor
     * @param  {integer} MAX_ROOMS_PER_LOBBY maximum rooms per lobby based on the number of rooms members per room & the app instance flavor (server performance)
     */
    constructor(MAX_ROOMS_PER_LOBBY) {
        this.MAX_ROOMS_PER_LOBBY= MAX_ROOMS_PER_LOBBY
        this.connectedClients = {}
        this.nameMap = {}
        this.udpConnections={}
        this.udpConnectionsPerRoom= {}
        this.rooms = []
        this.availableRooms = []
        this.fullRooms = []
    }
    /**
     * @param  {string} playerKey  unique identifier of the session using the |Sec-WebSocket-Key| header
     * @param  {ws} connection  websocket connection
     */
    addPlayer(playerKey, connection) {
        var playerId = uuidv4()
        this.nameMap[playerId] = playerKey
        this.connectedClients[playerKey] = connection
        return playerId
    }
    /**
     * @param  {string} playerId unique player id assigned once the connection is established using uuid package
     */
    removePlayer(playerId) {
        var playerKey = this.nameMap[playerId]
        delete this.nameMap[playerId]
        delete this.connectedClients[playerKey]
    }
    /**
     * @param  {Room} room room object, representing the room to be added
     */
    addRoom(room) {
        this.rooms.push(room)
        this.availableRooms.push(room)
    }
    /**
     * @param  {string} roomId the unique room id of the room to be removed
     */
    removeRoom(roomId) {
        this.rooms.forEach((room, index, object) => {
            if (room.roomId === roomId) {
                object.splice(index, 1)
            }
        })
        this.availableRooms.forEach((room, index, object) => {
            if (room.roomId === roomId) {
                object.splice(index, 1)
            }
        })
        this.fullRooms.forEach((room, index, object) => {
            if (room.roomId === roomId) {
                object.splice(index, 1)
            }
        })
    }
    /**
     * @param  {Event} Event event object, representing the event to be sent to Lobby members
     */
    notifyLobbyMembers(Event) {
        Object.values(this.connectedClients).forEach(client => {
            if (client !== undefined && client.readyState === WebSocket.OPEN) {
                client.send(Event.convertToJSONString())
            }
        })
    }
    /**
     * @param  {string} playerId unique player id assigned once the connection is established using uuid package
     */
    getPlayerConnection(playerId) {
        var playerKey = this.nameMap[playerId]
        var connection = this.connectedClients[playerKey]
        return connection
    }
    /**
     * @param  {string} roomId the unique room id of the room
     */
    getRoomById(roomId) {
        return this.rooms.find(room => room.roomId === roomId)
    }
    /**
     * @param  {string} roomId the unique room id of the room
     * @param  {UDPClient} udpClient UDPClient Object, representing the udp connection to be added to the udpClientsMap
     */
    updateRoomUDPClientsMap(roomId, udpClient) {
        
        if(this.udpConnectionsPerRoom[roomId] === undefined){
            this.udpConnectionsPerRoom[roomId] = [udpClient]
        }
        else{
            this.udpConnectionsPerRoom[roomId].push(udpClient)
        }
    }
    /**
     * @param  {Room} room room object, representing the room to be marked full
     */
    markRoomAsFull(room) {
        this.availableRooms.forEach((availableRoom, index, object) => {
            if (availableRoom.roomId === room.roomId) {
                object.splice(index, 1)
            }
        })
        this.fullRooms.push(room)
    }
    /**
     * @param  {UDPClient} udpClient UDPClient object
     */
    udpConnectionExists(udpClient){
       return this.udpConnections[JSON.stringify(udpClient)] === true
    }
    
}
module.exports.Lobby = Lobby