diff --git a/modules/kick/commands.js b/modules/kick/commands.js index 71308a3..75d8a1d 100644 --- a/modules/kick/commands.js +++ b/modules/kick/commands.js @@ -1,474 +1,512 @@ var _ = require('underscore')._, - uuid = require('node-uuid'); +uuid = require('node-uuid'); -var commands = function(dbot) { - var commands = { - /*** Kick Management ***/ - '~quiet': function(event) { - var server = event.server, - quieter = event.rUser, - duration = event.input[1], - channel = (event.input[2] || event.channel.name).trim(), - quietee = event.input[3].trim(), - reason = event.input[4] || "N/A"; +var commands = function (dbot) { + var commands = { + /*** Kick Management ***/ + '~quiet': function (event) { + var server = event.server, + quieter = event.rUser, + duration = event.input[1], + channel = (event.input[2] || event.channel.name).trim(), + quietee = event.input[3].trim(), + reason = event.input[4] || "N/A"; - this.api.quietUser(server, quieter, duration, channel, quietee, reason, function(response) { - event.reply(response); + this.api.quietUser(server, quieter, duration, channel, quietee, reason, function (response) { + event.reply(response); + }); + }, + + '~timeout': function (event) { + var server = event.server, + quieter = event.rUser, + duration = this.config.timeoutTime, + channel = event.channel.name, + quietee = event.input[1], + reason = event.input[2] || "N/A"; + + reason += ' #timeout'; + + dbot.api.users.resolveUser(server, quietee, function (err, user) { + if (!err && user) { + if (!_.has(this.recentTimeouts, user.id)) { + this.recentTimeouts[user.id] = 0; + } + + this.recentTimeouts[user.id] += 1; + setTimeout(function () { + this.recentTimeouts[user.id] -= 1; + if (this.recentTimeouts[user.id] == 0) { + delete this.recentTimeouts[user.id]; + } + } + .bind(this), 3600000); + + if (this.recentTimeouts[user.id] == 3) { + duration = null; + reason += ' #permatimeout'; + dbot.say(event.server, dbot.config.servers[event.server].admin_channel, quietee + ' has been given three timeouts in the last hour, and so has been quieted indefinitely in ' + channel + '. Please review.'); + } + + this.api.quietUser(server, quieter, duration, channel, quietee, reason, function (response) { + event.reply(response); }); - }, + } + } + .bind(this)); + }, - '~timeout': function(event) { - var server = event.server, - quieter = event.rUser, - duration = this.config.timeoutTime, - channel = event.channel.name, - quietee = event.input[1], - reason = event.input[2] || "N/A"; + '~unquiet': function (event) { + var server = event.server, + quieter = event.user, + channel = (event.input[1] || event.channel.name).trim(), + quietee = event.input[2].trim(); - reason += ' #timeout'; + if (_.has(this.hosts[server], quietee)) { + if (_.include(this.config.quietBans, channel)) { + this.api.unban(server, this.hosts[server][quietee], channel); + } else { + this.api.unquiet(server, this.hosts[server][quietee], channel); + } + event.reply(dbot.t('unquieted', { + 'quietee': quietee + })); + dbot.api.report.notify('unquiet', server, event.rUser, channel, + dbot.t('unquiet_notify', { + 'unquieter': quieter, + 'quietee': quietee + }), false, quietee); + } + }, - dbot.api.users.resolveUser(server, quietee, function(err, user) { - if(!err && user) { - if(!_.has(this.recentTimeouts, user.id)) { - this.recentTimeouts[user.id] = 0; + '~ckick': function (event) { + var server = event.server, + kicker = event.user, + kickee = event.input[2], + channel = event.input[1], + reason = event.input[3]; + + if (_.isUndefined(channel)) { + channel = event.channel.name; + } + channel = channel.trim(); + + this.api.kick(server, kickee, channel, reason + ' (requested by ' + kicker + ')'); + + dbot.api.report.notify('kick', server, event.rUser, channel, dbot.t('ckicked', { + 'kicker': kicker, + 'kickee': kickee, + 'reason': reason + }), false, kickee); + }, + + // Kick and ban from all channels on the network. + '~nban': function (event) { + if (!event.input) + return; + + var server = event.server, + banner = event.user, + timeout = event.input[1], + banee = event.input[2], + reason = event.input[3], + adminChannel = dbot.config.servers[server].admin_channel, + channels = _.keys(dbot.instance.connections[server].channels), + network = event.server; + + if (this.config.network_name[event.server]) { + network = this.config.network_name[event.server]; + } + + dbot.api.nickserv.getUserHost(event.server, banee, function (host) { + // Add host record entry + if (host) { + var didKill = false; + + if ((reason.match('#line') || reason.match('#specialk') || reason.match('#kline')) && _.include(dbot.access.moderator(), event.rUser.primaryNick)) { + didKill = true; + var t = ' !P '; + if (timeout) { + t = ' !T ' + (timeout * 60); + } + dbot.say(event.server, 'operserv', 'akill add ' + banee + t + banee + ' banned by ' + banner + ': ' + reason); + } + + // Do not ban if user was killed - redundant + if(!didKill) { + // Ban from current channel first + this.api.ban(server, host, event.channel); + this.api.kick(server, banee, event.channel, reason + + ' (network-wide ban)'); + channels = _.without(channels, event.channel); + if (!_.isUndefined(adminChannel)) { + channels = _.without(channels, adminChannel); + } else { + adminChannel = event.channel.name; + } + + // Ban the user from all channels + var i = 0; + var banChannel = function (channels) { + if (i >= channels.length) + return; + var channel = channels[i]; + this.api.ban(server, host, channel); + this.api.kick(server, banee, channel, reason + + ' (network-wide ban)'); + i++; + banChannel(channels); + } + .bind(this); + banChannel(channels); + } + + this.hosts[event.server][banee] = host; + + // Create notify string + if (!_.isUndefined(timeout)) { + timeout = timeout.trim(); + + var msTimeout = new Date(new Date().getTime() + (parseFloat(timeout) * 3600000)); + if (_.has(dbot.modules, 'remind')) { + msTimeout = dbot.api.remind.parseTime(timeout); + if (!msTimeout) { + return event.reply('Invalid time. Remember you must give e.g. 5m now.'); } - - this.recentTimeouts[user.id] += 1; - setTimeout(function() { - this.recentTimeouts[user.id] -= 1; - if(this.recentTimeouts[user.id] == 0) { - delete this.recentTimeouts[user.id]; - } - }.bind(this), 3600000); - - if(this.recentTimeouts[user.id] == 3) { - duration = null; - reason += ' #permatimeout'; - dbot.say(event.server, dbot.config.servers[event.server].admin_channel, quietee + ' has been given three timeouts in the last hour, and so has been quieted indefinitely in '+channel+'. Please review.'); - } - - this.api.quietUser(server, quieter, duration, channel, quietee, reason, function(response) { - event.reply(response); - }); + timeout = timeout.replace(/([\d]+)d/, '$1 days').replace(/([\d]+)h/, '$1 hours ').replace(/([\d]+)m/, '$1 minutes ').replace(/([\d]+)s/, '$1 seconds').trim(); + } else { + timeout += ' hours'; } - }.bind(this)); - }, - '~unquiet': function(event) { - var server = event.server, - quieter = event.user, - channel = (event.input[1] || event.channel.name).trim(), - quietee = event.input[2].trim(); - - if(_.has(this.hosts[server], quietee)) { - if(_.include(this.config.quietBans, channel)) { - this.api.unban(server, this.hosts[server][quietee], channel); - } else { - this.api.unquiet(server, this.hosts[server][quietee], channel); - } - event.reply(dbot.t('unquieted', { 'quietee': quietee })); - dbot.api.report.notify('unquiet', server, event.rUser, channel, - dbot.t('unquiet_notify', { - 'unquieter': quieter, - 'quietee': quietee - }), false, quietee); + // Do not schedule unbans if the user was killed as no ban was put in place + if(!didKill) { + if (!_.has(this.tempBans, event.server)) + this.tempBans[event.server] = {}; + this.tempBans[event.server][banee] = msTimeout; + this.internalAPI.addTempBan(event.server, banee, msTimeout); } - }, - '~ckick': function(event) { - var server = event.server, - kicker = event.user, - kickee = event.input[2], - channel = event.input[1], - reason = event.input[3]; - - if(_.isUndefined(channel)) { - channel = event.channel.name; - } - channel = channel.trim(); - - this.api.kick(server, kickee, channel, reason + ' (requested by ' + kicker + ')'); - - dbot.api.report.notify('kick', server, event.rUser, channel, dbot.t('ckicked', { - 'kicker': kicker, - 'kickee': kickee, + var notifyString = dbot.t('tbanned', { + 'network': network, + 'banner': banner, + 'banee': banee, + 'hours': timeout, + 'host': host, 'reason': reason - }), false, kickee); - }, + }); + } else { + var notifyString = dbot.t('nbanned', { + 'network': network, + 'banner': banner, + 'banee': banee, + 'host': host, + 'reason': reason + }); + } - // Kick and ban from all channels on the network. - '~nban': function(event) { - if(!event.input) return; - - var server = event.server, - banner = event.user, - timeout = event.input[1], - banee = event.input[2], - reason = event.input[3], - adminChannel = dbot.config.servers[server].admin_channel, - channels = _.keys(dbot.instance.connections[server].channels), - network = event.server; - - if(this.config.network_name[event.server]) { - network = this.config.network_name[event.server]; - } - - dbot.api.nickserv.getUserHost(event.server, banee, function(host) { - // Add host record entry - if(host) { - if((reason.match('#line') || reason.match('#specialk') || reason.match('#kline')) && _.include(dbot.access.moderator(), event.rUser.primaryNick)) { - var t = ' !P '; - if(timeout) { - t = ' !T ' + (timeout * 60); - } - dbot.say(event.server, 'operserv', 'akill add '+banee + t + banee + ' banned by ' + banner + ': ' + reason); - } - - // Ban from current channel first - this.api.ban(server, host, event.channel); - this.api.kick(server, banee, event.channel, reason + - ' (network-wide ban)'); - channels = _.without(channels, event.channel); - if(!_.isUndefined(adminChannel)) { - channels = _.without(channels, adminChannel); - } else { - adminChannel = event.channel.name; - } - - // Ban the user from all channels - var i = 0; - var banChannel = function(channels) { - if(i >= channels.length) return; - var channel = channels[i]; - this.api.ban(server, host, channel); - this.api.kick(server, banee, channel, reason + - ' (network-wide ban)'); - i++; banChannel(channels); - }.bind(this); - banChannel(channels); - - this.hosts[event.server][banee] = host; - - // Create notify string - if(!_.isUndefined(timeout)) { - timeout = timeout.trim(); - - var msTimeout = new Date(new Date().getTime() + (parseFloat(timeout) * 3600000)); - if(_.has(dbot.modules, 'remind')) { - msTimeout = dbot.api.remind.parseTime(timeout); - if(!msTimeout) { - return event.reply('Invalid time. Remember you must give e.g. 5m now.'); - } - timeout = timeout.replace(/([\d]+)d/, '$1 days').replace(/([\d]+)h/, '$1 hours ').replace(/([\d]+)m/, '$1 minutes ').replace(/([\d]+)s/, '$1 seconds').trim(); - } else { - timeout += ' hours'; - } - - if(!_.has(this.tempBans, event.server)) this.tempBans[event.server] = {}; - this.tempBans[event.server][banee] = msTimeout; - this.internalAPI.addTempBan(event.server, banee, msTimeout); - - var notifyString = dbot.t('tbanned', { - 'network': network, - 'banner': banner, - 'banee': banee, - 'hours': timeout, - 'host': host, - 'reason': reason - }); - } else { - var notifyString = dbot.t('nbanned', { - 'network': network, - 'banner': banner, - 'banee': banee, - 'host': host, - 'reason': reason - }); - } - - // Add db entry documenting ban - if(this.config.document_bans) { - var id = uuid.v4(); - var banRecord = { - 'id': id, - 'time': new Date().getTime(), - 'server': server, - 'banee': banee, - 'banner': banner, - 'host': host, - 'reason': reason - }; - this.db.save('nbans', id, banRecord, function() {}); - } - - // Notify moderators, banee - if(!_.isUndefined(adminChannel)) { - channels = _.without(channels, adminChannel); - } else { - adminChannel = event.channel.name; - } - - dbot.api.report.notify('ban', server, event.rUser, adminChannel, notifyString, false, banee); - dbot.say(event.server, adminChannel, notifyString); - - if(!_.isUndefined(timeout)) { - dbot.say(event.server, banee, dbot.t('tbanned_notify', { - 'network': network, - 'banner': banner, - 'reason': reason, - 'hours': timeout, - 'admin_channel': adminChannel - })); - } else { - dbot.say(event.server, banee, dbot.t('nbanned_notify', { - 'network': network, - 'banner': banner, - 'reason': reason, - 'hours': timeout, - 'admin_channel': adminChannel - })); - } - - // err - dbot.say(event.server, 'NickServ', 'FREEZE ' + banee + ' ON ' + reason); - } else { - event.reply(dbot.t('no_user', { 'user': banee })); - } - }.bind(this)); - }, - - '~nunban': function(event) { - var unbanee = event.params[1], - host = event.params[2] || undefined, - unbanner = event.rUser; - - this.api.networkUnban(event.server, unbanee, unbanner, host, function(err) { - if(err) { - event.reply(dbot.t('nunban_error', { 'unbanee': unbanee })); - } - }); - }, - - /*** Kick Stats ***/ - - // Give the number of times a given user has been kicked and has kicked - // other people. - '~kickcount': function(event) { - var username = event.params[1]; - - if(!_.has(dbot.db.kicks, username)) { - var kicks = '0'; - } else { - var kicks = dbot.db.kicks[username]; - } - - if(!_.has(dbot.db.kickers, username)) { - var kicked = '0'; - } else { - var kicked = dbot.db.kickers[username]; - } - - event.reply(dbot.t('user_kicks', { - 'user': username, - 'kicks': kicks, - 'kicked': kicked - })); - }, - - // Output a list of the people who have been kicked the most and those - // who have kicked other people the most. - '~kickstats': function(event) { - var orderedKickLeague = function(list, topWhat) { - var kickArr = _.chain(list) - .pairs() - .sortBy(function(kick) { return kick[1] }) - .reverse() - .first(10) - .value(); - - var kickString = "Top " + topWhat + ": "; - for(var i=0;i= 3 && vq.no.length < 2) { - event.reply('Attempt to quiet ' + target + ' succeeded. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); + if (!_.isUndefined(timeout)) { + dbot.say(event.server, banee, dbot.t('tbanned_notify', { + 'network': network, + 'banner': banner, + 'reason': reason, + 'hours': timeout, + 'admin_channel': adminChannel + })); + } else { + dbot.say(event.server, banee, dbot.t('nbanned_notify', { + 'network': network, + 'banner': banner, + 'reason': reason, + 'hours': timeout, + 'admin_channel': adminChannel + })); + } - this.api.quietUser(event.server, event.rUser, '10m', event.channel, target, reason + '[votequiet]', function(response) { - clearTimeout(vq.timer); - event.reply(response); - }); - } else { - event.reply('Attempt to quiet ' + target + ' failed. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); - } + // err + dbot.say(event.server, 'NickServ', 'FREEZE ' + banee + ' ON ' + reason); + } else { + event.reply(dbot.t('no_user', { + 'user': banee + })); + } + } + .bind(this)); + }, - var nString = 'A votequiet was attempted on ' + target + ' in ' + event.channel + '. It was initiated by ' + event.rUser.primaryNick + '. ' + - vq.yes.join(', ') + ' voted yes (' + vq.yes.length + '). '; - if(vq.no.length > 0) { - nString += vq.no.join(', ') + ' voted no (' + vq.no.length + ').' - } + '~nunban': function (event) { + var unbanee = event.params[1], + host = event.params[2] || undefined, + unbanner = event.rUser; - dbot.api.report.notify('votequiet', event.server, event.rUser, event.channel, nString, false, target); + this.api.networkUnban(event.server, unbanee, unbanner, host, function (err) { + if (err) { + event.reply(dbot.t('nunban_error', { + 'unbanee': unbanee + })); + } + }); + }, - setTimeout(function() { - delete this.voteQuiets[user.id]; - }.bind(this), 600000); - }.bind(this), 90000); - } else { - if(this.voteQuiets[user.id].spent) { - event.reply('A votequiet attempt has already been made on this user in the last 10 minutes.'); + /*** Kick Stats ***/ + + // Give the number of times a given user has been kicked and has kicked + // other people. + '~kickcount': function (event) { + var username = event.params[1]; + + if (!_.has(dbot.db.kicks, username)) { + var kicks = '0'; + } else { + var kicks = dbot.db.kicks[username]; + } + + if (!_.has(dbot.db.kickers, username)) { + var kicked = '0'; + } else { + var kicked = dbot.db.kickers[username]; + } + + event.reply(dbot.t('user_kicks', { + 'user': username, + 'kicks': kicks, + 'kicked': kicked + })); + }, + + // Output a list of the people who have been kicked the most and those + // who have kicked other people the most. + '~kickstats': function (event) { + var orderedKickLeague = function (list, topWhat) { + var kickArr = _.chain(list) + .pairs() + .sortBy(function (kick) { + return kick[1] + }) + .reverse() + .first(10) + .value(); + + var kickString = "Top " + topWhat + ": "; + for (var i = 0; i < kickArr.length; i++) { + kickString += kickArr[i][0] + " (" + kickArr[i][1] + "), "; + } + + return kickString.slice(0, -2); + }; + + event.reply(orderedKickLeague(dbot.db.kicks, 'Kicked')); + event.reply(orderedKickLeague(dbot.db.kickers, 'Kickers')); + }, + + '~votequiet': function (event) { + var target = event.input[1], + reason = event.input[2]; + + if (_.has(event.channel.nicks, target)) { + dbot.api.users.resolveUser(event.server, target, function (err, user) { + if (!err && user) { + if (_.include(dbot.access.power_user(), user.primaryNick) || target == dbot.config.name) { + return event.reply('User is immune to votequiet.'); + } + + if (!_.has(this.voteQuiets, user.id)) { + this.voteQuiets[user.id] = { + 'user': user.id, + 'reason': reason, + 'channel': event.channel, + 'yes': [event.rUser.primaryNick], + 'no': [] + }; + event.reply(event.user + ' has started a vote to quiet ' + target + ' for "' + reason + '." Type either "~voteyes ' + target + '" or "~voteno ' + target + '" in the next 90 seconds.'); + + this.voteQuiets[user.id].timer = setTimeout(function () { + var vq = this.voteQuiets[user.id]; + vq.spent = true; + if (vq.yes.length >= 3 && vq.no.length < 2) { + event.reply('Attempt to quiet ' + target + ' succeeded. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); + + this.api.quietUser(event.server, event.rUser, '10m', event.channel, target, reason + '[votequiet]', function (response) { + clearTimeout(vq.timer); + event.reply(response); + }); } else { - var vq = this.voteQuiets[user.id] - if(!_.include(vq.yes, event.rUser.primaryNick)) { - vq.yes.push(event.rUser.primaryNick); - - event.reply('There is already a votequiet attempt active for this user, adding yes vote to existing poll.'); - event.reply('Voted yes on votequiet for ' + target + '. New count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); - - if(vq.yes.length == 4) { - event.reply('Attempt to quiet ' + target + ' succeeded. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); - this.api.quietUser(event.server, event.rUser, '10m', event.channel, target, reason + '[votequiet]', function(response) { - clearTimeout(vq.timer); - vq.spent = true; - setTimeout(function() { - delete this.voteQuiets[user.id]; - }.bind(this), 600000); - event.reply(response); - }); - } - } else { - event.reply('There is already a votequiet attempt active for this user, and you already voted yes!'); - } + event.reply('Attempt to quiet ' + target + ' failed. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); } + + var nString = 'A votequiet was attempted on ' + target + ' in ' + event.channel + '. It was initiated by ' + event.rUser.primaryNick + '. ' + + vq.yes.join(', ') + ' voted yes (' + vq.yes.length + '). '; + if (vq.no.length > 0) { + nString += vq.no.join(', ') + ' voted no (' + vq.no.length + ').' + } + + dbot.api.report.notify('votequiet', event.server, event.rUser, event.channel, nString, false, target); + + setTimeout(function () { + delete this.voteQuiets[user.id]; + } + .bind(this), 600000); } + .bind(this), 90000); + } else { + if (this.voteQuiets[user.id].spent) { + event.reply('A votequiet attempt has already been made on this user in the last 10 minutes.'); } else { - event.reply('Target does not seem to be in the channel.'); + var vq = this.voteQuiets[user.id] + if (!_.include(vq.yes, event.rUser.primaryNick)) { + vq.yes.push(event.rUser.primaryNick); + + event.reply('There is already a votequiet attempt active for this user, adding yes vote to existing poll.'); + event.reply('Voted yes on votequiet for ' + target + '. New count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); + + if (vq.yes.length == 4) { + event.reply('Attempt to quiet ' + target + ' succeeded. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); + this.api.quietUser(event.server, event.rUser, '10m', event.channel, target, reason + '[votequiet]', function (response) { + clearTimeout(vq.timer); + vq.spent = true; + setTimeout(function () { + delete this.voteQuiets[user.id]; + } + .bind(this), 600000); + event.reply(response); + }); + } + } else { + event.reply('There is already a votequiet attempt active for this user, and you already voted yes!'); + } } - }.bind(this)); + } } else { event.reply('Target does not seem to be in the channel.'); } - }, - - '~voteyes': function(event) { - var target = event.params[1]; - - dbot.api.users.resolveUser(event.server, target, function(err, user) { - if(!err && user) { - if(user.id == event.rUser.id) { - return event.reply('You cannot vote on your own silencing. Be good.'); - } - if(_.has(this.voteQuiets, user.id) && !this.voteQuiets[user.id].spent) { - var vq = this.voteQuiets[user.id]; - if(event.channel != vq.channel) { - return event.reply('Vote must be in ' + vq.channel); - } - if(!_.include(vq.yes, event.rUser.primaryNick) && !_.include(vq.no, event.rUser.primaryNick)) { - vq.yes.push(event.rUser.primaryNick); - event.reply('Voted yes on votequiet for ' + target + '. New count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); - - if(vq.yes.length == 4) { - event.reply('Attempt to quiet ' + target + ' succeeded. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); - this.api.quietUser(event.server, event.rUser, '10m', event.channel, target, vq.reason + '[votequiet]', function(response) { - clearTimeout(vq.timer); - vq.spent = true; - setTimeout(function() { - delete this.voteQuiets[user.id]; - }.bind(this), 600000); - event.reply(response); - }); - } - } else { - event.reply('You have already voted.'); - } - } else { - event.reply('There is no active votequiet for this user. You can start one by typing "~votequiet ' + target + ' [reason].'); - } - } else { - event.reply('No idea who that is m8'); - } - }.bind(this)); - }, - - '~voteno': function(event) { - var target = event.params[1]; - - dbot.api.users.resolveUser(event.server, target, function(err, user) { - if(!err && user) { - if(user.id == event.rUser.id) { - return event.reply('You cannot vote on your own silencing. Be good.'); - } - if(_.has(this.voteQuiets, user.id) && !this.voteQuiets[user.id].spent) { - var vq = this.voteQuiets[user.id]; - if(event.channel != vq.channel) { - return event.reply('Vote must be in ' + vq.channel); - } - if(!_.include(vq.yes, event.rUser.primaryNick) && !_.include(vq.no, event.rUser.primaryNick)) { - vq.no.push(event.rUser.primaryNick); - event.reply('Voted no on votequiet for ' + target + '. New count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); - } else { - event.reply('You have already voted.'); - } - } else { - event.reply('There is no active votequiet for this user. You can start one by typing "~votequiet ' + target + ' [reason].'); - } - } else { - event.reply('No idea who that is m8'); - } - }.bind(this)); } - }; + .bind(this)); + } else { + event.reply('Target does not seem to be in the channel.'); + } + }, - _.each(commands, function(command) { - command.access = 'moderator'; - }); + '~voteyes': function (event) { + var target = event.params[1]; - commands['~kickcount'].access = 'regular'; - commands['~kickstats'].access = 'regular'; - commands['~votequiet'].access = 'regular'; - commands['~voteyes'].access = 'regular'; - commands['~voteno'].access = 'regular'; - commands['~quiet'].access = 'voice'; - commands['~timeout'].access = 'voice'; - commands['~unquiet'].access = 'voice'; - commands['~nban'].access = 'power_user'; - commands['~nunban'].access = 'power_user'; + dbot.api.users.resolveUser(event.server, target, function (err, user) { + if (!err && user) { + if (user.id == event.rUser.id) { + return event.reply('You cannot vote on your own silencing. Be good.'); + } + if (_.has(this.voteQuiets, user.id) && !this.voteQuiets[user.id].spent) { + var vq = this.voteQuiets[user.id]; + if (event.channel != vq.channel) { + return event.reply('Vote must be in ' + vq.channel); + } + if (!_.include(vq.yes, event.rUser.primaryNick) && !_.include(vq.no, event.rUser.primaryNick)) { + vq.yes.push(event.rUser.primaryNick); + event.reply('Voted yes on votequiet for ' + target + '. New count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); - commands['~ckick'].regex = /^ckick (#[^ ]+ )?([^ ]+) ?(.*)?$/; - commands['~nban'].regex = /^nban (\d[\d\.dhmsy]+)? ?([^ ]+) (.+)$/; - commands['~quiet'].regex = /^quiet (\d[\d\.hmsy]+)? ?(#[^ ]+ )?([^ ]+) ?(.*)?$/; - commands['~timeout'].regex = /^timeout ([^ ]+) ?(.*)?$/; - commands['~unquiet'].regex = /^unquiet (#[^ ]+ )?([^ ]+) ?$/; - commands['~votequiet'].regex = [/^votequiet ([^ ]+) (.+)$/, 3]; + if (vq.yes.length == 4) { + event.reply('Attempt to quiet ' + target + ' succeeded. Count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); + this.api.quietUser(event.server, event.rUser, '10m', event.channel, target, vq.reason + '[votequiet]', function (response) { + clearTimeout(vq.timer); + vq.spent = true; + setTimeout(function () { + delete this.voteQuiets[user.id]; + } + .bind(this), 600000); + event.reply(response); + }); + } + } else { + event.reply('You have already voted.'); + } + } else { + event.reply('There is no active votequiet for this user. You can start one by typing "~votequiet ' + target + ' [reason].'); + } + } else { + event.reply('No idea who that is m8'); + } + } + .bind(this)); + }, - return commands; + '~voteno': function (event) { + var target = event.params[1]; + + dbot.api.users.resolveUser(event.server, target, function (err, user) { + if (!err && user) { + if (user.id == event.rUser.id) { + return event.reply('You cannot vote on your own silencing. Be good.'); + } + if (_.has(this.voteQuiets, user.id) && !this.voteQuiets[user.id].spent) { + var vq = this.voteQuiets[user.id]; + if (event.channel != vq.channel) { + return event.reply('Vote must be in ' + vq.channel); + } + if (!_.include(vq.yes, event.rUser.primaryNick) && !_.include(vq.no, event.rUser.primaryNick)) { + vq.no.push(event.rUser.primaryNick); + event.reply('Voted no on votequiet for ' + target + '. New count: Yes (' + vq.yes.length + '). No (' + vq.no.length + ').'); + } else { + event.reply('You have already voted.'); + } + } else { + event.reply('There is no active votequiet for this user. You can start one by typing "~votequiet ' + target + ' [reason].'); + } + } else { + event.reply('No idea who that is m8'); + } + } + .bind(this)); + } + }; + + _.each(commands, function (command) { + command.access = 'moderator'; + }); + + commands['~kickcount'].access = 'regular'; + commands['~kickstats'].access = 'regular'; + commands['~votequiet'].access = 'regular'; + commands['~voteyes'].access = 'regular'; + commands['~voteno'].access = 'regular'; + commands['~quiet'].access = 'voice'; + commands['~timeout'].access = 'voice'; + commands['~unquiet'].access = 'voice'; + commands['~nban'].access = 'power_user'; + commands['~nunban'].access = 'power_user'; + + commands['~ckick'].regex = /^ckick (#[^ ]+ )?([^ ]+) ?(.*)?$/; + commands['~nban'].regex = /^nban (\d[\d\.dhmsy]+)? ?([^ ]+) (.+)$/; + commands['~quiet'].regex = /^quiet (\d[\d\.hmsy]+)? ?(#[^ ]+ )?([^ ]+) ?(.*)?$/; + commands['~timeout'].regex = /^timeout ([^ ]+) ?(.*)?$/; + commands['~unquiet'].regex = /^unquiet (#[^ ]+ )?([^ ]+) ?$/; + commands['~votequiet'].regex = [/^votequiet ([^ ]+) (.+)$/, 3]; + + return commands; }; -exports.fetch = function(dbot) { - return commands(dbot); +exports.fetch = function (dbot) { + return commands(dbot); }; diff --git a/modules/kick/kick.js b/modules/kick/kick.js index 1269e3f..4384aed 100644 --- a/modules/kick/kick.js +++ b/modules/kick/kick.js @@ -1,252 +1,270 @@ var _ = require('underscore')._; -var kick = function(dbot) { - if(!_.has(dbot.db, 'recentTimeouts')) { - dbot.db.recentTimeouts = {}; - } - this.recentTimeouts = dbot.db.recentTimeouts; +var kick = function (dbot) { + if (!_.has(dbot.db, 'recentTimeouts')) { + dbot.db.recentTimeouts = {}; + } + this.recentTimeouts = dbot.db.recentTimeouts; - this.api = { - 'ban': function(server, host, channel) { - dbot.instance.connections[server].send('MODE ' + channel + ' +b *!*@' + host); - }, + this.api = { + 'ban': function (server, host, channel) { + dbot.instance.connections[server].send('MODE ' + channel + ' +b *!*@' + host); + }, - 'quiet': function(server, host, channel) { - dbot.instance.connections[server].send('MODE ' + channel + ' +q *!*@' + host); - }, + 'quiet': function (server, host, channel) { + dbot.instance.connections[server].send('MODE ' + channel + ' +q *!*@' + host); + }, - 'unquiet': function(server, host, channel) { - dbot.instance.connections[server].send('MODE ' + channel + ' -q *!*@' + host); - }, + 'unquiet': function (server, host, channel) { + dbot.instance.connections[server].send('MODE ' + channel + ' -q *!*@' + host); + }, - 'devoice': function(server, nick, channel) { - dbot.instance.connections[server].send('MODE ' + channel + ' -v ' +nick); - }, + 'devoice': function (server, nick, channel) { + dbot.instance.connections[server].send('MODE ' + channel + ' -v ' + nick); + }, - 'voice': function(server, nick, channel) { - dbot.instance.connections[server].send('MODE ' + channel + ' +v ' +nick); - }, + 'voice': function (server, nick, channel) { + dbot.instance.connections[server].send('MODE ' + channel + ' +v ' + nick); + }, - 'kick': function(server, user, channel, msg) { - dbot.instance.connections[server].send('KICK ' + channel + ' ' + user + ' :' + msg); - }, + 'kick': function (server, user, channel, msg) { + dbot.instance.connections[server].send('KICK ' + channel + ' ' + user + ' :' + msg); + }, - 'kill': function(server, user, reason) { - dbot.instance.connections[server].send('kill ' + user + ' ' + reason); - }, + 'kill': function (server, user, reason) { + dbot.instance.connections[server].send('kill ' + user + ' ' + reason); + }, - 'unban': function(server, host, channel) { - // TODO: Wrest control from chanserv - //dbot.say(server, this.config.chanserv, 'unban ' + channel + ' *!*@' + host); - dbot.instance.connections[server].send('MODE ' + channel + ' -b *!*@' + host); - }, + 'unban': function (server, host, channel) { + // TODO: Wrest control from chanserv + //dbot.say(server, this.config.chanserv, 'unban ' + channel + ' *!*@' + host); + dbot.instance.connections[server].send('MODE ' + channel + ' -b *!*@' + host); + }, - 'quietUser': function(server, quieter, duration, channel, quietee, reason, callback) { - dbot.api.nickserv.getUserHost(server, quietee, function(host) { - // Add host record entry - if(host) { - this.hosts[server][quietee] = host; + 'quietUser': function (server, quieter, duration, channel, quietee, reason, callback) { + dbot.api.nickserv.getUserHost(server, quietee, function (host) { + // Add host record entry + if (host) { + this.hosts[server][quietee] = host; - if(!_.isUndefined(duration) && !_.isNull(duration)) { - duration = duration.trim(); - var msTimeout = new Date(new Date().getTime() + (parseFloat(duration) * 60000)); - if(_.has(dbot.modules, 'remind')) { - msTimeout = dbot.api.remind.parseTime(duration); - if(!msTimeout) { - return callback('Invalid time. Remember you must give e.g. 5m now.'); - } - duration = duration.replace(/([\d]+)d/, '$1 years').replace(/([\d]+)d/, '$1 days').replace(/([\d]+)h/, '$1 hours ').replace(/([\d]+)m/, '$1 minutes ').replace(/([\d]+)s/, '$1 seconds').trim(); - } else { - duration += ' minutes'; - } + if (!_.isUndefined(duration) && !_.isNull(duration)) { + duration = duration.trim(); + var msTimeout = new Date(new Date().getTime() + (parseFloat(duration) * 60000)); + if (_.has(dbot.modules, 'remind')) { + msTimeout = dbot.api.remind.parseTime(duration); + if (!msTimeout) { + return callback('Invalid time. Remember you must give e.g. 5m now.'); + } + duration = duration.replace(/([\d]+)d/, '$1 years').replace(/([\d]+)d/, '$1 days').replace(/([\d]+)h/, '$1 hours ').replace(/([\d]+)m/, '$1 minutes ').replace(/([\d]+)s/, '$1 seconds').trim(); + } else { + duration += ' minutes'; + } - var vStatus = dbot.instance.connections[server].channels[channel].nicks[quietee].voice; - dbot.api.timers.addTimeout(msTimeout, function() { - if(_.has(this.hosts[server], quietee)) { - if(_.include(this.config.quietBans, channel)) { - this.api.unban(server, this.hosts[server][quietee], channel); - this.api.voice(server, quietee, channel); - } else { - this.api.unquiet(server, this.hosts[server][quietee], channel); - } - - dbot.api.users.resolveUser(server, dbot.config.name, function(err, user) { - dbot.api.report.notify('unquiet', server, user, channel, - dbot.t('unquiet_notify', { - 'unquieter': dbot.config.name, - 'quietee': quietee - }), false, quietee); - }); - } - }.bind(this)); - callback(dbot.t('tquieted', { - 'quietee': quietee, - 'minutes': duration - })); - dbot.api.report.notify('quiet', server, quieter.primaryNick, channel, - dbot.t('tquiet_notify', { - 'minutes': duration, - 'quieter': quieter.primaryNick, - 'quietee': quietee, - 'reason': reason - }), false, quietee - ); - } else { - callback(dbot.t('quieted', { 'quietee': quietee })); - dbot.api.report.notify('quiet', server, quieter.primaryNick, channel, - dbot.t('quiet_notify', { - 'quieter': quieter.primaryNick, - 'quietee': quietee, - 'reason': reason - }), false, quietee); - } - - this.api.devoice(server, quietee, channel); - - if(_.include(this.config.quietBans, channel)) { - this.api.ban(server, this.hosts[server][quietee], channel); - } else { - this.api.quiet(server, host, channel); - } - - if(reason.indexOf('#warn') !== -1) { - dbot.api.warning.warn(server, quieter, quietee, - 'Quieted in ' + channel + ' for ' + reason, channel, - function() {}); - } + var vStatus = dbot.instance.connections[server].channels[channel].nicks[quietee].voice; + dbot.api.timers.addTimeout(msTimeout, function () { + if (_.has(this.hosts[server], quietee)) { + if (_.include(this.config.quietBans, channel)) { + this.api.unban(server, this.hosts[server][quietee], channel); + this.api.voice(server, quietee, channel); } else { - event.reply(dbot.t('no_user', { 'user': quietee })); - } - }.bind(this)); - }, - - 'networkUnban': function(server, unbanee, unbanner, manualHost, callback) { - var channels = dbot.config.servers[server].channels, - network = this.config.network_name[server] || server, - adminChannel = dbot.config.servers[server].admin_channel; - - if(!_.isUndefined(manualHost)) { - this.hosts[server][unbanee] = manualHost; - } - - if(_.has(this.hosts, server) && _.has(this.hosts[server], unbanee) && _.isString(this.hosts[server][unbanee])) { - var host = this.hosts[server][unbanee]; - - // Notify Staff - if(_.isUndefined(adminChannel)) { - adminChannel = event.channel.name; + this.api.unquiet(server, this.hosts[server][quietee], channel); } - var notifyString = dbot.t('nunbanned', { - 'network': network, - 'unbanee': unbanee, - 'host': host, - 'unbanner': unbanner.currentNick + dbot.api.users.resolveUser(server, dbot.config.name, function (err, user) { + dbot.api.report.notify('unquiet', server, user, channel, + dbot.t('unquiet_notify', { + 'unquieter': dbot.config.name, + 'quietee': quietee + }), false, quietee); }); - dbot.api.report.notify('unban', server, unbanner, adminChannel, notifyString, false, unbanee); - dbot.say(server, adminChannel, notifyString); - - // Notify Unbanee - dbot.say(server, unbanee, dbot.t('nunban_notify', { - 'network': network, - 'unbanee': unbanee, - 'unbanner': unbanner.currentNick - })); - - // Unban - var i = 0; - var unbanChannel = function(channels) { - if(i >= channels.length) return; - var channel = channels[i]; - this.api.unban(server, host, channel); - setTimeout(function() { - i++; unbanChannel(channels); - }, 1000); - }.bind(this); - unbanChannel(channels); - - dbot.say(server, 'NickServ', 'FREEZE ' + unbanee + ' OFF'); - callback(null); // Success - } else { - // Attempt to look up the host on-the-fly - dbot.api.nickserv.getUserHost(server, unbanee, unbanner, function(host) { - if(host) { - if(!_.has(this.hosts, server)) this.hosts[server] = {}; - this.hosts[server][unbanee] = host; - this.api.networkUnban(server, unbanee, unbanner); - } else { - callback(true); // No host could be found - } - }.bind(this)); + } } - } - }; + .bind(this)); + callback(dbot.t('tquieted', { + 'quietee': quietee, + 'minutes': duration + })); + dbot.api.report.notify('quiet', server, quieter.primaryNick, channel, + dbot.t('tquiet_notify', { + 'minutes': duration, + 'quieter': quieter.primaryNick, + 'quietee': quietee, + 'reason': reason + }), false, quietee); + } else { + callback(dbot.t('quieted', { + 'quietee': quietee + })); + dbot.api.report.notify('quiet', server, quieter.primaryNick, channel, + dbot.t('quiet_notify', { + 'quieter': quieter.primaryNick, + 'quietee': quietee, + 'reason': reason + }), false, quietee); + } - this.internalAPI = { - 'addTempBan': function(server, banee, timeout) { - dbot.api.users.resolveUser(server, dbot.config.name, function(err, bot) { - dbot.api.timers.addTimeout(timeout, function() { - this.api.networkUnban(server, banee, bot, undefined, function(err) {}); - delete this.tempBans[server][banee]; - }.bind(this)); - }.bind(this)); - }.bind(this) - }; - - this.listener = function(event) { - if(event.kickee == dbot.config.name) { - dbot.instance.join(event, event.channel.name); - event.reply(dbot.t('kicked_dbot', { 'botname': dbot.config.name })); - dbot.db.kicks[dbot.config.name] += 1; + this.api.devoice(server, quietee, channel); + + if (_.include(this.config.quietBans, channel)) { + this.api.ban(server, this.hosts[server][quietee], channel); + } else { + this.api.quiet(server, host, channel); + } + + if (reason.indexOf('#warn') !== -1) { + dbot.api.warning.warn(server, quieter, quietee, + 'Quieted in ' + channel + ' for ' + reason, channel, + function () {}); + } } else { - if(!_.has(dbot.db.kicks, event.kickee)) { - dbot.db.kicks[event.kickee] = 1; - } else { - dbot.db.kicks[event.kickee] += 1; - } - - if(!_.has(dbot.db.kickers, event.user)) { - dbot.db.kickers[event.user] = 1; - } else { - dbot.db.kickers[event.user] += 1; - } - - if(!this.config.countSilently) { - event.reply(event.kickee + '-- (' + dbot.t('user_kicks', { - 'user': event.kickee, - 'kicks': dbot.db.kicks[event.kickee], - 'kicked': dbot.db.kickers[event.kickee] - }) + ')'); - } + event.reply(dbot.t('no_user', { + 'user': quietee + })); } - }.bind(this); - this.on = 'KICK'; + } + .bind(this)); + }, - this.onLoad = function() { - if(!_.has(dbot.db, 'hosts')) { - dbot.db.hosts = {}; - _.each(dbot.config.servers, function(v, k) { - dbot.db.hosts[k] = {}; - }, this); - } - if(!_.has(dbot.db, 'tempBans')) dbot.db.tempBans = {}; - this.hosts = dbot.db.hosts; - this.tempBans = dbot.db.tempBans; - this.voteQuiets = {}; - - _.each(this.tempBans, function(bans, server) { - _.each(bans, function(timeout, nick) { - timeout = new Date(timeout); - this.internalAPI.addTempBan(server, nick, timeout); - }, this); - }, this); + 'networkUnban': function (server, unbanee, unbanner, manualHost, callback) { + var channels = dbot.config.servers[server].channels, + network = this.config.network_name[server] || server, + adminChannel = dbot.config.servers[server].admin_channel; - if(_.has(dbot.modules, 'web')) { - dbot.api.web.addIndexLink('/bans', 'Ban List'); + if (!_.isUndefined(manualHost)) { + this.hosts[server][unbanee] = manualHost; + } + + if (_.has(this.hosts, server) && _.has(this.hosts[server], unbanee) && _.isString(this.hosts[server][unbanee])) { + var host = this.hosts[server][unbanee]; + + // Notify Staff + if (_.isUndefined(adminChannel)) { + adminChannel = event.channel.name; } - }.bind(this); + + var notifyString = dbot.t('nunbanned', { + 'network': network, + 'unbanee': unbanee, + 'host': host, + 'unbanner': unbanner.currentNick + }); + dbot.api.report.notify('unban', server, unbanner, adminChannel, notifyString, false, unbanee); + dbot.say(server, adminChannel, notifyString); + + // Notify Unbanee + dbot.say(server, unbanee, dbot.t('nunban_notify', { + 'network': network, + 'unbanee': unbanee, + 'unbanner': unbanner.currentNick + })); + + // Unban + var i = 0; + var unbanChannel = function (channels) { + if (i >= channels.length) + return; + var channel = channels[i]; + this.api.unban(server, host, channel); + setTimeout(function () { + i++; + unbanChannel(channels); + }, 1000); + } + .bind(this); + unbanChannel(channels); + + dbot.say(server, 'NickServ', 'FREEZE ' + unbanee + ' OFF'); + callback(null); // Success + } else { + // Attempt to look up the host on-the-fly + dbot.api.nickserv.getUserHost(server, unbanee, unbanner, function (host) { + if (host) { + if (!_.has(this.hosts, server)) + this.hosts[server] = {}; + this.hosts[server][unbanee] = host; + this.api.networkUnban(server, unbanee, unbanner); + } else { + callback(true); // No host could be found + } + } + .bind(this)); + } + } + }; + + this.internalAPI = { + 'addTempBan': function (server, banee, timeout) { + dbot.api.users.resolveUser(server, dbot.config.name, function (err, bot) { + dbot.api.timers.addTimeout(timeout, function () { + this.api.networkUnban(server, banee, bot, undefined, function (err) {}); + delete this.tempBans[server][banee]; + } + .bind(this)); + } + .bind(this)); + } + .bind(this) + }; + + this.listener = function (event) { + if (event.kickee == dbot.config.name) { + dbot.instance.join(event, event.channel.name); + event.reply(dbot.t('kicked_dbot', { + 'botname': dbot.config.name + })); + dbot.db.kicks[dbot.config.name] += 1; + } else { + if (!_.has(dbot.db.kicks, event.kickee)) { + dbot.db.kicks[event.kickee] = 1; + } else { + dbot.db.kicks[event.kickee] += 1; + } + + if (!_.has(dbot.db.kickers, event.user)) { + dbot.db.kickers[event.user] = 1; + } else { + dbot.db.kickers[event.user] += 1; + } + + if (!this.config.countSilently) { + event.reply(event.kickee + '-- (' + dbot.t('user_kicks', { + 'user': event.kickee, + 'kicks': dbot.db.kicks[event.kickee], + 'kicked': dbot.db.kickers[event.kickee] + }) + ')'); + } + } + } + .bind(this); + this.on = 'KICK'; + + this.onLoad = function () { + if (!_.has(dbot.db, 'hosts')) { + dbot.db.hosts = {}; + _.each(dbot.config.servers, function (v, k) { + dbot.db.hosts[k] = {}; + }, this); + } + if (!_.has(dbot.db, 'tempBans')) + dbot.db.tempBans = {}; + this.hosts = dbot.db.hosts; + this.tempBans = dbot.db.tempBans; + this.voteQuiets = {}; + + _.each(this.tempBans, function (bans, server) { + _.each(bans, function (timeout, nick) { + timeout = new Date(timeout); + this.internalAPI.addTempBan(server, nick, timeout); + }, this); + }, this); + + if (_.has(dbot.modules, 'web')) { + dbot.api.web.addIndexLink('/bans', 'Ban List'); + } + } + .bind(this); }; -exports.fetch = function(dbot) { - return new kick(dbot); +exports.fetch = function (dbot) { + return new kick(dbot); }; diff --git a/modules/kick/pages.js b/modules/kick/pages.js index f513949..52edb75 100644 --- a/modules/kick/pages.js +++ b/modules/kick/pages.js @@ -1,42 +1,46 @@ var _ = require('underscore')._; -var pages = function(dbot) { - return { - '/bans': function(req, res) { - res.render('servers', { - 'servers': _.keys(dbot.config.servers) - }); - }, +var pages = function (dbot) { + return { + '/bans': function (req, res) { + res.render('servers', { + 'servers': _.keys(dbot.config.servers) + }); + }, - '/underbans': function(req, res) { - this.db.search('nbans', { 'server': server }, function(ban) { - if(ban.reason.match('#underban')) { - bans.push(ban); - } - }, function() { - res.render('bans', { - 'server': server, - 'bans': bans - }); - }); - }, - - '/bans/:server': function(req, res) { - var server = req.params.server, - bans = []; - - this.db.search('nbans', { 'server': server }, function(ban) { - bans.push(ban); - }, function() { - res.render('bans', { - 'server': server, - 'bans': bans - }); - }); + '/underbans': function (req, res) { + this.db.search('nbans', { + 'server': server + }, function (ban) { + if (ban.reason.match('#underban')) { + bans.push(ban); } + }, function () { + res.render('bans', { + 'server': server, + 'bans': bans + }); + }); + }, + + '/bans/:server': function (req, res) { + var server = req.params.server, + bans = []; + + this.db.search('nbans', { + 'server': server + }, function (ban) { + bans.push(ban); + }, function () { + res.render('bans', { + 'server': server, + 'bans': bans + }); + }); } + } }; -exports.fetch = function(dbot) { - return pages(dbot); +exports.fetch = function (dbot) { + return pages(dbot); }; diff --git a/modules/kill_namespam/config.json b/modules/kill_namespam/config.json index 3bafe0f..ca63f48 100644 --- a/modules/kill_namespam/config.json +++ b/modules/kill_namespam/config.json @@ -6,5 +6,6 @@ "________ ______" ], "cliconn_channel": "#dnsbl", - "cliconn_patterns": [] + "cliconn_patterns": [], + "exempt_channels": [] } diff --git a/modules/kill_namespam/kill_namespam.js b/modules/kill_namespam/kill_namespam.js index 9e81f5a..6f952a2 100644 --- a/modules/kill_namespam/kill_namespam.js +++ b/modules/kill_namespam/kill_namespam.js @@ -11,13 +11,16 @@ var kill_namespam = function(dbot) { dbot.customConfig.modules.kill_namespam = this.config; dbot.modules.admin.internalAPI.saveConfig(); }.bind(this); + + this.matchedKill = {}; this.listener = function(event) { + if(event.action == 'PRIVMSG') { // Here we listen for atropos if(event.channel == this.config.cliconn_channel) { if(event.message.match('▶')) { var matchedPattern = _.find(this.config.cliconn_patterns, - function(p) { try { return event.message.match(p); } catch(e) {}; }); // ok.jpg + function(p) { try { return event.message.match(p); } catch(e) {}; }); // ok.jpg if(matchedPattern) { var nick = event.message.split(' ')[2]; dbot.api.nickserv.getUserHost(event.server, nick, function(host) { @@ -28,18 +31,15 @@ var kill_namespam = function(dbot) { 'pattern': matchedPattern })); } else { - var ip = event.message.split(' ')[1] - - // Alternatively you can just do dbot.api.kick.kill(event.server, event.user, message); - dbot.say(event.server, 'operserv', 'akill add *@'+ ip +' !P Naughty Nelly Auto-kill v6.2. Matched pattern: /'+ matchedPattern +'/'); - - var msg = dbot.t('clikill_act', { - 'ip': ip, - 'pattern': matchedPattern - }); - event.reply(msg); - dbot.api.report.notify('autokill', event.server, event.rUser, - dbot.config.servers[event.server].admin_channel, msg, ip, ip); + if(!this.matchedKill[host]) { + // Defer killing this connection until after they join a non-exempted channel + this.matchedKill[host] = { + ip: event.message.split(' ')[1], + server: event.server, + matchedPattern: matchedPattern, + rUser: event.rUser + }; + } } }, true); } @@ -76,7 +76,7 @@ var kill_namespam = function(dbot) { if(naughty) { switch(this.config.action) { - case 'kickban': + case 'kickban': dbot.api.kick.ban(event.server, event.host, event.channel); dbot.api.kick.kick(event.server, event.user, message); break; @@ -87,8 +87,31 @@ var kill_namespam = function(dbot) { dbot.api.report.notify('spam', event.server, event.user, event.channel, message, event.host, event.user); } + } else if (event.action == 'JOIN') { + + if(this.matchedKill[event.host]) { + if(this.config.exempt_channels.indexOf(event.channel) == -1) { + var kill = this.matchedKill[event.host]; + delete this.matchedKill[event.host]; + + // Alternatively you can just do dbot.api.kick.kill(event.server, event.user, message); + dbot.say(event.server, 'operserv', 'akill add *@'+ kill.ip +' !P Naughty Nelly Auto-kill v6.2. Matched pattern: /'+ kill.matchedPattern +'/'); + + var msg = dbot.t('clikill_act', { + 'ip': kill.ip, + 'pattern': kill.matchedPattern + }); + dbot.api.report.notify('autokill', kill.server, kill.rUser, + dbot.config.servers[kill.server].admin_channel, msg, kill.ip, kill.ip); + } + } + } else if (event.action == 'QUIT') { + if(this.matchedKill[event.host]) { + delete this.matchedKill[event.host]; + } + } }.bind(this); - this.on = 'PRIVMSG'; + this.on = ['PRIVMSG', 'JOIN', 'QUIT']; this.commands = { '~add_spamkill': function(event) {