aboutsummaryrefslogtreecommitdiff
path: root/client/clientcmp.pl
blob: 29735f2a94cd8c61adeee98e855eb617513ccba5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/perl

################################################################################
# Simulate a game client
#   - open TCP connection
#   - authenticate
#   - request plain/compressed serverlist
#
################################################################################

use strict;
use warnings;
use AnyEvent;
use AnyEvent::Handle;
use Data::Dumper 'Dumper';
$|++;

our %S;
require "../common/supportedgames.pl";
require "../common/auth.pl";

# set masterserver
my $masteraddress = "rhea.333networks.com";
my $masterport    = 28900;

# set (our) simulated game client
my $gamename = "ut";
my $cmp = 0 ? "cmp" : ""; # 1 for compressed, 0 for plain

# loop
my $cv = AnyEvent->condvar;

my $buf = "";
my $handle; $handle = new AnyEvent::Handle(
    connect  => [$masteraddress => $masterport],
    timeout  => 15,
    poll     => 'r',
    on_error => sub 
    {
        print Dumper $!; 
        $handle->destroy;
        $cv->send;
    },
    on_eof   => sub 
    { # connection closed, assuming list was received
        $buf =~ s/\\final\\//ig;
        my @serverlist;

        # process serverlist for compressed/plain        
        if ($cmp eq "cmp")
        { # compressed list
            while (length $buf >= 6)
            {
                my $caddr = substr $buf, 0, 6, '';
                my ($A, $B, $C, $D, $E, $F) = split //, $caddr;
                my $addr = ord($A).".".ord($B).".".ord($C).".".ord($D);
                my $port = (ord($E) << 8) + ord($F);
                push @serverlist, "$addr:$port";
            }
        }
        else
        { # plain list 
            my @list = split /\\ip\\/, $buf;
            shift @list; # remove empty first element
            for my $l (@list)
            {
                push(@serverlist, $l) if ($l =~ m/:/);
            }
        }        
        
        # report result
        print "Received ".(scalar @serverlist)." [$gamename] games from $masteraddress.\n";
        #print Dumper \@serverlist;

        $handle->destroy;
        $cv->send;
    },
    on_read  => sub 
    {    
        $buf .= $_[0]->rbuf;
        $_[0]->rbuf = "";

        # part 1: receive \basic\\secure\$key
        if ($buf =~ m/\\basic\\\\secure\\/) 
        {
            # parse received data
            my @a = split /\\/, ($buf||"");
            shift @a;
            my %r = (@a, (scalar @a % 2 == 1) ? "dummy" : () );
            $buf = "";

            # respond to challenge
            my $validate = get_validate_string(
                $S{game}->{$gamename}->{key}, 
                $r{secure}, 
                $r{enctype}||0
            );

            # print and send response
            $handle->push_write("\\gamename\\$gamename\\location\\0\\validate\\$validate\\final\\");
            $handle->push_write("\\list\\$cmp\\gamename\\$gamename\\final\\");
        }
    }
);

$cv->recv;