# distributed under the "do-what-you-want-but-don't-blame-me" license :p # by MattAustin and Bigmouth # and that lamer ibeinvisible helped to, maybe. #This uses the CHAT2 protocol. package YahooSimple; use strict; use warnings; use IO qw(Socket Select); use LWP::UserAgent; use HTTP::Request; use Data::Dumper; #use Net::Ping::External qw(ping); #use Time::HiRes qw(setitimer ITIMER_REAL time); use Time::HiRes; use Time::HiRes qw(usleep ualarm gettimeofday tv_interval sleep); #edit .@ commands to match your username. #It's commonly known that the chat2 protocol has difficulties receiving messages from the YCHT protocol. This is not a bug in the code here, yahoo's servers are broken. sub new { my $class = shift; my $self = { ChatServer => 'dcs1.chat.dcn.yahoo.com', ChatPort => 5050, AuthServer => 'http://edit.my.yahoo.com', YahooID => '', Password => '', Select => new IO::Select(), Socket => undef, Yv => undef, Tz => undef, identifier => 0, Debug => 0, Roomn => undef, @_ }; bless( $self, $class ); return $self; } sub Connect{ my $self = shift; if($self->HTTPAuth()){ $self->{Socket} = new IO::Socket::INET(PeerAddr => $self->{ChatServer}, PeerPort => $self->{ChatPort}, Proto => 'tcp') || die "$!\n"; $self->{Select}->add(\*STDIN); $self->{Select}->add($self->{Socket}); $self->send(10,30,0,"\x30À€$self->{YahooID}À€1À€$self->{YahooID}À€6À€$self->{Yv}; $self->{Tz}"."À€"); $self->{LastPing} = time; } else{ die "ERROR: HTTP Auth Error\n"; } } sub HTTPAuth{ my $self = shift; my $req = HTTP::Request->new(POST => 'http://edit.my.yahoo.com'); $req->content(".src=&login=$self->{YahooID}&passwd=$self->{Password}&n=1"); return 0 unless( ($self->{Yv}, $self->{Tz}) = LWP::UserAgent->new()->request($req) ->as_string =~ /(Y=v=.*?);.*?(T=z=.*?);/s ); return 1; } sub do_one_loop{ #ping HErE my $self = shift; if(time >= ($self->{LastPing}+120)){ $self->send(10,161,0,"109\xC0\x80$self->{YahooID}\xC0\x80"); $self->{LastPing} = time; } my @ready = $self->{Select}->can_read(.1); my $buf; foreach my $fh (@ready){ sysread( $fh, my $buf, 2048, length( $buf || '' ) ); if($fh =~ "IO::Socket::INET"){ my ($signature, $version, $length, $event_code, $return, $identifier, $data) = unpack("a4nNnN2a*",$buf); $self->{identifier} = $identifier; $self->debug("SERVER: $version,$length,$event_code,$return,$identifier,$data"); if($event_code == 85){ #buddylist junk I guess. my ($listdata) = $data =~ /À€(.*?)À€/s; @{$self->{Buddy_List}->{$1}} = split(",", $2) while($listdata =~ m/(.*?):(.*?)\n/gs); $self->send(10,150,0,"1À€$self->{YahooID}À€6À€abcdefÀ€98À€usÀ€135À€dc125À80"); $self->call_event('Connected'); } elsif($event_code == 6){ #Incoming IM my ($to, $from, $poop, $message) = $data =~ /À€(.*?)À€4À€(.*?)À€\d+À€\d+À€\d+À€(.*?)À€\d+À€(.*?)À€/; print "This is eventc 6 data: $data TO: $to from $from mess $message\n"; $self->call_event('Message',$from, $message); my $microseconds = 500_000; print "PM $from: $message\n"; if ($message =~ /^\.say/){ my ($command, $text) = split(' ', $message, 2); $self->Comment($text); } elsif ($message =~ /^\.flood/){ for (my ($i) = (1); $i <11; $i++){ $self->Comment("deceptive_measures aka Mike the Butcher"); usleep $microseconds; } } elsif ($message =~ /^\.bomb/){ my ($command, $message2) = split(' ', $message, 2); for (my ($i) = (1); $i < 20; $i++){ $self->SendMessage($message2,"deceptive_measures aka Mike the Butcher"); usleep $microseconds; } } } elsif($event_code == 152){ #someone enters room my ($t1, $t2, $t3, $t4) = $data =~ /À€(.*?)À€(.*?)À€(.*?)À€(.*?)À€/; if ($t4 == 128){ print "***we just joined room: $t1***\n"; #$self->Comment("I have arrived in $t1"); my ($room, $banner, $vauth, $vauth2,$webcam) = $data =~ /À€(.*?)À€\d+À€(.*?)À€\d+À€\d+À€\d+À€\d+À€\d+À€\d+À€\d+À€(.*?)À€\d+À€-\d+À€\d+À€\d+À€\d+À€(.*?)À€\d+À€(.*?)/; $data =~ s/\d+À€(.*?)À€\d+À€(.*?)À€\d+À€\d+À€\d+À€\d+À€\d+À€\d+À€\d+À€(.*?)À€\d+À€-\d+À€\d+À€\d+À€\d+À€(.*?)À€\d+À€(.*?)À€(.*?)//; print "$room $banner $vauth $vauth2 $webcam\n"; $data =~ s/À€110(.*?)109À€/ /g; my @poop = $data; my @roomlist = sort @poop; print "poop @poop\n"; print "Roomlist @roomlist\n"; }elsif(($t4 == 108) || ($t2 == 108)){ my ($room, $enters) = $data =~ /À€(.*?)À€\d+À€\d+À€\d+À€(.*?)À€/; print ">>>$enters has joined the room***\n"; }else{ print "***Event_code 152 error I don't know what broke!!!!***\n"; } } elsif($event_code == 155){ #someone leaves room my ($room, $title, $leaves) = $data =~ /À€(.*?)À€\d+À€(.*?)À€\d+À€\d+À€\d+À€(.*?)À€/; print "<<<$leaves has left the room***\n"; } elsif($event_code == 168){ #Room text # print "$data\n"; # print "$buf\n"; #echo -e "\033[30mHello, World" my ($room, $from, $message) = $data =~ /À€(.*?)À€\d+À€(.*?)À€\d+À€(.*?)À€/; $message =~ s/<.*?>//g; $message =~ s/\x1B\[.*?m//g; $message =~ s/<(font.*?|fade.*?|b|i|u|alt.*?|ding.*?|black|blue|cyan|gray|green|magenta|orange|pink|purple|red|snd.*?|white|yellow)>//g; $message =~ s/<(\/font|\/fade)>//g; #$message =~ s/#.*?m//g; #$message =~ s/[0-9a-f]{5,7}m//; my $microseconds = 500_000; print "$from: $message\n"; if ($message =~ /^\./) { if ($message =~ /^\.say/) { my ($command, $text) = split(' ', $message, 2); $self->Comment($text); } elsif ($message =~ /\.pm/) { my ($command, $message2, $message3) = split(' ', $message, 3); print "Com:$command Mes2:$message2 Mes3:$message3\n"; print "I DID IT cauht .pm\n"; $self->SendMessage($message2, $message3); } elsif ($message =~ /^\.ping/){ my ($command, $host) = split(' ', $message, 2); $self->Comment("Pinging $host, may take up to 5 seconds"); my $alive = ping(hostname => $host, count => 1, size => 56, timeout => 5); print "$host is online\n" if $alive; $self->Comment("$host is online") if $alive; print "$host is not responding\n" if $alive == 0; $self->Comment("$host is not responding") if $alive == 0; } elsif ($message =~ /\.commands/){ my ($command, $message2) = split(' ', $message, 2); $self->Comment("say/pm/ping/commands/test/pray/flood/@/goto/quit"); } elsif($message =~ /\.test/){ $self->Comment("test received"); } elsif($message =~ /\.pray/){ $self->Comment("add stuff here"); } elsif($message =~ /\.flood/){ for (my ($i) = (1); $i < 50; $i++){ $self->Comment("deceptive_measures aka Mike the Butcher"); usleep $microseconds; } }elsif($message =~ /\.\@/){ my ($command, $shell) = split(' ', $message, 2); if ($shell =~ /root|pass|wget|ping|ftp|telnet|lynx|cat|vi|top|su/){ $self->Comment("Error"); } elsif($shell !~ /root|pass|wget|ping|ftp|telnet|lynx|cat|vi|top|su/){ #my $out = `$shell`; $self->Comment("$out"); } } elsif(($message =~ /\.goto/) && ($from =~ /\bibeinvisible\b/)){ my ($command, $room) = split(' ',$message,2); $self->Room($room); $self->{Roomn} = $room; } elsif(($message =~ /\.quit/) && ($from =~ "ibeinvisible")){ exit; } else{ print "Dunno George\n"; } } } }else{ #print "$buf\n"; $buf =~ /^\.(.+?)\s/; my $command = $1; if($buf =~ ".j"){ my ($command, $room); ($command, $room) = split(' ', $buf, 2); print "Room: $room\n"; $self->Room($room); $self->{Roomn} = $room; } elsif($buf =~ ".test"){ print "Test acknowledged I win\n"; } elsif($buf =~ /.quit/){ exit; } elsif($buf =~ /^\.pm/){ my ($command, $to, $message); ($command, $to, $message) = split(' ', $buf, 3); $self->SendMessage($to, $message); }else{ my $text = $buf; $self->Comment($text); } } $buf = ""; } } sub setHandler{ my ($self, $event, $handler) = @_; $self->{handler}->{$event} = $handler; } sub call_event{ my $self = shift; my $event = shift; my $function = $self->{handler}->{$event}; return &$function( $self, @_ ) if( defined $function ); return undef; } sub ListUsers{ my ($self, $group) = @_; return @{$self->{Buddy_List}->{$group}}; } sub ListGroups{ my $self = shift; return keys %{$self->{Buddy_List}}; } sub SendMessage { my ($self, $to, $message) = @_; my $body = "1À€$self->{YahooID}À€5À€$toÀ€14À€$messageÀ€97À€1À€63À€;0À€64À€0À€1002À€1À€206À€2À80"; $self->send(0,32,1515563605,$body); print "$body\n"; } sub Room{ my ($self, $room) = @_; my $body = "1\xC0\x80$self->{YahooID}\xC0\x80104\xC0\x80$room\xC0\x80129\xC0\x800\xC0\x8062\xC0\x802\xC0\x80"; $self->send(10,152,0,$body); } sub Comment{ my ($self, $text) = @_; my $body = "1\xC0\x80$self->{YahooID}\xC0\x80104\xC0\x80$self->{Roomn}\xC0\x80117\xC0\x80$text\xC0\x80124\xC0\x801\xC0\x80"; $self->send(10,168,0,$body); } sub send{ my ($self, $ver, $id, $ret, $body) = @_; my $pack = pack("a4nNnN2","YMSG",$ver,length($body),$id,$ret,$self->{identifier}).$body; $self->{Socket}->send($pack); $self->debug("Client: $ver,".length($body).",$id,$ret,".$self->{identifier}); } sub debug { my $self = shift; my $data = shift; print $data . "\n" if (length($data) != 0 && $self->{Debug} == 1); } return 1;