1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
package MasterServer::UDP::BeaconChecker;
use strict;
use warnings;
use AnyEvent::Handle::UDP;
use Exporter 'import';
our @EXPORT = qw| query_udp_server |;
################################################################################
## Get the server status from any server over UDP and store the received
## information in the database. $secure determines the type of query:
## secure/pending or information.
################################################################################
sub query_udp_server {
my ($self, $id, $ip, $port, $secure, $message_type) = @_;
my $buf = "";
# debug logging
# $self->log("debug", "Query server $id ($ip:$port)");
# connect with UDP server
my $udp_client; $udp_client = AnyEvent::Handle::UDP->new(
connect => [$ip, $port],
timeout => $self->{timeout_time},
on_timeout => sub {$udp_client->destroy();}, # do not report timeouts
on_error => sub {$udp_client->destroy();}, # or errors
on_recv => sub {
# add packet to buffer
$buf .= $_[0];
# FIXME: note to self: order is important when having combined queries!
# TODO: find a more elegant and long-time solution for this.
# message type 1: \basic\\secure\wookie
# if validate, assume that we sent a \basic\secure request.
if ($buf =~ m/\\validate\\/){
$self->process_udp_validate($buf, $ip, undef, $port);
}
# message type 0: \basic\\info\
# if gamename, ver, hostname and hostport are available, but NOT the value
# "listenserver", it would have been \basic\info
if ($buf =~ m/\\gamename\\/ &&
$buf =~ m/\\hostname\\/ &&
$buf =~ m/\\hostport\\/ &&
$buf !~ m/\\listenserver\\/ ) {
$self->process_query_response($buf, $ip, $port);
}
# message type 2: \status\
# contains same info as \basic\\info, but also "listenserver". Only for UT.
if ($buf =~ m/\\gamename\\ut/ &&
$buf =~ m/\\hostname\\/ &&
$buf =~ m/\\hostport\\/ &&
$buf =~ m/\\listenserver\\/ ) {
$self->process_status_response($buf, $ip, $port);
}
# else partial information received. wait for more.
# else { }
},
);
#
# Send secure message or status, depending on provided variables
# Message types can be
# 0: \basic\\info\
# 1: \basic\\secure\wookie
# 2: \status\
#
# determine the message
my $message = "\\basic\\\\info\\"; # default 0
$message = "\\basic\\\\secure\\$secure" if ($secure ne "" && $self->{require_secure_beacons} > 0); # message_type 1
$message = "\\status\\" if ($message_type == 2);
# send selected message
$udp_client->push_send($message);
}
1;
|