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;
|