From f38652f354219462de19406cec36426c5edc7f66 Mon Sep 17 00:00:00 2001 From: Ryan Drew Date: Thu, 18 Jun 2015 18:02:26 -0400 Subject: [PATCH 1/6] Basic irc join/part command. Admin check is not secure. --- borgil.js | 1 + bot/api.js | 15 +++++++++++++++ plugins/ircutil.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 plugins/ircutil.js diff --git a/borgil.js b/borgil.js index fbd5bd6..aaacbb5 100644 --- a/borgil.js +++ b/borgil.js @@ -13,4 +13,5 @@ borgil.use('sed'); borgil.use('url'); borgil.use('youtube'); borgil.use('eightball'); +borgil.use('ircutil'); diff --git a/bot/api.js b/bot/api.js index 04e298c..0b1efd4 100644 --- a/bot/api.js +++ b/bot/api.js @@ -94,6 +94,21 @@ API.prototype.say = function (network, target) { }; +API.prototype.join = function (network, channel) { + if (!this._bot.clients[network]) return; + + this._bot.clients[network].join(channel); +}; + + +API.prototype.part = function (network, channel) { + if (!this._bot.clients[network]) return; + + var msg = util.format.apply(null, Array.prototype.slice.call(arguments, 2)); + this._bot.clients[network].part(channel, msg); +}; + + // Add a line to the log API.prototype.log = function () { this._bot.log.info('%s:', this._plugin, util.format.apply(null, arguments)); diff --git a/plugins/ircutil.js b/plugins/ircutil.js new file mode 100644 index 0000000..9ebb192 --- /dev/null +++ b/plugins/ircutil.js @@ -0,0 +1,45 @@ +function checkForAdmin(nick, config) { + var admin = false; + var adminlist = config.get('admins'); + + for (i = 0; i < adminlist.length; i++) { + if (adminlist[i] === nick) { + admin = true; + break; + } + } + + return admin; +} + +module.exports = function (bot) { + + bot.addCommand('join', function (cmd) { + if (!checkForAdmin( cmd.nick, bot.config )) return bot.say(cmd.network, cmd.replyto, 'You\'re not my supervisor!'); + + var chan = cmd.args[0]; + var p = cmd.args[1]; + + if (!chan) return bot.say(cmd.network, cmd.replyto, 'Usage: .join '); + if (p) { chan += ' '; chan += p; } + bot.join(cmd.network, chan); + }); + + bot.addCommand('part', function (cmd) { + if (!checkForAdmin( cmd.nick, bot.config )) return bot.say(cmd.network, cmd.replyto, 'You\'re not my supervisor!'); + + var partmsg = cmd.args[0] || 'I\'ll show you.'; + + bot.part(cmd.network, cmd.replyto, partmsg); + }); + + bot.addCommand('disconnect', function (cmd) { + console.log(cmd); + }); + bot.addCommand('reconnect', function (cmd) { + }); + + bot.addCommand('getnick', function (cmd) { + + }); +}; From dda45e2486bc487d55e374aff2fbdee62db4c4e3 Mon Sep 17 00:00:00 2001 From: Ryan Drew Date: Thu, 18 Jun 2015 20:24:29 -0400 Subject: [PATCH 2/6] A more secure admin for OFTC.net, check if user is registered by cloaked host name. --- bot/api.js | 9 ++++++ plugins/ircutil.js | 70 +++++++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/bot/api.js b/bot/api.js index 0b1efd4..85b7ea4 100644 --- a/bot/api.js +++ b/bot/api.js @@ -94,6 +94,7 @@ API.prototype.say = function (network, target) { }; +// Join a channel API.prototype.join = function (network, channel) { if (!this._bot.clients[network]) return; @@ -101,6 +102,7 @@ API.prototype.join = function (network, channel) { }; +// Leave a channel API.prototype.part = function (network, channel) { if (!this._bot.clients[network]) return; @@ -109,6 +111,13 @@ API.prototype.part = function (network, channel) { }; +// Get whois info for a nickname +API.prototype.whois = function (network, nick, callback) { + if (!this._bot.clients[network]) return; + this._bot.clients[network].whois(nick, function (info) { callback(info); }); +}; + + // Add a line to the log API.prototype.log = function () { this._bot.log.info('%s:', this._plugin, util.format.apply(null, arguments)); diff --git a/plugins/ircutil.js b/plugins/ircutil.js index 9ebb192..caa7a44 100644 --- a/plugins/ircutil.js +++ b/plugins/ircutil.js @@ -1,45 +1,51 @@ -function checkForAdmin(nick, config) { +// Callback function (admin) {} +function checkForAdmin(nick, network, bot, callback) { var admin = false; - var adminlist = config.get('admins'); + var adminlist = bot.config.get('admins'); + var registered = false; - for (i = 0; i < adminlist.length; i++) { - if (adminlist[i] === nick) { - admin = true; - break; + bot.whois(network, nick, function (info) { + if (network === "oftc") { + var oftcre = /.*\.oftc\.net$/ + registered = oftcre.test(info.host); } - } - - return admin; + if (registered) { + for (i = 0; i < adminlist.length; i++) { + if (adminlist[i] === nick) { + admin = true; + break; + } + } + } + callback(admin); + }); } module.exports = function (bot) { bot.addCommand('join', function (cmd) { - if (!checkForAdmin( cmd.nick, bot.config )) return bot.say(cmd.network, cmd.replyto, 'You\'re not my supervisor!'); - - var chan = cmd.args[0]; - var p = cmd.args[1]; - - if (!chan) return bot.say(cmd.network, cmd.replyto, 'Usage: .join '); - if (p) { chan += ' '; chan += p; } - bot.join(cmd.network, chan); + checkForAdmin(cmd.nick, cmd.network, bot, function (admin) { + if (admin) { + var chan = cmd.args[0]; + var p = cmd.args[1]; + + if (!chan) return bot.say(cmd.network, cmd.replyto, 'Usage: .join '); + if (p) { chan += ' '; chan += p; } + bot.join(cmd.network, chan); + } else { + bot.say(cmd.network, cmd.replyto, 'You\'re not my supervisor!'); + } + }); }); bot.addCommand('part', function (cmd) { - if (!checkForAdmin( cmd.nick, bot.config )) return bot.say(cmd.network, cmd.replyto, 'You\'re not my supervisor!'); - - var partmsg = cmd.args[0] || 'I\'ll show you.'; - - bot.part(cmd.network, cmd.replyto, partmsg); - }); - - bot.addCommand('disconnect', function (cmd) { - console.log(cmd); - }); - bot.addCommand('reconnect', function (cmd) { - }); - - bot.addCommand('getnick', function (cmd) { - + checkForAdmin(cmd.nick, cmd.network, bot, function (admin) { + if (admin) { + var partmsg = cmd.args[0] || 'I\'ll show you.'; + bot.part(cmd.network, cmd.replyto, partmsg); + } else { + bot.say(cmd.network, cmd.replyto, 'You\'re not my supervisor!'); + } + }); }); }; From 5592c0a9de4940716baa82a5a4536480dd14776e Mon Sep 17 00:00:00 2001 From: Ryan Drew Date: Fri, 19 Jun 2015 23:36:43 -0400 Subject: [PATCH 3/6] Making a huge mess, almost sort of working again. --- borgil.js | 5 +++-- bot/api.js | 34 +++++++++++++++++++++++++++------- bot/bot.js | 16 ++++++++++++++++ plugins/eightball.js | 1 + plugins/ircutil.js | 5 +++-- plugins/plugin-manager.js | 25 +++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 plugins/plugin-manager.js diff --git a/borgil.js b/borgil.js index aaacbb5..34807f9 100644 --- a/borgil.js +++ b/borgil.js @@ -12,6 +12,7 @@ borgil.use('rss'); borgil.use('sed'); borgil.use('url'); borgil.use('youtube'); -borgil.use('eightball'); -borgil.use('ircutil'); +//borgil.use('eightball'); +//borgil.use('ircutil'); +borgil.use('plugin-manager'); diff --git a/bot/api.js b/bot/api.js index 85b7ea4..0b94f12 100644 --- a/bot/api.js +++ b/bot/api.js @@ -8,6 +8,9 @@ var API = module.exports = function (bot, plugin_name) { this.config = bot.config; this.memory = bot.memory; + //this.commands = []; + this.command_listeners = {}; + require('../plugins/' + plugin_name).call(this, this); }; @@ -64,13 +67,21 @@ API.prototype.addCommand = function (command, callback, ignorePrivate, ignorePub else if (ignorePublic) type = 'pm'; if (!command) return; - var commands = [].concat(command).filter(function (cmd) { - return typeof cmd == 'string' && cmd; - }); - - this._bot.addListener(type, function (client, nick, target, text, msg) { +// console.log("&&"); +// console.log(command); +// api.commands = api.commands.concat(command); +// api.commands = [].concat(command).filter(function (cmd) { +// return typeof cmd == 'string' && cmd; +// }); + +// console.log("**"); +// console.log(api.commands); + + api.command_listeners[command] = function (client, nick, target, text, msg) { var match = api.matchCommand(text); - if (match && commands.indexOf(match[1]) > -1) { + if (!match[1]) return; + if (match && api.command_listeners[match[1]]) { + console.log('ping'); callPlugin(api, callback, { network: client.__network, nick: nick, @@ -81,7 +92,16 @@ API.prototype.addCommand = function (command, callback, ignorePrivate, ignorePub args: (match[2] || '').split(/\s+/) }); } - }); + }; + + this._bot.addListener(type, api.command_listeners[command]); +}; + + +// Remove a command listener. +API.prototype.removeCommand = function (command, plugin_name) { + var type = 'message'; + this._bot.removeListener(type, this._bot.plugins[plugin_name].command_listeners[command]); }; diff --git a/bot/bot.js b/bot/bot.js index 5f168c4..342d079 100644 --- a/bot/bot.js +++ b/bot/bot.js @@ -7,6 +7,7 @@ var API = require('./api'); var Bot = module.exports = function (configfile) { this.clients = {}; this.plugins = {}; +// this.command_listeners = {}; this.memory = {}; // run the event emitter constructor @@ -27,3 +28,18 @@ util.inherits(Bot, EventEmitter); Bot.prototype.use = function (plugin_name) { this.plugins[plugin_name] = new API(this, plugin_name); }; + +// cut a plugin from the herd, leave it for dead +Bot.prototype.unlinkPlugin = function (plugin_name) { + if (this.plugins[plugin_name]) { + // get list of commands in plugin + // then remove their listeners + var i; + for (i = 0; i < this.plugins[plugin_name].commands.length; i++) { + var cmd = this.plugins[plugin_name].commands[i]; + this.plugins[plugin_name].removeCommand(cmd, plugin_name); + } + + this.plugins[plugin_name] = null; + } +}; diff --git a/plugins/eightball.js b/plugins/eightball.js index f497cb2..82950c3 100644 --- a/plugins/eightball.js +++ b/plugins/eightball.js @@ -1,5 +1,6 @@ var fs = require('fs'); + module.exports = function (bot) { var resps = []; diff --git a/plugins/ircutil.js b/plugins/ircutil.js index caa7a44..27c161d 100644 --- a/plugins/ircutil.js +++ b/plugins/ircutil.js @@ -22,12 +22,13 @@ function checkForAdmin(nick, network, bot, callback) { } module.exports = function (bot) { - + console.log("--"); bot.addCommand('join', function (cmd) { checkForAdmin(cmd.nick, cmd.network, bot, function (admin) { if (admin) { var chan = cmd.args[0]; var p = cmd.args[1]; + console.log("------"); if (!chan) return bot.say(cmd.network, cmd.replyto, 'Usage: .join '); if (p) { chan += ' '; chan += p; } @@ -37,7 +38,7 @@ module.exports = function (bot) { } }); }); - + console.log('=='); bot.addCommand('part', function (cmd) { checkForAdmin(cmd.nick, cmd.network, bot, function (admin) { if (admin) { diff --git a/plugins/plugin-manager.js b/plugins/plugin-manager.js new file mode 100644 index 0000000..b0848dd --- /dev/null +++ b/plugins/plugin-manager.js @@ -0,0 +1,25 @@ +module.exports = function (bot) { + bot.addCommand('plugin', function (cmd) { + var usage = "Usage: .plugin {load | unload | reload} "; + + if (!(cmd.args[0] && cmd.args[1])) { + bot.say(cmd.network, cmd.replyto, usage); + return; + } + + switch (cmd.args[0]) { + case 'unload': + bot._bot.unlinkPlugin(cmd.args[1]); + break; + case 'load': + bot._bot.use(cmd.args[1]); + break; + case 'reload': + bot._bot.unlinkPlugin(cmd.args[1]); + bot._bot.use(cmd.args[1]); + break; + default: + bot.say(cmd.network, cmd.replyto, usage); + } + }); +}; From aa2c4d494492ea844a07c0b313100fb0385116e9 Mon Sep 17 00:00:00 2001 From: Ryan Drew Date: Sat, 20 Jun 2015 15:54:29 -0400 Subject: [PATCH 4/6] Enable repl with bot object in context. --- borgil.js | 3 ++- bot/api.js | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/borgil.js b/borgil.js index 34807f9..a95b118 100644 --- a/borgil.js +++ b/borgil.js @@ -1,7 +1,8 @@ var Bot = require('./bot/bot'); - +var repl = require('repl'); var borgil = new Bot('config.json'); +repl.start('Borgil> ').context.bot = borgil; //borgil.use('echo'); //borgil.use('errortest'); diff --git a/bot/api.js b/bot/api.js index 0b94f12..3802775 100644 --- a/bot/api.js +++ b/bot/api.js @@ -79,9 +79,8 @@ API.prototype.addCommand = function (command, callback, ignorePrivate, ignorePub api.command_listeners[command] = function (client, nick, target, text, msg) { var match = api.matchCommand(text); - if (!match[1]) return; + if (typeof match !== 'object') return; if (match && api.command_listeners[match[1]]) { - console.log('ping'); callPlugin(api, callback, { network: client.__network, nick: nick, From 89f72612bb68f51e0edcca63b47a7a3cdacd6061 Mon Sep 17 00:00:00 2001 From: Ryan Drew Date: Sat, 20 Jun 2015 16:29:42 -0400 Subject: [PATCH 5/6] Working plugin/command load and unload. So far. --- bot/api.js | 12 +----------- bot/bot.js | 6 ++---- plugins/ircutil.js | 4 +--- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/bot/api.js b/bot/api.js index 3802775..b8b7dee 100644 --- a/bot/api.js +++ b/bot/api.js @@ -7,8 +7,7 @@ var API = module.exports = function (bot, plugin_name) { this.config = bot.config; this.memory = bot.memory; - - //this.commands = []; +; this.command_listeners = {}; require('../plugins/' + plugin_name).call(this, this); @@ -67,15 +66,6 @@ API.prototype.addCommand = function (command, callback, ignorePrivate, ignorePub else if (ignorePublic) type = 'pm'; if (!command) return; -// console.log("&&"); -// console.log(command); -// api.commands = api.commands.concat(command); -// api.commands = [].concat(command).filter(function (cmd) { -// return typeof cmd == 'string' && cmd; -// }); - -// console.log("**"); -// console.log(api.commands); api.command_listeners[command] = function (client, nick, target, text, msg) { var match = api.matchCommand(text); diff --git a/bot/bot.js b/bot/bot.js index 342d079..c2db76c 100644 --- a/bot/bot.js +++ b/bot/bot.js @@ -34,12 +34,10 @@ Bot.prototype.unlinkPlugin = function (plugin_name) { if (this.plugins[plugin_name]) { // get list of commands in plugin // then remove their listeners - var i; - for (i = 0; i < this.plugins[plugin_name].commands.length; i++) { - var cmd = this.plugins[plugin_name].commands[i]; + for (var cmd in this.plugins[plugin_name].command_listeners) { this.plugins[plugin_name].removeCommand(cmd, plugin_name); } - this.plugins[plugin_name] = null; + delete this.plugins[plugin_name]; } }; diff --git a/plugins/ircutil.js b/plugins/ircutil.js index 27c161d..e9988b9 100644 --- a/plugins/ircutil.js +++ b/plugins/ircutil.js @@ -22,13 +22,11 @@ function checkForAdmin(nick, network, bot, callback) { } module.exports = function (bot) { - console.log("--"); bot.addCommand('join', function (cmd) { checkForAdmin(cmd.nick, cmd.network, bot, function (admin) { if (admin) { var chan = cmd.args[0]; var p = cmd.args[1]; - console.log("------"); if (!chan) return bot.say(cmd.network, cmd.replyto, 'Usage: .join '); if (p) { chan += ' '; chan += p; } @@ -38,7 +36,7 @@ module.exports = function (bot) { } }); }); - console.log('=='); + bot.addCommand('part', function (cmd) { checkForAdmin(cmd.nick, cmd.network, bot, function (admin) { if (admin) { From 3d5a6d63114dc4ace1859620cc38040bb7efbc1f Mon Sep 17 00:00:00 2001 From: Ryan Drew Date: Sat, 20 Jun 2015 16:44:49 -0400 Subject: [PATCH 6/6] Plugin load/unload --- bot/bot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/bot.js b/bot/bot.js index c2db76c..92ca0de 100644 --- a/bot/bot.js +++ b/bot/bot.js @@ -7,7 +7,7 @@ var API = require('./api'); var Bot = module.exports = function (configfile) { this.clients = {}; this.plugins = {}; -// this.command_listeners = {}; + this.memory = {}; // run the event emitter constructor