File Coverage

blib/lib/Empire.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package Empire;
2              
3 1     1   20782 use 5.006;
  1         4  
  1         39  
4 1     1   5 use strict;
  1         2  
  1         38  
5 1     1   6 use warnings;
  1         7  
  1         61  
6              
7             our $VERSION;
8              
9 1     1   1195 use Socket 1.3;
  1         3930  
  1         578  
10 1     1   8 use Carp;
  1         2  
  1         58  
11 1     1   814 use IO::Socket;
  1         22515  
  1         5  
12 1     1   2098 use Net::Cmd;
  1         5847  
  1         86  
13 1     1   449 use Lingua::EN::Numericalize;
  0            
  0            
14             use Exporter;
15              
16             $VERSION = '0.121';
17              
18             our @ISA = qw(Net::Cmd IO::Socket::INET Empire::Commands Exporter);
19             our @EXPORT_OK = qw($C_CMDOK $C_DATA $C_INIT $C_EXIT
20             $C_FLUSH $C_NOECHO $C_PROMPT $C_ABORT
21             $C_REDIR $C_PIPE $C_CMDERR $C_BADCMD
22             $C_EXECUTE $C_FLASH $C_INFORM $C_SYNC);
23             our $C_CMDOK = '0';
24             our $C_DATA = '1';
25             our $C_INIT = '2';
26             our $C_EXIT = '3';
27             our $C_FLUSH = '4';
28             our $C_NOECHO = '5';
29             our $C_PROMPT = '6';
30             our $C_ABORT = '7';
31             our $C_REDIR = '8';
32             our $C_PIPE = '9';
33             our $C_CMDERR = 'a';
34             our $C_BADCMD = 'b';
35             our $C_EXECUTE = 'c';
36             our $C_FLASH = 'd';
37             our $C_INFORM = 'e';
38             our $C_SYNC = 'f';
39              
40              
41             # Preloaded methods go here.
42             sub new {
43              
44             my $self = shift;
45             my $class = ref($self) || $self;
46             my %param = @_;
47             my $emp = {};
48              
49             if (! $param{-user}) {
50             $param{-user} = $ENV{USER};
51             }
52             if (defined $param{-full} && $param{-full}) {
53             use Empire::Commands;
54             $emp = new Empire::Commands;
55             use Empire::Ship;
56             use Empire::Sector;
57             use Empire::SectorType;
58             use Empire::ProductType;
59             use Empire::Nation;
60             use Empire::Land;
61             use Empire::Plane;
62             use Empire::EConfig;
63             }
64             else {
65             $emp = {};
66             }
67             print "Using Empire.pm v$VERSION\n";
68             $emp->{HOST} = $param{-host};
69             $emp->{PORT} = $param{-port};
70             if ($param{-country} && $param{-player}) {
71             if ($param{-player}) {
72             $emp->{COUNTRY} = $param{-country};
73             $emp->{PLAYER} = $param{-player};
74             }
75             }
76             else {
77             $emp->{COUNTRY} = 'visitor';
78             $emp->{PLAYER} = 'visitor';
79             carp "No country name supplied, logging as visitor\n";
80             }
81             if ($param{-user}) {
82             $emp->{USER} = $param{-user};
83             }
84             if ($param{-kill}) {
85             $emp->{KILL} = $param{-kill};
86             }
87             else {
88             $emp->{KILL} = 'ask';
89             }
90             if ($param{-name}) {
91             $emp->{NAME} = $param{-name};
92             }
93             else {
94             $emp->{NAME} = 'Empire';
95             }
96             bless $emp,$class;
97             $emp->empconnect($class);
98             }
99             sub empconnect {
100              
101             my $emp = shift;
102             my $class = shift;
103             $emp->{SOCKET} = $class->SUPER::new(PeerAddr => $emp->{HOST},
104             PeerPort => $emp->{PORT},
105             Proto => 'tcp',
106             Timeout => 120,
107             );
108             unless (defined $emp->{SOCKET}) {
109             $emp->{RESPONSE} = "Failed to Connect to $emp->{HOST} port $emp->{PORT}\n";
110             $emp->{EMPSTATUS} = 'NOT CONNECTED';
111             return $emp;
112             }
113             my $welcome = $emp->{SOCKET}->getline;
114             my ($proto,$response) = ($welcome =~ /^(\S)\s+(\S.*)$/);
115             if ($proto != $C_INIT) {
116             carp "Mysterious server welcome!\n";
117             $emp->{SOCKET}->close;
118             $emp->{RESPONSE} = 'Mysterious server welcome';
119             $emp->{EMPSTATUS} = 'NOT CONNECTED';
120             return $emp;
121             }
122             unless ($emp->login()) {
123             carp "Login failed!\n";
124             $emp->{SOCKET}->close;
125             $emp->{EMPSTATUS} = 'NOT CONNECTED';
126             return $emp;
127             }
128             }
129             sub login {
130              
131             my $emp = shift;
132              
133             my ($proto,$response);
134             ($proto,$response) = $emp->coun($emp->{COUNTRY});
135             if ($proto ne $C_CMDOK) {
136             $emp->{SOCKET}->close;
137             $emp->{EMPSTATUS} = 'NOT CONNECTED';
138             $emp->{RESPONSE} = $response;
139             return 0;
140             }
141             ($proto,$response) = $emp->pass($emp->{PLAYER});
142             if ($proto ne $C_CMDOK) {
143             $emp->{SOCKET}->close;
144             $emp->{RESPONSE} = $response;
145             $emp->{EMPSTATUS} = 'NOT CONNECTED';
146             return 0;
147             }
148             if ($emp->{USER}) {
149             ($proto,$response) = $emp->user($emp->{USER});
150             if ($proto ne $C_CMDOK) {
151             $emp->{SOCKET}->close;
152             $emp->{RESPONSE} = "$response";
153             $emp->{EMPSTATUS} = 'NOT CONNECTED';
154             return 0;
155             }
156             }
157             ($proto,$response) = $emp->play();
158             if ($proto eq $C_EXIT) {
159             my $kill_resp;
160             if ($emp->{KILL} eq 'no') {
161             $emp->{RESPONSE} = $response;
162             $emp->{EMPSTATUS} = 'NOT CONNECTED';
163             return 0;
164             }
165             elsif ($emp->{KILL} eq 'yes') {
166             $emp->killit();
167             }
168             else {
169             print "Country in use! Kill? (y/n)";
170             $kill_resp = ; chomp $kill_resp;
171             if ($kill_resp eq 'y') {
172             $emp->killit();
173             }
174             else {
175             $emp->{SOCKET}->close;
176             $emp->{RESPONSE} = "Exit requested by user";
177             $emp->{EMPSTATUS} = 'NOT CONNECTED';
178             print "Exit requested by user!\n";
179             return 0;
180             }
181             }
182             }
183             if ($proto ne $C_INIT) {
184             carp "Mysterious welcome\n";
185             $emp->{SOCKET}->close;
186             $emp->{RESPONSE} = $response;
187             $emp->{EMPSTATUS} = 'NOT CONNECTED';
188             return 0;
189             }
190             $emp->{BUFFER} = '';
191             $emp->{ECHO} = 1;
192             $emp->{RESPONSE} = 'Logged in';
193             $emp->{EMPSTATUS} = 'CONNECTED';
194             $emp->{MAP} = {};
195             $emp->{FLASH} = '';
196             $emp->{INFORM} = '';
197             $emp->{ANNO} = 0;
198             $emp->{TELE} = 0;
199             ($proto,$response) = $emp->empreadline('update');
200             return $emp;
201             }
202             sub coun {
203              
204             my $emp = shift;
205             my $coun = shift;
206             my $cmd = "coun $coun";
207              
208             $emp->empcmd($cmd);
209             if ($emp->{SOCKET}) {
210             $_ = $emp->{SOCKET}->getline();
211             s/\r//g;
212             /^(\S)\s+(\S.*)$/;
213             return ($1,$2);
214             }
215             }
216             sub pass {
217              
218             my $emp = shift;
219             my $play = shift;
220             my $cmd = "pass $play";
221              
222             $emp->empcmd($cmd);
223             if ($emp->{SOCKET}) {
224             $_ = $emp->{SOCKET}->getline();
225             s/\r//g;
226             /^(\S)\s+(\S.*)$/;
227             return ($1,$2);
228             }
229             }
230             sub user {
231              
232             my $emp = shift;
233             my $user = shift;
234             my $cmd = "user $user";
235              
236             $emp->empcmd($cmd);
237             if ($emp->{SOCKET}) {
238             $_ = $emp->{SOCKET}->getline();
239             s/\r//g;
240             /^(\S)\s+(\S.*)$/;
241             return ($1,$2);
242             }
243              
244             }
245             sub play {
246              
247             my $emp = shift;
248             my $cmd = "play";
249              
250             $emp->empcmd($cmd);
251             if ($emp->{SOCKET}) {
252             $_ = $emp->{SOCKET}->getline();
253             s/\r//g;
254             /^(\S)\s+(\S.*)$/;
255             return ($1,$2);
256             }
257             }
258             sub empkill {
259              
260             my $emp = shift;
261             my $cmd = "kill";
262              
263             $emp->empcmd($cmd);
264             if ($emp->{SOCKET}) {
265             $_ = $emp->{SOCKET}->getline();
266             s/\r//g;
267             /^(\S)\s+(\.*)$/;
268             return ($1,$2);
269             }
270             }
271             sub killit {
272              
273             my $emp = shift;
274              
275             my ($proto,$response) = $emp->empkill();
276             if ($proto == $C_EXIT) {
277             ($proto,$response) = $emp->play();
278             if ($proto == $C_EXIT) {
279             $emp->{SOCKET}->close;
280             carp "Country still in use! Alert the deity!";
281             $emp->{RESPONSE} = $response;
282             $emp->{EMPSTATUS} = 'NOT CONNECTED';
283             return 0;
284             }
285             }
286             else {
287             $emp->{SOCKET}->close;
288             carp "Unknown kill error!";
289             $emp->{RESPONSE} = $response;
290             $emp->{EMPSTATUS} = 'NOT CONNECTED';
291             return 0;
292             }
293             }
294             sub empstatus {
295              
296             my $emp = shift;
297             my %empstatus;
298              
299             $empstatus{EMPSTATUS} = $emp->{EMPSTATUS};
300             $empstatus{RESPONSE} = $emp->{RESPONSE};
301             return %empstatus;
302             }
303             sub empreadline {
304              
305             my $emp = shift;
306             my $cmd = shift;
307             my $response;
308             my $data = '';
309             my $annos;
310             my $teles;
311              
312             $response = $emp->{SOCKET}->getline();
313             $response =~ s/\r//;
314             ($emp->{EMPSTATUS},$emp->{RESPONSE}) = ($response =~ /^(\S) (.*)/);
315             if ($cmd eq 'void') {
316             if ($emp->{EMPSTATUS} eq $C_FLASH) {
317             if ($emp->{RESPONSE} eq 'Server shutting down...') {
318             $emp->{EMPSTATUS} = $C_EXIT;
319             }
320             else {
321             $emp->{FLASH} .= $emp->{RESPONSE} . "\n";
322             }
323             }
324             elsif ($emp->{EMPSTATUS} eq $C_INFORM) {
325             $emp->{INFORM} .= $emp->{RESPONSE};
326             chomp $emp->{INFORM};
327             }
328             return($emp->{EMPSTATUS},'');
329             }
330             while ($emp->{EMPSTATUS} ne $C_PROMPT &&
331             $emp->{EMPSTATUS} ne $C_FLUSH &&
332             $emp->{EMPSTATUS} ne $C_EXIT) {
333             if ($emp->{EMPSTATUS} eq $C_DATA) {
334             if ($emp->{RESPONSE} =~ /You have (.*) new announcement/) {
335             $emp->{ANNO} = $emp->{RESPONSE};
336             }
337             elsif ($emp->{RESPONSE} =~ /You have (.*) new telegram/) {
338             $emp->{TELE} = $emp->{RESPONSE};
339             }
340             }
341             elsif ($emp->{EMPSTATUS} eq $C_FLASH) {
342             $emp->{FLASH} .= $emp->{RESPONSE} . "\n";
343             }
344             elsif ($emp->{EMPSTATUS} eq $C_INFORM) {
345             $emp->{INFORM} .= $emp->{RESPONSE};
346             chomp $emp->{INFORM};
347             }
348             $response = $emp->{SOCKET}->getline;
349             $response =~ s/\r//;
350             chomp $response;
351             ($emp->{EMPSTATUS},$emp->{RESPONSE}) = ($response =~ /^(\S) (.*)/);
352             }
353             $emp->{DATA}->{$cmd} = $data;
354             if ($emp->{EMPSTATUS} eq $C_PROMPT) {
355             my($min,$btu) = ($emp->{RESPONSE} =~ /(\d+)\s+(\d+)/);
356             $emp->{BTU} = $btu;
357             $emp->{MINUTES} = $min;
358             }
359             elsif ($emp->{EMPSTATUS} eq $C_FLUSH) {
360             $emp->{SUBPROMPT} = $emp->{RESPONSE};
361             }
362             elsif ($emp->{EMPSTATUS} eq $C_EXIT) {
363             $emp->{DATA}->{$cmd} .= $emp->{RESPONSE};
364             close $emp->{SOCKET};
365             }
366             return ($emp->{EMPSTATUS},$emp->{DATA}->{$cmd});
367             }
368             sub empcmd {
369              
370             my $emp = shift;
371             my $cmd = shift;
372              
373             chomp $cmd;
374             $emp->{SOCKET}->datasend($cmd . "\n");
375              
376             return;
377             }
378             sub empbuffer {
379              
380             my $emp = shift;
381             my $cont = shift;
382              
383             if (!defined $cont) {
384             return $emp->{BUFFER};
385             }
386             elsif ($cont eq 'VOID') {
387             $emp->{BUFFER} = '';
388             }
389             else {
390             $emp->{BUFFER} = $cont;
391             }
392             }
393             sub country {
394              
395             my $self = shift;
396             my $coun = shift;
397              
398             $self->{COUNTRY} = $coun if defined $coun;
399             return $self->{COUNTRY};
400             }
401             sub player {
402              
403             my $self = shift;
404             my $play = shift;
405              
406             $self->{PLAYER} = $play if defined $play;
407             return $self->{PLAYER};
408             }
409             sub port {
410              
411             my $self = shift;
412             my $port = shift;
413              
414             $self->{PORT} = $port if defined $port;
415             return $self->{HOST};
416             }
417             sub host {
418              
419             my $self = shift;
420             my $host = shift;
421              
422             $self->{HOST} = $host if defined $host;
423             return $self->{HOST};
424             }
425             sub name {
426              
427             my $self = shift;
428             my $name = shift;
429              
430             $self->{NAME} = $name if defined $name;
431             return $self->{NAME};
432             }
433             sub minutes {
434              
435             my $self = shift;
436              
437             return $self->{MINUTES};
438             }
439             sub btu {
440              
441             my $self = shift;
442             return $self->{BTU};
443             }
444             sub hasflash {
445              
446             my $self = shift;
447             return $self->{FLASH};
448             }
449             sub clearflash {
450              
451             my $self = shift;
452              
453             $self->{FLASH} = '';
454             }
455             sub hasinform {
456              
457             my $self = shift;
458             return $self->{INFORM};
459             }
460             sub clearinform {
461              
462             my $self = shift;
463              
464             $self->{INFORM} = '';
465             }
466             sub hastele {
467              
468             my $self = shift;
469              
470             return $self->{TELE};
471             }
472             sub cleartele {
473              
474             my $self = shift;
475              
476             $self->{TELE} = 0;
477             }
478             sub hasanno {
479              
480             my $self = shift;
481              
482             return $self->{ANNO};
483             }
484             sub clearanno {
485              
486             my $self = shift;
487              
488             $self->{ANNO} = 0;
489             }
490             sub subprompt {
491              
492             my $self = shift;
493              
494             return $self->{SUBPROMPT};
495             }
496             sub disconnect {
497              
498             my $self = shift;
499              
500             $self->{SOCKET}->close();
501             delete $self->{SOCKET};
502             }
503             1;
504             __END__