--- /dev/null
+/**
+ * Module dependencies.
+ */
+
+var crypto = require('crypto')
+ , rrange = 4294967296;
+
+/**
+ * Return an integer, pseudo-random number in the range [0, 2^32).
+ */
+
+var nextInt = function() {
+ return crypto.randomBytes(4).readUInt32BE(0);
+};
+
+/**
+ * Return a floating-point, pseudo-random number in the range [0, 1).
+ */
+
+var rand = function() {
+ return nextInt() / rrange;
+};
+
+/**
+ * Return an integer, pseudo-random number in the range [0, max).
+ */
+
+exports.randInt = function(max) {
+ return Math.floor(rand() * max);
+};
, config = require('../config')
, fifolength = config.songsinarun * config.gameswithnorepeats
, io
- , isUsername = require('./utils').isUsername
+ , randInt = require('./prng').randInt
, sockets
, songsdb = clients.songs
- , usersdb = clients.users;
+ , usersdb = clients.users
+ , utils = require('./utils')
+ , isUsername = utils.isUsername
+ , trackscount = utils.trackscount;
/**
* Expose the constructor.
, status
, title // Title in lowercase
, trackName
- , trackscount = 0
, trackViewUrl
, totusers = 0
, usersData = Object.create(null);
totusers++;
// Broadcast new user event
io.sockets.emit('updateoverview', roomname, totusers);
- socket.emit('ready', usersData, trackscount, loggedin);
+ socket.emit('ready', usersData, trackscount[roomname], loggedin);
socket.broadcast.to(roomname).emit('newuser', socket.nickname, usersData);
};
// Extract a random track from the database and send the load event
var sendLoadTrack = function() {
- songsdb.srandmember(roomname, function(err, res) {
+ var index = randInt(trackscount[roomname]);
+ songsdb.zrange(roomname, index, index, function(err, res) {
// Check if extracted track is in the list of already played tracks
if (~playedtracks.indexOf(res)) {
return sendLoadTrack();
// Start the room
this.start = function() {
- songsdb.scard(roomname, function(err, res) {
- trackscount = res;
+ songsdb.zcard(roomname, function(err, card) {
+ trackscount[roomname] = card;
+ sendLoadTrack();
});
- sendLoadTrack();
};
this.unignore = function(who, executor) {
return day+'/'+month+'/'+year;
};
+/**
+ * Helper object for faster and easier access to rooms' cardinalities (number of tracks).
+ */
+
+exports.trackscount = {};
+
/**
* Check whether a given string is a valid email address.
*/
"async": "0.2.x",
"canvas": "0.13.x",
"connect-redis": "1.4.x",
- "express": "3.x",
+ "express": "3.1.x",
"jade": "0.28.x",
"nodemailer": "0.3.x",
"redis": "0.7.x",
"socket.io": "0.9.x"
},
"devDependencies": {
- "JSONStream": "0.4.x"
+ "JSONStream": "0.6.x"
},
"engines": {
"node": "0.8.x"
"start": "node app.js"
},
"subdomain": "binb",
- "version": "0.3.5-14"
+ "version": "0.3.5-15"
}
var async = require('async')
, Captcha = require('../lib/captcha')
, db = require('../lib/redis-clients').songs
- , randomSlogan = require('../lib/utils').randomSlogan
- , rooms = require('../config').rooms;
+ , randInt = require('../lib/prng').randInt
+ , rooms = require('../config').rooms
+ , utils = require('../lib/utils')
+ , randomSlogan = utils.randomSlogan
+ , trackscount = utils.trackscount;
/**
* Generate a task.
var task = function(genre) {
return function(callback) {
- db.srandmember(genre, function(err, res) {
+ var index = randInt(trackscount[genre]);
+ db.zrange(genre, index, index, function(err, res) {
db.hget('song:'+res, 'artworkUrl100', callback);
});
};
, rc = require('redis').createClient()
, rockIds = artistIds.rock
, rooms = require('../config').rooms
+ , score
, skip = 0 // Skip counter
, songId = 0;
var updateRooms = function(artistId) {
rooms = ['mixed'];
+ score = 0;
if (artistId === popIds[0]) {
rooms.push('hits', 'pop');
// Set the skip counter (there is no need to update the rooms for the next pop artists)
);
rooms.forEach(function(room) {
- rc.sadd(room, songId);
+ var _score = (room === 'mixed') ? songId : score;
+ rc.zadd(room, _score, songId);
});
+ score++;
songId++;
});