switch to RcB2 build sys
[rofl0r-jsbot.git] / ircbot.js
blob00034c989373ce6eb0b4c95392311e1736ae1f60
1 /* this bot has some privileged commands. in order to authenticate to the bot,
2 send the command ",op" once you brought it online for the first time.
3 it will then write your hostmask into the json savefile and will from then
4 on only accept privileged commands from your hostmask.
5 note: that means you should use a registered account so your hostmask
6 is always the same. */
8 var botname = "";
9 var lastchan = "";
10 var connected = false;
11 var names;
13 var settings = (function() {
14 var tmp = readsettings() ||
15 '{"chans":{"#reaver":{"autojoin":true}},"doAuth":false,"nickservpass":"p4ssw0rd"}';
16 return JSON.parse(tmp);
17 })();
18 function part(chan) {send("PART " + chan);}
19 function join(chan) {send("JOIN " + chan);}
20 function init_chan_settings(chan) {
21 if(!(chan in settings.chans)) settings.chans[chan] = {};
23 function get_chan_setting(chan, setting) {
24 init_chan_settings(chan);
25 return settings.chans[chan][setting];
27 /* this function is the first function called after the bot is
28 * connected. use it to load settings, auth, join channels, etc */
29 function connect() {
30 connected = true;
31 for(var chan in settings.chans) {
32 if(get_chan_setting(chan, "autojoin")) join(chan);
36 function save_settings() {writesettings(JSON.stringify(settings, null, "\t"));}
38 function set_global(key, value) {
39 settings[key] = value;
40 save_settings();
42 function set_chan(chan, key, value) {
43 init_chan_settings(chan);
44 settings.chans[chan][key] = value;
45 save_settings();
48 function add_note(chan, mask, rcp, msg) {
49 init_chan_settings(chan);
50 if(!("notes" in settings.chans[chan]))
51 settings.chans[chan]["notes"] = [];
52 settings.chans[chan]["notes"].push(
53 {"sender":nick_from_mask(mask), "recipient": rcp, "message":msg});
54 save_settings();
55 return true;
57 function dispatch_note(chan, index) {
58 var note = settings.chans[chan]["notes"].splice(index,1)[0];
59 privmsg(chan, note.recipient + ": " + note.sender + " left the following note for you: " + note.message);
60 save_settings();
62 function check_notes(chan, usr) {
63 if("notes" in settings.chans[chan]) {
64 for (var i = 0; i < settings.chans[chan]["notes"].length;) {
65 var note = settings.chans[chan]["notes"][i];
66 if(note.recipient === usr) dispatch_note(chan, i);
67 else i++;
72 function botnick(nick) {
73 botname = nick;
75 function selfjoin(chan, nick) {
76 // privmsg(settings.master, "selfjoin chan " + chan + ", nick "+ nick);
77 botname = nick;
78 lastchan = chan;
79 if(get_chan_setting(chan, "dogreet")) privmsg(chan, "hi " + chan);
81 function has_status_sign(name) {
82 return (name.charAt(0) === '@' || name.charAt(0) === '+');
84 function nameshandler(chan, namelist) {
85 if(typeof names === 'undefined') names = {};
86 var nameblock = namelist.split(" ");
87 if(!(chan in names)) names[chan] = nameblock;
88 else names[chan] = names[chan].concat(nameblock);
90 // remove operator and voice signs
91 for(var i=0; i<names[chan].length;i++) {
92 if(has_status_sign(names[chan][i]))
93 names[chan][i] = names[chan][i].substring(1);
96 function add_name(chan, name) {
97 names[chan].push(name);
99 function remove_name(chan, name) {
100 for(var i = 0; i < names[chan].length; i++)
101 if(names[chan][i] === name) {
102 names[chan].splice(i,1);
103 return;
106 function change_name(chan, name, newname) {
107 for(var i = 0; i < names[chan].length; i++)
108 if(names[chan][i] === name) {
109 names[chan][i] = newname;
110 return;
113 function remove_name_global(name) {
114 for(var chan in names) {
115 remove_name(chan, name);
118 function nickchange(oldnick, newnick) {
119 //privmsg(settings.master, "nickchange " + oldnick + " -> " + newnick);
120 for(var chan in names) {
121 change_name(chan, oldnick, newnick);
124 function quithandler(nick, mask, msg) {
125 if(get_chan_setting(lastchan, "dogreet"))
126 privmsg(lastchan, "hmm. " + nick + " didn't like it here (" + msg + ")");
127 remove_name_global(nick);
129 function joinhandler(chan, nick, mask) {
130 lastchan = chan;
131 if(nick !== botname) {
132 if(get_chan_setting(chan, "dogreet"))
133 privmsg(chan, "Hello "+nick+". I am " + settings.master + "'s bot. If you want to talk to him, please be patient and wait here.");
134 add_name(chan, nick);
135 check_notes(chan, nick);
138 function parthandler(chan, nick, mask, msg) {
139 lastchan = chan;
140 if(get_chan_setting(chan, "dogreet"))
141 privmsg(chan, "oh, "+nick+" left :/ (reason: " + msg + ")");
142 remove_name(chan, nick);
144 function kickhandler(nick, mask, whom, chan, msg) {
145 privmsg(chan, "WOOT! " + nick + " kicked " + whom + "because of " + msg);
148 function nick_from_mask(mask) {
149 return(mask.substring(0, mask.indexOf('!')));
152 function hex2bin(input) {
153 var hextab = "0123456789abcdef";
154 var out = "";
155 for(var i = 0; i < input.length; i+=2) {
156 var h1 = hextab.indexOf(input.charAt(i));
157 var h2 = hextab.indexOf(input.charAt(i+1));
158 out = out + String.fromCharCode((h1 << 4) | h2);
160 return out;
163 function sanitize_value(v) {
164 if(v=== "false" || v === "0") return false;
165 if(v === "true" || v === "1") return true;
166 return v;
169 function runcmd(chan, mask, cmd, args) {
170 var isop = settings.opmask ? mask.match(RegExp(settings.opmask)) : false;
171 if(0) {
172 } else if(cmd === 'op' && !settings.opmask) {
173 var a = mask.split("!");
174 settings.opmask = ".*!" + a[1];
175 settings.master = a[0];
176 save_settings();
177 privmsg(chan, "opmask assigned");
178 } else if(cmd === "reload" && isop) {
179 if(!reload()) privmsg(chan, "oops. reload failed.");
180 else privmsg(chan, "reload OK.");
181 } else if(cmd === 'say') {
182 privmsg(chan, args);
183 } else if(cmd === 'nick') {
184 privmsg(chan, nick_from_mask(mask));
185 } else if(cmd === 'eval' && isop) {
186 privmsg(chan, eval(args));
187 } else if(cmd === 'disconnect' && isop) {
188 connected = false;
189 names = {};
190 disconnect();
191 } else if(cmd === 'join' && isop) {
192 join(args);
193 } else if(cmd == 'note' && isop) {
194 var x = args.indexOf(' ');
195 if(x === -1) {
196 privmsg(chan, "syntax: note recipient message");
197 return;
199 var rcp = args.substring(0,x);
200 var msg = args.substring(x+1);
201 if(add_note(chan, mask, rcp, msg))
202 privmsg(chan, "your note to " + rcp + " was saved, " + nick_from_mask(mask));
203 } else if((cmd == 'setg' || cmd == 'setc') && isop) {
204 var x = args.indexOf(' ');
205 if(x == -1) {
206 privmsg(chan, "invalid command");
207 return;
209 var k = args.substring(0,x);
210 var v = sanitize_value(args.substring(x+1));
211 if(cmd == 'setg') set_global(k,v);
212 else set_chan(chan, k, v);
213 } else if(cmd == 'leave' && isop) {
214 part(chan);
215 } else if(cmd == 'settings' && isop) {
216 privmsg(chan, JSON.stringify(settings));
217 } else if(cmd == 'hex' && isop) {
218 // attention, this can be abused to make the bot send raw commands
219 // for example with 0a51554954
220 privmsg(chan, hex2bin(args));
224 function noticehandler(dest, nick, mask, msg) {
225 /*ignore for now
226 if(connected && lastchan && dest.charAt(0) !== '*')
227 privmsg(master, nick + " noticed " + dest + " of " + msg);
231 function msghandler(chan, nick, mask, msg) {
232 lastchan = chan;
233 var query = false;
234 if(chan.charAt(0) !== '#') {
235 query = true;
236 botname = chan;
237 chan = nick;
239 if(nick == botname) return;
240 if(msg.charAt(0) == ',') {
241 var x = msg.indexOf(' ');
242 if(x == -1) x = msg.length;
243 var cmd = msg.substring(1,x);
244 var args = msg.substring(x+1);
245 runcmd(chan, mask, cmd, args);