require('babel-polyfill'); const express = require('express'), app = express(), server = require('http').createServer(app), io = require('socket.io')(server, { // wsEngine: 'ws' }), exphbs = require('express-handlebars'), qrCode = require('branded-qr-code'), fs = require('fs'); const scores = JSON.parse(fs.readFileSync('scores.json', 'utf8')); // Detect local IP let os = require('os'); let ifaces = os.networkInterfaces(); let ip; Object.keys(ifaces).forEach(function (ifname) { let alias = 0; ifaces[ifname].forEach(function (iface) { if ('IPv4' !== iface.family || iface.internal !== false) { // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses return; } if (alias >= 1) { // this single interface has multiple ipv4 addresses console.log(ifname + ':' + alias, iface.address); } else { // this interface has only one ipv4 adress console.log(ifname, iface.address); ip = iface.address; } ++alias; }); }); /** CONSTANTS */ const HOST = 'http://' + ip + ':8080/client/'; const players = [ { type: 'mario', name: 'Mario', id: guid(), score: 0 }, { type: 'luigi', name: 'Luigi', id: guid(), score: 0 }, ] console.log(players); app.set('views', 'src/views'); app.engine('.hbs', exphbs({ extname: '.hbs', })); app.set('view engine', '.hbs'); server.listen(8080, function () { console.log('Listening on *:' + this.address().port); }); app.get('/assets*', (req, res) => { if (req.originalUrl.includes('qr.png')) { const isMario = req.originalUrl.includes('mario'); qrCode.generate({ text: HOST + players[isMario ? 0 : 1].id, path: __dirname + '/assets/' + (isMario ? 'mario.png' : 'luigi.png'), ratio: 4, opt: { errorCorrectionLevel: 'H', width: 500, }, }).then(qr => { res.send(qr); }); } else if (!req.originalUrl.includes('.map')) res.sendFile(__dirname + req.originalUrl.split('?')[0]); }); app.get(['/', '/index.html'], (req, res) => { res.render('server', { layout: false, marioURL: HOST + players[0].id, luigiURL: HOST + players[1].id, marioId: players[0].id, luigiId: players[1].id, }); }); app.get('/client/:id', (req, res) => { console.log(req.params.id); if (req.params.id == players[0].id || req.params.id == players[1].id) res.render('client', { layout: false, id: getPlayerFromId(req.params.id).id, type: getPlayerFromId(req.params.id).type, }); else res.render('error', { layout: false }); }); const monitorNSP = io.of('/monitor'); const clientNSP = io.of('/client'); let count = 0; clientNSP.on('connection', socket => { let id = socket.request.headers.referer.split('/').slice(-1)[0]; if (!getPlayerFromId(id)) { console.error('Wrong ID'); return; } console.log('Client connected.'); monitorNSP.emit('clientConnect', getPlayerFromId(id).type); count++; if (count === 2) setTimeout(() => monitorNSP.emit('updateGameState', 1), 2000); let pl = getPlayerFromId(socket.request.headers.referer.split('/').slice(-1)[0]); socket.on('changeName', name => pl.name = name); socket.on('moveStart_left', () => { console.log('moveStart_left: ' + pl.type); monitorNSP.emit('moveStart_left', pl.type); }); socket.on('moveStart_right', () => { console.log('moveStart_right: ' + pl.type); monitorNSP.emit('moveStart_right', pl.type); }); socket.on('moveStart_jump', () => { console.log('moveStart_jump: ' + pl.type); monitorNSP.emit('moveStart_jump', pl.type) }); socket.on('moveStart_crouch', () => { console.log('moveStart_crouch: ' + pl.type); }); socket.on('moveEnd_left', () => { console.log('moveEnd_left: ' + pl.type); monitorNSP.emit('moveEnd_left', pl.type); }); socket.on('moveEnd_right', () => { console.log('moveEnd_right: ' + pl.type); monitorNSP.emit('moveEnd_right', pl.type); }); socket.on('moveEnd_jump', () => { console.log('moveEnd_jump: ' + pl.type); }); socket.on('moveEnd_crouch', () => { console.log('moveEnd_crouch: ' + pl.type); }); socket.on('disconnect', () => { console.log('Client disconnected.'); count--; monitorNSP.emit('clientDisconnect', getPlayerFromId(id).type); }); }); let playerDeaths = 0; monitorNSP.on('connection', socket => { console.log('Monitor connected.'); socket.emit('handshake', { scores, marioURL: HOST + players[0].id, luigiURL: HOST + players[1].id, marioId: players[0].id, luigiId: players[1].id, }); socket.on('playerDie', options => { console.log(options.score) playerDeaths++; let pl = players.filter(el => el.type == options.player)[0]; pl.score = options.score; if (pl.score > 0) { scores.push({ name: pl.name, score: pl.score }); fs.writeFile('scores.json', JSON.stringify(scores)); } if (playerDeaths === 2) { setTimeout(() => { monitorNSP.emit('handshake', { scores, marioId: players[0].id, luigiId: players[1].id, }); }, 4000); } }); socket.on('disconnect', () => { console.log('Monitor disconnected.'); }); }); function getPlayerFromId(id) { return players.filter(el => el.id == id)[0]; } function guid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); }