diff --git a/channel.js b/channel.js index f3232522..c29a0750 100644 --- a/channel.js +++ b/channel.js @@ -1227,11 +1227,20 @@ Channel.prototype.tryQueue = function(user, data) { return; } - if(user.rank < Rank.Moderator - && this.leader != user - && user.noflood("queue", 3)) { - return; - } else if (user.rank < Rank.Siteadmin && user.noflood("queue", 0.5)) { + var limit = { + burst: 3, + sustained: 1 + }; + + if (user.rank >= Rank.Moderator || this.leader == user) { + limit = { + burst: 10, + sustained: 2 + }; + } + + if (user.queueLimiter.throttle(limit)) { + user.socket.emit("queueFail", "You are adding videos too quickly"); return; } diff --git a/user.js b/user.js index 7978fbf1..e7e346cf 100644 --- a/user.js +++ b/user.js @@ -31,6 +31,7 @@ var User = function(socket, Server) { this.muted = false; this.throttle = {}; this.flooded = {}; + this.queueLimiter = $util.newRateLimiter(); this.profile = { image: "", text: "" diff --git a/utilities.js b/utilities.js index b4d5efe8..bff14a72 100644 --- a/utilities.js +++ b/utilities.js @@ -48,10 +48,55 @@ module.exports = { s = "" + (sec % 60); if(s.length < 2) s = "0" + s; - + if(h === "") return [m, s].join(":"); return [h, m, s].join(":"); + }, + + newRateLimiter: function () { + return { + count: 0, + lastTime: 0, + throttle: function (opts) { + if (typeof opts === "undefined") + opts = {}; + + var burst = +opts.burst, + sustained = +opts.sustained, + cooldown = +opts.cooldown; + + if (isNaN(burst)) + burst = 10; + + if (isNaN(sustained)) + sustained = 2; + + if (isNaN(cooldown)) + cooldown = burst / sustained; + + // Haven't reached burst cap yet, allow + if (this.count < burst) { + this.count++; + this.lastTime = Date.now(); + return false; + } + + // Cooled down, allow and clear buffer + if (this.lastTime < Date.now() - cooldown*1000) { + this.count = 0; + this.lastTime = Date.now(); + return false; + } + + var diff = Date.now() - this.lastTime; + if (diff < 1000/sustained) + return true; + + this.lastTime = Date.now(); + return false; + } + }; } };