diff options
| author | Darkelarious <darkelarious@333networks.com> | 2016-11-19 20:56:04 +0100 |
|---|---|---|
| committer | Darkelarious <darkelarious@333networks.com> | 2016-11-19 20:56:04 +0100 |
| commit | c3f8d65a4fb1f5674557ee67cf7f74369df86ad1 (patch) | |
| tree | 92aab2a394bda28da0ed7c7c75e633fdf386fc71 /lib/MasterServer/TCP/UCCAppletQuery.pm | |
| parent | 1de3da4b8027508a91144639455c934fd6ccb9b7 (diff) | |
| download | MasterServer-Perl-c3f8d65a4fb1f5674557ee67cf7f74369df86ad1.tar.gz MasterServer-Perl-c3f8d65a4fb1f5674557ee67cf7f74369df86ad1.zip | |
Massive improvements on efficiency, robustness, security, reliability and more
Diffstat (limited to 'lib/MasterServer/TCP/UCCAppletQuery.pm')
| -rwxr-xr-x | lib/MasterServer/TCP/UCCAppletQuery.pm | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/MasterServer/TCP/UCCAppletQuery.pm b/lib/MasterServer/TCP/UCCAppletQuery.pm new file mode 100755 index 0000000..e3eb587 --- /dev/null +++ b/lib/MasterServer/TCP/UCCAppletQuery.pm @@ -0,0 +1,72 @@ + +package MasterServer::TCP::UCCAppletQuery; + +use strict; +use warnings; +use AnyEvent; +use AnyEvent::Handle; +use Exporter 'import'; + +our @EXPORT = qw| query_applet |; + +################################################################################ +## The UCC Applet (Epic Megagames, Inc.) functions as a master server for one +## single game. However, it does not always follow the defined protocol. +## This module connects with UCC masterserver applets to receive the list. +################################################################################ +sub query_applet { + my ($self, $ms) = @_; + + # be nice to notify + $self->log("tcp","start querying $ms->{ip}:$ms->{port} for '$ms->{game}' games"); + + # list to store all IPs in. + my $master_list = ""; + + # connection handle + my $handle; + $handle = new AnyEvent::Handle( + connect => [$ms->{ip} => $ms->{port}], + timeout => 5, + poll => 'r', + on_error => sub {$self->log("error", "$! on $ms->{ip}:$ms->{port}."); $handle->destroy;}, + on_eof => sub {$self->process_ucc_applet_query($master_list, $ms); $handle->destroy;}, + on_read => sub { + + # receive and clear buffer + my $m = $_[0]->rbuf; + $_[0]->rbuf = ""; + + # remove string terminator + chop $m if $m =~ m/secure/; + + # part 1: receive \basic\\secure\$key + if ($m =~ m/\\basic\\\\secure\\/) { + + # received data + my %r; + $m =~ s/\\([^\\]+)\\([^\\]+)/$r{$1}=$2/eg; + + # respond to challenge + my $validate = $self->validate_string(gamename => $ms->{game}, + enctype => $r{enctype}||0, + secure => $r{secure}); + + # send response + $handle->push_write("\\gamename\\$ms->{game}\\location\\0\\validate\\$validate\\final\\"); + + # part 3: also request the list \list\gamename\ut -- skipped in UCC applets + $handle->push_write("\\list\\\\gamename\\$ms->{game}\\final\\"); + + } + + # part 3b: receive the entire list in multiple steps. + if ($m =~ m/\\ip\\/) { + # add buffer to the list + $master_list .= $m; + } + } + ); +} + +1; |
