Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixing admin plugin and adding allow/deny for chans/nicks

  • Loading branch information...
commit d4b4fe31d1ab82bf7630c24c1819b9ee7f41e52e 1 parent 819fbea
draggor draggor authored
9 example/bot.js
View
@@ -6,15 +6,16 @@ process.on('uncaughtException', function(err) {
console.log('Uncaught Exception: ' + err);
});
-b = new bot('irc.freenode.net', 'nodeboy1184-2', {
+b = new bot('irc.freenode.net', 'nodeboy1184', {
+ port: 6667,
userName: 'nodeboy',
realName: 'nodeboy',
-// debug: true,
+ debug: true,
secure: false,
- channels: ['#dracolair']
+ channels: ['#farkle', '#dracolair']
});
-b.loadPlugin('admin');
+b.loadPlugin('admin', {nick: ['draggor']});
//b.loadPlugin('dice');
var r = repl.start();
93 index.js
View
@@ -3,6 +3,16 @@ var irc = require('irc')
, util = require('./util')
;
+Array.prototype.has = function(item, c) {
+ c = c || function(a, b) { return a === b; };
+ for(var i = 0; i < this.length; i++) {
+ if(c(this[i], item)) {
+ return i;
+ }
+ }
+ return -1;
+};
+
function bot(server, nick, options) {
this.server = server;
this.nick = nick;
@@ -11,27 +21,87 @@ function bot(server, nick, options) {
this.throttle = options.throttle || 2000;
this.client = new irc.Client(server, nick, options);
this.say = util.throttle(irc.Client.prototype.say, this.throttle, this.client);
+ this.listeners = {};
}
function sanitize(str) {
return str.replace(/\.\.\//g, '');
}
-bot.prototype.modifyListeners = function(plugin, func) {
- var mod = func + 'Listener';
+bot.prototype.addListeners = function(plugin) {
+ var opt = plugin.options
+ , req = []
+ , reqf = function(listener) { return listener; }
+ ;
+ if(opt.chan) {
+ req.push(function(from, to, msg) {
+ return !!~opt.chan.indexOf(to.toLowerCase());
+ });
+ } else if (opt['!chan']) {
+ req.push(function(from, to, msg) {
+ return !~opt.chan.indexOf(to.toLowerCase());
+ });
+ }
+ if(opt.nick) {
+ req.push(function(from, to, msg) {
+ return !!~opt.nick.indexOf(from.toLowerCase());
+ });
+ } else if (opt['!nick']) {
+ req.push(function(from, to, msg) {
+ return !~opt.nick.indexOf(from.toLowerCase());
+ });
+ }
+ if(opt.chan || opt.nick) {
+ reqf = function(listener) {
+ return function(from, to, msg) {
+ if(!!~req.map(function(f) { return f(from, to, msg); }).indexOf(true)) {
+ listener(from, to, msg);
+ }
+ };
+ };
+ }
for(var i in plugin.listeners) {
var listener = plugin.listeners[i];
if(typeof listener === 'function') {
- this.modifyListener(i, listener, mod);
+ var f = reqf(listener);
+ this.listeners[opt.prefix + i] = f;
+ this.modifyListener(i, f, 'add');
} else {
for(var j in listener) {
- this.modifyListener(i, listener[j], mod);
+ var f = reqf(listener[j]);
+ this.listeners[opt.prefix + i] = this.listeners[opt.prefix + i] || [];
+ this.listeners[opt.prefix + i].push(f);
+ this.modifyListener(i, f, 'add');
}
}
}
};
+bot.prototype.removeListeners = function(plugin) {
+ for(var i in plugin.listeners) {
+ var listener = this.listeners[plugin.options.prefix + i];
+ if(typeof listener === 'function') {
+ this.modifyListener(i, listener, 'remove');
+ } else {
+ for(var j in listener) {
+ this.modifyListener(i, listener[j], 'remove');
+ }
+ }
+ delete this.listeners[plugin.options.prefix + i];
+ }
+
+}
+
+bot.prototype.chanListener = function(func) {
+ return function(from, to, msg) {
+ if(to[0] === '#' && to !== this.nick) {
+ func(from, to, msg);
+ }
+ };
+};
+
bot.prototype.modifyListener = function(name, func, mod) {
+ mod += 'Listener';
switch(name) {
case 'message':
this.client[mod]('message', func);
@@ -42,6 +112,15 @@ bot.prototype.modifyListener = function(name, func, mod) {
}
};
+bot.prototype.getPlugin = function(name) {
+ var cleanName = './plugins' + sanitize(name)
+ , full = require.resolve(cleanName)
+ , pl = require.cache[full]
+ ;
+
+ return pl;
+};
+
bot.prototype.loadPlugin = function(name, options) {
var cleanName = './plugins/' + sanitize(name)
, full = require.resolve(cleanName)
@@ -61,11 +140,12 @@ bot.prototype.loadPlugin = function(name, options) {
pl = require(full);
pl.options = options || {};
+ pl.options.prefix = name;
pl.bot = this;
this.plugins[cleanName] = pl;
- this.modifyListeners(pl, 'add');
+ this.addListeners(pl);
};
bot.prototype.unloadPlugin = function(name, options) {
@@ -74,9 +154,10 @@ bot.prototype.unloadPlugin = function(name, options) {
;
pl.options = options || {};
+ pl.options.prefix = name;
if(pl) {
- this.modifyListeners(pl, 'remove');
+ this.removeListeners(pl);
delete this.plugins[cleanName];
}
};
2  plugins/admin/cmd.js
View
@@ -10,7 +10,7 @@ exports.run = function(info) {
};
function listArgsCommand(func, info) {
- var sp = info.rest.split(' ')
+ var sp = info.rest.toLowerCase().split(' ')
, name = sp.shift()
, args = {}
;
157 plugins/farkle/index.js
View
@@ -3,9 +3,10 @@ var util = require('../../util');
Array.prototype.has = function(item) {
for(var i = 0; i < this.length; i++) {
if(this[i] === item) {
- return this[i];
+ return i;
}
}
+ return -1;
};
var games = {};
@@ -14,25 +15,35 @@ function Game(limit) {
this.limit = limit || 10000;
this.players = {};
this.order = [];
- this.state = ['join'];
+ this.state = ['join', 'start'];
this.lastRoll;
- this.runningTotal;
+ this.runningTotal = 0;
+ this.dice;
}
Game.prototype.shift = function() {
this.order.push(this.order.shift());
};
+Game.prototype.farkle = function() {
+ this.lastRoll = [];
+ this.runningTotal = 0;
+ this.dice = 0;
+ this.state = ['roll'];
+ this.shift();
+};
+
function Player(nick) {
this.nick = nick;
this.score = 0;
this.farkle = 0;
+ this.points = false;
}
function req(func) {
return function(info) {
- var game = games[info.from];
- if(game && game.state.has(info.cmdstr)) {
+ var game = games[info.to];
+ if(game && game.state.has(info.cmdstr) >= 0) {
func(info, game);
}
};
@@ -40,8 +51,8 @@ function req(func) {
function reqp(func) {
return function(info) {
- var game = games[info.from];
- if(game && game.state.has(info.cmdstr) && game.order[0] === info.from) {
+ var game = games[info.to];
+ if(game && game.state.has(info.cmdstr) >= 0 && game.order[0] === info.from) {
var player = game.players[game.order[0]];
func(info, game, player);
}
@@ -56,8 +67,8 @@ function parseLine(from, to, msg) {
to: to,
msg: msg,
cmdstr: sp[0].substr(1),
- rest: sp[1],
- bot: adminp.bot
+ rest: sp[1] ? sp[1].trim() : sp[1],
+ bot: farklep.bot
}
;
@@ -72,8 +83,8 @@ function runCmd(info) {
}
}
-function roll() {
- return [0,0,0,0,0,0].map(function() { return Math.floor(Math.random() * 6) + 1; });
+function roll(n) {
+ return [0,0,0,0,0,0].slice(6 - n).map(function() { return Math.floor(Math.random() * 6) + 1; });
}
function length(a) {
@@ -81,20 +92,35 @@ function length(a) {
}
function score(roll) {
- var sum = 0;
- var group = util.group(roll);
+ var sum = 0
+ , group = util.group(roll.slice().sort())
+ , hasZero = false;
if(group.length === 6) {
- return 1500;
+ return {
+ total: 1500,
+ hasZero: false
+ };
} else if(group.map(length).toString() === '2,2,2') {
- return 500;
+ return {
+ total: 500,
+ hasZero: false
+ };
}
var sr = group.map(scoreGroup);
for(var i = 0; i < sr.length; i++) {
- sum += sr[i]();
+ var gs = sr[i]();
+ if(gs == 0) {
+ hasZero = true;
+ } else {
+ sum += sr[i]();
+ }
}
- return sum;
+ return {
+ total: sum,
+ hasZero: hasZero
+ };
}
function zero () { return 0; }
@@ -129,14 +155,14 @@ function scoreGroup(group) {
var cmds = {
new: function(info) {
- if(!games[info.from]) {
- var g = games[info.from] = new Game(parseInt(info.rest));
+ if(!games[info.to]) {
+ var g = games[info.to] = new Game(parseInt(info.rest));
info.bot.say(info.to, 'New game started with limit ' + g.limit + '. Type !join to play!');
}
},
join: req(function(info, g) {
g.players[info.from] = new Player(info.from);
- g.order.push[info.from];
+ g.order.push(info.from);
info.bot.say(info.to, info.from + ' joined the game!');
}),
start: req(function(info, g) {
@@ -148,29 +174,97 @@ var cmds = {
info.bot.say(info.to, 'Game has started! ' + g.order[0] + ' is up first. You should !roll');
g.state = ['roll'];
}),
- info: req(function(info, g) {
- var p = game.players[info.rest];
- info.bot.say(info.to, p.nick + ': ' + p.score + ', ' + p.farkle + ' farkles');
- }),
+ info: function(info) {
+ var g = games[info.to];
+ if(g) {
+ var p = g.players[info.rest];
+ info.bot.say(info.to, p.nick + ': ' + p.score + ', ' + p.farkle + ' farkles');
+ }
+ },
roll: reqp(function(info, g, p) {
- // Roll stuff
+ var r = roll(6)
+ , s = score(r)
+ ;
+
+ info.bot.say(info.to, 'You rolled ' + r + '. !keep some dice');
+
+ if(s.total === 0) {
+ g.farkle();
+ if(++p.farkle >= 3) {
+ p.score -= 500;
+ info.bot.say(info.to, 'Six die farkle! Order is reversed! You lost 500 points!');
+ } else {
+ info.bot.say(info.to, 'Six die farkle! Order is reversed!');
+ }
+ info.bot.say(info.to, g.order[0] + ': You\'re up, !roll');
+ return;
+ }
+ g.lastRoll = r;
+ g.runningTotal = 0;
g.state = ['keep'];
}),
keep: reqp(function(info, g, p) {
- // Keep stuff
+ var ki = info.rest.split(' ').map(function(i) { return parseInt(i) - 1; })
+ , k = []
+ ;
+
+ for(var i = 0; i < ki.length; i++) {
+ k.push(g.lastRoll[ki[i]]);
+ }
+
+ var s = score(k);
+
+ if(s.hasZero) {
+ info.bot.say(info.to, 'You can only keep scoring dice!');
+ return;
+ }
+
+ g.runningTotal += s.total;
+ g.dice = g.lastRoll.length - k.length;
+ g.dice = g.dice === 0 ? 6 : g.dice;
g.state = ['ride', 'pass'];
+ info.bot.say(info.to, 'You kept ' + s.total + ' points. Your running total is ' + g.runningTotal + '. !ride or !pass');
}),
pass: reqp(function(info, g, p) {
+ if(!p.points && g.runningTotal < 750) {
+ info.bot.say(info.to, 'You need to break 750 first!');
+ return;
+ }
p.score += g.runningTotal;
p.farkle = 0;
-
+
g.shift();
- info.bot.say(info.to, info.from + ': The running total is ' + g.runningTotal + ' with ' + g.dice + ' dice. !roll or !ride');
+
+ // TODO: Change this so it turns cmds.pass into a special lastRound version
+ if(p.score >= g.limit && !g.lastRound) {
+ info.bot.say(info.to, p.nick + ' broke the limit with ' + p.score + '! One more round to go!'
+ g.lastRound = g.order.slice();
+ }
+
+ info.bot.say(info.to, g.order[0] + ': The running total is ' + g.runningTotal + ' with ' + g.dice + ' dice. !roll or !ride');
g.state = ['roll', 'ride'];
}),
ride: reqp(function(info, g, p) {
- // Ride stuff
- g.state = ['ride', 'pass'];
+ var r = roll(g.dice)
+ , s = score(r)
+ ;
+
+ info.bot.say(info.to, 'You rolled ' + r);
+
+ if(s.total === 0) {
+ g.farkle();
+ if(++p.farkle >= 3) {
+ p.score -= 500;
+ info.bot.say(info.to, 'Farkle! You lost 500 points!');
+ } else {
+ info.bot.say(info.to, 'Farkle!');
+ }
+ info.bot.say(info.to, g.order[0] + ': You\'re up, !roll');
+ return;
+ }
+
+ g.lastRoll = r;
+ g.state = ['keep'];
})
}
@@ -180,4 +274,5 @@ var farklep = {
}
};
-//module.exports = farklep;
+module.exports = farklep;
+module.exports.score = score;
35 plugins/farkle/test.js
View
@@ -0,0 +1,35 @@
+var farkle = require('./')
+ , repl = require('repl')
+ ;
+
+farkle.bot = {
+ say: function(to, msg) {
+ console.log(to + ': ' + msg);
+ }
+};
+
+var f = function(from, msg) {
+ farkle.listeners.message(from, '#chan', msg);
+}
+
+var tests = {
+ t1: function() {
+ f('neel', '!join');
+ },
+ t2: function() {
+ f('neel', '!new');
+ },
+ t3: function() {
+ f('neel', '!new');
+ f('neel', '!join');
+ f('bob', '!join');
+ f('neel', '!start');
+ }
+};
+
+module.exports = tests;
+
+r = repl.start();
+r.context.t = tests;
+r.context.f = f;
+r.context.farkle = farkle;
Please sign in to comment.
Something went wrong with that request. Please try again.