#!/usr/bin/perl ################################################################################ # Simulate a gameserver # - send beacon # - respond to secure # - respond to status # ################################################################################ use strict; use warnings; use AnyEvent; use AnyEvent::Handle::UDP; use Socket qw( sockaddr_in inet_aton); use Data::Dumper 'Dumper'; $|++; our %S; require "../common/supportedgames.pl"; require "../common/auth.pl"; require "../common/status.pl"; # set game (note that properties can be set in "common/status.pl") my $gamename = &getGameName; my $port = 7778; # set masterserver my $masteraddress = "localhost"; my $masterport = 27900; my $ma = sockaddr_in($masterport, inet_aton($masteraddress) ); # parse label my $label = ( $S{game}->{lc $gamename}->{label} || $gamename ); # start simulation print "Simulating [$label] gameserver on port $port.\n"; # loop my $cv = AnyEvent->condvar; # start UDP server on $port my $udp_server; $udp_server = AnyEvent::Handle::UDP->new( bind => ['0.0.0.0', $port], on_recv => sub { # beacon address, handle, packed client address my ($b, $c, $pa) = @_; # parse and remove trailing newline, leading undef chomp $b; my @data = split /\\/, $b; return if (scalar @data <= 1); shift @data; # if status if ($data[0] =~ m/^(basic|info|rules|players|status|echo)$/ig) { $udp_server->push_send(&getResponse($data[0], $data[1] || ""), $pa) } # respond to possible secure if ($b =~ m/(secure)/ig) { my %h; my @a = split /\\/, ($b||""); shift @a; %h = (@a, (scalar @a % 2 == 1) ? "dummy" : () ); # calculate validate my $validate = get_validate_string( $S{game}->{$gamename}->{key}, ($h{secure}|| "wookie"), int( $h{enctype} || 0) ); $udp_server->push_send("\\validate\\".$validate, $pa) } } ); # send out heartbeats my $timer = AnyEvent->timer ( after => 1, interval => 10, cb => sub { $udp_server->push_send("\\heartbeat\\$port\\gamename\\$gamename", $ma); }, ); $cv->recv; 1;