Skip to content
Snippets Groups Projects
Commit 0517b427 authored by cyan's avatar cyan
Browse files

* First revision of my JS IRC bot. Greatly customizable, check out

  load/ircbot_commands.js for an example of how to write your own bot commands.
parent 8417fbcc
No related branches found
No related tags found
No related merge requests found
;$Id$
command_prefix=bot
real_name=Synchronet IRC Bot
help_filename=ircbot_help.txt
config_write_delay=300
squelch_list=
[server_Synchronet]
;addresses=127.0.0.1
;nick=myIRCbot
;services_password=nothing
;channels=#synchronet,#bbs
;port=6667
[quotes]
1=<DigitalMan> I'm not sure why JS really needs all this fancy math shit.
2=<Cyan> "The box said 'Windows 95 or better required', therefore Linux was clearly a supported platform."
3=<pcm> I have a very hard time understanding you. Is english your native language? <kernel2> no <pcm> where are you from? <kernel2> Virginia
4=<Cyan> what bothers me more about TV is the high-pitched whine coming from the flyback transformer :P <Deuce> Uhhh... <Deuce> You sure that's not the power steering on your Ford?
5=ircd.txt: "This document is not a replacement for your brain."
6=<kernel2> For example mircosoft can not write software worth shit without releasing bugs in there programs, yahoo can not control there animals, hotmail.com is a joke because they are the second spammers in the us
7=<Vagabond> heh. Deuce only Codes. He does not make things Pretty.
// $Id$
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details:
http://www.gnu.org/licenses/gpl.txt
An IRC bot written in JS that interfaces with the local BBS.
Copyright 2010 Randolph E. Sommerfeld <sysop@rrx.ca>
*/
load("sockdefs.js");
load("sbbsdefs.js");
load("irclib.js");
load("load/ircbot_functions.js");
js.branch_limit=0; /* we're not an infinite loop. */
Module_Save_Data = new Object();
Bot_Commands = new Object();
Config_Last_Write = time(); /* Store when the config was last written. */
/* Global Arrays */
bot_servers = new Array();
masks = new Object();
quotes = new Array();
dcc_chats = new Array();
squelch_list = new Array();
var config_filename = "ircbot.ini";
for (cmdarg=0;cmdarg<argc;cmdarg++) {
switch(argv[cmdarg].toLowerCase()) {
case "-f":
config_filename = argv[++cmdarg];
break;
default:
break;
}
}
var config = new File(system.ctrl_dir + config_filename);
if (config.open("r")) {
/* Global Variables */
command_prefix = config.iniGetValue(null, "command_prefix");
real_name = config.iniGetValue(null, "real_name");
help_filename = config.iniGetValue(null, "help_filename");
help_file = new File(help_filename);
config_write_delay=parseInt(config.iniGetValue(null, "config_write_delay"));
// squelch_list = config.iniGetValue(null, "squelch_list").split(",");
/* Servers */
var ini_server_secs = config.iniGetSections("server_");
for (s in ini_server_secs) {
var mysec = ini_server_secs[s];
bot_servers.push(new Bot_IRC_Server(
0, /* Socket */
config.iniGetValue(mysec, "addresses"),
config.iniGetValue(mysec, "nick"),
config.iniGetValue(mysec, "services_password"),
config.iniGetValue(mysec, "channels"),
parseInt(config.iniGetValue(mysec, "port")),
mysec.slice(7) /* Network Name */
));
}
/* Quotes */
var ini_quotes = config.iniGetKeys("quotes");
for (q in ini_quotes) {
quotes.push(config.iniGetValue("quotes", ini_quotes[q]));
}
config.close();
} else {
exit("Couldn't open config file!");
}
var user_settings_files = directory("/home/bbs/data/user/*.ircbot.ini");
for (f in user_settings_files) {
var us_file = new File(user_settings_files[f]);
if (us_file.open("r")) {
var tokenized_path = user_settings_files[f].split("/");
var us_filename = tokenized_path[tokenized_path.length-1];
var uid_str = us_filename.split(".")[0];
while (uid_str[0] == "0") {
uid_str = uid_str.slice(1);
}
printf("***Reading: " + us_file.name + "\r\n");
var read_masks = us_file.iniGetValue(null, "masks");
if (read_masks)
masks[parseInt(uid_str)] = read_masks.split(",");
}
}
log("*** Entering Main Loop. ***");
function main() {
while (!js.terminated) {
for (my_srv in bot_servers) {
var cmdline;
var srv = bot_servers[my_srv];
if (!srv.sock &&(srv.lastcon <time())) { //we're not connected.
var consock = IRC_client_connect(srv.host, srv.nick,
command_prefix, real_name, srv.port);
if (consock) {
srv.sock = consock;
log("--- Connected to " + srv.host);
/* If we just connected, then clear all our joined channels. */
for (c in srv.channel) {
srv.channel[c].is_joined = false;
}
} else {
log("--- Connect to " + srv.host + " failed, "
+ "retry in 60 seconds.");
srv.lastcon = time() + 60;
}
} else if (srv.sock && srv.sock.data_waiting &&
(cmdline=srv.sock.recvline(4096,0))) {
var onick;
var ouh;
var outline;
var sorigin = cmdline.split(" ")[0].slice(1);
if ((cmdline[0] == ":") && sorigin.match(/[@]/)) {
onick = sorigin.split("!")[0];
ouh = sorigin.split("!")[1];
outline = "["+onick+"("+ouh+")] " + cmdline;
} else {
onick = "";
ouh = "";
outline = cmdline;
}
log("<-- " + srv.host + ": " + outline);
srv.server_command(IRC_parsecommand(cmdline),onick,ouh);
}
// Run through some commands.
if (srv.sock && srv.is_registered) {
for (c in srv.channel) {
if (!srv.channel[c].is_joined &&
(srv.channel[c].lastjoin < time())) {
srv.writeout("JOIN " + srv.channel[c].name);
srv.channel[c].lastjoin = time() + 60;
}
}
}
mswait(10); /* Don't peg the CPU */
}
if ( (time() - Config_Last_Write) > config_write_delay )
save_everything();
}
}
//////////////////// Objects and Functions ////////////////////
function Bot_IRC_Server(sock,host,nick,svspass,channels,port,name) {
// Static variables (never change)
this.sock = sock;
this.host = host;
this.nick = nick;
this.svspass = svspass;
this.port = port;
this.name = name;
// Channels
this.channel = new Array();
var my_channels = channels.split(",");
for (c in my_channels) {
log ("--- Adding Channel: " + my_channels[c]);
this.channel[my_channels[c].toUpperCase()] = new Bot_IRC_Channel(
my_channels[c]);
}
// Dynamic variables (used for the bot's state.
this.curnick = nick;
this.lastcon = 0; // When it's OK to reconnect.
this.is_registered = false;
this.juped = false;
this.users = new Object(); // Store local nicks & uh info.
// Functions
this.ctcp = Server_CTCP;
this.ctcp_reply = Server_CTCP_Reply;
this.o = Server_target_out;
this.writeout = Server_writeout;
this.server_command = Server_command;
this.check_bot_command = Server_check_bot_command;
this.bot_access = Server_Bot_Access;
}
function Bot_IRC_Channel(name) {
// Statics.
this.name = name;
// Dynamics.
this.is_joined = false;
this.lastjoin = 0;
// Functions.
}
function Server_User(uh) {
this.uh = uh;
this.ident = false;
}
function Bot_Command(min_security,args_needed,ident_needed) {
this.min_security = min_security;
this.args_needed = args_needed;
this.ident_needed = ident_needed;
this.command = false;
}
function DCC_Chat(sock,id) {
this.sock = sock;
this.id = id;
/* State info */
this.waiting_for_password = true;
/* Functions */
this.o = DCC_Out;
}
function DCC_Out(target,str) {
this.sock.write(str + "\r\n");
}
/* This must be at the very bottom. */
load("load/ircbot_commands.js");
//load("load/ircbot_functions.js");
//load("ircbot/fieldday.js");
main();
// $Id$
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details:
http://www.gnu.org/licenses/gpl.txt
Synchronet IRC Daemon as per RFC 1459, link compatible with Bahamut
Copyright 2010 Randolph Erwin Sommerfeld <sysop@rrx.ca>
An IRC bot written in JS that interfaces with the local BBS.
*/
Bot_Commands["RELOAD"] = new Bot_Command(50,false,false);
Bot_Commands["RELOAD"].usage =
"RELOAD";
Bot_Commands["RELOAD"].help =
"Reloads the internal bot command and function structure. No arguments.";
Bot_Commands["RELOAD"].command = function (target,onick,ouh,srv,lvl,cmd) {
load("load/ircbot_commands.js");
load("load/ircbot_functions.js");
srv.o(target,"Reloaded.");
return;
}
Bot_Commands["WHOIS"] = new Bot_Command(0,false,false);
Bot_Commands["WHOIS"].usage =
"WHOIS <nick>";
Bot_Commands["WHOIS"].help =
"Brings up information about a user. If the <nick> argument is omitted, "
+ "then it will display information about you.";
Bot_Commands["WHOIS"].command = function (target,onick,ouh,srv,lvl,cmd) {
if (!cmd[1]) {
srv.o(target,"You are recognized as access level " + lvl);
cmd[1] = onick;
}
var usr = new User(system.matchuser(cmd[1]));
if (usr.number > 0) {
srv.o(target,usr.alias+" has an access level of "
+usr.security.level+".");
if (masks[usr.number])
srv.o(target,"Masks: " + masks[usr.number].join(" "));
else
srv.o(target,usr.alias + " has no IRC masks defined.");
srv.o(target,usr.alias + " last signed on " + usr.laston_date + " via "
+ usr.connection + ".");
} else {
srv.o(target,"I have no such user in my database.");
}
return;
}
Bot_Commands["ADDMASK"] = new Bot_Command(50,1,false);
Bot_Commands["ADDMASK"].command = function (target,onick,ouh,srv,lvl,cmd) {
var addmask = false;
var delmask = false;
if (cmd[0] == "ADDMASK") {
addmask = true;
} else if (cmd[0] == "DELMASK") {
delmask = true;
}
if (!addmask && !delmask) {
srv.o(target,"Huh? I'm confused :(");
return;
}
if (!cmd[2]) {
cmd[2] = cmd[1];
cmd[1] = onick;
}
if (!cmd[2].match(/[@]/)) {
srv.o(target,"Typically, hostmasks need a '@' in them.");
return;
}
var usr = new User(system.matchuser(cmd[1]));
if (usr.number == 0) {
srv.o(target,"That user doesn't exist!");
return;
}
var self_change = (onick.toUpperCase() == cmd[1].toUpperCase());
if ( (lvl < 80) && !self_change) {
srv.o(target,"You do not have permission to change IRC masks "
+ "for other users.");
return;
}
if ((usr.security.level >= lvl) && !self_change) {
srv.o(target,"You cannot add or delete masks for a user whose "
+ "access level is equal to or greater than yours.");
return;
}
if (addmask) {
for (m in masks[usr.number]) {
if (wildmatch(cmd[2],masks[usr.number][m])) {
srv.o(target,"This user already has a mask matching that. "
+ "Try deleting it with 'DELMASK' first.");
return;
}
}
}
if (delmask) {
for (m in masks[usr.number]) {
if (masks[usr.number][m].toUpperCase() == cmd[2].toUpperCase()) {
masks[usr.number].splice(m,1);
srv.o(target,"Mask deleted for user " + usr.alias + ": "
+ cmd[2]);
return;
}
}
srv.o(target,"Couldn't find the mask you were looking for.");
} else if (addmask) {
if (!masks[usr.number])
masks[usr.number] = new Array();
masks[usr.number].push(cmd[2]);
srv.o(target,"Mask added for user " + usr.alias + ": " + cmd[2]);
}
return;
}
Bot_Commands["DELMASK"] = Bot_Commands["ADDMASK"];
Bot_Commands["ADDUSER"] = new Bot_Command(80,2,false);
Bot_Commands["ADDUSER"].command = function (target,onick,ouh,srv,lvl,cmd) {
if (IRC_check_nick(cmd[1],40)) {
srv.o(target,cmd[1] + " isn't a valid nickname.");
return;
}
var usr = cmd[1].toUpperCase();
var syncusr = new User(system.matchuser(cmd[1]));
if (!srv.users[usr] && !cmd[2]) {
srv.o(target,cmd[1] + " is not on any channels that I'm currently on. "
+ "To force an add for this user, please specify a mask.");
return;
} else if (syncusr.number > 0) {
srv.o(target,cmd[1] + " already exists in my database!");
return;
}
var mask;
var level = 50;
if (cmd[2] && cmd[2].match(/[.]/)) {//2nd arg is a mask
mask = cmd[2];
} else if (cmd[2]) { // must be a level.
if (!srv.users[usr] && !cmd[3]) {
srv.o(target,cmd[1] + " is not on any channels that I'm "
+ "currently on. To force an add for this user, please "
+ "specify a mask.");
return;
}
level = parseInt(cmd[2]);
if (level >= lvl) {
srv.o(target,"You may only add users with a lower access level "
+ "than your own.");
return;
}
}
if (cmd[3] && !mask)
mask = cmd[3];
// create a mask for this user.
if (!mask)
mask = IRC_create_default_mask(srv.users[usr].uh);
if (!mask && !level) {
srv.o(target,"Uh oh, something bogus happened. "
+ "Alert the bot owner. (!mask && !level)");
return;
}
var mask_array = mask.split(",");
var inval_mask = false;
for (my_mask in mask_array) {
if (IRC_check_host(mask_array[my_mask],true,true,false)) {
srv.o(target,"The mask (" + mask_array[my_mask] + ") is "
+ "invalid. No user added.");
inval_mask = true;
return;
}
}
if (inval_mask)
return;
srv.o(target,"Added " + cmd[1] + " as level " + level
+ " with mask(s): " + mask);
srv.o(target,"This user should now set a password with /MSG " + srv.nick
+ " PASS");
var newuser = system.new_user(cmd[1]);
masks[newuser.number] = mask_array;
login_user(newuser);
newuser.settings |= USER_INACTIVE;
newuser.security.level = level;
return;
}
Bot_Commands["CHANGE"] = new Bot_Command(80,2,false);
Bot_Commands["CHANGE"].command = function (target,onick,ouh,srv,lvl,cmd) {
var usr = new User(system.matchuser(cmd[1]));
if (usr.number == 0) {
srv.o(target,"The user " + cmd[1] + " doesn't exist in my database.");
return;
}
if (lvl <= usr.security.level) {
srv.o(target,"You can only use the change command on users with a "
+ "lower level than yours. (" + lvl + ") "
+ "This error message Copyright 2006 Deuce. ;)");
return;
}
if (parseInt(cmd[2]) >= lvl) {
srv.o(target,"You cannot change an access level to be higher or equal "
+ "to your own. (" + lvl + ")");
return;
}
srv.o(target,"Access level for " + usr.alias + " changed to "
+ parseInt(cmd[2]));
usr.security.level = parseInt(cmd[2]);
return;
}
Bot_Commands["RESETPASS"] = new Bot_Command(90,true,false);
Bot_Commands["RESETPASS"].command = function (target,onick,ouh,srv,lvl,cmd) {
var usr = new User(system.matchuser(cmd[1]));
if (usr.number > 0) {
srv.o(target,usr.alias + "'s password has been reset. "
+ "They should now set a new one with /MSG " + srv.nick + " "
+ "PASS <newpass>");
usr.security.password = "";
usr.settings |= USER_INACTIVE;
} else {
srv.o(target,cmd[1] + " doesn't exist in my database!");
}
return;
}
Bot_Commands["PASS"] = new Bot_Command(50,true,false);
Bot_Commands["PASS"].command = function (target,onick,ouh,srv,lvl,cmd) {
if ((target[0] == "#") || (target[0] == "&")) {
srv.o(target,"Fool! I'm not setting your password to something "
+ "you broadcast in a public channel. Pick a new password and "
+ "then /MSG " + srv.nick + " PASS <newpass>");
return;
}
var usr = new User(system.matchuser(onick));
if (usr.number == 0) {
srv.o(target,"Huh? You don't exist. Inform the bot owner (!usr)");
return;
}
if (usr.security.password != "") {
if (!cmd[2]) {
srv.o(target,"I need your old password too, bud. "
+ "/MSG " + srv.nick + " PASS <newpass> <oldpass>");
return;
}
if (cmd[2].toUpperCase() != usr.security.password) {
srv.o(target,"Password mismatch. /MSG " + srv.nick + " PASS "
+ "<newpass> <oldpass>");
return;
}
}
srv.o(target,"Your password has now been set to '" + cmd[1] + "', "
+"don't forget it!");
usr.security.password = cmd[1];
if (usr.settings&USER_INACTIVE)
usr.settings &= ~USER_INACTIVE;
return;
}
Bot_Commands["IDENT"] = new Bot_Command(0,true,false);
Bot_Commands["IDENT"].command = function (target,onick,ouh,srv,lvl,cmd) {
var usr = new User(system.matchuser(onick));
if (cmd[2]) { /* Username passed */
usr = new User(system.matchuser(cmd[1]));
cmd[1] = cmd[2];
}
if (!usr.number) {
srv.o(target,"No such user.");
return;
}
if ((target[0] == "#") || (target[0] == "&")) {
if (lvl >= 50) {
srv.o(target,"Fool! You've just broadcasted your password to "
+ "a public channel! Because of this, I've reset your "
+ "password. Pick a new password, then /MSG " + srv.nick + " "
+ "PASS <newpass>");
usr.security.password = "";
} else {
srv.o(target,"Is broadcasting a password to a public channel "
+ "really a smart idea?");
}
return;
}
if (usr.security.password == "") {
srv.o(target,"Your password is blank. Please set one with /MSG "
+ srv.nick + " PASS <newpass>, and then use IDENT.");
return;
}
if (cmd[1].toUpperCase() == usr.security.password) {
srv.o(target,"You are now recognized as user '" + usr.alias + "'");
srv.users[onick.toUpperCase()].ident = usr.number;
login_user(usr);
return;
}
srv.o(target,"Incorrect password.");
return;
}
Bot_Commands["EVAL"] = new Bot_Command(0,true,false);
Bot_Commands["EVAL"].command = function (target,onick,ouh,srv,lvl,cmd) {
cmd.shift();
var query = cmd.join(" ");
js.branch_limit=1000; // protection
js.branch_counter=0; // reset
try {
srv.o(target, strip_ctrl(js.eval(query)));
} catch(e) {
srv.o(target,"ERROR: "+e);
}
js.branch_limit=0; // protection off
return;
}
Bot_Commands["SEVAL"] = new Bot_Command(99,true,true);
Bot_Commands["SEVAL"].command = function (target,onick,ouh,srv,lvl,cmd) {
cmd.shift();
var query = cmd.join(" ");
try {
srv.o(target,eval(query));
} catch(e) {
srv.o(target,"ERROR: "+e);
}
return;
}
Bot_Commands["DIE"] = new Bot_Command(90,false,false);
Bot_Commands["DIE"].command = function (target,onick,ouh,srv,lvl,cmd) {
for (s in bot_servers) {
bot_servers[s].writeout("QUIT :" + onick + " told me to die.");
}
js.terminated=true;
return;
}
Bot_Commands["RESTART"] = new Bot_Command(90,false,false);
Bot_Commands["RESTART"].command = function (target,onick,ouh,srv,lvl,cmd) {
for (s in bot_servers) {
bot_servers[s].writeout("QUIT :Restarting as per " + onick);
}
exit();
return;
}
Bot_Commands["GROUPS"] = new Bot_Command(50,true,false);
Bot_Commands["GROUPS"].command = function (target,onick,ouh,srv,lvl,cmd) {
for (g in msg_area.grp_list) {
srv.o(target,"[" + msg_area.grp_list[g].number + "] "
+ msg_area.grp_list[g].description);
}
return;
}
/* HELP needs to be rewritten.
case "HELP":
if (!cmd[1])
cmd[1] = "HELP";
var search = "!" + cmd[1].toUpperCase();
if (help_file.open("r")) {
while (!help_file.eof) {
var hf_line = help_file.readln();
if (hf_line && (hf_line == search)) {
while (!hf_line[0] != "@") {
hf_line = help_file.readln();
if (hf_line[0] == "@") {
break;
} else if (hf_line[0] == "^") {
hf_line = parseInt(hf_line.slice(1));
if (bot_access(onick,ouh) < hf_line)
break;
} else if (hf_line[0] == ":") {
var str = hf_line.slice(1);
if (!str)
str = " ";
this.writeout("NOTICE "+onick+" :" + str);
}
}
if ((hf_line[0] == "@") && hf_line[1]) {
hf_line = hf_line.slice(1);
this.writeout("NOTICE "+onick+" :Restricted to access level " + hf_line);
}
help_file.close();
break;
}
}
}
break;
*/
Bot_Commands["SUBS"] = new Bot_Command(50,true,false);
Bot_Commands["SUBS"].command = function (target,onick,ouh,srv,lvl,cmd) {
var groupnum = parseInt(cmd[1]);
if (!msg_area.grp_list[groupnum]) {
srv.o(target,"Group number " + cmd[1] + " doesn't exist!");
return;
}
var sg = msg_area.grp_list[groupnum].sub_list;
for (g in msg_area.grp_list[groupnum].sub_list) {
srv.o(target,"[" + sg[g].number + "] " + sg[g].description
+ " (" + sg[g].code + ")");
}
return;
}
Bot_Commands["SUBGROUPS"] = Bot_Commands["SUBS"];
Bot_Commands["READ"] = new Bot_Command(50,true,false);
Bot_Commands["READ"].command = function (target,onick,ouh,srv,lvl,cmd) {
if (!cmd[2]) { // user wants to list msgs?
var msgs = new MsgBase(cmd[1]);
msgs.open();
srv.o(target,"There are " + msgs.total_msgs + " messages to read from "
+ msgs.first_msg + " to " + msgs.last_msg);
msgs.close();
return;
} else if (cmd[2]) { // reading a msg
var msgs = new MsgBase(cmd[1]);
var mn = parseInt(cmd[2]);
msgs.open();
var mh = msgs.get_msg_header(mn);
srv.o(target," To: " + mh.to);
srv.o(target,"From: " + mh.from);
srv.o(target,"Subj: " + mh.subject);
var my_msg = msgs.get_msg_body(mn).split("\r\n");
for (line in my_msg) {
if (!my_msg[line])
my_msg[line] = " ";
srv.o(target, my_msg[line]);
}
msgs.close();
return;
}
return;
}
Bot_Commands["FINGER"] = new Bot_Command(50,true,false);
Bot_Commands["FINGER"].command = function (target,onick,ouh,srv,lvl,cmd) {
var udpfinger = false;
if (cmd[0] == "UDPFINGER")
udpfinger = true;
var f_host;
var f_user;
if (cmd[1].match(/[@]/)) { // user@host
f_host = cmd[1].split("@")[1];
f_user = cmd[1].split("@")[0];
} else { // assume just host
f_host = cmd[1];
f_user = "";
}
var f_sock;
if (udpfinger) {
f_sock = new Socket(SOCK_DGRAM);
f_sock.nonblocking = true;
} else {
f_sock = new Socket();
}
if (!f_sock.connect(f_host,79)) {
srv.o(target,"Couldn't connect to "+ f_host +": " + f_sock.last_error);
return;
} else {
f_sock.send(f_user + "\r\n");
var f_line_count = 0;
var timeout = time()+10;
while(f_sock.is_connected) {
if (udpfinger) {
var tmp = f_sock.read();
if (tmp) {
var udp_lines = tmp.split("\r\n");
for (ul in udp_lines) {
srv.o(target, strip_ctrl(udp_lines[ul]));
f_line_count++;
if ((f_line_count > 10) && (lvl < 75) &&
((target[0] == "#") || (target[0] == "&")) ) {
srv.o(target,"*** Connection Terminated "
+ "(output squelched after 10 lines)");
return;
}
}
return;
}
} else {
srv.o(target, strip_ctrl(f_sock.readline()));
f_line_count++;
if ((f_line_count > 10) &&
(lvl < 75) &&
((target[0] == "#") ||
(target[0] == "&")) ) {
srv.o(target,"*** Connection Terminated "
+"(output squelched after 10 lines)");
return;
}
}
if (time() >= timeout) {
srv.o(target,"*** Your query timed out after 10 seconds.");
return;
}
}
f_sock.close();
}
return;
}
Bot_Commands["UDPFINGER"] = Bot_Commands["FINGER"];
Bot_Commands["ADDQUOTE"] = new Bot_Command(80,true,false);
Bot_Commands["ADDQUOTE"].command = function (target,onick,ouh,srv,lvl,cmd) {
cmd.shift();
var the_quote = cmd.join(" ");
quotes.push(the_quote);
srv.o(target,"Thanks for the quote!");
return;
}
Bot_Commands["GREET"] = new Bot_Command(50,false,false);
Bot_Commands["GREET"].command = function (target,onick,ouh,srv,lvl,cmd) {
var usr = new User(system.matchuser(onick));
if (!usr.number) {
srv.o(target,"You don't exist.");
return;
}
if (cmd[1]) {
if (cmd[1].toUpperCase() == "NULL")
cmd[1] = "";
cmd.shift();
var the_greet = cmd.join(" ");
srv.o(target,"Your greet has been changed.");
usr.comment = the_greet;
return;
} else {
srv.o(target,"[" + onick + "] " + usr.comment);
return;
}
return;
}
Bot_Commands["QUOTE"] = new Bot_Command(0,false,false);
Bot_Commands["QUOTE"].command = function (target,onick,ouh,srv,lvl,cmd) {
if (cmd[1]) {
cmd.shift();
var searched_quotes = new Array();
var search_params = cmd.join(" ");
var lucky_number;
var found_a_quote = false;
while (searched_quotes.length < quotes.length) {
lucky_number = random(quotes.length);
if (!searched_quotes[lucky_number]) {
if (quotes[lucky_number].toUpperCase().match(search_params.toUpperCase())) {
srv.o(target, quotes[lucky_number]);
found_a_quote = true;
break;
}
searched_quotes[lucky_number] = true;
}
}
if (!found_a_quote)
srv.o(target,"Couldn't find a quote that matches your criteria.");
return;
}
srv.o(target, quotes[random(quotes.length)]);
return;
}
Bot_Commands["SAVE"] = new Bot_Command(80,false,false);
Bot_Commands["SAVE"].command = function (target,onick,ouh,srv,lvl,cmd) {
if (save_everything()) {
srv.o(target,"Data successfully written. Congratulations.");
} else {
srv.o(target,"Oops, couldn't write to disk. Sorry, bud.");
}
return;
}
Bot_Commands["EXEC"] = new Bot_Command(99,true,true);
Bot_Commands["EXEC"].command = function (target,onick,ouh,srv,lvl,cmd) {
cmd.shift();
var query = cmd.join(" ");
var this_poutput = system.popen(query);
if (!this_poutput) {
srv.o(target,"Command failed. :(");
return;
}
for (line in this_poutput) {
if (!this_poutput[line])
this_poutput[line] = " ";
srv.o(target, this_poutput[line]);
}
return;
}
// $Id$
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details:
http://www.gnu.org/licenses/gpl.txt
Copyright 2010 Randolph E. Sommerfeld <sysop@rrx.ca>
*/
/********** Command Processors. **********/
function Server_command(cmd,onick,ouh) {
var cmdline = cmd.join(" ");
switch (cmd[0]) {
case "001": // "Welcome."
this.is_registered = true;
break;
case "352": // WHO reply. Process into local cache.
var nick = cmd[6].toUpperCase();
this.users[nick] = new Server_User(cmd[3] + "@" + cmd[4]);
break;
case "433": // Nick already in use.
this.juped = true;
var newnick = this.nick+"-"+random(50000).toString(36);
this.writeout("NICK " + newnick);
this.curnick = newnick;
log("*** Trying alternative nick, my nick is jupitered. "
+ "(Temp: " + newnick + ")");
break;
case "JOIN":
if (cmd[1][0] == ":")
cmd[1] = cmd[1].slice(1);
var chan = this.channel[cmd[1].toUpperCase()];
if ((onick == this.curnick) && chan && !chan.is_joined) {
chan.is_joined = true;
this.writeout("WHO " + cmd[1]);
break;
}
// Someone else joining.
this.users[onick.toUpperCase()] = new Server_User(ouh);
var lvl = this.bot_access(onick,ouh);
if (lvl >= 50) {
var usr = new User(system.matchuser(onick));
if (lvl >= 60)
this.writeout("MODE " + cmd[1] + " +o " + onick);
if (usr.number > 0) {
if (usr.comment)
this.o(cmd[1],"[" + onick + "] " + usr.comment);
login_user(usr);
}
}
break;
case "PRIVMSG":
if ((cmd[1][0] == "#") || (cmd[1][0] == "&")) {
var chan = this.channel[cmd[1].toUpperCase()];
if (!chan)
break;
if (!chan.is_joined)
break;
cmd[2] = cmd[2].slice(1);
if ( (cmd[2].toUpperCase() == command_prefix.toUpperCase())
&& cmd[3]) {
cmd[3] = cmd[3].toUpperCase();
cmd.shift();
cmd.shift();
cmd.shift();
this.check_bot_command(chan.name,onick,ouh,cmd);
break;
}
} else if (cmd[1].toUpperCase() ==
this.curnick.toUpperCase()) { // MSG?
cmd[2] = cmd[2].slice(1).toUpperCase();
cmd.shift();
cmd.shift();
if (cmd[0][0] == "\1") {
cmd[0] = cmd[0].slice(1).toUpperCase();
cmd[cmd.length-1] = cmd[cmd.length-1].slice(0,-1);
this.ctcp(onick,ouh,cmd);
break;
}
this.check_bot_command(onick,onick,ouh,cmd);
}
break;
case "PING":
this.writeout("PONG :" + IRC_string(cmdline));
break;
case "ERROR":
this.sock.close();
this.sock = 0;
break;
default:
break;
}
}
function Server_CTCP(onick,ouh,cmd) {
switch (cmd[0]) {
case "DCC":
if (cmd[4]) {
log("cmd1:" + cmd[1] + ":");
log("cmd2:" + cmd[2] + ":");
log("cmd3:" + cmd[3] + ":");
log("cmd4:" + cmd[4] + ":");
if ((cmd[1].toUpperCase() == "CHAT")
&& (cmd[2].toUpperCase() == "CHAT")
&& (parseInt(cmd[3]) == cmd[3])
&& (parseInt(cmd[4]) == cmd[4])) {
var ip = int_to_ip(cmd[3]);
var port = parseInt(cmd[4]);
var sock = new Socket();
sock.connect(ip, port, 3 /* Timeout */);
if (sock.is_connected) {
sock.write("Enter your password.\r\n");
dcc_chats.push(new DCC_Chat(sock,onick));
}
}
}
break;
case "PING":
var reply = "PING ";
if (parseInt(cmd[1]) == cmd[1]) {
reply += cmd[1];
if (cmd[2] && (parseInt(cmd[2]) == cmd[2]))
reply += " " + cmd[2];
this.ctcp_reply(onick, reply);
}
break;
case "VERSION":
this.ctcp_reply(onick, "VERSION "
+ "Synchronet IRC Bot by Randy E. Sommerfeld <cyan@rrx.ca>");
break;
case "FINGER":
this.ctcp_reply(onick, "FINGER "
+ "Finger message goes here.");
break;
default:
break;
}
return;
}
function Server_CTCP_Reply(nick,str) {
this.writeout("NOTICE " + nick + " :\1" + str + "\1");
}
function Server_check_bot_command(target,onick,ouh,cmd) {
var access_level = this.bot_access(onick,ouh);
var botcmd = Bot_Commands[cmd[0]];
if (botcmd) {
if (botcmd.ident_needed && !this.users[onick.toUpperCase()].ident) {
this.o(target,"You must be identified to use this command.");
return 0;
}
if (access_level < botcmd.min_security) {
this.o(target,"You do not have sufficient access to this command.");
return 0;
}
if ((botcmd.args_needed == true) && !cmd[1]) {
this.o(target,"Hey buddy, I need some arguments for this command.");
return 0;
} else if ((parseInt(botcmd.args_needed) == botcmd.args_needed)
&& !cmd[botcmd.args_needed]) {
this.o(target,"Hey buddy, incorrect number of arguments provided.");
return 0;
}
/* If we made it this far, we're good. */
botcmd.command(target,onick,ouh,this,access_level,cmd);
return 1;
}
return 0; /* No such command */
}
//////////////////// Non-object Functions ////////////////////
/* Save everything */
function save_everything() {
if (!config.open("r+"))
return false;
config.iniSetValue(null, "command_prefix", command_prefix);
config.iniSetValue(null, "real_name", real_name);
config.iniSetValue(null, "help_filename", help_filename);
config.iniSetValue(null, "config_write_delay", config_write_delay);
config.iniSetValue(null, "squelch_list", squelch_list.join(","));
for (m in masks) {
var uid_str = format("%04u", m);
var us_file = new File("/home/bbs/data/user/" +uid_str+ ".ircbot.ini");
if (us_file.open("r+")) {
us_file.iniSetValue(null, "masks", masks[m].join(","));
us_file.close();
}
}
for (q in quotes) {
config.iniSetValue("quotes", q, quotes[q]);
}
config.close();
for (s in Module_Save_Data) {
Module_Save_Data[s]();
}
Config_Last_Write = time();
return true;
}
function login_user(usr) {
usr.connection = "IRC";
usr.logontime = time();
}
// return the access level of this user.
function Server_Bot_Access(nick,uh) {
var ucnick = nick.toUpperCase();
if (this.users[ucnick].ident) {
var usrnum = this.users[ucnick].ident;
var thisuser = new User(usrnum);
return thisuser.security.level;
}
var usrnum = system.matchuser(nick);
if (!usrnum)
return 0;
var thisuser = new User(usrnum);
for (m in masks[usrnum]) {
if (wildmatch(uh,masks[usrnum][m]))
return thisuser.security.level;
}
return 0; // assume failure
}
function Server_writeout(str) {
log("--> " + this.host + ": " + str);
this.sock.write(str + "\r\n");
}
function Server_target_out(target,str) {
for (c in squelch_list) {
if (target.toUpperCase() == squelch_list[c].toUpperCase())
return;
}
var outstr = "PRIVMSG " + target + " :" + str;
log("--> " + this.host + ": " + outstr);
this.sock.write(outstr + "\r\n");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment