#!/usr/bin/perl
##
## cutemx client  (nocarrier)
##
## greetz to w00w00 (minus, interrupt, awr, and the rest of the homiez), ignitor
##
##  0wned!@#$%
##

$|++;

my($chat_host, $xfer_host) = ( "208.245.58.3:1999" , "208.245.58.50:1786" );
my($chat_sock, $xfer_sock, $sockets);

my($username) = shift @ARGV || "client";
my($channel) = "lobby";
my($version) = "B1.29";
my($ip) = "1.2.3.4";


############
### MAIN ###
############

use IO::Socket;
use IO::Select;
use IO::Handle;

$sockets = new IO::Select;

# open stdin as a filehandle
$input = new IO::Handle;
die "couldn't open stdin\n" if (!$input->fdopen(fileno(STDIN), "r"));
$sockets->add($input);

#  connect
print "connecting to $chat_host... ";
$chat_sock = new IO::Socket::INET("$chat_host");
if (!$chat_sock) {
    die "connect failed: $!\n";
} 
$chat_sock->autoflush(1);
$sockets->add($chat_sock);
print "ok\n";


# then say hello
print "logging in as $username\n";
print $chat_sock "#CI#$username#FB##RB#";    # check in

print "saying version, ";
print $chat_sock "#VC#$version#RB#";            # version client

print "ip\n";
print $chat_sock "#IP#$ip#FB##RB#";      # what's mah ip bitch!@#

#print "auto-joining $channel\n";
#print $chat_sock "#TC#$channel#FB##RB#";        # join the channel


while (@ready = $sockets->can_read()) {
    my($data, $client);

    foreach $sock (@ready) {
	if (fileno($sock) == fileno($input)) { # user input
	    chop($data = <$sock>);
	    
	    my($msg) = (substr($data,0,1) eq '/')?
		       build_cmd($data):
		       build_cmd("/say " . $data);

	    if (length($msg)) {
		print "send failed: $!\n"  
		    if (!$chat_sock->send($msg));
	    }
	} elsif (fileno($sock) == fileno($chat_sock)) { # output from server
	    recv($sock, $data, 2048, 0);

	    my(@lines) = parse_data($data);
	    foreach $line (@lines) {
		$line =~  s/%(..)/pack('c', hex($1))/eg;
		print "$line\n";
	    }
	}
    }
}


sub parse_data { 
    my($data, $channel, $msg) = (shift, "", "");

    my(@commands) = split('#RB#', $data);
    my(@lines);

    foreach $line (@commands) {
	$_ = $line;

      switch: {
	  /\#MH\#(\w+)\$\$([^\$\#]+)/ and do {
	      push @lines, "#$1 > $2";
	      last switch;
	  };

	  /\#GM\#(\w+)\#FB\#([^\#]+)/ and do {
	      push @lines, " *$1* $2";
	      last switch;
	  };
      };
    }

    return @lines;
}


sub build_cmd {
    my($cmd, @data) = split(' ', shift);
    my($data) = join(' ', @data);

    $_ = lc(substr($cmd,1,length($cmd)));

    switch: {
	/join/ and do {
	    $channel = $data;
	    return "#TC#$data#FB##RB#";
	};

	/part/ and do {
	    $channel = "";
	    return "#LC#$data#FB##RB#";
	};

	/say/ and do {
	    print "> $data\n";
	    return "#MH#$channel#FB#<$username> $data\$\$MS Sans Serif\$\$0:0:0\$\$204\$\$0:0:0:0#FB##RB#";
	};

	/me/ and do {
	    print "> $username $data\n";
	    return "#MH#$channel#FB#* $username $data\$\$MS Sans Serif\$\$0:0:0\$\$204\$\$0:0:0:0#FB##RB#";
	};

	/echo/ and do {
	    print "> $data\n";
	    return "#MH#$channel#FB#$data#RB#";
	};

	/msg/ and do {
	    my($to_user, @msg) = @data;
	    my($msg) = join(' ', @msg);
	    print "(->$to_user) $msg\n";
	    return "#GM#$to_user#FB#$msg#RB#";
	};

	/nick/ and do {
	    $username = "$data";
	    return "";
	};

	/quit/ and exit;
    };
}
	
