diff --git a/channel.js b/channel.js index cd40d2f3..153fd1eb 100644 --- a/channel.js +++ b/channel.js @@ -65,6 +65,7 @@ var Channel = function(name) { playlistclear: 2, pollctl: 1.5, pollvote: -1, + mute: 1.5, kick: 1.5, ban: 2, motdedit: 3, @@ -1719,6 +1720,14 @@ Channel.prototype.tryChat = function(user, data) { if(!this.hasPermission(user, "chat")) return; + if(user.muted) { + user.socket.emit("noflood", { + action: "chat", + msg: "You have been muted on this channel." + }); + return; + } + if(typeof data.msg !== "string") { return; } @@ -1770,6 +1779,7 @@ Channel.prototype.filterMessage = function(msg) { Channel.prototype.sendMessage = function(username, msg, msgclass, data) { // I don't want HTML from strangers + msg = msg.replace(/&/g, "&"); msg = msg.replace(//g, ">"); msg = this.filterMessage(msg); var msgobj = { diff --git a/chatcommand.js b/chatcommand.js index 65285fea..6ae9a9e9 100644 --- a/chatcommand.js +++ b/chatcommand.js @@ -55,6 +55,12 @@ function handle(chan, user, msg, data) { chan.chainMessage(user, cargs.join(" "), flair); } } + else if(msg.indexOf("/mute ") == 0) { + handleMute(chan, user, msg.substring(6).split(" ")); + } + else if(msg.indexOf("/unmute ") == 0) { + handleUnmute(chan, user, msg.substring(8).split(" ")); + } else if(msg.indexOf("/kick ") == 0) { handleKick(chan, user, msg.substring(6).split(" ")); } @@ -85,6 +91,46 @@ function handle(chan, user, msg, data) { } } +function handleMute(chan, user, args) { + if(chan.hasPermission(user, "mute") && args.length > 0) { + args[0] = args[0].toLowerCase(); + var person = false; + for(var i = 0; i < chan.users.length; i++) { + if(chan.users[i].name.toLowerCase() == args[0]) { + person = chan.users[i]; + break; + } + } + + if(person) { + person.meta.icon = "icon-volume-off"; + person.muted = true; + chan.broadcastUserUpdate(person); + chan.logger.log("*** " + user.name + " muted " + args[0]); + } + } +} + +function handleUnmute(chan, user, args) { + if(chan.hasPermission(user, "mute") && args.length > 0) { + args[0] = args[0].toLowerCase(); + var person = false; + for(var i = 0; i < chan.users.length; i++) { + if(chan.users[i].name.toLowerCase() == args[0]) { + person = chan.users[i]; + break; + } + } + + if(person) { + person.meta.icon = false; + person.muted = false; + chan.broadcastUserUpdate(person); + chan.logger.log("*** " + user.name + " unmuted " + args[0]); + } + } +} + function handleKick(chan, user, args) { if(chan.hasPermission(user, "kick") && args.length > 0) { args[0] = args[0].toLowerCase(); diff --git a/user.js b/user.js index b2dee674..26a74ae1 100644 --- a/user.js +++ b/user.js @@ -30,8 +30,10 @@ var User = function(socket, ip) { this.channel = null; this.name = ""; this.meta = { - afk: false + afk: false, + icon: false }; + this.muted = false; this.throttle = {}; this.flooded = {}; this.profile = { diff --git a/www/assets/js/util.js b/www/assets/js/util.js index f4f48253..353e56cb 100644 --- a/www/assets/js/util.js +++ b/www/assets/js/util.js @@ -98,6 +98,9 @@ function formatUserlistItem(div, data) { name.css("font-style", "italic"); $("").addClass("icon-time").appendTo(flair); } + if(data.meta && data.meta.icon) { + $("").addClass(data.meta.icon).prependTo(flair); + } } function getNameColor(rank) { @@ -1294,6 +1297,7 @@ function genPermissionsEditor() { makeOption("Vote", "pollvote", standard, CHANNEL.perms.pollvote+""); addDivider("Moderation"); + makeOption("Mute users", "mute", modleader, CHANNEL.perms.mute+""); makeOption("Kick users", "kick", modleader, CHANNEL.perms.kick+""); makeOption("Ban users", "ban", modplus, CHANNEL.perms.ban+""); makeOption("Edit MOTD", "motdedit", modplus, CHANNEL.perms.motdedit+"");