From: Luigi Pinca Date: Sun, 7 Apr 2013 08:48:10 +0000 (+0200) Subject: use a PRNG based on `crypto.randomBytes` to play tracks randomly X-Git-Url: https://git.saalbach.dev/?a=commitdiff_plain;h=30cec4c;p=binbsis50.git use a PRNG based on `crypto.randomBytes` to play tracks randomly --- diff --git a/lib/prng.js b/lib/prng.js new file mode 100644 index 0000000..be9cc80 --- /dev/null +++ b/lib/prng.js @@ -0,0 +1,30 @@ +/** + * 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); +}; diff --git a/lib/room.js b/lib/room.js index 9ea7d88..ab5ebf5 100644 --- a/lib/room.js +++ b/lib/room.js @@ -8,10 +8,13 @@ var amatch = require('./match') , 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. @@ -42,7 +45,6 @@ function Room(roomname) { , status , title // Title in lowercase , trackName - , trackscount = 0 , trackViewUrl , totusers = 0 , usersData = Object.create(null); @@ -135,7 +137,7 @@ function Room(roomname) { 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); }; @@ -331,7 +333,8 @@ function Room(roomname) { // 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(); @@ -451,10 +454,10 @@ function Room(roomname) { // 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) { diff --git a/lib/utils.js b/lib/utils.js index 367e601..d806a4f 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -39,6 +39,12 @@ exports.britishFormat = function(date) { 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. */ diff --git a/package.json b/package.json index c6aa8f7..18733e8 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,14 @@ "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" @@ -24,5 +24,5 @@ "start": "node app.js" }, "subdomain": "binb", - "version": "0.3.5-14" + "version": "0.3.5-15" } diff --git a/routes/site.js b/routes/site.js index 6e91359..42d4177 100644 --- a/routes/site.js +++ b/routes/site.js @@ -5,8 +5,11 @@ 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. @@ -14,7 +17,8 @@ var async = require('async') 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); }); }; diff --git a/util/load_sample_tracks.js b/util/load_sample_tracks.js index 54f3ada..dabac87 100644 --- a/util/load_sample_tracks.js +++ b/util/load_sample_tracks.js @@ -12,6 +12,7 @@ var artistIds = require('./artist-ids') , rc = require('redis').createClient() , rockIds = artistIds.rock , rooms = require('../config').rooms + , score , skip = 0 // Skip counter , songId = 0; @@ -29,6 +30,7 @@ var options = { 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) @@ -64,9 +66,11 @@ parser.on('data', function(track) { ); rooms.forEach(function(room) { - rc.sadd(room, songId); + var _score = (room === 'mixed') ? songId : score; + rc.zadd(room, _score, songId); }); + score++; songId++; });