File Coverage

blib/lib/App/Betting/Toolkit/Server.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package App::Betting::Toolkit::Server;
2              
3 1     1   28340 use 5.006;
  1         4  
  1         52  
4 1     1   6 use strict;
  1         2  
  1         38  
5 1     1   5 use warnings;
  1         15  
  1         30  
6              
7 1     1   1093 use Data::Dumper;
  1         13913  
  1         88  
8 1     1   984 use Try::Tiny;
  1         13830  
  1         96  
9              
10 1     1   485 use POE qw(Component::Server::TCP Filter::Reference);
  0            
  0            
11              
12             =head1 NAME
13              
14             =over 1
15              
16             App::Betting::Toolkit::Server - Recieve and process App::Betting::Toolkit::GameState objects
17              
18             =back
19              
20             =head1 VERSION
21              
22             Version 0.017
23              
24             =cut
25              
26             our $VERSION = '0.017';
27              
28             =head1 SYNOPSIS
29              
30             =over 1
31              
32             Quick summary of what the module does.
33              
34             Perhaps a little code snippet.
35              
36             use App::Betting::Toolkit::Server;
37              
38             my $server = App::Betting::Toolkit::Server->new();
39              
40             print "Server id: ".$server->ID;
41              
42             =back
43              
44             =head1 SUBROUTINES/METHODS
45              
46             =head2 function1
47              
48             =cut
49              
50             sub function1 {
51             }
52              
53             =head1 AUTHOR
54              
55             =over 1
56              
57             Paul G Webster, C<< >>
58              
59             =back
60              
61             =head1 BUGS
62              
63             =over 1
64              
65             Please report any bugs or feature requests to C, or through
66             the web interface at L. I will be notified, and then you'll
67             automatically be notified of progress on your bug as I make changes.
68              
69             =back
70              
71             =head1 SUPPORT
72              
73             =over 1
74              
75             You can find documentation for this module with the perldoc command.
76              
77             perldoc App::Betting::Toolkit::Server
78              
79              
80             You can also look for information at:
81              
82             =back
83              
84             =over 4
85              
86             =item * RT: CPAN's request tracker (report bugs here)
87              
88             L
89              
90             =item * AnnoCPAN: Annotated CPAN documentation
91              
92             L
93              
94             =item * CPAN Ratings
95              
96             L
97              
98             =item * Search CPAN
99              
100             L
101              
102             =back
103              
104              
105             =head1 ACKNOWLEDGEMENTS
106              
107              
108             =head1 LICENSE AND COPYRIGHT
109              
110             =over 1
111              
112             Copyright 2013 Paul G Webster.
113              
114             This program is distributed under the (Revised) BSD License:
115             L
116              
117             Redistribution and use in source and binary forms, with or without
118             modification, are permitted provided that the following conditions
119             are met:
120              
121             * Redistributions of source code must retain the above copyright
122             notice, this list of conditions and the following disclaimer.
123              
124             * Redistributions in binary form must reproduce the above copyright
125             notice, this list of conditions and the following disclaimer in the
126             documentation and/or other materials provided with the distribution.
127              
128             * Neither the name of Paul G Webster's Organization
129             nor the names of its contributors may be used to endorse or promote
130             products derived from this software without specific prior written
131             permission.
132              
133             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
134             "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
135             LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
136             A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
137             OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
138             SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
139             LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
140             DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
141             THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
142             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
143             OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144              
145             =back
146              
147             =cut
148              
149             sub new {
150             my $class = shift;
151             my $args = shift;
152              
153             my $cache = {};
154             my $self;
155              
156             die "Need to have parent passed" if (!$args->{parent});
157              
158             $self->{keystore} = {};
159              
160             if ( (!$args->{port}) || ($args->{port} !~ m#^\d+$#) || ($args->{port} > 65535) || ($args->{port} < 1) ) {
161             $args->{port} = 22122;
162             }
163              
164             $args->{alias} = 'betserver' if (!$args->{alias});
165             $args->{debug_handler} = 'debug_server' if (!$args->{debug_handler});
166              
167             POE::Kernel->post($args->{parent},$args->{debug_handler},"Starting server, port:".$args->{port}." alias:".$args->{alias});
168              
169             $self->{session} = POE::Component::Server::TCP->new(
170             Alias => $args->{alias},
171             Port => $args->{port},
172             ClientFilter => POE::Filter::Reference->new("Storable"),
173             ClientConnected => sub {
174             my ($kernel) = $_[KERNEL];
175             $kernel->yield('debug','Client connected');
176             },
177             ClientInput => sub {
178             my ($kernel, $session, $heap, $req) = @_[KERNEL, SESSION, HEAP, ARG0];
179              
180             # initilize $req
181             $req = { error=>1, gamestate=>{ } } if (!$req);
182              
183             $kernel->post($args->{parent},'debug',Dumper($req));
184              
185             # Check the packet has a valid query type
186             if (!defined $req->{query}) {
187             $heap->{client}->put({ error=>1, msg=>"Invalid query missing 'query'" });
188             return;
189             }
190              
191             $kernel->yield('handle_'.lc($req->{query}),$req);
192             },
193             InlineStates => {
194             debug => sub {
195             my ($kernel, $session, $heap, $req) = @_[KERNEL, SESSION, HEAP, ARG0];
196              
197             $kernel->post($args->{parent},$args->{debug_handler},$req);
198             },
199             send_to_parent => sub {
200             my ($kernel, $session, $heap, $req) = @_[KERNEL, SESSION, HEAP, ARG0];
201              
202             $kernel->post($args->{parent},$args->{handler},$req);
203             },
204             handle_register => sub {
205             my ($kernel, $session, $self, $heap, $req) = @_[KERNEL, SESSION, OBJECT, HEAP, ARG0];
206              
207             my $error = { query=>'register', error => 1, msg=> "Unknown error" };
208              
209             if ( $heap->{auth} ) {
210             $error = { query=>'register', error=>1, msg=>"Already registered" };
211             } elsif ( (defined $req->{keys}) && (ref $req->{keys} eq 'ARRAY')) {
212             my $unique = uc( join('_',@{ $req->{keys} }) );
213             $self->{authed}->{$unique} = {
214             key => int(rand(999999)),
215             created => time
216             };
217             $error = { error=>0, query=>'register', key=>$self->{authed}->{$unique} };
218             } elsif (defined $req->{keys}) {
219             $error = { error=>1, query=>'register', msg=>"keys must be an array" };
220             } else {
221             my $unique = uc( join('_','AUTOGEN',time,int(rand(999)),int(rand(999)),int(rand(999))) );
222             $self->{authed}->{$unique} = {
223             key => int(rand(999999)),
224             created => time
225             };
226             $error = { error=>0, query=>'register', key=>$self->{authed}->{$unique} };
227             }
228              
229             $heap->{auth} = 1 if (!$error->{error});
230              
231             $heap->{client}->put( $error );
232              
233             $kernel->yield('send_to_parent',$req);
234             },
235             handle_gamepacket => sub {
236             my ($kernel, $session, $heap, $req) = @_[KERNEL, SESSION, HEAP, ARG0];
237              
238             if (!$cache->{gamepacket}) {
239             $req->{client} = $session->ID;
240             $kernel->yield('send_to_parent',$req);
241             } else {
242             my $pkt = $req;
243             $req->{method} = 'update';
244             $req->{data} = $cache->{gamepacket};
245             $heap->{client}->put( $req );
246             }
247             },
248             handle_matchdata => sub {
249             my ($kernel, $session, $heap, $req) = @_[KERNEL, SESSION, HEAP, ARG0];
250              
251             $kernel->yield('send_to_parent',$req);
252             },
253             cache_send => sub {
254             my ($kernel, $session, $heap, $req) = @_[KERNEL, SESSION, HEAP, ARG0];
255              
256             my $key = $req->{query};
257              
258             $cache->{$key} = $req->{data};
259              
260             $heap->{client}->put( $req );
261             },
262             }
263             );
264              
265             bless $self, $class;
266              
267             return $self;
268             }
269              
270             1; # End of App::Betting::Toolkit::Server