diff options
Diffstat (limited to 'lib/MasterServer')
| -rwxr-xr-x | lib/MasterServer/Core/Logging.pm | 10 | ||||
| -rwxr-xr-x | lib/MasterServer/Core/Schedulers.pm | 7 | ||||
| -rwxr-xr-x | lib/MasterServer/Core/Util.pm | 4 | ||||
| -rwxr-xr-x | lib/MasterServer/Core/Version.pm | 4 | ||||
| -rwxr-xr-x | lib/MasterServer/Database/SQLite/dbAddServers.pm | 2 | ||||
| -rwxr-xr-x | lib/MasterServer/Database/SQLite/dbExtendedInfo.pm | 88 | ||||
| -rwxr-xr-x | lib/MasterServer/Database/SQLite/dbGetServers.pm | 2 | ||||
| -rwxr-xr-x | lib/MasterServer/Database/SQLite/dbMaintenance.pm | 2 | ||||
| -rwxr-xr-x | lib/MasterServer/Database/SQLite/dbStats.pm | 2 | ||||
| -rwxr-xr-x | lib/MasterServer/Database/SQLite/dbUTServerInfo.pm | 122 | ||||
| -rwxr-xr-x | lib/MasterServer/UDP/BeaconCatcher.pm | 3 | ||||
| -rwxr-xr-x | lib/MasterServer/UDP/DatagramProcessor.pm | 16 | ||||
| -rwxr-xr-x | lib/MasterServer/UDP/UDPTicker.pm | 5 | ||||
| -rwxr-xr-x | lib/MasterServer/UDP/UpLink.pm | 24 |
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); |
