File Coverage

blib/lib/Games/AssaultCube/MasterserverQuery.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             # Declare our package
2             package Games::AssaultCube::MasterserverQuery;
3              
4             # import the Moose stuff
5 2     2   13091 use Moose;
  0            
  0            
6             use MooseX::StrictConstructor;
7              
8             # Initialize our version
9             use vars qw( $VERSION );
10             $VERSION = '0.04';
11              
12             # get some utility stuff
13             use Games::AssaultCube::MasterserverQuery::Response;
14             use LWP::UserAgent;
15             use HTTP::Request;
16              
17             # TODO make validation so we accept a *real* URI
18             has 'server' => (
19             isa => 'Str',
20             is => 'ro',
21             default => 'http://masterserver.cubers.net/cgi-bin/AssaultCube.pl/retrieve.do?item=list',
22             );
23              
24             has 'timeout' => (
25             isa => 'Int',
26             is => 'rw',
27             default => 30,
28             );
29              
30             has 'useragent' => (
31             isa => 'LWP::UserAgent',
32             is => 'rw',
33             default => sub { return LWP::UserAgent->new },
34             );
35              
36             has 'request' => (
37             isa => 'HTTP::Request',
38             is => 'rw',
39             lazy => 1,
40             default => sub { return HTTP::Request->new( GET => $_[0]->server ) },
41             );
42              
43             sub BUILDARGS {
44             my $class = shift;
45              
46             if ( @_ == 1 && ! ref $_[0] ) {
47             # set the server as the first argument
48             return { server => $_[0] };
49             } else {
50             # normal hash/hashref way
51             return $class->SUPER::BUILDARGS(@_);
52             }
53             }
54              
55             sub run {
56             my $self = shift;
57              
58             # set the alarm, and wait for the response
59             my( $res );
60             eval {
61             # perldoc -f alarm says I need to put \n in the die... weird!
62             local $SIG{ALRM} = sub { die "alarm\n" };
63             alarm $self->timeout;
64             $res = $self->useragent->request( $self->request );
65             alarm 0;
66             };
67             if ( $@ ) {
68             if ( $@ =~ /^alarm/ ) {
69             die "Unable to query server: Timed out";
70             } else {
71             die "Unable to query server: $@";
72             }
73             } else {
74             if ( defined $res and $res->is_success ) {
75             return Games::AssaultCube::MasterserverQuery::Response->new( $self, $res );
76             } else {
77             return;
78             }
79             }
80             }
81              
82             # from Moose::Manual::BestPractices
83             no Moose;
84             __PACKAGE__->meta->make_immutable;
85              
86             1;
87             __END__
88              
89             =for stopwords masterserver CubeStats.net HTTP URI XML hostname ip useragent
90              
91             =head1 NAME
92              
93             Games::AssaultCube::MasterserverQuery - Queries an AssaultCube masterserver for the list of servers
94              
95             =head1 SYNOPSIS
96              
97             use Games::AssaultCube::MasterserverQuery;
98             my $query = Games::AssaultCube::MasterserverQuery->new;
99             #my $query = Games::AssaultCube::MasterserverQuery->new( 'http://foo.com/get.do' );
100             #my $query = Games::AssaultCube::MasterserverQuery->new({ server => 'http://foo.com/get.do', timeout => 5 });
101             my $response = $query->run;
102             if ( defined $response ) {
103             print "There is a total of " . $response->num_servers " servers in the list!\n";
104             } else {
105             print "Masterserver is not responding!\n";
106             }
107              
108             =head1 ABSTRACT
109              
110             This module queries an AssaultCube masterserver for the list of servers.
111              
112             =head1 DESCRIPTION
113              
114             This module queries an AssaultCube masterserver for the list of servers. It has been tested extensively
115             on the AssaultCube masterserver and the CubeStats.net masterserver.
116              
117             WARNING: This module doesn't parse the XML output, only the regular "list" format! In the future XML parsing
118             will be added as XML support gets stable in the masterserver.
119              
120             =head2 Constructor
121              
122             This module uses Moose, so you can pass either a hash, hashref, or a server to the constructor. Passing
123             a string means we're passing in a server URI. If you want to specify more options, please use the
124             hash/hashref method.
125              
126             The attributes are:
127              
128             =head3 server
129              
130             The server hostname or ip in HTTP URI format.
131              
132             Defaults to the AssaultCube masterserver: L<http://masterserver.cubers.net/cgi-bin/AssaultCube.pl/retrieve.do?item=list>
133              
134             =head3 timeout
135              
136             The timeout waiting for the server response in seconds. Defaults to 30.
137              
138             WARNING: We use alarm() internally to do the timeout. If you used it somewhere else, it will cause conflicts
139             and potentially render it useless. Please inform me if there's conflicts in your script and we can try to
140             work around it.
141              
142             =head3 useragent
143              
144             The LWP::UserAgent object we will use. Handy if you want to override it's configuration.
145              
146             =head2 Methods
147              
148             Currently, there is only one method: run(). You call this and get the response object back. For more
149             information please look at the L<Games::AssaultCube::MasterserverQuery::Response> class. You can call run() as
150             many times as you want, no need to re-instantiate the object for each query.
151              
152             WARNING: run() will die() if errors happen. For sanity, you should wrap it in an eval.
153              
154             =head2 Attributes
155              
156             You can modify some attributes before calling run() on the object. They are:
157              
158             =head3 timeout
159              
160             Same as the constructor
161              
162             =head3 useragent
163              
164             Same as the constructor
165              
166             =head3 request
167              
168             You can modify the HTTP::Request object, if needed to override stuff.
169              
170             =head1 AUTHOR
171              
172             Apocalypse E<lt>apocal@cpan.orgE<gt>
173              
174             Props goes to Getty and the BS clan for the support!
175              
176             This project is sponsored by L<http://cubestats.net>
177              
178             =head1 COPYRIGHT AND LICENSE
179              
180             Copyright 2009 by Apocalypse
181              
182             This library is free software; you can redistribute it and/or modify
183             it under the same terms as Perl itself.
184              
185             =cut