diff --git a/channel.js b/channel.js index 65e0b091..0378c1e5 100644 --- a/channel.js +++ b/channel.js @@ -21,6 +21,7 @@ var io = require("./server.js").io; var Rank = require("./rank.js"); var Auth = require("./auth.js"); var ChatCommand = require("./chatcommand.js"); +var Filter = require("./filter.js").Filter; var Channel = function(name) { Logger.syslog.log("Opening channel " + name); @@ -52,10 +53,9 @@ var Channel = function(name) { chat_antiflood: false }; this.filters = [ - [/`([^`]+)`/g , "$1" , true], - [/\*([^\*]+)\*/g , "$1", true], - [/(^| )_([^_]+)_/g , "$1$2" , true], - [/\\\\([-a-zA-Z0-9]+)/g, "[](/$1)" , true] + new Filter("monospace", "`([^`]+)`", "g", "$1"), + new Filter("bold", "\\*([^\\*]+)\\*", "g", "$1"), + new Filter("italic", "(^| )_([^_]+)_", "g", "$1$2"), ]; this.motd = { motd: "", @@ -117,9 +117,16 @@ Channel.prototype.loadDump = function() { 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], "g"), - data.filters[i][1], - data.filters[i][2]]; + var f = data.filters[i]; + // Backwards compatibility + if(f[0] != undefined) { + this.filters[i] = new Filter("", f[0], "g", f[1]); + this.filters[i].active = f[2]; + } + else { + this.filters[i] = new Filter(f.name, f.source, f.flags, f.replace); + this.filters[i].active = f.active; + } } } if(data.motd) { @@ -136,9 +143,7 @@ Channel.prototype.loadDump = function() { Channel.prototype.saveDump = 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]]; + filts[i] = this.filters[i].pack(); } var dump = { position: this.position, @@ -400,7 +405,7 @@ Channel.prototype.sendRankStuff = function(user) { 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]]; + filts[i] = this.filters[i].pack(); } user.socket.emit("chatFilters", {filters: filts}); } @@ -545,7 +550,7 @@ Channel.prototype.broadcastRankTable = function() { 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]]; + filts[i] = this.filters[i].pack(); } for(var i = 0; i < this.users.length; i++) { if(Rank.hasPermission(this.users[i], "chatFilter")) { @@ -1054,10 +1059,10 @@ Channel.prototype.trySetLock = function(user, 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) { + if(this.filters[i].name == filter.name + && this.filters[i].source == filter.source) { found = true; - this.filters[i][1] = filter[1]; - this.filters[i][2] = filter[2]; + this.filters[i] = filter; } } if(!found) { @@ -1066,9 +1071,10 @@ Channel.prototype.updateFilter = function(filter) { this.broadcastChatFilters(); } -Channel.prototype.removeFilter = function(regex) { +Channel.prototype.removeFilter = function(name, source) { for(var i = 0; i < this.filters.length; i++) { - if(this.filters[i][0].source == regex) { + if(this.filters[i].name == name + && this.filters[i].source == source) { this.filters.splice(i, 1); break; } @@ -1086,23 +1092,23 @@ Channel.prototype.tryChangeFilter = function(user, data) { } if(data.cmd == "update") { - var re = data.filter[0]; - var flags = "g"; - var slash = re.lastIndexOf("/"); - if(slash > 0 && re[slash-1] != "\\") { - flags = re.substring(slash+1); - re = re.substring(0, slash); - } + var re = data.filter.source; + var flags = data.filter.flags; try { - data.filter[0] = new RegExp(re, flags); + new RegExp(re, flags); } catch(e) { return; } - this.updateFilter(data.filter); + var f = new Filter(data.filter.name, + data.filter.source, + data.filter.flags, + data.filter.replace); + f.active = data.filter.active; + this.updateFilter(f); } else if(data.cmd == "remove") { - this.removeFilter(data.filter[0]); + this.removeFilter(data.filter.name, data.filter.source); } } @@ -1182,11 +1188,9 @@ Channel.prototype.filterMessage = function(msg) { msg = msg.replace(/(((https?)|(ftp))(:\/\/[0-9a-zA-Z\.]+(:[0-9]+)?[^\s$]+))/g, "$1"); // Apply other filters for(var i = 0; i < this.filters.length; i++) { - if(!this.filters[i][2]) + if(!this.filters[i].active) continue; - var regex = this.filters[i][0]; - var replace = this.filters[i][1]; - msg = msg.replace(regex, replace); + msg = this.filters[i].filter(msg); } return msg; } diff --git a/filter.js b/filter.js new file mode 100644 index 00000000..c26a1fec --- /dev/null +++ b/filter.js @@ -0,0 +1,24 @@ +var Filter = function(name, regex, flags, replace) { + this.name = name; + this.source = regex; + this.flags = flags; + this.regex = new RegExp(this.source, this.flags); + this.replace = replace; + this.active = true; +} + +Filter.prototype.pack = function() { + return { + name: this.name, + source: this.source, + flags: this.flags, + replace: this.replace, + active: this.active + } +} + +Filter.prototype.filter = function(text) { + return text.replace(this.regex, this.replace); +} + +exports.Filter = Filter; diff --git a/package.json b/package.json index fd17b976..8075feac 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Calvin Montgomery", "name": "CyTube", "description": "Online media synchronizer and chat", - "version": "1.4.3", + "version": "1.4.4", "repository": { "url": "http://github.com/calzoneman/sync" }, diff --git a/server.js b/server.js index 8bc48459..3e1d3638 100644 --- a/server.js +++ b/server.js @@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -const VERSION = "1.4.3"; +const VERSION = "1.4.4"; var fs = require("fs"); var Logger = require("./logger.js"); diff --git a/www/assets/js/functions.js b/www/assets/js/functions.js index c117b438..31598bfe 100644 --- a/www/assets/js/functions.js +++ b/www/assets/js/functions.js @@ -618,24 +618,29 @@ function updateChatFilters(entries) { $(tbl.children()[1]).remove(); } for(var i = 0; i < entries.length; i++) { + var f = entries[i]; var tr = $("").appendTo(tbl); var remove = $("