aboutsummaryrefslogtreecommitdiff
path: root/lib/MasterWebInterface/Handler/Tools/AddNew.pm
diff options
context:
space:
mode:
authorDarkelarious <darkelarious@333networks.com>2017-09-25 23:13:47 +0200
committerDarkelarious <darkelarious@333networks.com>2017-09-25 23:13:47 +0200
commit18921404e5454cdf202b7b4f70a2777f3e297998 (patch)
treed24abef8f510998423cb8f107228e253ee6b4825 /lib/MasterWebInterface/Handler/Tools/AddNew.pm
downloadWebInterface-Perl-MS-Perl-18921404e5454cdf202b7b4f70a2777f3e297998.tar.gz
WebInterface-Perl-MS-Perl-18921404e5454cdf202b7b4f70a2777f3e297998.zip
Web interface for MasterServer-Perl
Diffstat (limited to 'lib/MasterWebInterface/Handler/Tools/AddNew.pm')
-rwxr-xr-xlib/MasterWebInterface/Handler/Tools/AddNew.pm280
1 files changed, 280 insertions, 0 deletions
diff --git a/lib/MasterWebInterface/Handler/Tools/AddNew.pm b/lib/MasterWebInterface/Handler/Tools/AddNew.pm
new file mode 100755
index 0000000..dbeaa90
--- /dev/null
+++ b/lib/MasterWebInterface/Handler/Tools/AddNew.pm
@@ -0,0 +1,280 @@
+package MasterWebInterface::Handler::Tools::AddNew;
+use strict;
+use warnings;
+use Encode;
+use Socket;
+use IP::Country::Fast;
+use TUWF ':html';
+
+TUWF::register(
+ qr{new} => \&addnewserver,
+ qr{new/([\.\w]+):(\d+)/(\d+)} => \&valnewserver,
+);
+
+################################################################################
+# Helper page to add server addresses to the masterserver manually
+# Uses the valnewserver page/function to validate an active server.
+################################################################################
+sub addnewserver {
+ my $self = shift;
+ $self->htmlHeader(title => "Add a new server");
+
+ div class => "mainbox detail";
+ div class => "header";
+ h1 "Manually add a server";
+ p class => "alttitle", "333networks allows you to add supported servers manually. On this page is explained how to add your server to our masterserver.";
+ end;
+
+ p "You can add your server to our site in two ways:";
+ ol;
+ li;
+ txt "Follow the instructions on the ";
+ a href => "/masterserver", "MasterServer";
+ txt " page. This also allows other players to see your server online.";
+ end;
+ li "Follow the instructions below. This allows you to share links to your server page.";
+ end;
+
+ p;
+ txt "To link to your serverstatus, fill in your gameserver's IP and your gameserver's queryport, usually the game port +1. If your server does not show up, check for typos and verify that your firewall is not blocking your server. Your ip is ";
+ span class => "ext", $ENV{'REMOTE_ADDR'};
+ txt ".";
+ end;
+
+ table class => "shareopts new";
+ Tr;
+ td "IP address:";
+ td; input type => "text", class => "text", id => "ip", value => $ENV{'REMOTE_ADDR'}; end;
+ end;
+ Tr;
+ td "Query port (game port + 1):";
+ td; input type => "text", class => "text", id => "port", value => "7778"; end;
+ end;
+ Tr;
+ td "";
+ td; input type => "submit", class => "submit", value => "Search Server", onclick => "QueryLink()"; end;
+ end;
+ end;
+
+ p id => "newlink", class => "ext";
+ txt "Please enter the server's ip and port in the fields above.";
+ end;
+
+ end;
+
+ div id => "validate";
+ end;
+
+ $self->htmlFooter;
+}
+
+
+################################################################################
+# Query and validate a manually added server.
+# Arguments passed on via javascript (unsafe)
+# Random number prevents some browsers from caching the request and also
+# prevents the /gamename/ip:port regex from catching this function/page.
+################################################################################
+sub valnewserver {
+ my ($self, $s_addr, $s_port, $s_rand) = @_;
+ my ($ip,$port) = $self->valid_address($s_addr, $s_port);
+
+ # return "invalid" if no valid ip/port
+ if (!$ip || !$port){die "invalid";return;}
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # DANGEROUS CODE: DO NOT EDIT UNLESS YOU KNOW WHAT YOU ARE DOING
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ #
+ # Query the game server here on the spot. This may cause timeouts/errors with
+ # slow or unresponsive servers. Will generate an error in the browser if so.
+ #
+ # TODO: consider safer code for this part.
+ #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ # prepare target
+ my $qaddr = sockaddr_in($port, inet_aton($ip) );
+ my ($data, $buf) = ("","");
+
+ eval {
+ # return error stats on time-out
+ local $SIG{ALRM} = sub {die "timeout"};
+
+ alarm 2;
+ socket(SERVER, PF_INET, SOCK_DGRAM, getprotobyname("udp")) or die "timeout";
+ connect(SERVER, $qaddr);
+ send(SERVER, "\\status\\", 0, $qaddr);
+
+ #receive server info
+ while($data !~ /\\final\\/) {
+ recv(SERVER, $data, 0xFFFF, 0);
+ $buf .= $data;
+ }
+ shutdown(SERVER, 2);
+ alarm 0;
+ };
+
+ # turn buffer into hashref
+ my @a = split /\\/, encode('UTF-8', $buf || "");
+ shift @a;
+ my %h = (@a, (scalar @a % 2 == 1) ? "dummy" : () );
+ %h = map { lc $_ => $h{$_} } keys %h;
+ my $r = \%h;
+
+ # any text received?
+ # check for some random, supposedly existing tags like gamename, gamever
+ if ($r->{gamename} || $r->{gamever}) {
+ div class => "mainbox detail";
+ div class => "header";
+ h1 $r->{hostname} || "Unnamed Server";
+ end;
+
+ div class => "container";
+ div class => "thumbnail";
+
+ # find the correct thumbnail, otherwise standard 333 esrb pic
+ my $mapfig = "$self->{map_url}/default/333esrb.jpg";
+
+ # get prefix and mapname
+ my $mapname = lc $r->{mapname};
+ my ($pre,$post) = $mapname =~ /^(DM|CTF\-BT|BT|CTF|DOM|AS|JB|TO|SCR|MH)-(.*)/i;
+ my $prefix = ($pre ? uc $pre : "other");
+
+ # if map figure exists, use it
+ if (-e "$self->{map_dir}/$r->{gamename}/$prefix/$mapname.jpg") {
+ $mapfig = "$self->{map_url}/$r->{gamename}/$prefix/$mapname.jpg";
+ }
+
+ # if not, game default image
+ elsif (-e "$self->{map_dir}/default/$r->{gamename}.jpg") {
+ $mapfig = "$self->{map_url}/default/$r->{gamename}.jpg";
+ }
+
+ img src => $mapfig,
+ alt => $mapfig,
+ title => ($r->{mapname} || "Unknown");
+ span ($r->{maptitle} || "Unknown");
+ end;
+
+ table class => "mapinfo";
+ if ($r->{maxplayers}) {
+ Tr;
+ td class => "wc1", "Players:";
+ td;
+ txt $r->{numplayers} || 0;
+ txt "/";
+ txt $r->{maxplayers} || 0;
+ end;
+ end;
+ }
+ if ($r->{botskill} && $r->{minplayers}) {
+ Tr;
+ td "Bots:";
+ td;
+ txt $r->{minplayers} || 0;
+ txt " ";
+ txt ($r->{botskill} || "Standard");
+ txt " bot"; txt ($r->{minplayers} == 1 ? "" : "s");
+ end;
+ end;
+ }
+ end;
+ end; # container
+
+ #
+ # Specific server entry information
+ #
+ table class => "serverinfo";
+ Tr;
+ th class => "wc1", "Server Info";
+ th "";
+ end;
+ Tr;
+ td "Address:";
+ td title => $r->{port}, (($r->{ip} || $ip). ":". ($r->{hostport} || $port));
+ end;
+ if ($r->{adminname}) {
+ Tr;
+ td "Admin:";
+ td $r->{adminname};
+ end;
+ }
+ Tr;
+ td class => "wc1", "Contact:";
+ td;
+ if ($r->{adminemail}) {txt $r->{adminemail}}
+ end;
+ end;
+ Tr;
+ td class => "wc1", "Location:";
+ my $reg = IP::Country::Fast->new();
+ my ($flag, $country) = $self->countryflag($reg->inet_atocc($ip) || "");
+ td;
+ img class => "flag", src => "/flag/$flag.svg";
+ txt " ". $country;
+ end;
+ end;
+ end;
+
+ #
+ # Specific game and version information
+ #
+ table class => "gameinfo";
+ Tr;
+ th class => "wc1", "Game Info";
+ th "";
+ end;
+ Tr;
+ td "Game:";
+ td $self->dbGetGameDesc($r->{gamename}) || "unknown game";
+ end;
+ if ($r->{gametype}) {
+ Tr;
+ td "Type:";
+ td $r->{gametype};
+ end;
+ }
+ if ($r->{gamestyle}) {
+ Tr;
+ td "Style:";
+ td $r->{gamestyle};
+ end;
+ }
+ if ($r->{gamever}) {
+ Tr;
+ td "Version:";
+ td $r->{gamever};
+ end;
+ }
+ end;
+
+ #
+ # Mutator list
+ #
+ table class => "mutators";
+ Tr;
+ th "Mutators";
+ end;
+ Tr;
+ td;
+ if (defined $r->{mutators}) {
+ txt $r->{mutators};}
+ else {i "This server does not have any mutators listed.";}
+ end;
+ end;
+ end;
+
+ # add this server to the list of pending IPs if it does not exist in the db already
+ p class => "ext", ( $self->dbAddServer(ip => $ip, port => $port) ? "The server was added to the database." : "The server already exists in the database." );
+ end; # mainbox detail
+
+ }
+ else {
+ # else return "invalid" to make AJAX understand that the query failed.
+ txt "invalid";
+ }
+}
+
+1;
+