From 248ca9b790cd197b569efa8aa8ca6a5355ff9039 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Tue, 6 Mar 2012 23:54:52 +0000 Subject: [PATCH 01/66] Create and/or fix a missing/incomplete DB on running. --- run.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/run.js b/run.js index fc29667..73d51b2 100644 --- a/run.js +++ b/run.js @@ -6,7 +6,33 @@ require('./snippets'); var DBot = function(timers) { // Load external files this.config = JSON.parse(fs.readFileSync('config.json', 'utf-8')); - this.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); + try { + this.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); + } catch (e) { + this.db = {}; + } finally { /* fill any missing parts of the db; if this is a new DB, that's all of them */ + if(!this.db.hasOwnProperty("bans")) { + this.db.bans = {}; + } + if(!this.db.bans.hasOwnProperty("*")) { + this.db.bans["*"] = []; + } + if(!this.db.hasOwnProperty("quoteArrs")) { + this.db.quoteArrs = {}; + } + if(!this.db.hasOwnProperty("kicks")) { + this.db.kicks = {}; + } + if(!this.db.hasOwnProperty("kickers")) { + this.db.kickers = {}; + } + if(!this.db.hasOwnProperty("modehate")) { + this.db.modehate = []; + } + if(!this.db.hasOwnProperty("locks")) { + this.db.locks = []; + } + } // Populate bot properties with config data this.name = this.config.name || 'dbox'; From cfe2c0db4f64318d1116a67b76b12b23ba347720 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Wed, 7 Mar 2012 03:22:25 +0000 Subject: [PATCH 02/66] Sum function. --- snippets.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/snippets.js b/snippets.js index b769658..8e6a9af 100644 --- a/snippets.js +++ b/snippets.js @@ -27,6 +27,14 @@ Array.prototype.include = function(value) { return false; }; +Array.prototype.sum = function() { + var sum = 0; + for(var i=0;i Date: Wed, 7 Mar 2012 03:22:52 +0000 Subject: [PATCH 03/66] Basic dice-rolling functionality. Next, modifiers. --- modules/dice.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 modules/dice.js diff --git a/modules/dice.js b/modules/dice.js new file mode 100644 index 0000000..922baf4 --- /dev/null +++ b/modules/dice.js @@ -0,0 +1,66 @@ +var parseDiceSpec = function (specString) { + var rawSpec = specString.valMatch(/^([0-9]*)d(%|[0-9]*)$/i, 3); + if (rawSpec !== false) { + if (rawSpec[2] === "%") { + rawSpec[2] = 100; + } + return { + "count": parseInt(rawSpec[1] || 1), + "sides": parseInt(rawSpec[2] || 6) + }; + } else { + return false; + } +}; + +var normalizeDiceSpec = function (specString) { + var diceSpec = parseDiceSpec(specString); + return (diceSpec["count"] > 1 ? diceSpec["count"] : "") + "d" + (diceSpec["sides"] === 100 ? "%" : diceSpec["sides"]); +}; + +var dice = function(dbot) { + var commands = { + '~roll': function (data, params) { + var rolls = []; + + if (params.length === 1) { + params.push("d6"); + } + + for (var i = 1; i < params.length; i++) { + var diceSpec = parseDiceSpec(params[i]); + if (diceSpec === false) { + rolls.push([params[i], false]); + } else { + rolls.push([normalizeDiceSpec(params[i]), []]); + for (var j = 0; j < diceSpec["count"] ; j++) { + rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"])); + } + } + } + + for (var i = 0; i < rolls.length; i++) { + if (rolls[i][1] === false) { + dbot.say(data.channel, rolls[i][0] + ": invalid dice spec"); + } else { + if (rolls[i][1].length > 1) { + var total = " (total " + rolls[i][1].sum() + ")"; + } else { + var total = ""; + } + dbot.say(data.channel, rolls[i][0] + ": " + rolls[i][1].join(" ") + total); + } + } + } + }; + + return { + 'onLoad': function() { + return commands; + } + }; +} + +exports.fetch = function(dbot) { + return dice(dbot); +}; From e925021714367670cb696b0325461a197dab810a Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Wed, 7 Mar 2012 03:33:18 +0000 Subject: [PATCH 04/66] And there's the modifiers. Beautiful. --- modules/dice.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/modules/dice.js b/modules/dice.js index 922baf4..d794e7b 100644 --- a/modules/dice.js +++ b/modules/dice.js @@ -1,12 +1,13 @@ var parseDiceSpec = function (specString) { - var rawSpec = specString.valMatch(/^([0-9]*)d(%|[0-9]*)$/i, 3); + var rawSpec = specString.valMatch(/^([0-9]*)d(%|[0-9]*)(|[+-][0-9]+)$/i, 4); if (rawSpec !== false) { if (rawSpec[2] === "%") { rawSpec[2] = 100; } return { "count": parseInt(rawSpec[1] || 1), - "sides": parseInt(rawSpec[2] || 6) + "sides": parseInt(rawSpec[2] || 6), + "modifier": parseInt(rawSpec[3] || 0) }; } else { return false; @@ -15,7 +16,28 @@ var parseDiceSpec = function (specString) { var normalizeDiceSpec = function (specString) { var diceSpec = parseDiceSpec(specString); - return (diceSpec["count"] > 1 ? diceSpec["count"] : "") + "d" + (diceSpec["sides"] === 100 ? "%" : diceSpec["sides"]); + + if (diceSpec["count"] > 1) { + var count = diceSpec["count"]; + } else { + var count = ""; + } + + if (diceSpec["sides"] === 100) { + var sides = "%"; + } else { + var sides = diceSpec["sides"]; + } + + if (diceSpec["modifier"] > 0) { + var modifier = "+" + diceSpec["modifier"]; + } else if (diceSpec["modifier"] < 0) { + var modifier = diceSpec["modifier"]; + } else { + var modifier = ""; + } + + return (count + "d" + sides + modifier); }; var dice = function(dbot) { @@ -34,7 +56,7 @@ var dice = function(dbot) { } else { rolls.push([normalizeDiceSpec(params[i]), []]); for (var j = 0; j < diceSpec["count"] ; j++) { - rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"])); + rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"]) + diceSpec["modifier"]); } } } From 61c6aaf1877a625f327778177dcff2b076e9bbc3 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Wed, 7 Mar 2012 04:25:07 +0000 Subject: [PATCH 05/66] Don't fail to have a realityonce quote array. --- run.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/run.js b/run.js index 9479300..4d683fc 100644 --- a/run.js +++ b/run.js @@ -20,6 +20,9 @@ var DBot = function(timers) { if(!this.db.hasOwnProperty("quoteArrs")) { this.db.quoteArrs = {}; } + if(!this.db.quoteArrs.hasOwnProperty("realityonce")) { + this.db.quoteArrs.realityonce = []; + } if(!this.db.hasOwnProperty("kicks")) { this.db.kicks = {}; } From 1d2659f3618506955c0e374e5572f0fe9044fd35 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Wed, 7 Mar 2012 22:13:31 +0000 Subject: [PATCH 06/66] Interpolated quotes, because why not? --- modules/puns.js | 4 ++-- modules/quotes.js | 6 +++--- run.js | 18 +++++++++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/modules/puns.js b/modules/puns.js index 1cc2661..29b7ae9 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -4,9 +4,9 @@ var puns = function(dbot) { return { 'listener': function(data) { if(data.user == 'reality') { - dbot.instance.say(data.channel, dbot.db.quoteArrs['realityonce'].random()); + dbot.instance.say(data.channel, dbot.interpolatedQuote('realityonce')); } else if(dbot.db.quoteArrs.hasOwnProperty(data.user.toLowerCase())) { - dbot.say(data.channel, data.user + ': ' + dbot.db.quoteArrs[data.user.toLowerCase()].random()); + dbot.say(data.channel, data.user + ': ' + dbot.interpolatedQuote(data.user.toLowerCase())); } else if(dbot.instance.inChannel(data.channel)) { dbot.instance.say('aisbot', '.karma ' + data.user); dbot.waitingForKarma = data.channel; diff --git a/modules/quotes.js b/modules/quotes.js index 03e62a7..340adf2 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -10,7 +10,7 @@ var quotes = function(dbot) { q[1] = q[1].trim(); key = q[1].toLowerCase(); if(quotes.hasOwnProperty(key)) { - dbot.say(data.channel, q[1] + ': ' + quotes[key].random()); + dbot.say(data.channel, q[1] + ': ' + dbot.interpolatedQuote(key)); } else { dbot.say(data.channel, 'Nobody loves ' + q[1]); } @@ -189,11 +189,11 @@ var quotes = function(dbot) { '~rq': function(data, params) { var rQuote = Object.keys(quotes).random(); - dbot.say(data.channel, rQuote + ': ' + quotes[rQuote].random()); + dbot.say(data.channel, rQuote + ': ' + dbot.interpolatedQuote(rQuote)); }, '~d': function(data, params) { - dbot.say(data.channel, data.user + ': ' + dbot.db.quoteArrs['depressionbot'].random()); + dbot.say(data.channel, data.user + ': ' + dbot.interpolatedQuote('depressionbot')); }, '~link': function(data, params) { diff --git a/run.js b/run.js index 4d683fc..1071f15 100644 --- a/run.js +++ b/run.js @@ -61,6 +61,22 @@ var DBot = function(timers) { this.instance.connect(); }; +// Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it +DBot.prototype.interpolatedQuote = function(key) { + var quoteString = this.db.quoteArrs[key].random(); + var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/); + if (quoteRefs) { + quoteRefs = quoteRefs.slice(1); + for(var i=0;i Date: Wed, 7 Mar 2012 23:18:19 +0000 Subject: [PATCH 07/66] Correct handling of modifiers, per golem --- modules/dice.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/dice.js b/modules/dice.js index d794e7b..f29c2f9 100644 --- a/modules/dice.js +++ b/modules/dice.js @@ -54,9 +54,9 @@ var dice = function(dbot) { if (diceSpec === false) { rolls.push([params[i], false]); } else { - rolls.push([normalizeDiceSpec(params[i]), []]); + rolls.push([normalizeDiceSpec(params[i]), [], diceSpec["modifier"]]); for (var j = 0; j < diceSpec["count"] ; j++) { - rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"]) + diceSpec["modifier"]); + rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"])); } } } @@ -66,7 +66,16 @@ var dice = function(dbot) { dbot.say(data.channel, rolls[i][0] + ": invalid dice spec"); } else { if (rolls[i][1].length > 1) { - var total = " (total " + rolls[i][1].sum() + ")"; + var total = " (total " + rolls[i][1].sum(); + if (rolls[i][2] != 0) { + if (rolls[i][2] > 0) { + total += " + "; + } else { + total += " - "; + } + total += Math.abs(rolls[i][2]) + " -> " + (rolls[i][1].sum() + rolls[i][2]); + } + total += ")" } else { var total = ""; } From 678a2ed9be200902b0d0a2964f6c6db9752c19b0 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Fri, 9 Mar 2012 21:44:05 +0000 Subject: [PATCH 08/66] admin 'act' command, and fix to action syntax. --- modules/admin.js | 16 +++++++++++++++- run.js | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/admin.js b/modules/admin.js index d1dfc26..a8a14cd 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -24,11 +24,25 @@ var adminCommands = function(dbot) { }, 'say': function(data, params) { - var c = params[1]; + if (params[1] === "@") { + var c = data.channel; + } else { + var c = params[1]; + } var m = params.slice(2).join(' '); dbot.say(c, m); }, + 'act': function(data, params) { + if (params[1] === "@") { + var c = data.channel; + } else { + var c = params[1]; + } + var m = params.slice(2).join(' '); + dbot.act(c, m); + }, + 'load': function(data, params) { dbot.moduleNames.push(params[1]); dbot.reloadModules(); diff --git a/run.js b/run.js index 1071f15..9f4a2eb 100644 --- a/run.js +++ b/run.js @@ -83,7 +83,7 @@ DBot.prototype.say = function(channel, data) { }; DBot.prototype.act = function(channel, data) { - this.instance.send('PRIVMSG', channel, ':\001ACTION' + data + '\001'); + this.instance.send('PRIVMSG', channel, ':\001ACTION ' + data + '\001'); } // Save the database file From d5296b0ea02c252f9129ede2948fcdeb48603063 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 14:38:47 +0000 Subject: [PATCH 09/66] Multiple admins supported --- modules/admin.js | 6 +++--- modules/drama.js | 4 ++-- modules/js.js | 2 +- modules/puns.js | 3 --- modules/quotes.js | 6 +++--- run.js | 2 +- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/modules/admin.js b/modules/admin.js index a8a14cd..70be12b 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -6,11 +6,11 @@ var adminCommands = function(dbot) { var commands = { 'join': function(data, params) { dbot.instance.join(params[1]); - dbot.say(dbot.admin, 'Joined ' + params[1]); + dbot.say(data.channel, 'Joined ' + params[1]); }, 'opme': function(data, params) { - dbot.instance.send('MODE ' + params[1] + ' +o ', dbot.admin); + dbot.instance.send('MODE ' + params[1] + ' +o ', data.user); }, 'part': function(data, params) { @@ -106,7 +106,7 @@ var adminCommands = function(dbot) { if(data.channel == dbot.name) data.channel = data.user; params = data.message.split(' '); - if(commands.hasOwnProperty(params[0]) && data.user == dbot.admin) { + if(commands.hasOwnProperty(params[0]) && dbot.admin.include(data.user)) { commands[params[0]](data, params); dbot.save(); } diff --git a/modules/drama.js b/modules/drama.js index c7d3daa..d68cca8 100644 --- a/modules/drama.js +++ b/modules/drama.js @@ -26,7 +26,7 @@ var drama = function(dbot) { var commands = { '~train': function(data, params) { - if(data.user == dbot.admin || data.user == 'golem' || data.user == 'Sam') { + if(dbot.admin.include(data.user)) { bayes.train(last[params[1]][params[2]], params[3]); dbot.say(data.channel, 'Last thing ' + params[2] + ' said in ' + params[1] + ' (' + last[params[1]][params[2]] + ') classified as \'' + params[3] + '\''); @@ -34,7 +34,7 @@ var drama = function(dbot) { }, '~rtrain': function(data, params) { - if(data.user == dbot.admin || data.user == 'golem' || data.user == 'Sam') { + if(dbot.admin.include(data.user)) { var category = params[1]; params.splice(0, 2); var msg = params.join(' '); diff --git a/modules/js.js b/modules/js.js index 9547c85..3a5ee5f 100644 --- a/modules/js.js +++ b/modules/js.js @@ -15,7 +15,7 @@ var js = function(dbot) { '~ajs': function(data, params) { var q = data.message.valMatch(/^~ajs (.*)/, 2); - if(data.user == dbot.admin) { + if(dbot.admin.include(data.user)) { dbot.say(data.channel, eval(q[1])); } } diff --git a/modules/puns.js b/modules/puns.js index 29b7ae9..8578129 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -7,9 +7,6 @@ var puns = function(dbot) { dbot.instance.say(data.channel, dbot.interpolatedQuote('realityonce')); } else if(dbot.db.quoteArrs.hasOwnProperty(data.user.toLowerCase())) { dbot.say(data.channel, data.user + ': ' + dbot.interpolatedQuote(data.user.toLowerCase())); - } else if(dbot.instance.inChannel(data.channel)) { - dbot.instance.say('aisbot', '.karma ' + data.user); - dbot.waitingForKarma = data.channel; } }, diff --git a/modules/quotes.js b/modules/quotes.js index 340adf2..912142e 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -65,13 +65,13 @@ var quotes = function(dbot) { }, '~rmlast': function(data, params) { - if(rmAllowed == true || data.user == dbot.admin) { + if(rmAllowed == true || dbot.admin.include(data.user)) { var q = data.message.valMatch(/^~rmlast ([\d\w\s-]*)/, 2); if(q) { q[1] = q[1].trim() key = q[1].toLowerCase(); if(quotes.hasOwnProperty(q[1])) { - if(!dbot.db.locks.include(q[1]) || data.user == dbot.admin) { + if(!dbot.db.locks.include(q[1]) || dbot.admin.include(data.user)) { var quote = quotes[key].pop(); if(quotes[key].length === 0) { delete quotes[key]; @@ -104,7 +104,7 @@ var quotes = function(dbot) { }, '~rm': function(data, params) { - if(rmAllowed == true || data.user == dbot.admin) { + if(rmAllowed == true || dbot.admin.include(data.user)) { var q = data.message.valMatch(/^~rm ([\d\w\s-]*) (.+)$/, 3); if(q) { if(quotes.hasOwnProperty(q[1])) { diff --git a/run.js b/run.js index 9f4a2eb..6fa1d1a 100644 --- a/run.js +++ b/run.js @@ -39,7 +39,7 @@ var DBot = function(timers) { // Populate bot properties with config data this.name = this.config.name || 'dbox'; - this.admin = this.config.admin || 'reality'; + this.admin = this.config.admin || [ 'reality' ]; this.password = this.config.password || 'lolturtles'; this.nickserv = this.config.nickserv || 'zippy'; this.server = this.config.server || 'elara.ivixor.net'; From 28f78373d855c923d8f807a8831ef0dd5d5714f1 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 14:56:06 +0000 Subject: [PATCH 10/66] dont print result of ajs if its undefined --- modules/js.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/js.js b/modules/js.js index 3a5ee5f..cf08699 100644 --- a/modules/js.js +++ b/modules/js.js @@ -15,8 +15,11 @@ var js = function(dbot) { '~ajs': function(data, params) { var q = data.message.valMatch(/^~ajs (.*)/, 2); - if(dbot.admin.include(data.user)) { - dbot.say(data.channel, eval(q[1])); + if(dbot.admin.include(data.user) ) { + var ret = eval(q[1]); + if(ret != undefined) { + dbot.say(data.channel, ret); + } } } }; From 34a642228dc36bc4b22d9282ad2e97eb37ce6991 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 15:28:42 +0000 Subject: [PATCH 11/66] command execution syntax is now in modules/command.js --- modules/command.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++ run.js | 47 +---------------------------------- 2 files changed, 62 insertions(+), 46 deletions(-) create mode 100644 modules/command.js diff --git a/modules/command.js b/modules/command.js new file mode 100644 index 0000000..7f27361 --- /dev/null +++ b/modules/command.js @@ -0,0 +1,61 @@ +// Module which handles the command execution syntax for DBot. Not much is going +// to work without this. +var command = function(dbot) { + var dbot = dbot; + + return { + 'listener': function(data) { + params = data.message.split(' '); + if(data.channel == dbot.name) data.channel = data.user; + + if(dbot.commands.hasOwnProperty(params[0])) { + if((dbot.db.bans.hasOwnProperty(params[0]) && + dbot.db.bans[params[0]].include(data.user)) || dbot.db.bans['*'].include(data.user)) + dbot.say(data.channel, data.user + + ' is banned from using this command. Commence incineration.'); + else { + dbot.commands[params[0]](data, params); + dbot.save(); + } + } else { + var q = data.message.valMatch(/^~([\d\w\s-]*)/, 2); + if(q) { + if(dbot.db.bans['*'].include(data.user)) { + dbot.say(data.channel, data.user + + ' is banned from using this command. Commence incineration.'); + } else { + q[1] = q[1].trim(); + key = dbot.cleanNick(q[1]) + if(dbot.db.quoteArrs.hasOwnProperty(key)) { + dbot.say(data.channel, q[1] + ': ' + dbot.interpolatedQuote(key)); + } else { + // See if it's similar to anything + var winnerDistance = Infinity; + var winner = false; + for(var commandName in dbot.commands) { + var distance = String.prototype.distance(params[0], commandName); + if(distance < winnerDistance) { + winner = commandName; + winnerDistance = distance; + } + } + + if(winnerDistance < 3) { + dbot.say(data.channel, 'Did you mean ' + winner + '? Learn to type, hippie!'); + } + } + } + } + } + }, + + 'on': 'PRIVMSG', + + 'requires': [ 'quotes' ] + }; +}; + +exports.fetch = function(dbot) { + return command(dbot); +}; + diff --git a/run.js b/run.js index 6fa1d1a..5bcd963 100644 --- a/run.js +++ b/run.js @@ -44,7 +44,7 @@ var DBot = function(timers) { this.nickserv = this.config.nickserv || 'zippy'; this.server = this.config.server || 'elara.ivixor.net'; this.port = this.config.port || 6667; - this.moduleNames = this.config.modules || [ 'js', 'admin', 'kick', 'modehate', 'quotes', 'puns', 'spelling', 'web', 'youare' ]; + this.moduleNames = this.config.modules || [ 'command', 'js', 'admin', 'kick', 'modehate', 'quotes', 'puns', 'spelling', 'web', 'youare' ]; this.timers = timers.create(); @@ -142,51 +142,6 @@ DBot.prototype.reloadModules = function() { return module; }.bind(this)); - - this.instance.addListener('PRIVMSG', function(data) { - params = data.message.split(' '); - if(data.channel == this.name) data.channel = data.user; - - if(this.commands.hasOwnProperty(params[0])) { - if((this.db.bans.hasOwnProperty(params[0]) && - this.db.bans[params[0]].include(data.user)) || this.db.bans['*'].include(data.user)) - this.say(data.channel, data.user + - ' is banned from using this command. Commence incineration.'); - else { - this.commands[params[0]](data, params); - this.save(); - } - } else { - var q = data.message.valMatch(/^~([\d\w\s-]*)/, 2); - if(q) { - if(this.db.bans['*'].include(data.user)) { - this.say(data.channel, data.user + - ' is banned from using this command. Commence incineration.'); - } else { - q[1] = q[1].trim(); - key = this.cleanNick(q[1]) - if(this.db.quoteArrs.hasOwnProperty(key)) { - this.say(data.channel, q[1] + ': ' + this.interpolatedQuote(key)); - } else { - // See if it's similar to anything - var winnerDistance = Infinity; - var winner = false; - for(var commandName in this.commands) { - var distance = String.prototype.distance(params[0], commandName); - if(distance < winnerDistance) { - winner = commandName; - winnerDistance = distance; - } - } - - if(winnerDistance < 3) { - this.say(data.channel, 'Did you mean ' + winner + '? Learn to type, hippie!'); - } - } - } - } - } - }.bind(this)); }; DBot.prototype.cleanNick = function(key) { From 4ea99c75660fb8739777a8128c65885c89557bcd Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Sat, 10 Mar 2012 15:30:15 +0000 Subject: [PATCH 12/66] Use bot's name when fetching ~d quotes, rather than hardcoding 'depressionbot'. --- modules/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes.js b/modules/quotes.js index 912142e..bb583db 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -193,7 +193,7 @@ var quotes = function(dbot) { }, '~d': function(data, params) { - dbot.say(data.channel, data.user + ': ' + dbot.interpolatedQuote('depressionbot')); + dbot.say(data.channel, data.user + ': ' + dbot.interpolatedQuote(dbot.name)); }, '~link': function(data, params) { From 6c337bf1a0a49a97ef11cd764135d46a3e399b07 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 15:32:44 +0000 Subject: [PATCH 13/66] actually screw it i'll do the requirements thing later --- modules/command.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/command.js b/modules/command.js index 7f27361..ed7451f 100644 --- a/modules/command.js +++ b/modules/command.js @@ -49,9 +49,7 @@ var command = function(dbot) { } }, - 'on': 'PRIVMSG', - - 'requires': [ 'quotes' ] + 'on': 'PRIVMSG' }; }; From c852a4ada86f208e22609e1b9aa04b490ebde25f Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Sat, 10 Mar 2012 17:35:50 +0000 Subject: [PATCH 14/66] Enforce command.js being loaded. Still reloadable, but can't be omitted. --- run.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/run.js b/run.js index 5bcd963..0390b3f 100644 --- a/run.js +++ b/run.js @@ -107,6 +107,11 @@ DBot.prototype.reloadModules = function() { this.timers.clearTimers(); this.save(); + // enforce having command. it can still be reloaded, but dbot _will not_ function without it, so not having it should be impossible + if(!this.moduleNames.include("command")) { + this.moduleNames.push("command"); + } + // Reload Javascript snippets var path = require.resolve('./snippets'); delete require.cache[path]; From a0158ceac4cf66fe66d770ebdaab44e192910acd Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Sat, 10 Mar 2012 17:48:49 +0000 Subject: [PATCH 15/66] Remove category when emptied by ~rm. --- modules/quotes.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/quotes.js b/modules/quotes.js index bb583db..fbb17ee 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -112,6 +112,9 @@ var quotes = function(dbot) { var index = quotes[q[1]].indexOf(q[2]); if(index != -1) { quotes[q[1]].splice(index, 1); + if(quotes[q[1]].length === 0) { + delete quotes[q[1]]; + } rmAllowed = false; dbot.say(data.channel, '\'' + q[2] + '\' removed from ' + q[1]); } else { From 59adda4221e2dd17fdf5957b4320b2b5b8e4200a Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 17:49:57 +0000 Subject: [PATCH 16/66] name in title instead of dbot --- modules/web.js | 8 ++++---- views/layout.jade | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/web.js b/modules/web.js index 2f7c1f0..b188487 100644 --- a/modules/web.js +++ b/modules/web.js @@ -18,23 +18,23 @@ var webInterface = function(dbot) { // Lists the quote categories app.get('/quotes', function(req, res) { - res.render('quotelist', { 'quotelist': Object.keys(dbot.db.quoteArrs) }); + res.render('quotelist', { 'name': dbot.name, 'quotelist': Object.keys(dbot.db.quoteArrs) }); }); // Lists quotes in a category app.get('/quotes/:key', function(req, res) { var key = req.params.key.toLowerCase(); if(dbot.db.quoteArrs.hasOwnProperty(key)) { - res.render('quotes', { 'quotes': dbot.db.quoteArrs[key], locals: { 'url_regex': RegExp.prototype.url_regex() } }); + res.render('quotes', { 'name': dbot.name, 'quotes': dbot.db.quoteArrs[key], locals: { 'url_regex': RegExp.prototype.url_regex() } }); } else { - res.render('error', { 'message': 'No quotes under that key.' }); + res.render('error', { 'name': dbot.name, 'message': 'No quotes under that key.' }); } }); // Load random quote category page app.get('/rq', function(req, res) { var rCategory = Object.keys(dbot.db.quoteArrs).random(); - res.render('quotes', { 'quotes': dbot.db.quoteArrs[rCategory], locals: { 'url_regex': RegExp.prototype.url_regex() } }); + res.render('quotes', { 'name': dbot.name, 'quotes': dbot.db.quoteArrs[rCategory], locals: { 'url_regex': RegExp.prototype.url_regex() } }); }); app.listen(443); diff --git a/views/layout.jade b/views/layout.jade index fe4fd48..9fd0226 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -3,7 +3,7 @@ html(lang='en') head meta(charset='utf-8') link(rel='stylesheet', type='text/css', href='/styles.css') - title Depressionbot web interface + title #{name} web interface body div#page div#title From c7fcb9fe1805c474eef8e64ee01713d389d3cff6 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 17:51:24 +0000 Subject: [PATCH 17/66] do that in heading instead of just title --- views/layout.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/layout.jade b/views/layout.jade index 9fd0226..be03d24 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -7,7 +7,7 @@ html(lang='en') body div#page div#title - a(href='/') Depressionbot web interface + a(href='/') #{name} web interface div#main !{body} script(type="text/javascript", src="/script.js") From d4320bbde78ccf179d21df42428144cf169f473b Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 17:56:38 +0000 Subject: [PATCH 18/66] greload command to git pull then reload --- modules/admin.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/admin.js b/modules/admin.js index 70be12b..6395fb5 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -1,4 +1,6 @@ var fs = require('fs'); +var sys = require('sys') +var exec = require('child_process').exec; var adminCommands = function(dbot) { var dbot = dbot; @@ -17,6 +19,15 @@ var adminCommands = function(dbot) { dbot.instance.part(params[1]); }, + // Do a git pull and reload + 'greload': function(data, params) { + var child; + + child = exec("cd ../ && git pull", function (error, stdout, stderr) { + commands.reload(data, params); + }.bind(this)); + }, + 'reload': function(data, params) { dbot.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); dbot.reloadModules(); From b3a6aa2322a27c05818b89b9cd225c092c1d52b5 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 17:57:34 +0000 Subject: [PATCH 19/66] test change for greload :| --- modules/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes.js b/modules/quotes.js index bb583db..5353fd8 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -12,7 +12,7 @@ var quotes = function(dbot) { if(quotes.hasOwnProperty(key)) { dbot.say(data.channel, q[1] + ': ' + dbot.interpolatedQuote(key)); } else { - dbot.say(data.channel, 'Nobody loves ' + q[1]); + dbot.say(data.channel, 'No one loves ' + q[1]); } } }, From ae28db6e702b0f5b8b96032693ce9aef3055c4ee Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 17:58:57 +0000 Subject: [PATCH 20/66] print output of greload --- modules/admin.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/admin.js b/modules/admin.js index 6395fb5..d7af0c8 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -24,6 +24,7 @@ var adminCommands = function(dbot) { var child; child = exec("cd ../ && git pull", function (error, stdout, stderr) { + console.log(stdout); commands.reload(data, params); }.bind(this)); }, From 90866a095d97abeb074cac5fa6322c61ae45ffd4 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 18:00:16 +0000 Subject: [PATCH 21/66] stderr? --- modules/admin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/admin.js b/modules/admin.js index d7af0c8..7ddc950 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -23,8 +23,8 @@ var adminCommands = function(dbot) { 'greload': function(data, params) { var child; - child = exec("cd ../ && git pull", function (error, stdout, stderr) { - console.log(stdout); + child = exec("git pull", function (error, stdout, stderr) { + console.log(stderr); commands.reload(data, params); }.bind(this)); }, From 62900670cb92e1f302a34e0a4ef55a0ff56309ed Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 18:02:03 +0000 Subject: [PATCH 22/66] nobody --- modules/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes.js b/modules/quotes.js index 5353fd8..bb583db 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -12,7 +12,7 @@ var quotes = function(dbot) { if(quotes.hasOwnProperty(key)) { dbot.say(data.channel, q[1] + ': ' + dbot.interpolatedQuote(key)); } else { - dbot.say(data.channel, 'No one loves ' + q[1]); + dbot.say(data.channel, 'Nobody loves ' + q[1]); } } }, From df33de486c3e42f2e57725a463df0e00f20258ed Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Sat, 10 Mar 2012 18:10:04 +0000 Subject: [PATCH 23/66] Pruning. --- modules/quotes.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/quotes.js b/modules/quotes.js index 491233c..73f681c 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -205,6 +205,23 @@ var quotes = function(dbot) { } else { dbot.say(data.channel, 'Link to "'+params[1]+'" - http://nc.no.de:443/quotes/'+params[1]); } + }, + + '~qprune': function(data) { + var pruned = [] + for(key in quotes) { + if(quotes.hasOwnProperty(key)) { + if(quotes[key].length == 0) { + delete quotes[key]; + pruned.push(key); + } + } + } + if(pruned.length > 0) { + dbot.say(data.channel, "Pruned empty quote categories: " + pruned.join(", ")); + } else { + dbot.say(data.channel, "No empty quote categories. You're good to go!"); + } } }; From bd85694018290e6b92a7433964ad94a8505793ec Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 18:13:00 +0000 Subject: [PATCH 24/66] we can't make him too friendly now can we --- modules/quotes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index dcc9a28..cedd678 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -218,9 +218,9 @@ var quotes = function(dbot) { } } if(pruned.length > 0) { - dbot.say(data.channel, "Pruned empty quote categories: " + pruned.join(", ")); + dbot.say(data.channel, "Pruning empty quote categories: " + pruned.join(", ")); } else { - dbot.say(data.channel, "No empty quote categories. You're good to go!"); + dbot.say(data.channel, "No empty quote categories. Commence incineration."); } } }; From f136636093d9f8964af19ba1228b4d33d2833988 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Sat, 10 Mar 2012 18:21:50 +0000 Subject: [PATCH 25/66] webPort config option, default 443 --- modules/web.js | 2 +- run.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/web.js b/modules/web.js index b188487..e3ac0fa 100644 --- a/modules/web.js +++ b/modules/web.js @@ -37,7 +37,7 @@ var webInterface = function(dbot) { res.render('quotes', { 'name': dbot.name, 'quotes': dbot.db.quoteArrs[rCategory], locals: { 'url_regex': RegExp.prototype.url_regex() } }); }); - app.listen(443); + app.listen(dbot.webPort); return { 'onDestroy': function() { diff --git a/run.js b/run.js index 0390b3f..be242b4 100644 --- a/run.js +++ b/run.js @@ -44,6 +44,7 @@ var DBot = function(timers) { this.nickserv = this.config.nickserv || 'zippy'; this.server = this.config.server || 'elara.ivixor.net'; this.port = this.config.port || 6667; + this.webPort = this.config.webPort || 443; this.moduleNames = this.config.modules || [ 'command', 'js', 'admin', 'kick', 'modehate', 'quotes', 'puns', 'spelling', 'web', 'youare' ]; this.timers = timers.create(); From 92767dbfb188b8af812fb8beac89567b5654031f Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Sat, 10 Mar 2012 18:38:56 +0000 Subject: [PATCH 26/66] Fail on invalid-syntax DBs, instead of replacing them. Also, shunt creation of 'realityonce' array to the realityonce listener, so it's not created before being needed. --- modules/quotes.js | 3 +++ run.js | 57 +++++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index cedd678..f08b3e1 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -247,6 +247,9 @@ var quotes = function(dbot) { dbot.db.bans['*'].include(data.user)) { dbot.say(data.channel, data.user + ' is banned from using this command. Commence incineration.'); } else { + if(!dbot.db.quoteArrs.hasOwnProperty('realityonce')) { + dbot.db.quoteArrs['realityonce'] = []; + } dbot.db.quoteArrs['realityonce'].push('reality ' + once[1] + '.'); addStack.push('realityonce'); rmAllowed = true; diff --git a/run.js b/run.js index be242b4..f9b5927 100644 --- a/run.js +++ b/run.js @@ -6,35 +6,38 @@ require('./snippets'); var DBot = function(timers) { // Load external files this.config = JSON.parse(fs.readFileSync('config.json', 'utf-8')); + this.db = null; + var rawDB; try { - this.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); + var rawDB = fs.readFileSync('db.json', 'utf-8'); } catch (e) { - this.db = {}; - } finally { /* fill any missing parts of the db; if this is a new DB, that's all of them */ - if(!this.db.hasOwnProperty("bans")) { - this.db.bans = {}; - } - if(!this.db.bans.hasOwnProperty("*")) { - this.db.bans["*"] = []; - } - if(!this.db.hasOwnProperty("quoteArrs")) { - this.db.quoteArrs = {}; - } - if(!this.db.quoteArrs.hasOwnProperty("realityonce")) { - this.db.quoteArrs.realityonce = []; - } - if(!this.db.hasOwnProperty("kicks")) { - this.db.kicks = {}; - } - if(!this.db.hasOwnProperty("kickers")) { - this.db.kickers = {}; - } - if(!this.db.hasOwnProperty("modehate")) { - this.db.modehate = []; - } - if(!this.db.hasOwnProperty("locks")) { - this.db.locks = []; - } + this.db = {}; /* if no db file, make empty one */ + } + if(!this.db) { /* if it wasn't empty */ + this.db = JSON.parse(rawDB); + } + + /* repair any deficiencies in the DB; if this is a new DB, that's everything */ + if(!this.db.hasOwnProperty("bans")) { + this.db.bans = {}; + } + if(!this.db.bans.hasOwnProperty("*")) { + this.db.bans["*"] = []; + } + if(!this.db.hasOwnProperty("quoteArrs")) { + this.db.quoteArrs = {}; + } + if(!this.db.hasOwnProperty("kicks")) { + this.db.kicks = {}; + } + if(!this.db.hasOwnProperty("kickers")) { + this.db.kickers = {}; + } + if(!this.db.hasOwnProperty("modehate")) { + this.db.modehate = []; + } + if(!this.db.hasOwnProperty("locks")) { + this.db.locks = []; } // Populate bot properties with config data From 5e02d154de506af7014316de86893bb1d015fa70 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:40:02 +0000 Subject: [PATCH 27/66] started writing documentation file --- README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..a69235d --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# Depressionbot IRC Bot + +## Introduction + +Depressionbot is an IRC bot which aims to be the fanciest IRC bot around - On +the general standard of software fanciness, dbot is rated as being '75% the same +as bathing in fine, fine grape juice.' + +Requirements: + - Node JS + - JSbot, the Javascript library I wrote to handle the IRC protocol and event + listeners etc. + - Various modules have their own requirements also. + +## Modules: + +### Quotes + +### Admin + +Various administration functionality such as banning users, hot-reloading the +code and ordering him to talk. Note that commands added here are handled with +their own listener, rather than being part of the command logic which is handled +by the Command module. + +### JS - Run Javascript code + +This module provides two commands which allow the execution of Javascript code. +For regular users, there is the *~js* command, which is completely sandboxed, +but can still be used for calculation and the like. + +Example: + > ~js Array(16).join('wat'-1) + " Batman!"; + 'NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!' + +This feature is fairly safe as the user doesn't have access to anything +dangerous, and is safe from infinite loops or locking DBot up because the code +which is run is killed if it does not finish within a short amount of time. + +For administrators, the incredibly useful *~ajs* command is also available. The +input for this command is simply 'eval'-ed and therefore has full access to +DBot's memory. Of course, this is incredibly unsafe, but I find it rather fun. +It's useful for administrative activity for which there isn't an in-built +command. For example, you could hot-add a new administrator like this: + + > ~ajs dbot.admin.push('batman'); + 2 + +You can also use this for debugging, or even adding new commands while DBot is +running. From 6c154869892ef842da02f888428268665a0776ee Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:40:46 +0000 Subject: [PATCH 28/66] format fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a69235d..76d2775 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ For regular users, there is the *~js* command, which is completely sandboxed, but can still be used for calculation and the like. Example: - > ~js Array(16).join('wat'-1) + " Batman!"; + ~js Array(16).join('wat'-1) + " Batman!"; 'NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!' This feature is fairly safe as the user doesn't have access to anything From 8a1047e42780f193900aad901012dac8a7bb07e6 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:41:19 +0000 Subject: [PATCH 29/66] format fix --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 76d2775..a5dbbf0 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,7 @@ This module provides two commands which allow the execution of Javascript code. For regular users, there is the *~js* command, which is completely sandboxed, but can still be used for calculation and the like. -Example: - ~js Array(16).join('wat'-1) + " Batman!"; + > ~js Array(16).join('wat'-1) + " Batman!"; 'NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!' This feature is fairly safe as the user doesn't have access to anything From b5b51c6828425f1793ae7f1cb12cf7bee6272b3c Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:45:08 +0000 Subject: [PATCH 30/66] additions to readme --- README.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a5dbbf0..be7b602 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,18 @@ Requirements: ### Quotes +This is the original reason that DBot was created. + +Commands: + - ~qadd category=newquote - Add a new quote to the database. + ### Admin Various administration functionality such as banning users, hot-reloading the code and ordering him to talk. Note that commands added here are handled with their own listener, rather than being part of the command logic which is handled -by the Command module. +by the Command module. Functionality in this module can be slightly unsafe as +not much error checking on the input is performed. ### JS - Run Javascript code @@ -38,9 +44,14 @@ which is run is killed if it does not finish within a short amount of time. For administrators, the incredibly useful *~ajs* command is also available. The input for this command is simply 'eval'-ed and therefore has full access to -DBot's memory. Of course, this is incredibly unsafe, but I find it rather fun. -It's useful for administrative activity for which there isn't an in-built -command. For example, you could hot-add a new administrator like this: +DBot's memory. Of course, this is incredibly unsafe, but I find it rather fun; +remember to only give extremely trusted friends administrator access to DBot, as +there's nothing to stop them wiping the database or something similar - if +you're worried about that kind of thing, do not load this module. + +However, it's useful for many things, such as administrative activity for +which there isn't a command in the admin module. For example, you could hot-add +a new administrator like this: > ~ajs dbot.admin.push('batman'); 2 From 3a55069cf1d9321e037962b541419ed4a01aa484 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:46:23 +0000 Subject: [PATCH 31/66] additions to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index be7b602..2cd0df5 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Requirements: This is the original reason that DBot was created. Commands: + - ~qadd category=newquote - Add a new quote to the database. ### Admin From 813488db5775fa71990f10c7c3882ebc9fb8df5b Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:46:51 +0000 Subject: [PATCH 32/66] additions to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2cd0df5..402b38b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This is the original reason that DBot was created. Commands: - - ~qadd category=newquote - Add a new quote to the database. +- ~qadd category=newquote - Add a new quote to the database. ### Admin From 90b95fae439451fdf60ca534f3259d75627513e7 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:53:11 +0000 Subject: [PATCH 33/66] quote command --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 402b38b..00c2a93 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,19 @@ This is the original reason that DBot was created. Commands: -- ~qadd category=newquote - Add a new quote to the database. +- _~q category_ - Display a random quote from a given category. +- _~qadd category=newquote_ - Add a new quote to the database. +- _~qstats_ - Show a list of the biggest quote categories. +- _~qsearch category needle_ - Search for a quote in a given category. +- _~rmlast [category]_ - Remove the last quote added to a given category, or the + last quote added. +- _~rm category quote_ - Remove a given quote from the given category. +- _~qcount category_ - Show the number of quotes stored in the given category. +- _~rq_ - Show a random quote from a random category. +- _~d_ - Show a quote from the category which matches the bot's name. +- _~link category_ - Create a link to the page on the web interface which displays the + given category's quotes. +- _~qprune_ - Delete empty quote categories. ### Admin From 4067368fba0f26f7fa8874948d9ab3a62c69f554 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 19:58:13 +0000 Subject: [PATCH 34/66] command docs --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 00c2a93..34163a4 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,22 @@ Requirements: ## Modules: +### Command + +This handles the command execution logic for DBot. + +1. Does the input match a command key in *dbot.commands* ? +2. Is there a quote category which matches the first part of the input + (*~category*)? +3. Is there a command name similar to to the first part of the input (*~name*) + in *dbot.commands*? + +This is the only module which is force loaded, even if it's not in the +configuration. + ### Quotes -This is the original reason that DBot was created. +This is the original reason that DBot was created, stores and displays quotes. Commands: @@ -34,6 +47,11 @@ Commands: given category's quotes. - _~qprune_ - Delete empty quote categories. +Unfortunately, this module is fairly highly coupled with certain other areas of +the program. I am working on this, but note, for example, that one can still +access quotes with the *~category* syntax even if the quotes module isn't +loaded. + ### Admin Various administration functionality such as banning users, hot-reloading the From c6d767ccdf5926a9ae3236fb1707e04d757cbd07 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 20:04:03 +0000 Subject: [PATCH 35/66] spelling docs --- README.md | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 34163a4..f524f16 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ the general standard of software fanciness, dbot is rated as being '75% the same as bathing in fine, fine grape juice.' Requirements: - - Node JS - - JSbot, the Javascript library I wrote to handle the IRC protocol and event - listeners etc. - - Various modules have their own requirements also. +- Node JS +- JSbot, the Javascript library I wrote to handle the IRC protocol and event + listeners etc. +- Various modules have their own requirements also. ## Modules: @@ -60,7 +60,28 @@ their own listener, rather than being part of the command logic which is handled by the Command module. Functionality in this module can be slightly unsafe as not much error checking on the input is performed. -### JS - Run Javascript code +TODO: Add summaries for each command in this module. + +### Spelling + +Will attempt to correct a users' spelling by using the levenshtein distance +algorithm. One corrects the spelling of their previous message by simply posting +a message with their correction and an asterisk: + + > user: I am a tutrle. + > user: *turtle + user meant: I am a turtle. + +The regular expression for this module also accepts two asterisks at the +beginning of the correction, or at the end, and also accepts several words as +corrections, and deals with these fairly intelligently. Users may also attempt +to correct another users like so: + + > userone: I am a tutrle. + > usertwo: userone: *turtle + > usertwo thinks userone meant: I am a turtle. + +### JS This module provides two commands which allow the execution of Javascript code. For regular users, there is the *~js* command, which is completely sandboxed, From 41763580af684247f87bed92b7d7e16609dc94ac Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 20:10:49 +0000 Subject: [PATCH 36/66] format requirements properly --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f524f16..6526788 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ the general standard of software fanciness, dbot is rated as being '75% the same as bathing in fine, fine grape juice.' Requirements: + - Node JS - JSbot, the Javascript library I wrote to handle the IRC protocol and event listeners etc. @@ -73,8 +74,8 @@ a message with their correction and an asterisk: user meant: I am a turtle. The regular expression for this module also accepts two asterisks at the -beginning of the correction, or at the end, and also accepts several words as -corrections, and deals with these fairly intelligently. Users may also attempt +beginning of the correction, or at the end; it also accepts several words as the +correction and deals with these fairly intelligently. Users may also attempt to correct another users like so: > userone: I am a tutrle. From 7f9eb8d0cf4c8f660b538488b2f3675019049bfd Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 20:12:21 +0000 Subject: [PATCH 37/66] link to jsbot --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6526788..50426be 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ as bathing in fine, fine grape juice.' Requirements: - Node JS -- JSbot, the Javascript library I wrote to handle the IRC protocol and event - listeners etc. +- [JSBot](http://github.com/reality/JSBot "JSBot"), the Javascript library I + wrote to handle the IRC protocol and event listeners etc. - Various modules have their own requirements also. ## Modules: From 6171e31a64054bf73a32e81748ebe17bc9a4be0d Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 20:14:47 +0000 Subject: [PATCH 38/66] disclaimer --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 50426be..4557dd7 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ Depressionbot is an IRC bot which aims to be the fanciest IRC bot around - On the general standard of software fanciness, dbot is rated as being '75% the same as bathing in fine, fine grape juice.' +Please note that this documentation is not complete, given I started it rather a +long time after I began development of the project. Please don't judge me too +harshly for this as I am, in fact, mildly allergic to writing documentation. + Requirements: - Node JS From 7e0d6b05cd83d5bf54523844355d581d97c0d64b Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 10 Mar 2012 20:15:13 +0000 Subject: [PATCH 39/66] disclaimer --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4557dd7..7383937 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,10 @@ Depressionbot is an IRC bot which aims to be the fanciest IRC bot around - On the general standard of software fanciness, dbot is rated as being '75% the same as bathing in fine, fine grape juice.' -Please note that this documentation is not complete, given I started it rather a -long time after I began development of the project. Please don't judge me too -harshly for this as I am, in fact, mildly allergic to writing documentation. +Please note that this documentation is not complete and is a work in progress, +given I started it rather a long time after I began development of the project. +Please don't judge me too harshly for this as I am, in fact, mildly allergic to +writing documentation. Requirements: From 94430e52a11272ca2f7be62717b87c82072c7b77 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Mon, 12 Mar 2012 13:07:24 +0000 Subject: [PATCH 40/66] sessionData hash for storage which should explicitly not survive beyond full restarts (as opposed to reloading modules). --- run.js | 1 + 1 file changed, 1 insertion(+) diff --git a/run.js b/run.js index f9b5927..9da733a 100644 --- a/run.js +++ b/run.js @@ -49,6 +49,7 @@ var DBot = function(timers) { this.port = this.config.port || 6667; this.webPort = this.config.webPort || 443; this.moduleNames = this.config.modules || [ 'command', 'js', 'admin', 'kick', 'modehate', 'quotes', 'puns', 'spelling', 'web', 'youare' ]; + this.sessionData = {}; this.timers = timers.create(); From 064d898f4a845b1ba10f665d7cba3c06cdac6ddc Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Mon, 12 Mar 2012 13:45:52 +0000 Subject: [PATCH 41/66] ~ignore command for, well, ignoring commands temporarily. Add a timer.js wrapper for setTimeout, too. --- modules/command.js | 44 +++++++++++++++++++++++++++++++++++++++++--- timer.js | 8 ++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/modules/command.js b/modules/command.js index ed7451f..434b2db 100644 --- a/modules/command.js +++ b/modules/command.js @@ -3,17 +3,55 @@ var command = function(dbot) { var dbot = dbot; + var ignoreCommands = function (data, params) { + if(data.channel == dbot.name) data.channel = data.user; + var targetCommand = params[1]; + var ignoreMins = parseFloat(params[2]); + + if(!dbot.sessionData.hasOwnProperty("ignoreCommands")) { + dbot.sessionData.ignoreCommands = {}; + } + if(!dbot.sessionData.ignoreCommands.hasOwnProperty(targetCommand)) { + dbot.sessionData.ignoreCommands[targetCommand] = []; + } + + if(dbot.sessionData.ignoreCommands[targetCommand].include(data.channel)) { + dbot.say(data.channel, "Already ignoring '" + targetCommand + "' in '" + data.channel + "'."); + } else { + dbot.sessionData.ignoreCommands[targetCommand].push(data.channel); + dbot.timers.addOnceTimer(ignoreMins * 60 * 1000, function() { + dbot.sessionData.ignoreCommands[targetCommand].splice(dbot.sessionData.ignoreCommands[targetCommand].indexOf(data.channel), 1); + dbot.say(data.channel, "No longer ignoring '" + targetCommand + "' in '" + data.channel + "'."); + }); + dbot.say(data.channel, "Ignoring '" + targetCommand + "' in '" + data.channel + "' for the next " + ignoreMins + " minute" + (ignoreMins == 1 ? "" : "s") + "."); + } + }; + return { + 'onLoad': function() { + return { + '~ignore': ignoreCommands + }; + }, 'listener': function(data) { params = data.message.split(' '); if(data.channel == dbot.name) data.channel = data.user; - if(dbot.commands.hasOwnProperty(params[0])) { + var ignoringCommand = false; + if(dbot.sessionData.hasOwnProperty("ignoreCommands")) { + if(dbot.sessionData.ignoreCommands.hasOwnProperty(params[0])) { + if(dbot.sessionData.ignoreCommands[params[0]].include(data.channel)) { + ignoringCommand = true; + } + } + } + + if(dbot.commands.hasOwnProperty(params[0]) && (!(ignoringCommand))) { if((dbot.db.bans.hasOwnProperty(params[0]) && - dbot.db.bans[params[0]].include(data.user)) || dbot.db.bans['*'].include(data.user)) + dbot.db.bans[params[0]].include(data.user)) || dbot.db.bans['*'].include(data.user)) { dbot.say(data.channel, data.user + ' is banned from using this command. Commence incineration.'); - else { + } else { dbot.commands[params[0]](data, params); dbot.save(); } diff --git a/timer.js b/timer.js index de260dd..7d494a6 100644 --- a/timer.js +++ b/timer.js @@ -1,15 +1,23 @@ var timers = function() { var timers = []; + var timeouts = []; return { 'addTimer': function(interval, callback) { // Because who puts the callback first. Really. timers.push(setInterval(callback, interval)); }, + + 'addOnceTimer': function(delay, callback) { // Because who seriously puts the callback first here too? + timeouts.push(setTimeout(callback, delay)); + }, 'clearTimers': function() { for(var i;i Date: Mon, 12 Mar 2012 13:49:55 +0000 Subject: [PATCH 42/66] Oops, stop falling out of the command logic when commands are ignored. --- modules/command.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/command.js b/modules/command.js index 434b2db..7c23cec 100644 --- a/modules/command.js +++ b/modules/command.js @@ -46,11 +46,13 @@ var command = function(dbot) { } } - if(dbot.commands.hasOwnProperty(params[0]) && (!(ignoringCommand))) { + if(dbot.commands.hasOwnProperty(params[0])) { if((dbot.db.bans.hasOwnProperty(params[0]) && dbot.db.bans[params[0]].include(data.user)) || dbot.db.bans['*'].include(data.user)) { dbot.say(data.channel, data.user + ' is banned from using this command. Commence incineration.'); + } else if(ignoringCommand) { + // do nothing, this stops us falling through to the non-command stuff } else { dbot.commands[params[0]](data, params); dbot.save(); From d5197fbcd6e8875eb3eb8e80b4bed16ea2c140b1 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 12 Mar 2012 21:00:17 +0000 Subject: [PATCH 43/66] Improved interpolatedQuote --- run.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run.js b/run.js index 0390b3f..8401192 100644 --- a/run.js +++ b/run.js @@ -64,8 +64,8 @@ var DBot = function(timers) { // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it DBot.prototype.interpolatedQuote = function(key) { var quoteString = this.db.quoteArrs[key].random(); - var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/); - if (quoteRefs) { + var quoteRefs; + while( (quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/)) ) { quoteRefs = quoteRefs.slice(1); for(var i=0;i Date: Mon, 12 Mar 2012 21:29:29 +0000 Subject: [PATCH 44/66] Made interpolateQuote recursive --- run.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/run.js b/run.js index 8401192..609b825 100644 --- a/run.js +++ b/run.js @@ -62,7 +62,9 @@ var DBot = function(timers) { }; // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it -DBot.prototype.interpolatedQuote = function(key) { +DBot.prototype.interpolatedQuote = function(key, quoteTree) { + if( quoteTree !== undefined && quoteTree.indexOf( key ) != -1 ) return ''; + else if( quoteTree === undefined ) quoteTree = []; var quoteString = this.db.quoteArrs[key].random(); var quoteRefs; while( (quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/)) ) { @@ -70,7 +72,10 @@ DBot.prototype.interpolatedQuote = function(key) { for(var i=0;i Date: Mon, 12 Mar 2012 21:38:09 +0000 Subject: [PATCH 45/66] Auto-embed youtube videos, in much the same way as images are already done. --- public/ytembed.js | 22 ++++++++++++++++++++++ views/quotes.jade | 14 +++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 public/ytembed.js diff --git a/public/ytembed.js b/public/ytembed.js new file mode 100644 index 0000000..b3b4ff3 --- /dev/null +++ b/public/ytembed.js @@ -0,0 +1,22 @@ +// let's fetch us some goddamn API +var apiEmbed = document.createElement('script'); +apiEmbed.src = 'http://www.youtube.com/player_api'; +document.getElementsByTagName('script')[0].parentNode.insertBefore(apiEmbed, document.getElementsByTagName('script')[0]); + +// this will be called by the player API when it's finished downloading +function onYouTubePlayerAPIReady() { + var youTubePlaceholders = document.getElementsByClassName('ytplaceholder'); + for(var i = 0; i < youTubePlaceholders.length; i++) { + var videoURL = youTubePlaceholders[i].innerText; + var videoIDMaybe = videoURL.match(/[?&]v=([A-Za-z0-9\-_]+)(?:[?&]|$)/); + youTubePlaceholders[i].innerText = ''; + if(videoIDMaybe) { + var ytVideoID = videoIDMaybe[1]; + var player = new YT.Player(youTubePlaceholders[i], { + height: '290', + width: '480', + videoId: ytVideoID + }); + } + } +} diff --git a/views/quotes.jade b/views/quotes.jade index 0010440..b0aedd5 100644 --- a/views/quotes.jade +++ b/views/quotes.jade @@ -1,11 +1,19 @@ ul#quotelist + -var hasYouTubeVids=false -each quote in quotes -if(quote.match(locals.url_regex)) li.quote - a(href=quote) - -if(quote.match(/(jpg|png|gif|jpeg|tiff)$/)) + -if(quote.match(/(jpg|png|gif|jpeg|tiff)$/)) + a(href=quote) img(src=quote) - -else + -else if(quote.match(/youtube.com\/watch/)) + -hasYouTubeVids = true + span(class='ytplaceholder') + =quote + -else + a(href=quote) =quote -else li.quote #{quote} + -if(hasYouTubeVids) + script(src='/ytembed.js') From 39f5bbdc8bc00929ce85bb0297ee78c2a7790b30 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Mon, 12 Mar 2012 21:57:55 +0000 Subject: [PATCH 46/66] Smaller videos don't needlessly overlap each other. --- public/ytembed.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/ytembed.js b/public/ytembed.js index b3b4ff3..28e23bf 100644 --- a/public/ytembed.js +++ b/public/ytembed.js @@ -13,8 +13,8 @@ function onYouTubePlayerAPIReady() { if(videoIDMaybe) { var ytVideoID = videoIDMaybe[1]; var player = new YT.Player(youTubePlaceholders[i], { - height: '290', - width: '480', + height: '203', + width: '336', videoId: ytVideoID }); } From bef96ebc519eaf6643481b4d14a019041f9ebdf1 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Mon, 12 Mar 2012 22:07:08 +0000 Subject: [PATCH 47/66] So apparently some people still use Firefox? --- public/ytembed.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/ytembed.js b/public/ytembed.js index 28e23bf..3a979b6 100644 --- a/public/ytembed.js +++ b/public/ytembed.js @@ -7,7 +7,7 @@ document.getElementsByTagName('script')[0].parentNode.insertBefore(apiEmbed, doc function onYouTubePlayerAPIReady() { var youTubePlaceholders = document.getElementsByClassName('ytplaceholder'); for(var i = 0; i < youTubePlaceholders.length; i++) { - var videoURL = youTubePlaceholders[i].innerText; + var videoURL = youTubePlaceholders[i].innerHTML; var videoIDMaybe = videoURL.match(/[?&]v=([A-Za-z0-9\-_]+)(?:[?&]|$)/); youTubePlaceholders[i].innerText = ''; if(videoIDMaybe) { From 9001cfefcf46bde609b5f25a52d254a28cc5b86b Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Tue, 13 Mar 2012 16:06:19 +0000 Subject: [PATCH 48/66] Fixed quotes --- run.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/run.js b/run.js index 609b825..1583aac 100644 --- a/run.js +++ b/run.js @@ -63,20 +63,17 @@ var DBot = function(timers) { // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it DBot.prototype.interpolatedQuote = function(key, quoteTree) { - if( quoteTree !== undefined && quoteTree.indexOf( key ) != -1 ) return ''; + if( quoteTree !== undefined && quoteTree.indexOf( key ) != -1 ) { console.log('nrll'); return ''; } else if( quoteTree === undefined ) quoteTree = []; var quoteString = this.db.quoteArrs[key].random(); - var quoteRefs; - while( (quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/)) ) { - quoteRefs = quoteRefs.slice(1); - for(var i=0;i Date: Wed, 14 Mar 2012 13:59:26 +0000 Subject: [PATCH 49/66] '~CATEGORY' now dispatches a '~q CATEGORY' command. --- modules/command.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/command.js b/modules/command.js index 7c23cec..df617bf 100644 --- a/modules/command.js +++ b/modules/command.js @@ -66,8 +66,14 @@ var command = function(dbot) { } else { q[1] = q[1].trim(); key = dbot.cleanNick(q[1]) - if(dbot.db.quoteArrs.hasOwnProperty(key)) { - dbot.say(data.channel, q[1] + ': ' + dbot.interpolatedQuote(key)); + if(dbot.db.quoteArrs.hasOwnProperty(key) && dbot.moduleNames.include('quotes')) { + var params = ['~q']; + key.split(' ').each((function(word) { + this.push(word); + }).bind(params)); + data.message = params.join(' '); + dbot.commands[params[0]](data, params); + dbot.save(); } else { // See if it's similar to anything var winnerDistance = Infinity; From a08e904ea674f40148a42ed5d6289479a9039609 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Wed, 14 Mar 2012 14:20:59 +0000 Subject: [PATCH 50/66] Puns also changed to dispatch a '~q' --- modules/puns.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/puns.js b/modules/puns.js index 8578129..2b591ed 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -3,10 +3,14 @@ var puns = function(dbot) { return { 'listener': function(data) { - if(data.user == 'reality') { - dbot.instance.say(data.channel, dbot.interpolatedQuote('realityonce')); - } else if(dbot.db.quoteArrs.hasOwnProperty(data.user.toLowerCase())) { - dbot.say(data.channel, data.user + ': ' + dbot.interpolatedQuote(data.user.toLowerCase())); + if(dbot.moduleNames.include('quotes')) { + if(data.user == 'reality') { + data.message = '~q realityonce'; + } else if(dbot.db.quoteArrs.hasOwnProperty(data.user.toLowerCase())) { + data.message = '~q ' + data.user.toLowerCase(); + } + var params = data.message.split(' '); + dbot.commands[params[0]](data, params); } }, From 155a2f2f84865149701cd1fa9db201614282cbc5 Mon Sep 17 00:00:00 2001 From: Psychedelic Squid Date: Wed, 14 Mar 2012 14:35:37 +0000 Subject: [PATCH 51/66] interpolatedQuote fully transplanted into quotes.js, should reduce pesky run.js reloading to near-zero --- modules/quotes.js | 24 +++++++++++++++++++++--- run.js | 18 ------------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index f08b3e1..d001260 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -2,6 +2,24 @@ var quotes = function(dbot) { var quotes = dbot.db.quoteArrs; var addStack = []; var rmAllowed = true; + + // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it + var interpolatedQuote = function(key, quoteTree) { + if( quoteTree !== undefined && quoteTree.indexOf( key ) != -1 ) { console.log('nrll'); return ''; } + else if( quoteTree === undefined ) quoteTree = []; + var quoteString = quotes[key].random(); + var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/g); + var thisRef; + while( quoteRefs && (thisRef = quoteRefs.shift()) !== undefined ) { + var cleanRef = dbot.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); + if (quotes.hasOwnProperty(cleanRef)) { + quoteTree.push( key ); + quoteString = quoteString.replace("~~"+cleanRef+"~~", interpolatedQuote(cleanRef, quoteTree.slice())); + quoteTree.pop(); + } + } + return quoteString; + }; var commands = { '~q': function(data, params) { @@ -10,7 +28,7 @@ var quotes = function(dbot) { q[1] = q[1].trim(); key = q[1].toLowerCase(); if(quotes.hasOwnProperty(key)) { - dbot.say(data.channel, q[1] + ': ' + dbot.interpolatedQuote(key)); + dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key)); } else { dbot.say(data.channel, 'Nobody loves ' + q[1]); } @@ -192,11 +210,11 @@ var quotes = function(dbot) { '~rq': function(data, params) { var rQuote = Object.keys(quotes).random(); - dbot.say(data.channel, rQuote + ': ' + dbot.interpolatedQuote(rQuote)); + dbot.say(data.channel, rQuote + ': ' + interpolatedQuote(rQuote)); }, '~d': function(data, params) { - dbot.say(data.channel, data.user + ': ' + dbot.interpolatedQuote(dbot.name)); + dbot.say(data.channel, data.user + ': ' + interpolatedQuote(dbot.name)); }, '~link': function(data, params) { diff --git a/run.js b/run.js index be13c93..bdb5e1b 100644 --- a/run.js +++ b/run.js @@ -66,24 +66,6 @@ var DBot = function(timers) { this.instance.connect(); }; -// Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it -DBot.prototype.interpolatedQuote = function(key, quoteTree) { - if( quoteTree !== undefined && quoteTree.indexOf( key ) != -1 ) { console.log('nrll'); return ''; } - else if( quoteTree === undefined ) quoteTree = []; - var quoteString = this.db.quoteArrs[key].random(); - var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/g); - var thisRef; - while( quoteRefs && (thisRef = quoteRefs.shift()) !== undefined ) { - var cleanRef = this.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); - if (this.db.quoteArrs.hasOwnProperty(cleanRef)) { - quoteTree.push( key ); - quoteString = quoteString.replace("~~"+cleanRef+"~~", this.interpolatedQuote(cleanRef, quoteTree.slice())); - quoteTree.pop(); - } - } - return quoteString; -}; - // Say something in a channel DBot.prototype.say = function(channel, data) { this.instance.say(channel, data); From 8f891835e4905332d7c9cca34f9e2be62220dd2e Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 14 Mar 2012 15:47:00 +0000 Subject: [PATCH 52/66] fix split on undefined message in puns --- modules/command.js | 2 +- modules/puns.js | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/command.js b/modules/command.js index df617bf..6f7f289 100644 --- a/modules/command.js +++ b/modules/command.js @@ -34,7 +34,7 @@ var command = function(dbot) { }; }, 'listener': function(data) { - params = data.message.split(' '); + var params = data.message.split(' '); if(data.channel == dbot.name) data.channel = data.user; var ignoringCommand = false; diff --git a/modules/puns.js b/modules/puns.js index 2b591ed..6f5357d 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -4,13 +4,11 @@ var puns = function(dbot) { return { 'listener': function(data) { if(dbot.moduleNames.include('quotes')) { - if(data.user == 'reality') { - data.message = '~q realityonce'; - } else if(dbot.db.quoteArrs.hasOwnProperty(data.user.toLowerCase())) { + if(dbot.db.quoteArrs.hasOwnProperty(data.user.toLowerCase())) { data.message = '~q ' + data.user.toLowerCase(); + var params = data.message.split(' '); + dbot.commands[params[0]](data, params); } - var params = data.message.split(' '); - dbot.commands[params[0]](data, params); } }, From 7a5a25134ef584578241874e9048abff1c515d57 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 14 Mar 2012 15:49:49 +0000 Subject: [PATCH 53/66] Why in blue shit was that in there? --- modules/modehate.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/modehate.js b/modules/modehate.js index 813a6ae..b769198 100644 --- a/modules/modehate.js +++ b/modules/modehate.js @@ -13,8 +13,6 @@ var modehate = function(dbot) { 'on': 'MODE' }; }; -~ajs dbot.instance.addListener('MODE', function(data) { if(data.channel == '#42' && data.raw[0].indexOf('Snow') != -1 && data.raw[0].indexOf('+o') != -1) { dbot.instance.send('MODE #42 -o Snow'); } } - exports.fetch = function(dbot) { return modehate(dbot); From 05fc0418d302388c28ca480606da6d15839e7744 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Thu, 15 Mar 2012 12:52:47 +0000 Subject: [PATCH 54/66] cleaned interpolatedquote so it fits with the coding style --- modules/quotes.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index d001260..e805ebd 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -5,19 +5,27 @@ var quotes = function(dbot) { // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it var interpolatedQuote = function(key, quoteTree) { - if( quoteTree !== undefined && quoteTree.indexOf( key ) != -1 ) { console.log('nrll'); return ''; } - else if( quoteTree === undefined ) quoteTree = []; + if(quoteTree !== undefined && quoteTree.indexOf(key) != -1) { + console.log('nrll'); + return ''; + } else if(quoteTree === undefined) { + quoteTree = []; + } + var quoteString = quotes[key].random(); var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/g); var thisRef; - while( quoteRefs && (thisRef = quoteRefs.shift()) !== undefined ) { + + while(quoteRefs && (thisRef = quoteRefs.shift()) !== undefined) { var cleanRef = dbot.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); if (quotes.hasOwnProperty(cleanRef)) { - quoteTree.push( key ); - quoteString = quoteString.replace("~~"+cleanRef+"~~", interpolatedQuote(cleanRef, quoteTree.slice())); + quoteTree.push(key); + quoteString = quoteString.replace("~~" + cleanRef + "~~", + interpolatedQuote(cleanRef, quoteTree.slice())); quoteTree.pop(); } } + return quoteString; }; From 12e62df84630bcf2ee7d2099c4c61385ec7f9a30 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Thu, 15 Mar 2012 12:57:54 +0000 Subject: [PATCH 55/66] Removed debugging console.logs --- modules/quotes.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index e805ebd..f4b1641 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -6,7 +6,6 @@ var quotes = function(dbot) { // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it var interpolatedQuote = function(key, quoteTree) { if(quoteTree !== undefined && quoteTree.indexOf(key) != -1) { - console.log('nrll'); return ''; } else if(quoteTree === undefined) { quoteTree = []; @@ -173,7 +172,6 @@ var quotes = function(dbot) { } else { // Give total quote count var totalQuoteCount = 0; for(var category in quotes) { - console.log('adding ' + category.length); totalQuoteCount += category.length; } dbot.say(data.channel, 'There are ' + totalQuoteCount + ' quotes in total.'); From 653264e46a11bce1664dee8197eff12e7a6837b9 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Thu, 15 Mar 2012 18:08:40 +0000 Subject: [PATCH 56/66] comment formatting --- run.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/run.js b/run.js index bdb5e1b..b8e8d74 100644 --- a/run.js +++ b/run.js @@ -11,13 +11,13 @@ var DBot = function(timers) { try { var rawDB = fs.readFileSync('db.json', 'utf-8'); } catch (e) { - this.db = {}; /* if no db file, make empty one */ + this.db = {}; // If no db file, make empty one } - if(!this.db) { /* if it wasn't empty */ + if(!this.db) { // If it wasn't empty this.db = JSON.parse(rawDB); } - /* repair any deficiencies in the DB; if this is a new DB, that's everything */ + // Repair any deficiencies in the DB; if this is a new DB, that's everything if(!this.db.hasOwnProperty("bans")) { this.db.bans = {}; } @@ -96,7 +96,8 @@ DBot.prototype.reloadModules = function() { this.timers.clearTimers(); this.save(); - // enforce having command. it can still be reloaded, but dbot _will not_ function without it, so not having it should be impossible + // Enforce having command. it can still be reloaded, but dbot _will not_ + // function without it, so not having it should be impossible if(!this.moduleNames.include("command")) { this.moduleNames.push("command"); } From de873c03029873f5fe6dd55ed0eada6d2c8e9bae Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:17:58 +0000 Subject: [PATCH 57/66] possibly ignore whitespace in qadd..? --- modules/admin.js | 1 + modules/quotes.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/admin.js b/modules/admin.js index 7ddc950..678e707 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -25,6 +25,7 @@ var adminCommands = function(dbot) { child = exec("git pull", function (error, stdout, stderr) { console.log(stderr); + dbot.say(data.channel, 'Git pulled that shit.'); commands.reload(data, params); }.bind(this)); }, diff --git a/modules/quotes.js b/modules/quotes.js index f4b1641..141e73f 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -179,7 +179,7 @@ var quotes = function(dbot) { }, '~qadd': function(data, params) { - var q = data.message.valMatch(/^~qadd ([\d\w\s-]*)=(.+)$/, 3); + var q = data.message.valMatch(/^~qadd ([\d\w\s-]*)\t?=\t?(.+)$/, 3); if(q) { key = q[1].toLowerCase(); if(!Object.isArray(quotes[key])) { From cb0bacfabd8f5a065a246038d3b16eeafc88ada0 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:20:21 +0000 Subject: [PATCH 58/66] possibly ignore whitespace in qadd..? --- modules/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes.js b/modules/quotes.js index 141e73f..2a16d9d 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -179,7 +179,7 @@ var quotes = function(dbot) { }, '~qadd': function(data, params) { - var q = data.message.valMatch(/^~qadd ([\d\w\s-]*)\t?=\t?(.+)$/, 3); + var q = data.message.valMatch(/^~qadd ([\d\w\s-]*)[ ]?=[ ]?(.+)$/, 3); if(q) { key = q[1].toLowerCase(); if(!Object.isArray(quotes[key])) { From 63039f4e2c66b47fac7b759e8926918e732abbaf Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:22:25 +0000 Subject: [PATCH 59/66] possibly ignore whitespace in qadd..? --- modules/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes.js b/modules/quotes.js index 2a16d9d..e33b425 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -179,7 +179,7 @@ var quotes = function(dbot) { }, '~qadd': function(data, params) { - var q = data.message.valMatch(/^~qadd ([\d\w\s-]*)[ ]?=[ ]?(.+)$/, 3); + var q = data.message.valMatch(/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3); if(q) { key = q[1].toLowerCase(); if(!Object.isArray(quotes[key])) { From 77cc1ddafd287c47d3e6a4981ce9b3712356442a Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:38:03 +0000 Subject: [PATCH 60/66] quote parameters --- modules/quotes.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index e33b425..5ae7e4c 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -4,7 +4,7 @@ var quotes = function(dbot) { var rmAllowed = true; // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it - var interpolatedQuote = function(key, quoteTree) { + var interpolatedQuote = function(key, quoteTree, params) { if(quoteTree !== undefined && quoteTree.indexOf(key) != -1) { return ''; } else if(quoteTree === undefined) { @@ -12,6 +12,8 @@ var quotes = function(dbot) { } var quoteString = quotes[key].random(); + + // Parse quote interpolations var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/g); var thisRef; @@ -25,9 +27,19 @@ var quotes = function(dbot) { } } + // Parse quote parameters + var paramRefs = quoteString.match(/~~\$([1-9])~~/g); + var thisParam; + + while(paramRefs && (thisParam = paramRefs.shift()) !== undefined) { + if(thisParam < params.length) { + quoteString = quoteString.replace("~~$" + + "~~", params[thisParam]); + } + } + return quoteString; }; - + var commands = { '~q': function(data, params) { var q = data.message.valMatch(/^~q ([\d\w\s-]*)/, 2); From e6b50b248d0e7b681c7bd2fefece63d0066d90d9 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:42:15 +0000 Subject: [PATCH 61/66] need to call interpolated quote with params --- modules/quotes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index 5ae7e4c..387787b 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -47,7 +47,7 @@ var quotes = function(dbot) { q[1] = q[1].trim(); key = q[1].toLowerCase(); if(quotes.hasOwnProperty(key)) { - dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key)); + dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key, params)); } else { dbot.say(data.channel, 'Nobody loves ' + q[1]); } @@ -228,11 +228,11 @@ var quotes = function(dbot) { '~rq': function(data, params) { var rQuote = Object.keys(quotes).random(); - dbot.say(data.channel, rQuote + ': ' + interpolatedQuote(rQuote)); + dbot.say(data.channel, rQuote + ': ' + interpolatedQuote(rQuote, params)); }, '~d': function(data, params) { - dbot.say(data.channel, data.user + ': ' + interpolatedQuote(dbot.name)); + dbot.say(data.channel, data.user + ': ' + interpolatedQuote(dbot.name, params)); }, '~link': function(data, params) { From 64f4979a85a3910da92b861dde6faca38cb0a3d8 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:45:36 +0000 Subject: [PATCH 62/66] first reference --- modules/quotes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/quotes.js b/modules/quotes.js index 387787b..06c708b 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -32,6 +32,7 @@ var quotes = function(dbot) { var thisParam; while(paramRefs && (thisParam = paramRefs.shift()) !== undefined) { + thisParam = thisParam[1]; if(thisParam < params.length) { quoteString = quoteString.replace("~~$" + + "~~", params[thisParam]); } From e0e1d6100d17f44f93855b7161109550799696a1 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:47:06 +0000 Subject: [PATCH 63/66] first reference --- modules/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes.js b/modules/quotes.js index 06c708b..da57a11 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -34,7 +34,7 @@ var quotes = function(dbot) { while(paramRefs && (thisParam = paramRefs.shift()) !== undefined) { thisParam = thisParam[1]; if(thisParam < params.length) { - quoteString = quoteString.replace("~~$" + + "~~", params[thisParam]); + quoteString = quoteString.replace("~~$" + thisParam + "~~", params[thisParam]); } } From 309755ba5d3504dbd007809a2a853869c0e3654d Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:49:08 +0000 Subject: [PATCH 64/66] err debug --- modules/quotes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/quotes.js b/modules/quotes.js index da57a11..f65989b 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -33,6 +33,7 @@ var quotes = function(dbot) { while(paramRefs && (thisParam = paramRefs.shift()) !== undefined) { thisParam = thisParam[1]; + console.log(thisParam); if(thisParam < params.length) { quoteString = quoteString.replace("~~$" + thisParam + "~~", params[thisParam]); } From a6024c9b7d7f7e31f586324e4822e5025cac6b21 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:51:01 +0000 Subject: [PATCH 65/66] Oh shit, forgot that quote categories may be several words long. Removed parametisation until further thought takes place. --- modules/quotes.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/quotes.js b/modules/quotes.js index f65989b..75fe809 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -28,6 +28,7 @@ var quotes = function(dbot) { } // Parse quote parameters + /* var paramRefs = quoteString.match(/~~\$([1-9])~~/g); var thisParam; @@ -38,6 +39,7 @@ var quotes = function(dbot) { quoteString = quoteString.replace("~~$" + thisParam + "~~", params[thisParam]); } } + */ return quoteString; }; From eedbe1f2878bc557e8a6108c954c6f616761a634 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 17 Mar 2012 13:53:58 +0000 Subject: [PATCH 66/66] params argument was being passed as the quoteTree, breaking quotes FOREVER --- modules/quotes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index 75fe809..29c0a5e 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -4,7 +4,7 @@ var quotes = function(dbot) { var rmAllowed = true; // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it - var interpolatedQuote = function(key, quoteTree, params) { + var interpolatedQuote = function(key, quoteTree) { if(quoteTree !== undefined && quoteTree.indexOf(key) != -1) { return ''; } else if(quoteTree === undefined) { @@ -51,7 +51,7 @@ var quotes = function(dbot) { q[1] = q[1].trim(); key = q[1].toLowerCase(); if(quotes.hasOwnProperty(key)) { - dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key, params)); + dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key)); } else { dbot.say(data.channel, 'Nobody loves ' + q[1]); } @@ -232,11 +232,11 @@ var quotes = function(dbot) { '~rq': function(data, params) { var rQuote = Object.keys(quotes).random(); - dbot.say(data.channel, rQuote + ': ' + interpolatedQuote(rQuote, params)); + dbot.say(data.channel, rQuote + ': ' + interpolatedQuote(rQuote)); }, '~d': function(data, params) { - dbot.say(data.channel, data.user + ': ' + interpolatedQuote(dbot.name, params)); + dbot.say(data.channel, data.user + ': ' + interpolatedQuote(dbot.name)); }, '~link': function(data, params) {