From: Luigi Pinca Date: Sat, 20 Oct 2012 20:46:29 +0000 (+0200) Subject: refactored code and added ability to ignore players X-Git-Url: https://git.saalbach.dev/?a=commitdiff_plain;h=80f9b33ae15d747ef5de65025acc73f9a43a9441;p=binbsis50.git refactored code and added ability to ignore players --- diff --git a/app.js b/app.js index b0f700a..2c0c329 100644 --- a/app.js +++ b/app.js @@ -125,19 +125,44 @@ io.set('authorization', function(data, accept) { io.sockets.on('connection', function(socket) { var session = socket.handshake.session; - socket.on('getoverview', function() { + socket.on('disconnect', function() { + if (socket.roomname) { + rooms[socket.roomname].removeUser(socket.nickname); + } + }); + socket.on('getoverview', function(callback) { + if (typeof callback !== 'function') { + return; + } var data = Object.create(null); for (var prop in rooms) { data[prop] = rooms[prop].getPopulation(); } - socket.join('home'); - socket.emit('overview', data); + callback(data); }); - socket.on('loggedin', function(fn) { - return (session.user) ? fn(session.user) : fn(false); + socket.on('getstatus', function(callback) { + if (socket.roomname && typeof callback === 'function') { + rooms[socket.roomname].sendStatus(callback); + } + }); + socket.on('guess', function(guess) { + if (socket.roomname && typeof guess === 'string') { + rooms[socket.roomname].guess(socket, guess); + } + }); + socket.on('ignore', function(baduser, callback) { + if (socket.roomname && typeof baduser === 'string' && typeof callback === 'function') { + rooms[socket.roomname].ignore(baduser, socket.nickname, callback); + } + }); + socket.on('joinanonymously', function(nickname, roomname) { + if (!socket.nickname && typeof nickname === 'string' && nickname !== '' && + config.rooms.indexOf(roomname) !== -1) { + rooms[roomname].setNickName(socket, nickname); + } }); socket.on('joinroom', function(room) { - if (session.user && typeof room === 'string' && config.rooms.indexOf(room) !== -1) { + if (session.user && config.rooms.indexOf(room) !== -1) { if (sockets[session.user]) { // User already in a room socket.emit('alreadyinaroom'); return; @@ -146,30 +171,20 @@ io.sockets.on('connection', function(socket) { rooms[room].joinRoom(socket); } }); - socket.on('joinanonymously', function(nickname, roomname) { - if (!socket.nickname && typeof nickname === 'string' && nickname !== '' && - typeof roomname === 'string' && config.rooms.indexOf(roomname) !== -1) { - rooms[roomname].setNickName(socket, nickname); - } - }); - socket.on('getstatus', function() { - if (socket.roomname) { - rooms[socket.roomname].sendStatus(socket); + socket.on('loggedin', function(callback) { + if (typeof callback !== 'function') { + return; } + return (session.user) ? callback(session.user) : callback(false); }); socket.on('sendchatmsg', function(msg, to) { if (socket.roomname && typeof msg === 'string') { rooms[socket.roomname].sendChatMessage(msg, socket, to); } }); - socket.on('guess', function(guess) { - if (socket.roomname && typeof guess === 'string') { - rooms[socket.roomname].guess(socket, guess); - } - }); - socket.on('disconnect', function() { - if (socket.roomname) { - rooms[socket.roomname].removeUser(socket.nickname); + socket.on('unignore', function(baduser) { + if (socket.roomname && typeof baduser === 'string') { + rooms[socket.roomname].unignore(baduser, socket.nickname); } }); }); diff --git a/lib/room.js b/lib/room.js index 78ba92c..a764933 100644 --- a/lib/room.js +++ b/lib/room.js @@ -42,111 +42,6 @@ module.exports = function(params) { , totusers = 0 , usersData = Object.create(null); - // Add a new user in the room. - var addUser = function(socket, loggedin) { - sockets[socket.nickname] = socket; - usersData[socket.nickname] = { - nickname: socket.nickname, - registered: loggedin, - points: 0, - roundpoints: 0, - matched: null, - guessed: 0, - guesstime: null, - totguesstime: 0, - golds: 0, - silvers: 0, - bronzes: 0 - }; - totusers++; - // Broadcast new user event - io.sockets.in('home').emit('update', roomname, totusers); - socket.emit('ready', usersData, trackscount, loggedin); - socket.broadcast.to(roomname).emit('newuser', socket.nickname, usersData); - }; - - // A user has left (DCed, etc.) - this.removeUser = function(nickname) { - // Delete the references - delete sockets[nickname]; - delete usersData[nickname]; - totusers--; - // Broadcast the event - io.sockets.in('home').emit('update', roomname, totusers); - io.sockets.in(roomname).emit('userleft', nickname, usersData); - }; - - // Return the number of users in the room. - this.getPopulation = function() { - return totusers; - }; - - this.joinRoom = function(socket) { - socket.roomname = roomname; - socket.join(roomname); - addUser(socket, true); - }; - - // A user requested an invalid name - var invalidNickName = function(socket, feedback) { - socket.emit('invalidnickname', feedback); - }; - - // A user is submitting a name - this.setNickName = function(socket, nickname) { - var feedback = null; - - if (nickname.length > 15) { - feedback = 'That name is too long.'; - } - else if (nickname === 'binb') { - feedback = 'That name is reserved.'; - } - else if (sockets[nickname]) { - feedback = 'Name already taken.'; - } - - if (feedback) { - return invalidNickName(socket, feedback); - } - - // Check if requested nickname belong to a registered user - var key = 'user:'+nickname; - usersdb.exists(key, function(err, resp) { - if (resp === 1) { - feedback = 'That name belongs '; - feedback += 'to a registered user.'; - return invalidNickName(socket, feedback); - } - socket.nickname = nickname; - socket.roomname = roomname; - socket.join(roomname); - addUser(socket, false); - }); - }; - - // A user is sending a chat message - this.sendChatMessage = function(msg, socket, to) { - if (typeof to === 'string') { - // Check if the recipient is in the room - if (usersData[to]) { - socket.emit('chatmsg', msg, socket.nickname, to); - var recipient = sockets[to]; - recipient.emit('chatmsg', msg, socket.nickname, to); - } - return; - } - // Censor answers from chat - var msglcase = msg.toLowerCase(); - if (allowedguess && (amatch(artist, msglcase, true) || - (feat && amatch(feat, msglcase, true)) || amatch(title, msglcase))) { - var notice = 'You are probably right, but you have to use the box above.'; - socket.emit('chatmsg', notice, 'binb', socket.nickname); - return; - } - io.sockets.in(roomname).emit('chatmsg', msg, socket.nickname); - }; - // User points and statistics var addPointsAndStats = function(nickname, allinone) { usersData[nickname].guesstime = 30000 - songtimeleft; @@ -216,6 +111,68 @@ module.exports = function(params) { } }; + // Add a new user in the room + var addUser = function(socket, loggedin) { + sockets[socket.nickname] = socket; + usersData[socket.nickname] = { + nickname: socket.nickname, + registered: loggedin, + points: 0, + roundpoints: 0, + matched: null, + guessed: 0, + guesstime: null, + totguesstime: 0, + golds: 0, + silvers: 0, + bronzes: 0 + }; + totusers++; + // Broadcast new user event + io.sockets.emit('updateoverview', roomname, totusers); + socket.emit('ready', usersData, trackscount, loggedin); + socket.broadcast.to(roomname).emit('newuser', socket.nickname, usersData); + }; + + var gameOver = function() { + status = 3; // Game over + + // Build podium + var users = []; + for (var key in usersData) { + users.push(usersData[key]); + } + users.sort(function(a, b) {return b.points - a.points;}); + var podium = users.slice(0,3); + io.sockets.in(roomname).emit('gameover', podium); + + // Collect podium stats + if (podium[0] && podium[0].registered) { + collectStats(podium[0].nickname, {firstplace:true}); + } + if (podium[1] && podium[1].registered) { + collectStats(podium[1].nickname, {secondplace:true}); + } + if (podium[2] && podium[2].registered) { + collectStats(podium[2].nickname, {thirdplace:true}); + } + + resetPoints(false); + songcounter = 0; + // Check if FIFO is full + if (playedtracks.length === fifolength) { + playedtracks.splice(0, songsinarun); + } + + // Start a new game + setTimeout(sendLoadTrack, 5000); + }; + + // Return the number of users in the room + this.getPopulation = function() { + return totusers; + }; + // A user is sending a guess this.guess = function(socket, guess) { if (allowedguess) { @@ -282,6 +239,34 @@ module.exports = function(params) { } }; + this.ignore = function(baduser, executor, callback) { + // Check if the player to be ignored is in the room + if (usersData[baduser]) { + // Inform the bad player that he/she is being ignored + var recipient = sockets[baduser]; + recipient.emit('chatmsg', executor+' is ignoring you.', 'binb', baduser); + return callback(baduser); + } + callback(false); + }; + + this.joinRoom = function(socket) { + socket.roomname = roomname; + socket.join(roomname); + addUser(socket, true); + }; + + // A user has left (DCed, etc.) + this.removeUser = function(nickname) { + // Delete the references + delete sockets[nickname]; + delete usersData[nickname]; + totusers--; + // Broadcast the event + io.sockets.emit('updateoverview', roomname, totusers); + io.sockets.in(roomname).emit('userleft', nickname, usersData); + }; + var resetPoints = function(roundonly) { for (var key in usersData) { if (!roundonly) { @@ -298,6 +283,28 @@ module.exports = function(params) { } }; + // A user is sending a chat message + this.sendChatMessage = function(msg, socket, to) { + if (typeof to === 'string') { + // Check if the recipient is in the room + if (usersData[to]) { + socket.emit('chatmsg', msg, socket.nickname, to); + var recipient = sockets[to]; + recipient.emit('chatmsg', msg, socket.nickname, to); + } + return; + } + // Censor answers from chat + var msglcase = msg.toLowerCase(); + if (allowedguess && (amatch(artist, msglcase, true) || + (feat && amatch(feat, msglcase, true)) || amatch(title, msglcase))) { + var notice = 'You are probably right, but you have to use the box above.'; + socket.emit('chatmsg', notice, 'binb', socket.nickname); + return; + } + io.sockets.in(roomname).emit('chatmsg', msg, socket.nickname); + }; + // Extract a random track from the database and send the load event var sendLoadTrack = function() { songsdb.srandmember(roomname, function(err, res) { @@ -324,22 +331,13 @@ module.exports = function(params) { status = 1; // Loading next song }; - // Timer for the playing song - var songTimeLeft = function(end, delay) { - songtimeleft = end - Date.now(); - if (songtimeleft < delay) { - return; - } - setTimeout(songTimeLeft, delay, end, delay); - }; - var sendPlayTrack = function() { songcounter++; status = 0; // Playing track var data = { - counter:songcounter, - tot:songsinarun, - users:usersData + counter: songcounter, + tot: songsinarun, + users: usersData }; io.sockets.in(roomname).emit('playtrack', data); songTimeLeft(Date.now() + 30000, 50); @@ -347,13 +345,23 @@ module.exports = function(params) { setTimeout(sendTrackInfo, 30000); }; + // Send the room status + this.sendStatus = function(callback) { + var data = { + status: status, + timeleft: songtimeleft, + previewUrl: previewUrl + }; + callback(data); + }; + var sendTrackInfo = function() { var trackinfo = { - artworkUrl:artworkUrl, - artistName:artistName, - trackName:trackName, - trackViewUrl:trackViewUrl, - collectionName:collectionName + artworkUrl: artworkUrl, + artistName: artistName, + trackName: trackName, + trackViewUrl: trackViewUrl, + collectionName: collectionName }; io.sockets.in(roomname).emit('trackinfo', trackinfo); finishline = 1; @@ -369,48 +377,46 @@ module.exports = function(params) { setTimeout(gameOver, 5000); }; - var gameOver = function() { - status = 3; // Game over - - // Build podium - var users = []; - for (var key in usersData) { - users.push(usersData[key]); - } - users.sort(function(a, b) {return b.points - a.points;}); - var podium = users.slice(0,3); - io.sockets.in(roomname).emit('gameover', podium); + // A user is submitting a name + this.setNickName = function(socket, nickname) { + var feedback = null; - // Collect podium stats - if (podium[0] && podium[0].registered) { - collectStats(podium[0].nickname, {firstplace:true}); + if (nickname.length > 15) { + feedback = 'That name is too long.'; } - if (podium[1] && podium[1].registered) { - collectStats(podium[1].nickname, {secondplace:true}); + else if (nickname === 'binb') { + feedback = 'That name is reserved.'; } - if (podium[2] && podium[2].registered) { - collectStats(podium[2].nickname, {thirdplace:true}); + else if (sockets[nickname]) { + feedback = 'Name already taken.'; } - resetPoints(false); - songcounter = 0; - // Check if FIFO is full - if (playedtracks.length === fifolength) { - playedtracks.splice(0, songsinarun); + if (feedback) { + return socket.emit('invalidnickname', feedback); } - // Start a new game - setTimeout(sendLoadTrack, 5000); + // Check if requested nickname belong to a registered user + var key = 'user:'+nickname; + usersdb.exists(key, function(err, resp) { + if (resp === 1) { + feedback = 'That name belongs '; + feedback += 'to a registered user.'; + return socket.emit('invalidnickname', feedback); + } + socket.nickname = nickname; + socket.roomname = roomname; + socket.join(roomname); + addUser(socket, false); + }); }; - // Send the room status - this.sendStatus = function(socket) { - var data = { - status:status, - timeleft:songtimeleft, - previewUrl:previewUrl - }; - socket.emit('status', data); + // Timer for the playing song + var songTimeLeft = function(end, delay) { + songtimeleft = end - Date.now(); + if (songtimeleft < delay) { + return; + } + setTimeout(songTimeLeft, delay, end, delay); }; // Start the room @@ -420,6 +426,15 @@ module.exports = function(params) { }); sendLoadTrack(); }; + + this.unignore = function(baduser, executor) { + if (usersData[baduser]) { + // Inform the wicked player that he/she is no longer ignored + var recipient = sockets[baduser]; + var notice = executor+' has stopped ignoring you.'; + recipient.emit('chatmsg', notice, 'binb', baduser); + } + }; } return Room; diff --git a/package.json b/package.json index 5b09ca3..839c1bc 100644 --- a/package.json +++ b/package.json @@ -21,5 +21,5 @@ "start": "app.js" }, "subdomain": "binb", - "version": "0.3.4" + "version": "0.3.4-2" } \ No newline at end of file diff --git a/public/static/js/home.js b/public/static/js/home.js index fe72972..f23c620 100644 --- a/public/static/js/home.js +++ b/public/static/js/home.js @@ -19,13 +19,12 @@ $(function() { var uri = window.location.protocol+'//'+window.location.host; var socket = io.connect(uri, {'reconnect':false}); socket.on('connect', function() { - socket.emit('getoverview'); - socket.on('overview', function(data) { + socket.emit('getoverview', function(data) { for (var prop in data) { $('#'+prop).text(data[prop]); } }); - socket.on('update', function(room, players) { + socket.on('updateoverview', function(room, players) { $('#'+room).text(players); }); }); diff --git a/public/static/js/room.js b/public/static/js/room.js index ecaf934..36e8922 100644 --- a/public/static/js/room.js +++ b/public/static/js/room.js @@ -4,6 +4,7 @@ , DOM = {} , historycursor = 0 , historyvalues = [] + , ignoredplayers = {} , jplayer , nickname , pvtmsgto @@ -11,7 +12,7 @@ , socket , stopanimation = false , touchplay - , urlregex = /(https?:\/\/[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|])/; + , urlregex = /(https?:\/\/[\-A-Za-z0-9+&@#\/%?=~_()|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|])/; var amstrings = [ 'Yes, that\'s the artist. What about the title?' @@ -388,7 +389,7 @@ html += '
'; html += '
GuessedMean time'; html += ''; - + for(var i=0;i<3;i++) { if (podium[i]) { var playername = podium[i].nickname.encodeEntities(); @@ -416,6 +417,9 @@ // Receive a chat message var getChatMessage = function(chatmsg, from, to) { + if (ignoredplayers[from]) { + return; + } var prefix = from; var msgspan = $(''); if (to) { @@ -435,6 +439,19 @@ DOM.togglechat.click(showChat); }; + // Put a player in the ignore list + var ignore = function(baduser, outcome) { + socket.emit('ignore', baduser, function(player) { + if (player) { + ignoredplayers[player] = true; + outcome.text('(From binb): '+player+' is now ignored.'); + return addChatEntry(outcome); + } + outcome.append('player not found.'); + addChatEntry(outcome); + }); + }; + // Submitted name was invalid var invalidNickName = function(feedback) { joinAnonymously(feedback+'
Try with another one:'); @@ -548,7 +565,7 @@ if (!loggedin && !/nickname\s*\=/.test(document.cookie)) { document.cookie = 'nickname='+encodeURIComponent(nickname)+';path=/;'; } - + DOM.modal.modal('hide').empty(); $('#total-tracks span').text(trackscount); var msg = nickname+' joined the game'; @@ -564,6 +581,9 @@ if (pvtmsgto) { socket.emit('sendchatmsg', val, pvtmsgto); } + else if (/^\/[^ ]/.test(val)) { + slashCommandHandler(val); + } else { socket.emit('sendchatmsg', val); } @@ -621,7 +641,6 @@ addFeedback(nmstrings[Math.floor(Math.random()*nmstrings.length)], 'wrong'); }); socket.on('playtrack', playTrack); - socket.on('status', setStatus); socket.on('stoptrying', function() { addFeedback('You guessed both artist and title. Please wait...'); }); @@ -631,7 +650,7 @@ socket.on('trackinfo', addTrackInfo); socket.on('updateusers', updateUsers); socket.on('userleft', userLeft); - socket.emit('getstatus'); + socket.emit('getstatus', setStatus); }; // Show the number of players inside each room @@ -687,16 +706,58 @@ DOM.togglechat.click(hideChat); }; + var slashCommandHandler = function(line) { + var matches = line.match(/^(\/[^ ]+) ?(.*)/) + , argument = matches[2] + , command = matches[1] + , outcome = $('(From binb): '); + + if (/^\/(?:(?:un)?ignore|kick)$/.test(command)) { + if (!argument) { + outcome.append('usage: '+command+' <player name>'); + return addChatEntry(outcome); + } + if (argument === nickname) { + outcome.append('you can\'t '+command.replace(/^\//, '')+' yourself.'); + return addChatEntry(outcome); + } + switch (command) { + case '/ignore': + if (!ignoredplayers[argument]) { + return ignore(argument, outcome); + } + outcome.text('(From binb): '+argument+' is already ignored.'); + break; + case '/kick': + // TO DO + break; + case '/unignore': + if (ignoredplayers[argument]) { + delete ignoredplayers[argument]; + socket.emit('unignore', argument); + outcome.text('(From binb): '+argument+' is no longer ignored.'); + } + else { + outcome.text('(From binb): you have not ignored '+argument+'.'); + } + } + } + else { + outcome.append('unknown command '+command+'.'); + } + addChatEntry(outcome); + }; + // Update the list of players var updateUsers = function(usersData) { DOM.users.empty(); - + var users = []; for (var key in usersData) { users.push(usersData[key]); } users.sort(function(a, b) {return b.points - a.points;}); - + // Flag to test if our private recipient is in the list of active users var found = false; for (var i=0; i'); } DOM.users.append(li); - + if (pvtmsgto === user.nickname) { pvt.show(); username.click(clearPrivate); @@ -726,14 +787,14 @@ addPrivate($(this).text()); }); } - + if (nickname === user.nickname) { username.addClass('you'); roundpoints = user.roundpoints; DOM.rank.text(i+1); DOM.points.text(user.points); } - + if (user.roundpoints > 0) { roundpointsel.text('+'+user.roundpoints); if (user.roundpoints === 1) { @@ -750,7 +811,7 @@ } } } - + if (!found && pvtmsgto) { var width = DOM.recipient.outerWidth(true) + 1; DOM.recipient.css('margin-right', '0'); @@ -787,9 +848,9 @@ // A new player has joined the game var userJoin = function(username, usersData) { - var msg = username+' joined the game'; + var joinmsg = username+' joined the game'; var joinspan = $(''); - joinspan.text(msg); + joinspan.text(joinmsg); addChatEntry(joinspan); updateUsers(usersData); }; @@ -829,10 +890,9 @@ socket.on('alreadyinaroom', alreadyInARoom); socket.on('disconnect', disconnect); socket.on('invalidnickname', invalidNickName); - socket.on('overview', roomsOverview); socket.on('ready', ready); - socket.on('update', updateRoomsOverview); - socket.emit('getoverview'); + socket.on('updateoverview', updateRoomsOverview); + socket.emit('getoverview', roomsOverview); }); });