aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rwxr-xr-xlib/MasterServer/Core/Logging.pm10
-rwxr-xr-xlib/MasterServer/Core/Schedulers.pm7
-rwxr-xr-xlib/MasterServer/Core/Util.pm4
-rwxr-xr-xlib/MasterServer/Core/Version.pm4
-rwxr-xr-xlib/MasterServer/Database/SQLite/dbAddServers.pm2
-rwxr-xr-xlib/MasterServer/Database/SQLite/dbExtendedInfo.pm88
-rwxr-xr-xlib/MasterServer/Database/SQLite/dbGetServers.pm2
-rwxr-xr-xlib/MasterServer/Database/SQLite/dbMaintenance.pm2
-rwxr-xr-xlib/MasterServer/Database/SQLite/dbStats.pm2
-rwxr-xr-xlib/MasterServer/Database/SQLite/dbUTServerInfo.pm122
-rwxr-xr-xlib/MasterServer/UDP/BeaconCatcher.pm3
-rwxr-xr-xlib/MasterServer/UDP/DatagramProcessor.pm16
-rwxr-xr-xlib/MasterServer/UDP/UDPTicker.pm5
-rwxr-xr-xlib/MasterServer/UDP/UpLink.pm24
14 files changed, 122 insertions, 169 deletions
diff --git a/lib/MasterServer/Core/Logging.pm b/lib/MasterServer/Core/Logging.pm
index d2094ed..260b379 100755
--- a/lib/MasterServer/Core/Logging.pm
+++ b/lib/MasterServer/Core/Logging.pm
@@ -18,15 +18,15 @@ sub error {
# which one?
switch ($error) {
# connection timed out
- case m/Connection timed out/i {$self->log("timeout", "on $instigator.");}
+ case m/Connection timed out/i {$self->log("timeout", "on $instigator");}
# connection reset by peer
- case m/Connection reset by peer/i {$self->log("reset", "on $instigator.");}
+ case m/Connection reset by peer/i {$self->log("reset", "on $instigator");}
# connection refused
- case m/Connection refused/i {$self->log("refused", "on $instigator.");}
+ case m/Connection refused/i {$self->log("refused", "on $instigator");}
# no such device or address
- case m/No such device or address/i {$self->log("nodevice", "on $instigator.");}
+ case m/No such device or address/i {$self->log("nodevice", "on $instigator");}
# if all else fails
- else {$self->log("error", "$error on $instigator.");}
+ else {$self->log("error", "$error on $instigator");}
}
}
diff --git a/lib/MasterServer/Core/Schedulers.pm b/lib/MasterServer/Core/Schedulers.pm
index 230a423..fa47d11 100755
--- a/lib/MasterServer/Core/Schedulers.pm
+++ b/lib/MasterServer/Core/Schedulers.pm
@@ -18,7 +18,7 @@ sub long_periodic_tasks {
return AnyEvent->timer (
after => 90, # grace time receiving beacons
- interval => 3600,
+ interval => 1800,
cb => sub {
# update Killing Floor stats
@@ -37,8 +37,9 @@ sub long_periodic_tasks {
# get serverlist
my $masterserverlist = $self->get_server(
- updated => 7200,
gamename => "333networks",
+ $self->{firstrun} ? (
+ updated => 7200 ) : (),
);
foreach my $ms (@{$masterserverlist}) {
@@ -53,7 +54,7 @@ sub long_periodic_tasks {
# do NOT reset $t, keep padding time -- you should not have more than 300
# entries in applets/syncer in total anyway.
- # Query Epic Games-based UCC applets periodically to get an additional
+ # Query Epic Games-alike applets periodically to get an additional
# list of online UT, Unreal and other game servers.
if ($self->{master_applet_enabled}) {
diff --git a/lib/MasterServer/Core/Util.pm b/lib/MasterServer/Core/Util.pm
index 5af8264..3ca009d 100755
--- a/lib/MasterServer/Core/Util.pm
+++ b/lib/MasterServer/Core/Util.pm
@@ -54,8 +54,8 @@ sub valid_address {
my $val_addr = ($a =~ '^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$') if $a;
my $val_port = ($p =~ m/^\d+$/ && 0 < $p && $p <= 65535) if $p;
- # exclude addresses where we don't want people sniffing
- for (qw|192.168.(.\d*).(.\d*) 127.0.(.\d*).(.\d*) 10.0.(.\d*).(.\d*)|){$val_addr = 0 if ($a =~ m/$_/)}
+ # exclude local addresses
+ if ($a =~ m/192.168.(\d).(\d)/ || $a =~ m/127.0.(\d).(\d)/ || $a =~ m/10.0.(\d).(\d)/) { $val_addr = 0; }
# only return true if both are valid
return ($val_addr && $val_port);
diff --git a/lib/MasterServer/Core/Version.pm b/lib/MasterServer/Core/Version.pm
index 0b4d058..277cd04 100755
--- a/lib/MasterServer/Core/Version.pm
+++ b/lib/MasterServer/Core/Version.pm
@@ -27,13 +27,13 @@ sub version {
$self->{build_type} = "333networks Masterserver-Perl Multidb";
# version
- $self->{build_version} = "2.4.0";
+ $self->{build_version} = "2.4.1";
# short version for uplinks
$self->{short_version} = "MS-perl $self->{build_version}";
# date yyyy-mm-dd
- $self->{build_date} = "2017-08-22";
+ $self->{build_date} = "2017-09-25";
#author, email
$self->{build_author} = "Darkelarious, darkelarious\@333networks.com";
diff --git a/lib/MasterServer/Database/SQLite/dbAddServers.pm b/lib/MasterServer/Database/SQLite/dbAddServers.pm
index 88b1bc8..084e0b4 100755
--- a/lib/MasterServer/Database/SQLite/dbAddServers.pm
+++ b/lib/MasterServer/Database/SQLite/dbAddServers.pm
@@ -44,7 +44,7 @@ sub update_server {
$o{gamever} ? ( 'gamever = ?' => $o{gamever}) : (),
$o{hostname} ? ('hostname = ?' => $o{hostname}) : (),
$o{hostport} ? ('hostport = ?' => $o{hostport}) : (),
- $o{direct} ? ( 'b333ms = CAST(? AS BOOLEAN)' => $o{direct}) : (),
+ $o{direct} ? ( 'b333ms = ?' => $o{direct}) : (),
$o{direct} ? ( 'beacon = datetime(?, \'unixepoch\')' => $o{updated}) : (),
$o{updated} ? ( 'updated = datetime(?, \'unixepoch\')' => $o{updated}) : (),
);
diff --git a/lib/MasterServer/Database/SQLite/dbExtendedInfo.pm b/lib/MasterServer/Database/SQLite/dbExtendedInfo.pm
new file mode 100755
index 0000000..e2eb1bc
--- /dev/null
+++ b/lib/MasterServer/Database/SQLite/dbExtendedInfo.pm
@@ -0,0 +1,88 @@
+package MasterServer::Database::SQLite::dbExtendedInfo;
+
+use strict;
+use warnings;
+use MasterServer::Core::Util 'sqlprint';
+use Exporter 'import';
+our @EXPORT = qw| insert_extended
+ update_extended
+ delete_players
+ insert_players |;
+
+################################################################################
+## Add extended server information for a new server.
+## opts: ipm hostport
+################################################################################
+sub insert_extended {
+ my $self = shift;
+ my %o = ( @_);
+ return $self->{dbh}->do(
+ "INSERT INTO extended_info (server_id)
+ SELECT (SELECT id FROM serverlist WHERE ip = ? AND hostport = ?)",
+ undef, $o{ip}, $o{hostport});
+}
+
+################################################################################
+## Update serverinfo for an existing address to the utserver list.
+## opts: all server info data fields.
+################################################################################
+sub update_extended {
+ my $self = shift;
+ my %o = (updated => time, @_);
+
+ # try updating it in serverlist
+ my %H = (
+ $o{minnetver} ? ( 'minnetver = ?' => $o{minnetver} ) : (),
+ $o{location} ? ( 'location = ?' => $o{location} ) : (),
+ $o{listenserver} ? ( 'listenserver = ?' => $o{listenserver}) : (),
+ $o{AdminName} ? ( 'adminname = ?' => $o{AdminName}) : (),
+ $o{AdminEMail} ? ( 'adminemail = ?' => $o{AdminEMail}) : (),
+ $o{password} ? ( 'password = ?' => $o{password}) : (),
+ $o{gametype} ? ( 'gametype = ?' => $o{gametype}) : (),
+ $o{gamestyle} ? ( 'gamestyle = ?' => $o{gamestyle}) : (),
+ $o{changelevels} ? ( 'changelevels = ?' => $o{changelevels}) : (),
+ $o{maptitle} ? ( 'maptitle = ?' => $o{maptitle}) : (),
+ $o{mapname} ? ( 'mapname = ?' => $o{mapname}) : (),
+ $o{numplayers} ? ( 'numplayers = ?' => $o{numplayers}) : ('numplayers = ?' => 0),
+ $o{maxplayers} ? ( 'maxplayers = ?' => $o{maxplayers}) : ('maxplayers = ?' => 0),
+ $o{minplayers} ? ( 'minplayers = ?' => $o{minplayers}) : ('minplayers = ?' => 0),
+ $o{botskill} ? ( 'botskill = ?' => $o{botskill}) : (),
+ $o{balanceteams} ? ( 'balanceteams = ?' => $o{balanceteams} ) : (),
+ $o{playersbalanceteams} ? ( 'playersbalanceteams = ?' => $o{playersbalanceteams}) : (),
+ $o{friendlyfire} ? ( 'friendlyfire = ?' => $o{friendlyfire}) : (),
+ $o{maxteams} ? ( 'maxteams = ?' => $o{maxteams}) : (),
+ $o{timelimit} ? ( 'timelimit = ?' => $o{timelimit}) : (),
+ $o{goalteamscore} ? ( 'goalteamscore = ?' => $o{goalteamscore}) : (),
+ $o{fraglimit} ? ( 'fraglimit = ?' => $o{fraglimit}) : (),
+ $o{mutators} ? ( 'mutators = ?' => $o{mutators}) : ('mutators = ?' => "None"),
+ $o{updated} ? ( 'updated = datetime(?, \'unixepoch\')' => $o{updated}) : (),
+ );
+
+ my($q, @p) = sqlprint("UPDATE extended_info !H WHERE server_id = ?", \%H, $o{sid});
+ return $self->{dbh}->do($q, undef, @p);
+}
+
+################################################################################
+## Delete all players from a certain server ID
+## opts: server id
+################################################################################
+sub delete_players {
+ my ($self, $sid) = @_;
+
+ # delete players with server_id
+ return $self->{dbh}->do(
+ "DELETE FROM player_info WHERE server_id = ?",
+ undef, $sid);
+}
+
+################################################################################
+## Insert player info for a single player in server sid
+## opts: server id, player info
+################################################################################
+sub insert_players {
+ my ($self, @pl) = @_;
+ my($q, @p) = sqlprint("INSERT INTO player_info (server_id, player, team, frags, mesh, skin, face, ping, ngsecret) VALUES (!l)", \@pl);
+ return $self->{dbh}->do($q, undef, @p);
+}
+
+1;
diff --git a/lib/MasterServer/Database/SQLite/dbGetServers.pm b/lib/MasterServer/Database/SQLite/dbGetServers.pm
index 7ddce2b..e899485 100755
--- a/lib/MasterServer/Database/SQLite/dbGetServers.pm
+++ b/lib/MasterServer/Database/SQLite/dbGetServers.pm
@@ -31,7 +31,7 @@ sub get_server {
$o{before} ? ('updated < datetime(?, \'unixepoch\')' => (time-$o{before})) : (),
# never process blacklisted servers, unless explicitly specified
- ('blacklisted = CAST(? AS BOOLEAN)' => $o{blacklisted}),
+ ('blacklisted = ?' => $o{blacklisted}),
);
my @select = ( qw|
diff --git a/lib/MasterServer/Database/SQLite/dbMaintenance.pm b/lib/MasterServer/Database/SQLite/dbMaintenance.pm
index ec9b5cc..a729b2f 100755
--- a/lib/MasterServer/Database/SQLite/dbMaintenance.pm
+++ b/lib/MasterServer/Database/SQLite/dbMaintenance.pm
@@ -1,4 +1,4 @@
-package MasterServer::Database::Pg::dbMaintenance;
+package MasterServer::Database::SQLite::dbMaintenance;
use strict;
use warnings;
diff --git a/lib/MasterServer/Database/SQLite/dbStats.pm b/lib/MasterServer/Database/SQLite/dbStats.pm
index 57d3100..0d0b8eb 100755
--- a/lib/MasterServer/Database/SQLite/dbStats.pm
+++ b/lib/MasterServer/Database/SQLite/dbStats.pm
@@ -69,7 +69,7 @@ sub write_direct_beacons {
my $self = shift;
my $u = $self->{dbh}->do(
"UPDATE serverlist
- SET b333ms = CAST(0 AS BOOLEAN)
+ SET b333ms = 0
WHERE beacon < datetime(?, \'unixepoch\') AND b333ms",
undef, time-3600);
$self->log("unset", "Lost $u direct beacons.") if ($u > 0);
diff --git a/lib/MasterServer/Database/SQLite/dbUTServerInfo.pm b/lib/MasterServer/Database/SQLite/dbUTServerInfo.pm
deleted file mode 100755
index 5a579ac..0000000
--- a/lib/MasterServer/Database/SQLite/dbUTServerInfo.pm
+++ /dev/null
@@ -1,122 +0,0 @@
-package MasterServer::Database::SQLite::dbUTServerInfo;
-
-use strict;
-use warnings;
-use MasterServer::Core::Util 'sqlprint';
-use Exporter 'import';
-
-our @EXPORT = qw| add_utserver
- update_utserver
- delete_utplayers
- insert_utplayer |;
-
-################################################################################
-## Update serverinfo for an existing address to the utserver list.
-## opts: all server info data fields.
-################################################################################
-sub update_utserver {
- my $self = shift;
- my $id = shift;
- my %s = (
- # defaults
- updated => time,
- @_);
-
- # try updating it in serverlist
- my %H = (
- $s{minnetver} ? ( 'minnetver = ?' => $s{minnetver} ) : (),
- $s{gamever} ? ( 'gamever = ?' => int( $s{gamever}) ) : (),
- $s{location} ? ( 'location = ?' => $s{location} ) : (),
- $s{listenserver} ? ( 'listenserver = ?' => ( $s{listenserver} ? 1 : 0) ) : (),
- $s{hostport} ? ( 'hostport = ?' => $s{hostport}) : (),
- $s{hostname} ? ( 'hostname = ?' => $s{hostname}) : (),
- $s{AdminName} ? ( 'adminname = ?' => $s{AdminName}) : (),
- $s{AdminEMail} ? ( 'adminemail = ?' => $s{AdminEMail}) : (),
- $s{password} ? ( 'password = ?' => ( $s{password} ? 1 : 0) ) : (),
- $s{gametype} ? ( 'gametype = ?' => $s{gametype}) : (),
- $s{gamestyle} ? ( 'gamestyle = ?' => $s{gamestyle}) : (),
- $s{changelevels} ? ( 'changelevels = ?' => ( $s{changelevels} ? 1 : 0) ) : (),
- $s{maptitle} ? ( 'maptitle = ?' => $s{maptitle}) : (),
- $s{mapname} ? ( 'mapname = ?' => $s{mapname}) : (),
- $s{numplayers} ? ( 'numplayers = ?' => $s{numplayers}) : ('numplayers = ?' => 0),
- $s{maxplayers} ? ( 'maxplayers = ?' => $s{maxplayers}) : ('maxplayers = ?' => 0),
- $s{minplayers} ? ( 'minplayers = ?' => $s{minplayers}) : ('minplayers = ?' => 0),
- $s{botskill} ? ( 'botskill = ?' => $s{botskill}) : (),
- $s{balanceteams} ? ( 'balanceteams = ?' => ( $s{balanceteams} ? 1 : 0) ) : (),
- $s{playersbalanceteams} ? ( 'playersbalanceteams = ?' => ( $s{playersbalanceteams} ? 1 : 0) ) : (),
- $s{friendlyfire} ? ( 'friendlyfire = ?' => $s{friendlyfire}) : (),
- $s{maxteams} ? ( 'maxteams = ?' => $s{maxteams}) : (),
- $s{timelimit} ? ( 'timelimit = ?' => $s{timelimit}) : (),
- $s{goalteamscore} ? ( 'goalteamscore = ?' => int( $s{goalteamscore}) ) : (),
- $s{fraglimit} ? ( 'fraglimit = ?' => int( $s{fraglimit}) ) : (),
- $s{mutators} ? ( 'mutators = ?' => $s{mutators}) : ('mutators = ?' => "None"),
- $s{updated} ? ('updated = datetime(?, \'unixepoch\')' => $s{updated}) : (),
- );
-
- my($q, @p) = sqlprint("UPDATE utserver_info !H WHERE server_id = ?", \%H, $id);
- return $self->{dbh}->do($q, undef, @p);
-}
-
-
-################################################################################
-## Add a new utserver and trigger the update routine above.
-## opts: id, server info data
-################################################################################
-sub add_utserver {
- my ($self, $ip, $port) = @_;
-
- # create new entry
- return $self->{dbh}->do(
- "INSERT INTO utserver_info (server_id)
- SELECT (SELECT id FROM serverlist WHERE ip = ? AND port = ?)",
- undef, $ip, $port);
-}
-
-
-################################################################################
-## Delete all players from a certain server ID
-## opts: server id
-################################################################################
-sub delete_utplayers {
- my ($self, $sid) = @_;
-
- # delete players for server_id
- return $self->{dbh}->do(
- "DELETE FROM utplayer_info WHERE server_id = ?",
- undef, $sid);
-}
-
-################################################################################
-## Insert player info for a single player in server sid
-## opts: server id, player info
-################################################################################
-sub insert_utplayer {
- my $self = shift;
- my $sid = shift;
- my %s = (
- updated => time,
- @_);
-
- # apparently useless chunk of code
- # FIXME move to site part
- my %H = (
- $s{server_id} ? ( 'server_id = ?' => $s{server_id}) : (),
- $s{player} ? ( 'player = ?' => $s{player}) : (),
- $s{team} ? ( 'team = ?' => int( $s{team})) : (),
- $s{frags} ? ( 'frags = ?' => int( $s{frags})) : (),
- $s{mesh} ? ( 'mesh = ?' => $s{mesh}) : (),
- $s{skin} ? ( 'skin = ?' => $s{skin}) : (),
- $s{face} ? ( 'face = ?' => $s{face}) : (),
- $s{ping} ? ( 'ping = ?' => int( $s{ping})) : (),
- $s{ngsecret} ? ( 'ngsecret = ?' => $s{ngsecret}) : (),
- $s{updated} ? ('updated = datetime(?, \'unixepoch\')' => $s{updated}) : (),
- );
-
- # insert
- return $self->{dbh}->do(
- "INSERT INTO utplayer_info (server_id, player, team, frags, mesh, skin, face, ping, ngsecret)
- VALUES (?,?,?,?,?,?,?,?,?)",
- undef, $sid, $s{player}, $s{team}, $s{frags}, $s{mesh}, $s{skin}, $s{face}, $s{ping}, $s{ngsecret});
-}
-
-1;
diff --git a/lib/MasterServer/UDP/BeaconCatcher.pm b/lib/MasterServer/UDP/BeaconCatcher.pm
index 6058bfa..1bfc5b0 100755
--- a/lib/MasterServer/UDP/BeaconCatcher.pm
+++ b/lib/MasterServer/UDP/BeaconCatcher.pm
@@ -34,6 +34,9 @@ sub recv_beacon {
# unpack ip from packed client address
my ($port, $iaddr) = sockaddr_in($paddress);
my $beacon_address = inet_ntoa($iaddr);
+
+ # ignore localhost and restricted IPs like localhost
+ return unless $self->valid_address($beacon_address, $port);
# determine and process heartbeat
if ($buffer =~ m/\\heartbeat\\/) {
diff --git a/lib/MasterServer/UDP/DatagramProcessor.pm b/lib/MasterServer/UDP/DatagramProcessor.pm
index 5587875..87c23a1 100755
--- a/lib/MasterServer/UDP/DatagramProcessor.pm
+++ b/lib/MasterServer/UDP/DatagramProcessor.pm
@@ -77,14 +77,12 @@ sub process_datagram {
enctype => $rx->{enctype},
validate => $rx->{validate},
);
- $self->log("secure","$o{ip}, $o{port} failed validation for ".
- ($rx->{gamename} || "empty_gamename")
- ."; sent: '". ($o{secure} || "empty_secure")
- ."', expected '". ($val_str || "empty_v_string")
- ."', got '". ($rx->{validate} || "empty_r_validate")
- ."' with cipher '". ($self->get_game_props(gamename => $rx->{gamename})->[0]->{cipher} || "empty_cipher")
- ."'"
- );
+ $self->log("secure","$o{ip}, $o{port} failed validation for ".($rx->{gamename} || "empty_gamename") );
+ $self->log("secure",
+ "cipher: " .($self->get_game_props(gamename => $rx->{gamename})->[0]->{cipher} || "empty_cipher") . ", "
+ ."secure: " .($o{secure} || "empty_secure"). ", "
+ ."expected: " .($val_str || "empty_v_string"). ", "
+ ."received: " .($rx->{validate} || "empty_r_validate"));
# remove addresses anyway to prevent error spamming in log
$self->remove_pending(ip => $o{ip}, port => $o{port});
@@ -143,7 +141,7 @@ sub unify_information {
my %uei; # unified extended info
my @upi; # unified player info
- # FIXME unify with player playername name
+ # FIXME unify with {player playername name, other keys/columns}
# first process all available player entries
for (my $i = 0; exists $rx->{"player_$i"}; $i++) {
diff --git a/lib/MasterServer/UDP/UDPTicker.pm b/lib/MasterServer/UDP/UDPTicker.pm
index 0566449..f5673a4 100755
--- a/lib/MasterServer/UDP/UDPTicker.pm
+++ b/lib/MasterServer/UDP/UDPTicker.pm
@@ -30,8 +30,9 @@ sub udp_ticker {
# tick through pending list and server list
my $server_info = AnyEvent->timer (
- after => 120, # grace time receiving beacons
- interval => 0.2, # ~5 servers/s
+ after => 120, # grace time receiving beacons -- MUST be the last
+ # function to start as it controls the first_run parameter
+ interval => 0.2, # ~5 servers/second
cb => sub {
# reset counters if minimum time before reset passed + list processed
if ($self->{firstrun}) {
diff --git a/lib/MasterServer/UDP/UpLink.pm b/lib/MasterServer/UDP/UpLink.pm
index d523ad0..16550c3 100755
--- a/lib/MasterServer/UDP/UpLink.pm
+++ b/lib/MasterServer/UDP/UpLink.pm
@@ -70,8 +70,7 @@ sub do_uplink {
}
################################################################################
-## Respond to status-like queries. Supported queries are basic, info, rules,
-## players, status.
+## Respond to status-like queries. Supported: basic, info, rules, status.
## Note: this replaces the \about\ query in the TCP handler!
################################################################################
sub handle_status_query {
@@ -124,31 +123,16 @@ sub handle_status_query {
# rules query
if (defined $rx->{rules} || defined $rx->{status}) {
- $response .= "\\mutators\\333networks synchronization, UCC Master applet synchronization, Display Stats As Players"
+ $response .= "\\mutators\\333networks synchronization, UCC Master applet synchronization, Server Status Checker"
. "\\AdminName\\".($self->{masterserver_name} || "")
. "\\AdminEMail\\".($self->{masterserver_contact} || "")
. "\\queryid\\$query_id.".$sub_id++;
}
-
- # players query
- if (defined $rx->{players} || defined $rx->{status}) {
- # list game stats as if they were players. let the client figure out how
- # to list this information on their website (hint: that's us)
- my $c = 0;
- foreach my $p (@{$gameinfo}) {
- $response .= "\\player_$c\\".($p->{description} || "")
- . "\\team_$c\\" .($p->{gamename} || "")
- . "\\skin_$c\\" .($p->{num_total} || 0) . " total"
- . "\\mesh_$c\\" .($p->{num_uplink} || 0) . " direct";
- $c++; # start with player_0, increment
- }
- $response .= "\\queryid\\$query_id.".$sub_id++;
- }
-
+
# close query with final tag
$response .= "\\final\\";
- # split the response in chunks of 512 bytes and send
+ # split the response in chunks of 512 characters and send
while (length $response > 512) {
my $chunk = substr $response, 0, 512, '';
$udp->push_send($chunk, $paddress);