From ddc50164972177d23e081beabd12f88d5f410f45 Mon Sep 17 00:00:00 2001 From: calzoneman Date: Sun, 31 Mar 2013 14:27:54 -0500 Subject: [PATCH] Serverside support for custom chat filters --- channel.js | 91 +++++++++++++++++++++++++++++++++++++++++++++--------- rank.js | 1 + server.js | 9 +++++- user.js | 14 ++++++--- 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/channel.js b/channel.js index e03947c8..8d0cabb9 100644 --- a/channel.js +++ b/channel.js @@ -43,9 +43,10 @@ var Channel = function(name) { customcss: "" }; this.filters = [ - [new RegExp("`([^`]+)`", "g"), "$1", true], - [new RegExp("\\*([^\\*]+)\\*", "g"), "$1", true], - [new RegExp(" _([^_]+)_", "g"), " $1", true] + [/`([^`]+)`/g , "$1" , true], + [/\*([^\*]+)\*/g , "$1", true], + [/(^| )_([^_]+)_/g , "$1$2" , true], + [/\\\\([-a-zA-Z0-9]+)/g, "[](/$1)" , true] ]; this.ipbans = {}; @@ -67,6 +68,14 @@ var Channel = function(name) { this.currentPosition = data.currentPosition - 1; this.playNext(); this.opts = data.opts; + if(data.filters) { + this.filters = new Array(data.filters.length); + for(var i = 0; i < data.filters.length; i++) { + this.filters[i] = [new RegExp(data.filters[i][0]), + data.filters[i][1], + data.filters[i][2]]; + } + } } catch(e) { Logger.errlog.log("Channel dump load failed: "); @@ -426,17 +435,6 @@ Channel.prototype.userJoin = function(user) { user.socket.emit("newPoll", this.poll.packUpdate()); } user.socket.emit("channelOpts", this.opts); - var ents = []; - for(var ip in this.ipbans) { - if(this.ipbans[ip] != null) { - ents.push({ - ip: ip, - name: this.ipbans[ip][0], - banner: this.ipbans[ip][1] - }); - } - } - user.socket.emit("banlist", {entries: ents}); if(user.playerReady) this.sendMediaUpdate(user); this.logger.log("+++ /" + user.ip + " joined"); @@ -762,6 +760,31 @@ Channel.prototype.moveMedia = function(data) { } } +Channel.prototype.updateFilter = function(filter) { + var found = false; + for(var i = 0; i < this.filters.length; i++) { + if(this.filters[i][0].source == filter[0].source) { + found = true; + this.filters[i][1] = filter[1]; + this.filters[i][2] = filter[2]; + } + } + if(!found) { + this.filters.push(filter); + } + this.broadcastChatFilters(); +} + +Channel.prototype.removeFilter = function(regex) { + for(var i = 0; i < this.filters.length; i++) { + if(this.filters[i][0].source == regex) { + this.filters.splice(i, 1); + break; + } + } + this.broadcastChatFilters(); +} + // Chat message from a user Channel.prototype.chatMessage = function(user, msg) { if(msg.indexOf("/") == 0) @@ -950,6 +973,28 @@ Channel.prototype.broadcastRankUpdate = function(user) { rank: user.rank, leader: this.leader == user }); + + // Rank specific stuff + if(Rank.hasPermission(user, "ipban")) { + var ents = []; + for(var ip in this.ipbans) { + if(this.ipbans[ip] != null) { + ents.push({ + ip: ip, + name: this.ipbans[ip][0], + banner: this.ipbans[ip][1] + }); + } + } + user.socket.emit("banlist", {entries: ents}); + } + if(Rank.hasPermission(user, "chatFilter")) { + var filts = new Array(this.filters.length); + for(var i = 0; i < this.filters.length; i++) { + filts[i] = [this.filters[i][0].source, this.filters[i][1], this.filters[i][2]]; + } + user.socket.emit("chatFilters", {filters: filts}); + } } Channel.prototype.broadcastPoll = function() { @@ -979,7 +1024,23 @@ Channel.prototype.broadcastIpbans = function() { }); } } - this.sendAll("banlist", {entries: ents}); + for(var i = 0; i < this.users.length; i++) { + if(Rank.hasPermission(this.users[i], "ipban")) { + this.users[i].socket.emit("banlist", {entries: ents}); + } + } +} + +Channel.prototype.broadcastChatFilters = function() { + var filts = new Array(this.filters.length); + for(var i = 0; i < this.filters.length; i++) { + filts[i] = [this.filters[i][0].source, this.filters[i][1], this.filters[i][2]]; + } + for(var i = 0; i < this.users.length; i++) { + if(Rank.hasPermission(this.users[i], "ipban")) { + this.users[i].socket.emit("chatFilters", {filters: filts}); + } + } } // Send to ALL the clients! diff --git a/rank.js b/rank.js index c8baa454..2598596e 100644 --- a/rank.js +++ b/rank.js @@ -29,6 +29,7 @@ var permissions = { shout : exports.Moderator, channelOpts : exports.Moderator, jump : exports.Moderator, + chatFilter : exports.Moderator, search : exports.Guest, chat : exports.Guest, }; diff --git a/server.js b/server.js index 7d856956..0f4937ff 100644 --- a/server.js +++ b/server.js @@ -56,10 +56,17 @@ function shutdown() { Logger.syslog.log("Unloading channels..."); for(var name in exports.channels) { var chan = exports.channels[name]; + var filts = new Array(chan.filters.length); + for(var i = 0; i < chan.filters.length; i++) { + filts[i] = [chan.filters[i][0].source, + chan.filters[i][1], + chan.filters[i][2]]; + } var dump = { currentPosition: chan.currentPosition, queue: chan.queue, - opts: chan.opts + opts: chan.opts, + filters: filts }; var text = JSON.stringify(dump); fs.writeFileSync("chandump/" + name, text); diff --git a/user.js b/user.js index 071f5327..7cdef2d4 100644 --- a/user.js +++ b/user.js @@ -248,6 +248,16 @@ User.prototype.initCallbacks = function() { this.channel.broadcastOpts(); } }.bind(this)); + + this.socket.on("chatFilter", function(data) { + if(data.cmd && data.cmd == "update" && this.channel != null) { + data.filter[0] = new RegExp(data.filter[0], "g"); + this.channel.updateFilter(data.filter); + } + else if(data.cmd && data.cmd == "remove" && this.channel != null) { + this.channel.removeFilter(data.filter[0]); + } + }.bind(this)); } // Handle administration @@ -339,8 +349,6 @@ User.prototype.login = function(name, pw) { }); if(this.channel != null) { this.channel.logger.log(this.ip + " signed in as " + name); - if(this.rank >= Rank.Moderator) - this.channel.sendPlaylist(this); this.channel.broadcastNewUser(this); } } @@ -365,8 +373,6 @@ User.prototype.login = function(name, pw) { this.name = name; if(this.channel != null) { this.channel.logger.log(this.ip + " logged in as " + name); - if(this.rank >= Rank.Moderator) - this.channel.sendPlaylist(this); this.channel.broadcastNewUser(this); } }