]> git.example.dev Git - binbsis50.git/commitdiff
refactored code and added ability to ignore players
authorLuigi Pinca <luigipinca@gmail.com>
Sat, 20 Oct 2012 20:46:29 +0000 (22:46 +0200)
committerLuigi Pinca <luigipinca@gmail.com>
Sat, 20 Oct 2012 20:46:29 +0000 (22:46 +0200)
app.js
lib/room.js
package.json
public/static/js/home.js
public/static/js/room.js

diff --git a/app.js b/app.js
index b0f700a14e5724cdff387192608188e2cd67c7a5..2c0c3295ea9100c0f28c51d0740659abdaa4f9da 100644 (file)
--- 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);
         }
     });
 });
index 78ba92c9397b99f156aad0f417537013a4f44878..a764933dd84ea251cd4990493b0331d2e106e6ed 100644 (file)
@@ -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 = '<span class="label label-important">That name is too long.</span>';
-            }
-            else if (nickname === 'binb') {
-                feedback = '<span class="label label-important">That name is reserved.</span>';
-            }
-            else if (sockets[nickname]) {
-                feedback = '<span class="label label-important">Name already taken.</span>';
-            }
-
-            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 = '<span class="label label-important">That name belongs ';
-                    feedback += 'to a registered user.</span>';
-                    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 = '<span class="label label-important">That name is too long.</span>';
             }
-            if (podium[1] && podium[1].registered) {
-                collectStats(podium[1].nickname, {secondplace:true});
+            else if (nickname === 'binb') {
+                feedback = '<span class="label label-important">That name is reserved.</span>';
             }
-            if (podium[2] && podium[2].registered) {
-                collectStats(podium[2].nickname, {thirdplace:true});
+            else if (sockets[nickname]) {
+                feedback = '<span class="label label-important">Name already taken.</span>';
             }
 
-            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 = '<span class="label label-important">That name belongs ';
+                    feedback += 'to a registered user.</span>';
+                    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;
index 5b09ca3e04d8debb11ab0b5f5cd6160b03c6f0a9..839c1bc166310bd6822a3bddc35037f10b5dc97e 100644 (file)
@@ -21,5 +21,5 @@
     "start": "app.js"
   },
   "subdomain": "binb",
-  "version": "0.3.4"
+  "version": "0.3.4-2"
 }
\ No newline at end of file
index fe72972dd4a89c2572da76ecc8140424035880ea..f23c6204f6f8e4cbbe05261264dd7a1eaf5a3c0e 100644 (file)
@@ -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);
         });
     });
index ecaf93402695e48435d62858c0378d4395ff41c2..36e892299448b7b032286bae8289abba2ab84b51 100644 (file)
@@ -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?'
         html += '<th><div class="icons cups stand2"></div></th>';
         html += '<th><div class="icons cups stand3"></div></th><th>Guessed</th><th>Mean time</th>';
         html += '</thead><tbody>';
-        
+
         for(var i=0;i<3;i++) {
             if (podium[i]) {
                 var playername = podium[i].nickname.encodeEntities();
 
     // Receive a chat message
     var getChatMessage = function(chatmsg, from, to) {
+        if (ignoredplayers[from]) {
+            return;
+        }
         var prefix = from;
         var msgspan = $('<span class="message"></span>');
         if (to) {
         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+'<br/>Try with another one:');
         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';
                     if (pvtmsgto) {
                         socket.emit('sendchatmsg', val, pvtmsgto);
                     }
+                    else if (/^\/[^ ]/.test(val)) {
+                        slashCommandHandler(val);
+                    }
                     else {
                         socket.emit('sendchatmsg', val);
                     }
             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...');
         });
         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
         DOM.togglechat.click(hideChat);
     };
 
+    var slashCommandHandler = function(line) {
+        var matches = line.match(/^(\/[^ ]+) ?(.*)/)
+            , argument = matches[2]
+            , command = matches[1]
+            , outcome = $('<span class="message private">(From binb): </span>');
+
+        if (/^\/(?:(?:un)?ignore|kick)$/.test(command)) {
+            if (!argument) {
+                outcome.append('usage: '+command+' &lt;player name&gt;');
+                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<users.length; i++) {
                 pvt.after('<a class="icons registered" target="_blank" '+href+'></a>');
             }
             DOM.users.append(li);
-            
+
             if (pvtmsgto === user.nickname) {
                 pvt.show();
                 username.click(clearPrivate);
                     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) {
                 }
             }
         }
-        
+
         if (!found && pvtmsgto) {
             var width = DOM.recipient.outerWidth(true) + 1;
             DOM.recipient.css('margin-right', '0');
 
     // 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 = $('<span class="join"></span>');
-        joinspan.text(msg);
+        joinspan.text(joinmsg);
         addChatEntry(joinspan);
         updateUsers(usersData);
     };
             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);
         });
     });