File Coverage

blib/lib/Games/CroqueMonster.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Games::CroqueMonster;
2              
3 2     2   57213 use warnings;
  2         6  
  2         64  
4 2     2   12 use strict;
  2         4  
  2         65  
5              
6 2     2   1790 use LWP::Simple;
  2         194446  
  2         19  
7 2     2   2295 use XML::Simple;
  0            
  0            
8             use Data::Dumper;
9              
10             =head1 NAME
11              
12             Games::CroqueMonster - An interface for the French web game CroqueMonster.
13              
14             =head1 VERSION
15              
16             Version 0.8.1-2
17              
18             =cut
19              
20             our $VERSION = '0.8.1-2';
21              
22              
23             =head1 SYNOPSIS
24              
25             This module implements the 0.8.1 version of the CroqueMonster web game (http://www.croquemonster.com).
26              
27             I decided to give version number of this module after the CroqueMonster API's own version number. I think it is easier for peoples to know what API version this module implements.
28              
29             The number after the dash (-) is this module own version (0.8.1-1 means this is the first version of this module implementing the version 0.8.1 of CroqueMonster's API).
30              
31             There is few required dependencies (all available from CPAN) : LWP::Simple and XML::Simple.
32              
33             use Games::CroqueMonster;
34              
35             my $cm = Games::CroqueMonster->new(agency_name => 'UglyBeasts');
36             my $agency_info = $cm->agency();
37              
38             So far the CroqueMonster's API only allow to retrieve informations, but maybe in some uncertain futur it will be possible to take actions with it...
39              
40             Technically speaking, this module interacts with a webb service. So you cannot get a fully functionnal game with this module alone, only easily create interfaces for the game itself.
41              
42             =head1 CONSTRUCTOR
43              
44             =head2 new
45              
46             This is the object constructor. It takes the following optionnal parameters :
47              
48             * api_key : your CroqueMonster API password
49             * agency_name : the agency name
50             * syndicate_name : the syndicate name
51              
52             =cut
53              
54             sub new {
55             my ($class,%params) = @_;
56             my $self = { _data => {%params} };
57             bless($self,$class);
58             return $self;
59             }
60              
61             =head1 METHODS
62              
63             =head1 Publicly available data access methods
64              
65             =head2 agency
66              
67             Implements: http://www.croquemonster.com/api/help#h2n3n1 (page in french)
68             Take one parameter : the name of the agency (this is not mandatory if constructor's agency_name parameter was filled).
69              
70             my $agency = $cm->agency('UglyBeasts') ;
71              
72             On success, the returned hashref look like that :
73              
74             $VAR1 = {
75             'agency' => {
76             'failedA' => '0',
77             'contractsD' => '0',
78             'contractsA' => '9',
79             'reputation' => '135',
80             'failedC' => '0',
81             'gold' => '490',
82             'id' => '383869',
83             'maxMonsters' => '7',
84             'failedD' => '0',
85             'scared' => '8',
86             'portails' => '1',
87             'failedB' => '0',
88             'name' => 'UglyBeasts',
89             'score' => '91',
90             'description' => {'Here we are hiring only the ugliest and the more saddistics monsters !'},
91             'contractsB' => '0',
92             'days' => '2',
93             'monsters' => '4',
94             'level' => '3',
95             'devoured' => '1',
96             'mails' => '0',
97             'contractsC' => '0',
98             'cities' => '3'
99             }
100             };
101              
102             The following keys are present only when you provide a valid "api_key" :
103              
104             * gold
105             * mails
106              
107             On error it looks like that :
108              
109             $VAR1 = {
110             'err' => {
111             'error' => 'API access disabled',
112             should_retry => 0,
113             }
114             };
115              
116             Please see the ERRORS, section for a list of all error strings.
117              
118             =cut
119              
120             sub agency {
121             my ($self,$agency) = @_;
122             $agency = $self->{_data}->{agency_name} if( !defined($agency) && defined($self->{_data}->{agency_name}));
123             my $param="name=$agency";
124             $param .= "&pass=$self->{_data}->{api_key}" if( defined($self->{_data}->{api_key}) );
125             my $content = get("http://www.croquemonster.com/api/agency.xml?$param");
126             return _parse_data($content);
127             }
128              
129             =head2 syndicate
130              
131             Implements: http://www.croquemonster.com/api/help#h2n3n2 (in french)
132              
133             Take one parameter : the name of the agency (this is not mandatory if constructor's agency_name parameter was filled).
134              
135             my $syndicate = $cm->syndicate('Tenebrae') ;
136              
137             On success, the returned hashref look like that (When you see [...] it just means that there was too many data and I cutted some) :
138              
139             $VAR1 = {
140             'syndicate' => {
141             'co2' => '2736',
142             'co2bonus' => '105',
143             'name' => 'ChupAngelic',
144             'score' => '4374',
145             'description' => "
146            

\"Image\"/

147            

Origines

148            

D-Tritus \x{2026} plan\x{e8}te hostile, peupl\x{e9}e en surnombre par des monstres de tout horizon.

149             [...]
150            

27/04/08: Hordal was here...directeur du syndicat le temps de booster la mont\x{e9}e du tas d'ordures. Mission r\x{e9}ussie!

151             ",
152             'war' => [
153             '1235',
154             {
155             'date' => '2008-01-28 08:31:50',
156             'name' => 'Soul Society',
157             'id' => '1'
158             },
159             [...]
160             {
161             'date' => '2008-09-08 21:15:57',
162             'name' => 'One Piece',
163             'id' => '2650'
164             }
165             ],
166             'days' => '381',
167             'co2max' => '2631',
168             'agency' => {
169             'Kakarott13' => {
170             'level' => '20',
171             'reputation' => '99529',
172             'score' => '102754',
173             'id' => '41550'
174             },
175             [...]
176             'hedu89' => {
177             'level' => '29',
178             'reputation' => '609505',
179             'score' => '359193',
180             'id' => '41692'
181             }
182             },
183             'id' => '796',
184             'influence' => '403'
185             }
186             };
187              
188             The first value of the war array reference ( $VAR1->{syndicate}->{war}->[0] ) is the syndicate war score (points won during wars).
189              
190             Please see ERRORS section for values returned on error.
191              
192             =cut
193              
194             sub syndicate {
195             my $self = shift ;
196             my $input = shift;
197             my $content = get("http://www.croquemonster.com/api/syndicate.xml?name=$input");
198             return _parse_data($content, ForceArray => ['agency','war']);
199              
200             }
201              
202             =head2 items
203              
204             Implements: http://www.croquemonster.com/api/help#h2n3n3
205              
206             Return the list of all game's usable items. Those one can be used to improved your monsters.
207              
208             Takes no parameters.
209              
210             my $items = $cm->items() ;
211              
212             On success, the returned hashref look like that (When you see [...] it just means that there was too many data and I cutted some) :
213              
214             $VAR1 = {
215             'items' => {
216             'item' => {
217             '11' => {
218             'name' => "R\x{e9}gime di\x{e9}t\x{e9}tique",
219             'id' => '11',
220             'image' => '/gfx/tech/icone_regime.gif'
221             },
222             [...]
223             '5' => {
224             'name' => "Insectes dress\x{e9}s",
225             'id' => '5',
226             'image' => '/gfx/tech/icone_insecte.gif'
227             }
228             }
229             }
230             };
231              
232             Path representing the item image is relative to http://www.croquemonster.com.
233              
234             Please see ERRORS section for values returned on error.
235              
236             =cut
237              
238             sub items {
239             my $self = shift;
240             my $content = get("http://www.croquemonster.com/api/items.xml");
241             return _parse_data($content, KeyAttr => {'item' => '+id'});
242             }
243              
244             =head1 Private informations access methods
245              
246             Those methods cannot be called without filling the api_key and agency_name constructor's parameters (well... you can call them but they will end in error).
247              
248             =cut
249              
250             =head2 monsters
251              
252             Implements: http://www.croquemonster.com/api/help#h2n4n2
253              
254             Takes no parameters.
255              
256             On success, the returned hashref look like that (When you see [...] it just means that there was too many data and I cutted some) :
257              
258             $VAR1 = {
259             'monsters' => {
260             'monster' => {
261             '2195056' => {
262             'fight' => '0',
263             'fusions' => '0',
264             'contractItems' => '',
265             'endurance' => '2',
266             'permanentItems' => '',
267             'successes' => '1',
268             'power' => '0',
269             'ugliness' => '0',
270             'id' => '2195056',
271             'fatigue' => '1',
272             'control' => '0',
273             'failures' => '0',
274             'contract' => '239582559',
275             'bounty' => '0',
276             'name' => 'UB0004',
277             'greediness' => '1',
278             'sadism' => '0',
279             'firePrize' => '1440',
280             'swfjs' => 'http://www.croquemonster.com/monster/drawSWF.js?face=Gfu2_cYikII05c7Wd:I7aIVqfmM8SSu7Pf_',
281             'devoured' => '1'
282             },
283             [...]
284             '2187820' => {
285             'fight' => '0',
286             'fusions' => '0',
287             'contractItems' => '',
288             'endurance' => '1',
289             'permanentItems' => '15',
290             'successes' => '2',
291             'power' => '1',
292             'ugliness' => '1',
293             'id' => '2187820',
294             'fatigue' => '0',
295             'control' => '2',
296             'failures' => '1',
297             'contract' => '239582555',
298             'bounty' => '0',
299             'name' => 'UB0001',
300             'greediness' => '0',
301             'sadism' => '0',
302             'firePrize' => '2640',
303             'swfjs' => 'http://www.croquemonster.com/monster/drawSWF.js?face=Gfu2_d:aHLI05c7md:s7bIVqfmk8SSKgieq',
304             'devoured' => '0'
305             }
306             },
307             'id' => '383869',
308             'agency' => 'UglyBeasts'
309             }
310             };
311              
312             Please see ERRORS section for values returned on error.
313              
314             =cut
315              
316             sub monsters {
317             my $self = shift;
318             my $content = get("http://www.croquemonster.com/api/monsters.xml?name=$self->{_data}->{agency_name};pass=$self->{_data}->{api_key}
319             ");
320             return _parse_data($content, KeyAttr => {'monster' => '+id'});
321             }
322              
323             =head2 portals
324              
325             Implements: http://www.croquemonster.com/api/help#h2n4n3
326              
327             Takes no parameters.
328              
329             On success, the returned hashref look like that (When you see [...] it just means that there was too many data and I cutted some) :
330              
331             $VAR1 = {
332             'portails' => {
333             'portail' => {
334             '1141215' => {
335             'country' => 'Allemagne',
336             'city' => 'Saarbruck',
337             'level' => '1',
338             'timezone' => '0',
339             'defense' => '0',
340             'id' => '1141215'
341             },
342             '1160353' => {
343             'country' => 'Etats-Unis',
344             'city' => 'Columbus',
345             'level' => '1',
346             'timezone' => '-6',
347             'defense' => '0',
348             'id' => '1160353'
349             }
350             },
351             'id' => '383869',
352             'agency' => 'UglyBeasts'
353             }
354             };
355              
356             Please see ERRORS section for values returned on error.
357              
358             =cut
359              
360             sub portals {
361             my $self = shift;
362             my $content = get("http://www.croquemonster.com/api/portails.xml?name=$self->{_data}->{agency_name};pass=$self->{_data}->{api_key}");
363             return _parse_data($content, KeyAttr => {'portail' => '+id'});
364             }
365              
366             =head2 contracts
367              
368             Implements: http://www.croquemonster.com/api/help#h2n4n4
369              
370             Takes no parameters.
371              
372             On success, the returned hashref look like that (When you see [...] it just means that there was too many data and I cutted some) :
373              
374             $VAR1 = {
375             'contracts' => {
376             'contract' => {
377             '239582560' => {
378             'country' => 'Allemagne',
379             'difficulty' => '2',
380             'timezone' => '0',
381             'name' => 'Marine',
382             'greediness' => '0',
383             'age' => '4',
384             'sex' => '1',
385             'city' => 'Saarbruck',
386             'sadism' => '0',
387             'accepted' => 'false',
388             'power' => '0',
389             'id' => '239582560',
390             'ugliness' => '0',
391             'countdown' => '10275',
392             'prize' => '135'
393             },
394             [...]
395             '239582555' => {
396             'country' => 'Allemagne',
397             'difficulty' => '6',
398             'timezone' => '1',
399             'name' => 'Mathis',
400             'greediness' => '0',
401             'age' => '7',
402             'sex' => '0',
403             'city' => 'Mannheim',
404             'sadism' => '0',
405             'monster' => '2187820',
406             'accepted' => 'true',
407             'power' => '1',
408             'id' => '239582555',
409             'ugliness' => '0',
410             'countdown' => '6675',
411             'prize' => '570'
412             }
413             },
414             'paradox' => {
415             'level' => '1',
416             'next' => '2008-09-13 07:31:52'
417             },
418             'id' => '383869',
419             'agency' => 'UglyBeasts'
420             }
421             };
422              
423              
424             Please see ERRORS section for values returned on error.
425              
426             =cut
427              
428             sub contracts {
429             my $self = shift;
430             my $content = get("http://www.croquemonster.com/api/contracts.xml?name=$self->{_data}->{agency_name};pass=$self->{_data}->{api_key}");
431             return _parse_data($content, KeyAttr => {'contract' => '+id'});
432             }
433              
434             =head2 inventory
435              
436             Implements: http://www.croquemonster.com/api/help#h2n4n5
437              
438             Takes no parameters.
439              
440             On success, the returned hashref look like that (When you see [...] it just means that there was too many data and I cutted some) :
441              
442             $VAR1 = {
443             'inventory' => {
444             'factory' => {
445             'next' => [
446             {
447             'name' => "Cr\x{e8}me \x{e0} acn\x{e9}",
448             'id' => '2',
449             'end' => '2008-10-28 08:33:50'
450             },
451             {
452             'name' => "Cr\x{e8}me \x{e0} acn\x{e9}",
453             'id' => '3',
454             'end' => '2008-10-28 08:35:50'
455             }
456             ],
457             'name' => "Cr\x{e8}me \x{e0} acn\x{e9}",
458             'id' => '1',
459             'end' => '2008-10-28 08:31:50'
460             },
461             'resource' => {
462             '1' => {
463             'name' => 'Chaussette sale',
464             'id' => '1',
465             'qty' => '2'
466             },
467             '2' => {
468             'name' => 'petite voiture',
469             'id' => '2',
470             'qty' => '1'
471             }
472             },
473             'item' => {
474             '1' => {
475             'name' => "Cr\x{e8}me \x{e0} acn\x{e9}",
476             'id' => '1',
477             'qty' => '3'
478             },
479             '2' => {
480             'name' => "Ombres port\x{e9}es",
481             'id' => '2',
482             'qty' => '3'
483             }
484             },
485             'id' => 'ID agence',
486             'agency' => 'NOM Agence'
487             }
488             };
489              
490              
491             Please see ERRORS section for values returned on error.
492              
493             =cut
494              
495             sub inventory {
496             my $self = shift;
497             my $content = get("http://www.croquemonster.com/api/inventory.xml?name=$self->{_data}->{agency_name};pass=$self->{_data}->{api_key}");
498             return _parse_data($content, KeyAttr => {'resource' => '+id','item' => '+id','factory' => '+id', 'next' => '+id'});
499             }
500              
501             sub _parse_data {
502             my $content = shift ;
503             my %parse_options = @_;
504             my $xml_data = XML::Simple::XMLin( $content , KeepRoot => 1,%parse_options);
505             if(exists($xml_data->{locked}) ){
506             $xml_data = {
507             'err' => {
508             'error' => 'Timezone opened',
509             'should_retry' => 1,
510             }
511             };
512             }elsif(defined($xml_data->{err}) ){
513             $xml_data->{err}->{should_retry} = 0;
514             }
515             return $xml_data;
516             }
517              
518             =head1 ERRORS
519              
520             When a call end up in error, a hash reference is returned. This hashref look like this :
521              
522             $VAR1 = {
523             'err' => {
524             'error' => '',
525             'should_retry' => 0|1
526             }
527             };
528              
529             The error string can be :
530              
531             * Unknown user : the agency name does not exist.
532             * Unknown syndicate : the syndicate name does not exist
533             * API access disabled : user have not activates the API key (it is done on the web account).
534             * Bad password : API key is not correct.
535             * Timezone opened : every hours, a timezone is opened and the website block all users for few seconds. You should wait a little an retry.
536              
537             For all those errors the 'should_retry' parameter is set to 0 (false), but for "Timezone opened" wich is a temporary error and the application should wait a little and retry.
538              
539             =head1 AUTHOR
540              
541             Arnaud Dupuis, C<< >>
542              
543             =head1 BUGS
544              
545             Please report any bugs or feature requests to C, or through
546             the web interface at L. I will be notified, and then you'll
547             automatically be notified of progress on your bug as I make changes.
548              
549              
550              
551              
552             =head1 SUPPORT
553              
554             You can find documentation for this module with the perldoc command.
555              
556             perldoc Games::CroqueMonster
557              
558              
559             You can also look for information at:
560              
561             =over 4
562              
563             =item * Infinity Perl (author website)
564              
565             L
566              
567             =item * CroqueMonster's API
568              
569             L
570              
571             =item * RT: CPAN's request tracker
572              
573             L
574              
575             =item * AnnoCPAN: Annotated CPAN documentation
576              
577             L
578              
579             =item * CPAN Ratings
580              
581             L
582              
583             =item * Search CPAN
584              
585             L
586              
587             =back
588              
589              
590             =head1 ACKNOWLEDGEMENTS
591              
592              
593             =head1 COPYRIGHT & LICENSE
594              
595             Copyright 2008-2010 Arnaud Dupuis, all rights reserved.
596              
597             This program is free software; you can redistribute it and/or modify it
598             under the same terms as Perl itself.
599              
600              
601             =cut
602              
603             1; # End of Games::CroqueMonster