#!/usr/bin/perl $version = "DreamBot 0.0.1 - Experimental PerlBot by Spectre/fLare"; $config = "config"; $curserver=0; $curnick=0; $seenflag=false; $params=""; for ($i=0; $i<$#ARGV+1; $i++) { if ($ARGV[$i] eq "-h" || $ARGV[$i] eq "--help") { printf("$version\n"); printf("Usage: $0 \n\n"); printf(" -c --config use the file for configuration\n"); printf(" -d --datadir sets the datadir, default is set in config file\n"); printf(" -h --help help\n"); exit(0); } elsif ($ARGV[$i] eq "-c" || $ARGV[$i] eq "--config") { $i++; if ($ARGV[$i] ne "") { $config = $ARGV[$i]; $params .= " -c $config"; } else { printf("Usage:\n --config \n"); exit(0); } } elsif ($ARGV[$i] eq "-d" || $ARGV[$i] eq "--datadir") { $i++; if ($ARGV[$i] ne "") { $datadir = $ARGV[$i]; $params .= " -d $datadir"; } else { printf("Usage:\n --datadir \n"); exit(0); } } } if (open(FILE,"/tmp/dreambot.pid")) { # $pid = ; close(FILE); exit(0); } else { open(FILE,">/tmp/dreambot.pid"); printf FILE "$$\n"; close(FILE); } do "$config"; $SIG{KILL}='terminate'; $SIG{TERM}='terminate'; $SIG{INT}='terminate'; $SIG{ALRM}='saveall'; use Socket; @dunno = ('I\'ve no idea', 'I dunno', 'never heard about it', 'no idea', 'umm.. dunno', 'lemme think about it'); $| = 1; alarm 3600; loadusers(); loadfacts(); loadnotes(); loadseen(); loadtopiclocks(); loadtalkers(); serverconnect(); while (1) { parser(getline()); } sub konnekt { ($server, $port) = @_; $iaddr = inet_aton($server); $paddr = sockaddr_in($port,$iaddr); $proto = getprotobyname('tcp'); socket (SOCK, PF_INET, SOCK_STREAM, $proto) or die "socket failed: $!"; $sockaddr = 'S n a4 x8'; if (!connect(SOCK,$paddr)) { unlink("/tmp/dreambot.pid"); die "connect failed: $!"; } } sub sockwrite { $stuff = $_[0]; select(SOCK); $| = 1; print SOCK "$stuff\n"; select(STDOUT); } sub fhbits { my(@fhlist) = split(' ',$_[0]); my($bits); for (@fhlist) { vec($bits,fileno($_),1) = 1; } $bits; } sub getline { my $line = ""; while (1) { ($nfound,$timeleft) = select($rout=$rin, undef, undef, 0); if ($rout & SOCK) { if (sysread(SOCK,$buf,1) <= 0) { last; } if ($buf=~/\n/) { $line.=$buf; return $line; } else { $line.=$buf; } } } } sub loadusers { open(FILE,"$datadir/users"); while (!eof(FILE)) { $uline = ; $uline =~ /(.*):(.*):(.*):(.*)/; $uhosts{lc($1)}=$2; $uflags{lc($1)}=$3; $uchans{lc($1)}=$4; } close(FILE); printf "*** loaded users\n"; } sub saveusers { open(FILE,">$datadir/users"); foreach $key (keys %uhosts) { if ($key ne $nick && $uhosts{$key} ne "" && defined($uflags{$key}) && defined($uchans{$key})) { printf FILE "$key:$uhosts{$key}:$uflags{$key}:$uchans{$key}\n"; } } close(FILE); printf "*** saved users\n"; } sub loadfacts { open(FILE,"$datadir/facts"); while (!eof(FILE)) { $line = ; if ($line =~ /^([^:]*): (.*) -> (.*)$/) { $facts{$2} = "$1: $3"; } } close(FILE); printf "*** loaded facts\n"; } sub savefacts { open(FILE,">$datadir/facts"); foreach $key (keys %facts) { $facts{$key} =~ /^([^:]*): (.*)$/; printf FILE "%s: %s -> %s\n",$1,$key,$2; } close(FILE); printf "*** saved facts\n"; } sub loadnotes { open(FILE,"$datadir/notes"); while (!eof(FILE)) { $line = ; if ($line =~ /^([^ ]*) (.*)$/) { $notes{lc($1)} = $2; } } close(FILE); printf "*** loaded notes\n"; } sub savenotes { open(FILE,">$datadir/notes"); foreach $key (keys %notes) { printf FILE "%s %s\n",$key,$notes{$key}; } close(FILE); printf "*** saved notes\n"; } sub loadseen { open(FILE,"$datadir/seen"); while (!eof(FILE)) { $line = ; if ($line =~ /^(.*):(.*):(.*):(.*):(.*)$/) { $seen{lc($1)} = "$2:$3:$4:$5"; } } close(FILE); printf "*** loaded seen\n"; } sub saveseen { open(FILE,">$datadir/seen"); foreach $key (keys %seen) { $seen{$key} =~ /^(.*):(.*):(.*):(.*)$/; printf FILE "%s:%s:%s:%s:%s\n",$key,$1,$2,$3,$4; } close(FILE); printf "*** saved seen\n"; } sub loadtalkers { open(FILE,"$datadir/talkers"); while (!eof(FILE)) { $line = ; if ($line =~ /^(.*) (.*)$/) { $talkers{lc($1)} = int($2); } } close(FILE); printf "*** loaded talkers\n"; } sub savetalkers { open(FILE,">$datadir/talkers"); foreach $key (keys %talkers) { printf FILE "%s %d\n",$key,$talkers{$key}; } close(FILE); printf "*** saved talkers\n"; } sub loadtopiclocks { open(FILE,"$datadir/topiclocks"); while (!eof(FILE)) { $line = ; if ($line =~ /^([^ ]*) ([^ ]*) (.*)$/) { $topiclock{lc($1)} = $2; $oldtopic{lc($1)} = $3; } } close(FILE); printf "*** loaded topiclocks\n"; } sub savetopiclocks { open(FILE,">$datadir/topiclocks"); foreach $key (keys %topiclock) { printf FILE "%s %s %s\n",$key,$topiclock{$key},$oldtopic{$key}; } close(FILE); printf "*** saved topiclocks\n"; } sub checkonehost { @hosts = split(' ',$_[0]); undef $chost; foreach $chost (@hosts) { if ($_[1] =~ $chost) { return true; } } return false; } sub checkhost { if ($_[0] eq $nick) { return $nick; } if ($uhosts{$_[0]} ne "" && checkonehost($uhosts{$_[0]},$_[1]) eq true) { return $_[0]; } foreach $key (%uhosts) { if ($uhosts{$key} ne "" && checkonehost($uhosts{$key},$_[1]) eq true) { return $key; } } return false; } sub jumptoserver { printf "*** connecting to $server:$port\n"; konnekt($server,$port); sockwrite("USER $ident dummy dummy :$username"); sockwrite("NICK $nick"); printf "*** done\n"; } sub serverconnect { $servers[$curserver] =~ /(.*):(.*)/; $server=$1; $port=$2; $curserver++; if ($curserver > $#servers) { $curserver=0; } $nick=$nicks[$curnick]; jumptoserver(); $rin = fhbits('SOCK'); } sub backend { if (open(FILE,"$datadir/$_[0]")) { $data=""; while(!eof(FILE)) { $line = ; if ($line =~ //) { $line = ; if ($line =~ /(.*)<\/title>$/) { $data.="$1, "; } } } close(FILE); chop($data); chop($data); $data =~ s/\&/\&/; $data =~ s/\</\</; $data =~ s/\>/\>/; $data =~ s/\'/\'>/; $data =~ s/\"/\">/; return $data; } else { $data = "This feature is disabled right now"; } } sub pickrandom { $num = rand($#_+1); return $_[$num]; } sub terminate { sockwrite("QUIT :Terminated"); close(SOCK); unlink("/tmp/dreambot.pid"); printf("*** terminated\n"); exit(0); } sub saveall { saveusers(); savefacts(); savenotes(); saveseen(); savetalkers(); savetopiclocks(); printf("*** saved all\n"); alarm 3600; } sub parser { my ($line) = $_[0]; if ($line =~ /^ERROR :Closing Link: (.*)/) { printf("*** ERROR: $1\n"); close(SOCK); serverconnect(); return; } elsif ($line =~ /^PING :(.*)\n/) { sockwrite("PONG :$1"); } elsif ($line =~ /^:([^: ]*)!([^: ]*) PRIVMSG ([^: ]+) :(.*)\r\n$/) { $unick = $1; $uhost = $2; $uchan = $3; $utext = $4; $uhost =~ /(.*)\@(.*)/; $uident = $1; $uaddy = $2; $query = false; if (lc($uchan) eq lc($nick)) { $uchan=$unick; $query=true; } if ($utext =~ /^\x01PING (.*)\x01/) { printf("[$unick] PING\n"); # if ($uchan =~ /^[#\$\*]/) { $nnick=$unick; } # else { $nnick=$uchan; } sockwrite("NOTICE $unick :\x01PING $1\x01"); } elsif ($utext =~ /^\x01VERSION\x01/) { printf("[$unick] VERSION\n"); sockwrite("NOTICE $uchan :\x01VERSION $version\x01"); } elsif ($utext =~ /^\x01ACTION (.*)\x01/) { printf("[$uchan] $unick $1\n"); } else { printf("\[%s\] <%s> %s\n",$uchan,$unick,$utext); if ($query ne true) { $talkers{lc($unick)}+=length($utext); } } if ($utext =~ /(?i:$nick)[,:\-\; ]*how (are|r) (you|ya|u)[ \?!]*/i) { sockwrite("PRIVMSG $uchan :it's ok, $unick."); } elsif ($utext =~ /(?i:$nick)[,:\-\; ]*(?:fm|fresh|freshmeat)(?: news)?[ \?!]*/i) { $data=backend("fm.rdf"); sockwrite("PRIVMSG $uchan :$data"); } elsif ($utext =~ /(?i:$nick)[,:\-\; ]*(?:\/\.|slash|slashdot)(?: news)?[ \?!]*/i) { $data=backend("slashdot.rdf"); sockwrite("PRIVMSG $uchan :$data"); } $nnick = checkhost(lc($unick),$uhost); if ($utext =~ /^\./ && $nnick ne false && $uflags{$nnick} =~ /m/) { if ($utext =~ /^.raw (.*)/ || $utext =~ /^.order (.*)/) { sockwrite("$1"); printf("*** order: $1\n"); } elsif ($utext =~ /^.adduser (.*):([^\?\[\]\(\)\+]*):(.*):(.*)$/) { printf "*** added user $1\n"; sockwrite("PRIVMSG $uchan :added user $1"); $uhosts{lc($1)}=$2; $uflags{lc($1)}=$3; $uchans{lc($1)}=$4; saveusers(); } elsif ($utext =~ /^.remuser (.*)$/) { printf "*** removed user $1\n"; sockwrite("PRIVMSG $uchan :removed user $1"); delete $uhosts{lc($1)}; delete $uflags{lc($1)}; delete $uchans{lc($1)}; saveusers(); } elsif ($utext =~ /^.showuser (.*)$/) { printf "*** showing user $1\n"; if (defined($uhosts{lc($1)})) { sockwrite("PRIVMSG $uchan :$1:$uhosts{lc($1)}:$uflags{lc($1)}:$uchans{lc($1)}"); } else { sockwrite("PRIVMSG $uchan :I don't know any person named $1"); } } elsif ($utext =~ /^.save$/) { saveusers(); savefacts(); savenotes(); saveseen(); savetopiclocks(); savetalkers(); sockwrite("PRIVMSG $uchan :saved all"); } elsif ($utext =~ /^.load$/ || $utext =~ /^.rehash$/) { undef %uhosts; undef %uflags; undef %uchans; undef %facts; undef %notes; undef %topiclock; loadusers(); loadfacts(); loadnotes(); loadtopiclocks(); sockwrite("PRIVMSG $uchan :reloaded all"); } elsif ($utext =~ /^.saveusers$/) { saveusers(); sockwrite("PRIVMSG $uchan :saved users"); } elsif ($utext =~ /^.loadusers$/) { undef %uhosts; undef %uflags; undef %uchans; loadusers(); sockwrite("PRIVMSG $uchan :reloaded users"); } elsif ($utext =~ /^.savefacts$/) { savefacts(); sockwrite("PRIVMSG $uchan :saved facts"); } elsif ($utext =~ /^.loadfacts$/) { loadfacts(); sockwrite("PRIVMSG $uchan :reloaded facts"); } elsif ($utext =~ /^.savenotes$/) { savenotes(); sockwrite("PRIVMSG $uchan :saved notes"); } elsif ($utext =~ /^.loadnotes$/) { loadnotes(); sockwrite("PRIVMSG $uchan :reloaded notes"); } elsif ($utext =~ /^.topiclock (.*)$/) { $key = $1; undef($nchan); if ($query eq true) { if ($utext =~ /^.topiclock (.*) (.*)$/) { $key = $1; $nchan = $2; } else { sockwrite("PRIVMSG $uchan :Use .topiclock <on/off> <channel> syntax on query"); } } else { $nchan = $uchan; } if (defined($nchan)) { if ($key eq "on") { $topiclock{lc($nchan)}=true; undef($oldtopic{lc($nchan)}); sockwrite("TOPIC $nchan"); #$oldtopic{lc($nchan)}=getline(); #$oldtopic{lc($nchan)} =~ /^:[^:]*:(.*)/; #$oldtopic{lc($nchan)}=$1; printf("*** topiclock on $nchan is on\n"); sockwrite("PRIVMSG $uchan :topiclock on $nchan is on"); } else { $topiclock{lc($nchan)}=false; printf("*** topiclock on $nchan is off\n"); sockwrite("PRIVMSG $uchan :topiclock on $nchan is off"); } } } elsif ($utext =~ /^.nick (.*)$/) { $nick = $1; sockwrite("NICK :$1"); } elsif ($utext =~ /^.join (.*)$/) { sockwrite("PRIVMSG $uchan :joining $1"); sockwrite("JOIN $1"); } elsif ($utext =~ /^.part (.*)$/) { sockwrite("PRIVMSG $uchan :leaving $1"); sockwrite("PART $1"); } elsif ($utext =~ /^.op ([^ ]*)[ ]?([^ ]*)$/) { if ($query eq false) { sockwrite("MODE $uchan +o $1"); } elsif ($2 eq "") { sockwrite("PRIVMSG $uchan :You need to use .op <person> <channel> syntax on query."); } else { sockwrite("MODE $2 +o $1"); } } elsif ($utext =~ /^.d[e]?op ([^ ]*)[ ]?([^ ]*)$/) { if ($query eq false) { sockwrite("MODE $uchan -o $1"); } elsif ($2 eq "") { sockwrite("PRIVMSG $uchan :You need to use .d[e]op <person> <channel> syntax on query."); } else { sockwrite("MODE $2 -o $1"); } } elsif ($utext =~ /^.flag[s]? (.*) (.*)$/) { if (!defined($uhosts{lc($1)})) { sockwrite("PRIVMSG $uchan :I don't know any person named $1"); } else { $unick=$1; $flags=$2; if ($flags =~ /^\+(.*)/) { $uflags{lc($unick)}.=$1; } else { $uflags{lc($unick)}=$flags; } printf("*** $unick\'s flags are now: %s\n",$uflags{lc($unick)}); sockwrite("PRIVMSG $uchan :$unick\'s flags are now: $uflags{lc($unick)}"); } } elsif ($utext =~ /^.addhost (.*) ([^\?\[\]\(\)\+]*)$/) { if (!defined($uhosts{lc($1)})) { sockwrite("PRIVMSG $uchan :I don't know any person named $1"); } else { $uhosts{lc($1)}.=" $2"; sockwrite("PRIVMSG $uchan :added host $2 to $1"); } } elsif ($utext =~ /^.remhost (.*) (.*)$/) { if (!defined($uhosts{lc($1)})) { sockwrite("PRIVMSG $uchan :I don't know any person named $1"); } else { @hosts = split(' ',$uhosts{lc($1)}); undef($newhosts); $changed = 0; for ($i=0; $i<=$#hosts; $i++) { printf("$hosts[$i]\n"); if ($hosts[$i] ne $2) { $newhosts .= "$hosts[$i] "; } else { $changed = 1; } } printf("newhosts: $newhosts\n"); if ($changed == 0) { sockwrite("PRIVMSG $uchan :host not found"); } else { chop($newhosts); $uhosts{lc($1)}=$newhosts; sockwrite("PRIVMSG $uchan :host $2 removed from $1"); } } } elsif ($utext =~ /^.addchanuser (.*) (.*)$/) { if (!defined($uhosts{lc($1)})) { sockwrite("PRIVMSG $uchan :No such user: $1"); } else { $uchans{lc($1)}.=" $2"; sockwrite("PRIVMSG $uchan :$1's channels are now: $uchans{lc($1)}"); } } elsif ($utext =~ /^.die[ ]?(.*)$/) { if ($1 ne "") { $reason=$1; } else { $reason=".die by $unick"; } sockwrite("QUIT :$reason"); close(SOCK); unlink("/tmp/dreambot.pid"); exit(0); } elsif ($utext =~ /^.restart[ ]?(.*)$/) { if ($1 ne "") { $reason=$1; } else { $reason=".restart by $unick"; } sockwrite("QUIT :$reason"); close(SOCK); unlink("/tmp/dreambot.pid"); exec("$0$params"); } elsif ($utext =~ /^.ctcp (.*) (.*)$/) { printf("*** ctcp: $2\n"); sockwrite("PRIVMSG $1 :\x01$2\x01"); } elsif ($utext =~ /^.jump (.*):(.*)$/) { $server=$1; $port=$2; sockwrite("QUIT :.jump by $unick"); close(SOCK); jumptoserver(); } elsif ($utext =~ /^.cycle (.*)$/) { sockwrite("PRIVMSG $uchan :cycling $1"); sockwrite("PART $1"); sockwrite("JOIN $1"); } elsif ($utext =~ /^.userlist$/) { $i=0; $total=0; $data="PRIVMSG $uchan :"; foreach $key (sort keys %uhosts) { $data.="$key"; $i++; $total++; if ($i==20) { $i=0; sockwrite("$data"); $data="PRIVMSG $uchan :"; } else { $data.=","; } } if (length($data)>16) { chop($data); sockwrite("$data"); } sockwrite("PRIVMSG $uchan :Total $total users"); } elsif ($utext =~ /^.serverlist$/) { $data="PRIVMSG $uchan :"; foreach $key (@servers) { $data.="$key,"; } chop($data); sockwrite("$data"); } elsif ($utext =~ /^.help$/) { sockwrite("PRIVMSG $uchan :available commands are: raw|order,ctcp,cycle,adduser,remuser,showuser,userlist,load|rehash,save,loadusers,saveusers,loadfacts,savefacts,loadnotes,savenotes,topiclock,nick,join,part,op,d[e]op,flag[s],addhost,remhost,addchanuser,die,restart,jump,help"); } } if ($utext =~ /^(?i:$nick)[,:\-\; ]*(?:note|memo|message|msg) to ([^,:\; ]*)[,:\;]? (.*)$/i) { if (!defined($uhosts{lc($1)})) { sockwrite("PRIVMSG $uchan :$unick, I don't know any person named $1"); } else { $notes{lc($1)}.="$unick: $2\x01"; sockwrite("PRIVMSG $uchan :$unick, your note is saved"); } } elsif ($utext =~ /^read notes$/i) { if (defined($notes{$nnick})) { @nts = split("\x01",$notes{$nnick}); for ($i=0; $i<=$#nts; $i++) { $nts[$i] =~ /^([^:]*): (.*)$/; sockwrite("PRIVMSG $uchan :[$i] $1: $2"); } } else { sockwrite("PRIVMSG $uchan :You've no notes waiting."); } } elsif ($utext =~ /^delete (notes|note)[ ]?(.*)$/i) { if ($1 eq "notes") { delete $notes{$nnick}; sockwrite("PRIVMSG $uchan :Your notes are deleted."); } else { @nts = split("\x01",$notes{$nnick}); if ($2>$#nts) { sockwrite("PRIVMSG $uchan :Invalid note number"); } else { undef($newnotes); for ($i=0; $i<=$#nts; $i++) { if ($i != $2) { $newnotes.="$nts[$i]\n"; } } $notes{$nnick}=$newnotes; sockwrite("PRIVMSG $uchan :Note #$2 is deleted."); } } } elsif ($utext =~ /^(?i:$nick)?[,:\-\; ]*seen ([^ \?!\*]*)[ \?!]*$/) { $seenkey = $1; if (lc($seenkey) eq lc($nick)) { sockwrite("PRIVMSG $uchan :$unick, looking for me?"); } elsif (lc($seenkey) eq lc($unick)) { sockwrite("PRIVMSG $uchan :$unick, looking for yourself?"); } else { $seenflag = true; sockwrite("NAMES $uchan"); } } elsif ($utext =~ /^(?i:$nick)?[,:\-\; ]*topten[ ]?([^ \?!]*)[ \?!]*$/) { $i=0; undef($data); foreach $key (sort { $talkers{$b} <=> $talkers{$a} } keys %talkers) { $i++; $data.="$i. $key\[$talkers{$key}\] "; last if ($i==10); } chop($data); $nchan = $uchan; if ($1 ne "") { $nchan = $1; } sockwrite("PRIVMSG $nchan :$data"); } elsif ($utext =~ /^(?i:$nick)[,:\-\; ]*(?:what|what the fuck|what the hell|who|where)( is| are|\'s|\'re) ([^\?!]*)[ \?!]*$/i) { $dum = $1; $key = $2; if ($dum eq "\'s") { $dum=" is"; } elsif ($dum eq "\'re") { $dum=" are"; } if (defined($facts{$key})) { $facts{$key} =~ /^([^:]*): (.*)$/; printf("*** object: %s -> %s\n",$key,$2); $num = int(rand(4)); if ($num == 0) { $reply = "from what I\'ve heard from $1: $key$dum $2"; } elsif ($num == 1) { $reply = "according to $1, $key$dum $2"; } elsif ($num == 2) { $reply = "I think $key$dum $2"; } elsif ($num == 3) { $reply = "I\'ve heard that $key$dum $2"; } sockwrite("PRIVMSG $uchan :$reply"); } else { $reply = pickrandom(@dunno); sockwrite("PRIVMSG $uchan :$unick, $reply"); } } elsif ($utext =~ /^(?:$nick)?[,:\-\; ]*(.*)(?: is| are|\'s|\'re) (.*)/i) { $key = $1; $val = $2; if ($key !~ /^(what|that|it|these|those|you|he|she)$/i && $nick ne $unick && !defined($facts{$key})) { printf("*** learning: $key -> $val\n"); open(FILE,">>$datadir/facts"); printf FILE "%s: %s -> %s\n",$unick,$key,$val; close(FILE); $facts{$key} = "$unick: $val"; } } elsif ($utext =~ /^(?i:$nick)[,:\-\; ]*forget (.*)$/i) { if (defined($facts{lc($1)})) { delete $facts{lc($1)}; sockwrite("PRIVMSG $uchan :$unick, I forgot $1"); printf("*** forgot $1\n"); savefacts(); } else { sockwrite("PRIVMSG $uchan :$unick, I didn't know anything like that"); } } } elsif ($line =~ /^:(.*)!(.*) JOIN [:]?(.*)\r\n$/) { $unick = $1; $uhost = $2; $uchan = $3; $uhost =~ /(.*)\@(.*)/; $uident = $1; $uaddy = $2; printf("\[$uchan\] $unick ($uident!$uaddy) joined\n"); $nnick = checkhost(lc($unick),$uhost); if ($nnick ne false && ($uchans{$nnick} =~ $uchan || $uchans{$nnick} eq "*" || lc($uchan) eq lc($nick))) { if ($uflags{$nnick} =~ /o/) { sockwrite("MODE $uchan +o $unick"); } elsif ($uflags{$nnick} =~ /v/) { sockwrite("MODE $uchan +v $unick"); } elsif ($uflags{$nnick} =~ /b/) { sockwrite("MODE $uchan +b *!$uhost\nKICK $uchan $unick :autobanned"); } } if ($nnick ne false && defined($notes{$nnick})) { @nts = split("\x01",$notes{$nnick}); $count = $#nts+1; if ($count>1) { $data = "$count notes" } else { $data = "a note"; } sockwrite("NOTICE $unick :You got $data waiting, \"/msg $nick read notes\" to read them, \"/msg $nick delete notes\" to delete them all, or \"/msg $nick delete note <num>\" to delete a specific note."); } } elsif ($line =~ /^:(.*) PART ([^: ]+) [:]?(.*)\r\n$/) { $uhost = $1; $uchan = $2; $reason = $3; $uhost =~ /(.*)!(.*)\@(.*)/; $unick = $1; $uident = $2; $uaddy = $3; printf("\[$uchan\] $unick ($uident!$uaddy) left \[$reason\]\n"); $seen{lc($unick)}=time().":$uchan:$reason:leaving"; } elsif ($line =~ /^:(.*) QUIT :?(.*)\r\n$/) { $uhost = $1; $reason = $2; $uhost =~ /(.*)!(.*)\@(.*)/; $unick = $1; $uident = $2; $uaddy = $3; printf("*** $unick ($uident!$uaddy) signed off \[$reason\]\n"); $seen{lc($unick)}=time().":$uchan:$reason:quitting"; } elsif ($line =~ /^:(.*)!(.*)\@(.*) KICK ([^: ]+) (.*) :(.*)\r\n$/) { printf("\[$4\] $5 is kicked by $1 \($6\)\n"); if ($5 eq $nick) { sockwrite("JOIN $4"); } $seen{lc($5)}=time().":$4:$6:being kicked"; } elsif ($line =~ /^:(.*) MODE ([^: ]+) [:]?(.*)\r\n$/) { $uhost = $1; $uchan = $2; $modes = $3; if ($uhost =~ /(.*)!(.*)\@(.*)/) { $uhost = $1; } printf("\[$uchan\] $uhost set mode: $modes\n"); } elsif ($line =~ /^:(.*) TOPIC ([^: ]+) :(.*)\r\n$/) { $uhost = $1; $uchan = $2; $topic = $3; $uhost =~ /(.*)!(.*)\@(.*)/; $unick = $1; $uident = $2; $uaddy = $3; printf("\[$uchan\] $unick sets topic: $topic\n"); if ($topiclock{lc($uchan)} eq true && $unick ne $nick) { sockwrite("TOPIC $uchan :$oldtopic{$uchan}"); } } elsif ($line =~ /^:(.*) NICK :(.*)\r\n$/) { $uhost = $1; $nnick = $2; $uhost =~ /(.*)!(.*)\@(.*)/; $unick = $1; printf("*** $unick is now known as $nnick\n"); } elsif ($line =~ /^:(.*) NOTICE ([^: ]+) :?(.*)\r\n$/) { $uhost = $1; $uchan = $2; $notice = $3; $uhost =~ /(.*)!(.*)\@(.*)/; $unick = $1; $uident = $2; $uaddy = $3; printf("\[$unick\] NOTICE: $notice\n"); } elsif ($line =~ /^:(.*) ([0-9]{3}) ([^ :]*) [:]?(.*)\r\n$/) { $text = $4; # auto join if connected properly # and reset topiclock stuff if ($2=="001") { printf("*** auto joining\n"); foreach $chan (@channels) { sockwrite("JOIN $chan"); #$topiclock{$chan}=false; #$oldtopic{$chan}=""; } } elsif ($2=="433") { $curnick++; if ($curnick > $#nicks) { $curnick=0; } $nick=$nicks[$curnick]; sockwrite("NICK $nick"); printf("*** changed nick to $nick\n"); } elsif ($2=="332") { $text =~ /^(.*) :(.*)$/; # printf("channel: $1, topic: $2\n"); if ($topiclock{lc($1)} eq true) { if (!defined($oldtopic{lc($1)})) { $oldtopic{lc($1)} = $2; } elsif ($oldtopic{lc($1)} ne $2) { sockwrite("TOPIC $1 :$oldtopic{lc($1)}"); } } } elsif ($2=="353" && $seenflag eq true) { $seenflag = false; $text =~ /^.*:(.*)$/; $data = $1; printf("*names: $data\n"); $key=quotemeta($key); if ($data =~ /$key/i) { sockwrite("PRIVMSG $uchan :$unick, $seenkey is on the channel right now, don't you see?!"); } elsif (defined($seen{lc($seenkey)})) { $seen{lc($seenkey)} =~ /^(.*):(.*):(.*):(.*)$/; $ts = time() - int($1); $days = int($ts / 86400); $hours = (int($ts / 3600))%24; $mins = (int($ts / 60))%60; $secs = (int($ts))%60; #($secs,$mins,$hours,$days,$mon,$year,$wday,$yday,$isdst) = localtime($ts); sockwrite("PRIVMSG $uchan :$unick, I last saw $seenkey $4 from $2, $days days $hours hours $mins mins $secs secs ago [$3]"); } else { sockwrite("PRIVMSG $uchan :$unick, I never saw $seenkey"); } } printf("$text\n"); } else { printf("%s",$line); } }