aboutsummaryrefslogtreecommitdiff
path: root/lib/MasterServer/Util
diff options
context:
space:
mode:
authorDarkelarious <darkelarious@333networks.com>2017-08-22 11:00:13 +0200
committerDarkelarious <darkelarious@333networks.com>2017-08-22 11:00:13 +0200
commitc06322da38b4cb76b2036af1a5448083adb8ff20 (patch)
tree189c9f0fec3325be927f763aba23cf18aa68cfe4 /lib/MasterServer/Util
parente0d727670cbeda0db0812c5c9efc503d75f8d0a4 (diff)
downloadMasterServer-Perl-2.4.0.tar.gz
MasterServer-Perl-2.4.0.zip
new server checking mechanism, complete recode of major functionsv2.4.0
Diffstat (limited to 'lib/MasterServer/Util')
-rwxr-xr-xlib/MasterServer/Util/KFStatsWatcher.pm22
-rwxr-xr-xlib/MasterServer/Util/UDPBrowser.pm54
2 files changed, 60 insertions, 16 deletions
diff --git a/lib/MasterServer/Util/KFStatsWatcher.pm b/lib/MasterServer/Util/KFStatsWatcher.pm
index 6601aa3..d78fbf9 100755
--- a/lib/MasterServer/Util/KFStatsWatcher.pm
+++ b/lib/MasterServer/Util/KFStatsWatcher.pm
@@ -4,51 +4,41 @@ use strict;
use warnings;
use AnyEvent::IO;
use Exporter 'import';
-
our @EXPORT = qw| read_kfstats |;
################################################################################
## Read Killing Floor Statistics from the file.
################################################################################
sub read_kfstats {
- my ($self) = shift;
+ my $self = shift;
# open file and read content
return aio_load($self->{kfstats_file},
sub {
my $f = shift;
-
- # process player data as blocks
my $block = "";
# read player stats
for my $l (split /^/, $f) {
-
- # add data to block
+ # add data to "player" block
$block .= $l;
# if block contains last item GamesLost, process block
if ($l =~ m/^(GamesLost=)/i){
-
- # treat as array
my @s = split "\n", $block;
# process items
my %h;
for my $m (@s) {
- if ($m =~ m/(KFPlayerStats\])$/i) { $h{UTkey} = substr $m, 1, index($m, " ")-1; }
- if ($m =~ m/=/) {$h{substr $m, 0, index($m, "=")} = substr $m, index($m, "=")+1; }
+ if ($m =~ m/(KFPlayerStats\])$/i) {
+ $h{UTkey} = substr $m, 1, index($m, " ")-1;}
+ if ($m =~ m/=/) {
+ $h{substr $m, 0, index($m, "=")} = substr $m, index($m, "=")+1;}
}
-
- # store in db
$self->write_kfstats(\%h);
-
- # clear block for next player
$block = "";
}
}
-
- # notify
$self->log("kfstat", "Updated Killing Floor player stats.");
}
);
diff --git a/lib/MasterServer/Util/UDPBrowser.pm b/lib/MasterServer/Util/UDPBrowser.pm
new file mode 100755
index 0000000..045a7a8
--- /dev/null
+++ b/lib/MasterServer/Util/UDPBrowser.pm
@@ -0,0 +1,54 @@
+package MasterServer::Util::UDPBrowser;
+
+use strict;
+use warnings;
+use AnyEvent::Handle::UDP;
+use Socket qw(sockaddr_in inet_ntoa);
+use Exporter 'import';
+our @EXPORT = qw| udpbrowser_host |;
+
+################################################################################
+## Wait for incoming UDP messages from game clients and other masterservers.
+## In contrary to the compliant TCP browser host, this function handles the
+## request in a single query and responds with a single udp list.
+## This read-only method is slightly unsafe as it bypasses the secure/validate
+## challenge; however, this list is freely available over the JSON api, so not
+## worth protecting against exploits.
+## Request format: \echo\request\gamename\postal2\list\\final\
+################################################################################
+sub udpbrowser_host {
+ # self, handle, packed address, buffer
+ my ($self, $udp, $paddress, $buffer) = @_;
+ my $rx = $self->data2hashref($buffer);
+ my $response = "";
+
+ # unpack ip from packed client address
+ my ($port, $iaddr) = sockaddr_in($paddress);
+ my $addr = inet_ntoa($iaddr);
+
+ # list request with valid gamename and list request
+ if ($rx->{gamename} && exists $rx->{list}) {
+ # get list and log
+ $response = $self->generate_list($rx->{gamename}, $rx->{list});
+ $self->log("list","$addr:$port retrieved the list for $rx->{gamename} over UDP");
+ }
+ else {
+ # log error
+ $response = "\\echo\\incorrect request format";
+ $self->log("warning","$addr:$port failed to retrieve the list over UDP for ".
+ ($rx->{gamename} || "empty_gamename"));
+ }
+
+ # close query with final tag
+ $response .= "\\final\\";
+
+ # split the response in chunks of 512 bytes and send (for large lists)
+ while (length $response > 512) {
+ my $chunk = substr $response, 0, 512, '';
+ $udp->push_send($chunk, $paddress);
+ }
+ # last <512 chunk
+ $udp->push_send($response, $paddress);
+}
+
+1;