use Net::ICQ; #$uin = 115401070; #bot $uin = 115419198; #bot2 #$uin = 115420091; #bot3 (coop) $password = "ph0rg3t"; $filename = ".micqbot"; $icq = Net::ICQ->new($uin,$password); $icq->connect() || die ("could not connect!?"); $icq->add_handler('SRV_SYS_DELIVERED_MESS', \&on_msg); $icq->add_handler('SRV_USER_ONLINE', \&on_online); $icq->add_handler('SRV_USER_OFFLINE', \&on_offline); $icq->add_handler('SRV_STATUS_UPDATE', \&on_status); print ("Logged in\n"); my(%users); my(%status); $SIG{INT} = \&disconnect; print ("Loading users\n"); load(); update_listen(); print ("Starting event loop\n"); $icq->start(); ####################### subs ####################### ################### on_msg ################### sub on_msg { my ($icq, $event) = @_; my ($in_params, $out_params, $uin, $user); $in_params = $event->{params}; $uin=$in_params->{uin}; print("Message received from $uin\n"); if ($in_params->{type} == 1) { # normal text message print("$uin: \t$in_params->{text}\n"); $out_params = {}; $out_params->{type} = 1; $out_params->{receiver_uin} = $uin; if ($in_params->{text} =~ /^#/) { if ($in_params->{text} =~ /^#help$/) { help($uin); } elsif ($in_params->{text} =~ /^#all$/) { foreach $key (keys %users) { $out_params->{text} = "$users{$key}\n$out_params->{text}"; } if ($out_params->{text} eq "") { $out_params->{text} = " [none]\n"; } $out_params->{text} = "User List:\n\n$out_params->{text}"; $icq->send_event('CMD_SEND_MESSAGE',$out_params); } elsif ($in_params->{text} =~ /^#who$/) { foreach $key (keys %users) { if ($status{$key} eq "online") { $out_params->{text} = "$users{$key}\n$out_params->{text}"; } } if ($out_params->{text} eq "") { $out_params->{text} = " [none]\n"; } $out_params->{text} = "User List (online):\n\n$out_params->{text}"; $icq->send_event('CMD_SEND_MESSAGE',$out_params); } elsif ($in_params->{text} =~ /^#subscribe .*/) { #verify the user number isn't already subscribed my ($name) = substr($in_params->{text},11,length($in_params->{text})); my (%ids) = reverse(%users); if (exists($users{$uin})) { $out_params->{text} = "You are already subscribed as $users{$uin}"; $icq->send_event('CMD_SEND_MESSAGE',$out_params); #verify the user name doesn't already exist } elsif (exists($ids{$name})) { $out_params->{text} = "You are already subscribed as $users{$uin}"; $icq->send_event('CMD_SEND_MESSAGE',$out_params); #subscribe the user } else { #alert any $users{$uin} = $name; spam("[$users{$uin} has subscribed]"); save(); update_listen(); } } elsif ($in_params->{text} =~ /^#unsubscribe$/) { $user = $users{$uin}; delete ($users{$uin}); update_listen(); spam("[$user has unsubscribed]"); save(); } elsif ($in_params->{text} =~ /^#whisper .*/) { } elsif ($in_params->{text} =~ /^###die###$/) { disconnect(); } else { # unknown command help($uin,"Unknown command: $in_params->{text}"); } } else { # not a command #go through all users, figure out who is online, send message to them spam ("Message from $users{$uin}:\n\n$in_params->{text}",$uin); } } else { # some othersort of message print("Some other sort of message\n"); } } ################### alert_status ################### sub alert_status { my($uin, $old, $new) = @_; print("$uin changed from $old to $new:\n"); if ($old eq "online" and $new ne "online") { print("that means $uin logged off\n"); spam("$users{$uin} has logged OFF."); } elsif ($old ne "online" and $new eq "online") { print("that means $uin logged on\n"); spam("$users{$uin} has logged ON."); } } ################### on_status ################### sub on_status { my ($icq, $event) = @_; my ($uin, $params, $state, $oldstate); $params = $event->{params}; $uin=$params->{uin}; $state=$params->{status}; $oldstate=$status{$uin}; if ($state == 0) { alert_status($uin, $oldstate,"online"); $status{$uin} = "online"; } else { $status{$uin}="deleted"; delete $status{$uin}; alert_status($uin, $oldstate,"offline"); } } ################### on_online ################### sub on_online { #update the status of someone my ($icq, $event) = @_; my ($uin, $params, $state,$oldstate); $params = $event->{params}; $uin=$params->{uin}; $state=$params->{status}; $oldstate=$status{$uin}; if ($state == 0) { alert_status($uin, $oldstate,"online"); $status{$uin} = "online"; } else { $status{$uin}="deleted"; delete $status{$uin}; alert_status($uin, $oldstate,"offline"); } } ################### on_offline ################### sub on_offline { #update the status of someone my ($icq, $event) = @_; my ($uin, $params, $state, $oldstate); $params = $event->{params}; $uin=$params->{uin}; $oldstate = $status{$uin}; $status{$uin}; alert_status($uin, $oldstate,"offline"); } ################### update_listen ################### sub update_listen { #tell the server who we're listening to/for my (@ids) = keys %users; my ($params) = { 'num_contacts' => $#ids + 1, 'uins' => \@ids }; $icq->send_event('CMD_CONTACT_LIST',$params); } ################### disconnect ################### sub disconnect { $icq->disconnect(); #save users to a file? print ("Saving users.\n"); save(); exit(); } ################### save ################### sub save { open(ELIF,">$filename"); foreach $key (keys %users) { print ELIF "$key\n$users{$key}\n"; } close ELIF ; } ################### load ################### sub load { my($id,$name); open(ELIF,"<$filename"); while() { $id=$_; $name=; chop($id); chop($name); $users{$id}=$name; print("user: '$name'->'$id'\n"); } close ELIF ; } ################### help ################### sub help { my ($uin,$message) = @_; my ($params); $params = {}; $params->{type} = 1; $params->{text} = " #help -- this menu #who -- subscribed users currently on #all -- all subscribed users #subscribe -- subscribe #unsubscribe -- unsubscribe "; #whisper message -- send a specific user a message if ($message ne "") { $params->{text} = "$message\n$params->{text}"; } $params->{receiver_uin} = $uin; $icq->send_event('CMD_SEND_MESSAGE',$params); } ################### spam ################### sub spam { #send a message to all online folks except for uin my ($message,$uin) = @_; my ($params); $params = {}; $params->{type} = 1; $params->{text} = $message; foreach $key (keys %users) { if ($key == $uin || $status{$key} ne "online") { next; } $params->{receiver_uin}=$key; $icq->send_event('CMD_SEND_MESSAGE',$params); } }