const server = require('http').createServer(); const io = require('../sockets'); const nsp = io.of('/randomFree'); const crypto = require('crypto-js'); const cryptoSHA256= crypto.SHA256; const GameMachine= require('../../game').GameMachine; let Users = require('../../database').Repositories.Users; class randomFree { constructor() { const updateLobby = () => { io.clients((err, clients) => { io.emit('lobbySize', clients.length); nsp.emit('lobbySize', clients.length); }); } const chatMsg = (msg) => { msg.time = new Date().toISOString(); io.to('chat').emit('newChatMsg', msg); nsp.to('chat').emit('newChatMsg', msg); } nsp.on('connection', (socket) => { //console.log('Someone connected'); socket.join('chat'); socket.on('chatMsg', chatMsg); socket.emit('test'); //socket.on('disconnect', informOpponent); this.userInGame(socket).then((flag) => { if(!flag){ socket.join('queue'); console.log("Matching!"); this.match(); } else { this.setupSocket(socket, flag.currentGame.channel); } }); }); // is always called io.on('connection', (socket) => { this.userInGame(socket); socket.on('disconnect', updateLobby); socket.join('chat'); socket.on('chatMsg', chatMsg); updateLobby(); }); } userInGame(socket) { let token = socket.request._query['token']; return Users.getUser(token) .then((user) => { if(user.currentGame !== null && user.currentGame !== undefined) { console.log("Game in progress... Sending details...") socket.emit('gameInProgress', user.currentGame); return user; } return false; }); } match() { nsp.in('queue').clients((error, clients) => { if (error) throw error; if(clients.length > 1) { let p1 = nsp.sockets[clients[0]]; let p2 = nsp.sockets[clients[1]]; p1.emit('test'); p2.emit('test'); const channel = clients[0] + clients[1]; console.log(channel); let token1 = p1.request._query['token']; let token2 = p2.request._query['token']; // maybe i need to change to username let matchInfo = this.joinGame(token1, token2, channel); const saveUser = (user, state) => { user.currentGame = state; Users.save(user); }; // fix this shit! // Main parameters : p1,p2(sockets) -> matchInfo -> channel // Split function for each Socket -> Keep channel on matchInfo! // this.saveUser(token1, matchInfo.playerOneState) .then(() => this.saveUser(token1, matchInfo.playerTwoState)) .then(() => nsp.in(channel).clients((err, clients) => { console.log('Channel: ' + channel); console.log(clients); console.log("Joining Game"); this.setupSocket(p1, channel); this.setupSocket(p2, channel); p1.emit('joinGame', matchInfo.playerOneState); p2.emit('joinGame', matchInfo.playerTwoState); })); } nsp.in('queue').clients((err, clients) => { console.log('Queue'); console.log(clients); io.emit('queueSize', clients.length); nsp.emit('queueSize', clients.length); }); }); } saveUser(token, currentGame) { return Users.getUser(token).then((user) => saveUser(user, currentGame)); } setupSocket(socket, channel) { socket.on('broadcast', (data) => this.broadcast(data, channel)); socket.on('abandon', (data) => this.abandon(data, channel)); socket.on('gameOver', (data) => this.gameOver(data, channel)); socket.on('dispute', (data) => this.dispute(data, channel)); socket.leave('queue', this.errorHandler); socket.join(channel, this.errorHandler); } abandon(data, channel) { // implement abandon } broadcast(data, channel) { data.timestamp = new Date().getTime(); nsp.in(channel).emit('move', data); } dispute(data, channel) { let result; // result. gameService.dispute(data); //may change to 'disputeResult' nsp.in(channel).emit('result', result); } gameOver(data, channel) { // TODO this should be emitted ONLY if all 9 moves have been played // TODO verify move stack (compare with hashed cards) console.log("[---!!!---]GameOver is called!!! "); let gameMachine = new GameMachine(data.setup); let winner = gameMachine.runMatch(data.stack.moves); console.log("[!!!!--->]Winner is " + winner); nsp.in(channel).emit('winner', winner); } errorHandler(e) { if(e)throw e; return 0; }; joinGame(playerOne, playerTwo, channel){ let playerOneCards = this.createRandomCards(); let playerTwoCards = this.createRandomCards(); let setup = this.createSetupArray(playerOne, playerTwo, playerOneCards, playerTwoCards); let playerOneState = {cards: playerOneCards, setup: setup, channel}; let playerTwoState = {cards: playerTwoCards, setup: setup, channel}; return {playerOneState, playerTwoState}; } createSetupArray(playerOne, playerTwo, playerOneCards, playerTwoCards){ let id = [ playerOne, playerTwo ]; let cards = [ playerOneCards.hashedCardsArray, playerTwoCards.hashedCardsArray ]; let setup = {id, cards }; return setup; } createRandomCards(){ let playerCardsArray = []; let saltArray = []; let hashedCardsArray= []; for (let i =0; i<5; i++){ let playerCard = Math.floor((Math.random()*100 ) % 100 ); let salt = crypto.lib.WordArray.random(128 / 8).toString(); let hashedCard = cryptoSHA256(playerCard.toString() + salt); playerCardsArray.push(playerCard); saltArray.push(salt); hashedCardsArray.push(hashedCard.toString()); } return {playerCardsArray, saltArray, hashedCardsArray}; } } module.exports = new randomFree();