'use strict'; import PlayerId from './players/player-id'; import DuelController from './game-server/duel-controller'; import MariadbConnector from './db/mariadb-connector'; import ServerToolListner from './tools/server-tool-listener'; function Server() { console.log('Starting 12 heroes server'); const io = require('socket.io'); const server = io.listen(2610); let mariadbConn = new MariadbConnector(); let authorizedPlayers = new Map(); let connectedPlayers = new Map(); let authorizedPlayersNames = new Set(); // let players = []; // let addNewPlayer = function (playerSocket, playerName) { // console.log('players length : ' + players.length + ' : ' + players); // if (players.length < 2) { // let newPlayer = new PlayerId(playerSocket, playerName); // console.log('push player : ' + newPlayer); // players.push(newPlayer); // } // if (players.length === 2) { // let duelController = new DuelController(players[0], players[1]); // } // }; server.on('connection', function(socket) { console.log('A player connected with id : ' + socket.id); socket.on('disconnect', reason => { try { removeAllGamesCreatedByPlayer(connectedPlayers.get(socket.id)); } catch (err) { console.log('Error removing games : ' + err.message); } forceClientsReloadGames(); if ( reason === 'client namespace disconnect' || reason === 'server namespace disconnect' ) { console.log('A player disconnected with id : ' + socket.id); let playerName = connectedPlayers.get(socket.id); if (playerName) { connectedPlayers.delete(socket.id); authorizedPlayers.get(playerName).setConnected(false); authorizedPlayers.get(playerName).setSocket(null); console.log(playerName + ' disconnected'); } } else { console.log('disconnected unexpectidly with reason : ' + reason); } }); socket.on('connect', () => { console.log('Connected to server'); }); socket.on('auth', async (playerName, callback) => { console.log(' Received auth message, player name : ' + playerName); await updatePlayersFromDb(); let response = {}; let kickout = false; if (!authorizedPlayersNames.has(playerName)) { response = { res: 'ko', message: playerName + ' Not found' }; kickout = true; } // If the player is already connected and active else if ( authorizedPlayers.get(playerName).isConnected() && authorizedPlayers.get(playerName).getSocket().connected ) { response = { res: 'ko', message: playerName + ' already connected' }; kickout = true; } else { // Player marked as connected but socket is down, clean it if (authorizedPlayers.get(playerName).isConnected()) { authorizedPlayers .get(playerName) .getSocket() .disconnect(true); } else { // In case server did not detect disconnection and did not clean the pending created games try { removeAllGamesCreatedByPlayer(playerName); } catch (err) { console.log('Error removing games : ' + err.message); } } response = { res: 'ok', message: playerName + ' connected' }; authorizedPlayers.get(playerName).setConnected(true); authorizedPlayers.get(playerName).setSocket(socket); connectedPlayers.set(socket.id, playerName); } callback(response); if (kickout === true) { setTimeout(() => { socket.disconnect(true); }, 600); } }); socket.on('games-list', async (playerName, callback) => { console.log(' Received games-list message, player name : ' + playerName); let response = {}; try { let games = await getJoinableGames(playerName); response = { res: 'ok', message: games }; } catch (error) { response = { res: 'ko', message: 'Error from server' }; } callback(response); }); socket.on('create-game', async (game, callback) => { let response = {}; try { let id = await addGameDb(game); response = { res: 'ok', message: id }; console.log('Force all clients to reload their games'); forceClientsReloadGames(); } catch (error) { response = { res: 'ko', message: 'Error from server' }; } callback(response); }); socket.on('remove-created-game', async (username, callback) => { try { removeAllGamesCreatedByPlayer(username); } catch (err) { console.log('Error removing games : ' + err.message); } callback(true); forceClientsReloadGames(); }); }); let updatePlayersFromDb = async function() { try { let usernames = await mariadbConn.getUsernames(); authorizedPlayersNames = new Set(usernames); console.log('authorizedPlayersNames update : ', authorizedPlayersNames); authorizedPlayersNames.forEach(name => { if (!authorizedPlayers.has(name)) { console.log('New username authorized :', name); authorizedPlayers.set(name, new PlayerId(name)); } }); return 'ok'; } catch (error) { console.log('Error getting usernames from DB : ', error); return error.Error; } }; let getCurrentListAuthorizedPlayers = function() { return [...authorizedPlayersNames]; }; let addPlayerDb = async function(username) { console.log('add player in db : ' + username); try { let response = await mariadbConn.addPlayer(username); authorizedPlayersNames.add(username); authorizedPlayers.set(username, new PlayerId(username)); return 'OK ' + JSON.stringify(response); } catch (err) { return 'KO ' + err.message; } }; let removePlayerDb = async function(username) { console.log('remove player in db : ' + username); try { let response = await mariadbConn.removePlayer(username); authorizedPlayersNames.delete(username); authorizedPlayers.delete(username); return 'OK ' + JSON.stringify(response); } catch (err) { return 'KO ' + err.message; } }; let addGameDb = async function(game) { try { let response = await mariadbConn.addNewGame(game); return response; } catch (err) { console.log('KO ' + err.message); throw err; } }; let removeGameDb = async function(method, ...args) { try { let response; switch (method) { case 'byId': response = await mariadbConn.removeGameById(args[0]); break; case 'byPlayer1': response = await mariadbConn.removeGamesByPlayer1(args[0]); break; case 'byPlayerAny': response = await mariadbConn.removeGamesByPlayerAny(args[0]); break; case 'byStatus': response = await mariadbConn.removeGamesByStatus(args[0]); break; case 'byDays': response = await mariadbConn.removeGamesByDays(args[0]); break; case 'finishedByDays': response = await mariadbConn.removeFinishedGamesByDays(args[0]); break; default: return 'KO : Unknown method to remove game from DB : ' + method; } return 'OK ' + JSON.stringify(response); } catch (err) { return 'KO ' + err.message; } }; let getJoinableGames = async function(username) { try { let games = await mariadbConn.getJoinableGamesForPlayer(username); return games; } catch (err) { console.log('KO : not able to get games : ' + err); throw err; } }; let removeAllGamesCreatedByPlayer = async function(playerName) { let result = await mariadbConn.removeCreatedGamesByPlayer1(playerName); return result; }; let forceClientsReloadGames = function() { server.emit('reload-games-list'); }; return { updatePlayersFromDb, getCurrentListAuthorizedPlayers, addPlayerDb, removePlayerDb, addGameDb, removeGameDb, getJoinableGames }; } let server = new Server(); let serverToolListner = new ServerToolListner(server); serverToolListner.listen(1664);