diff Ikariam.pm @ 101:592d3b3b7898

implemented the WAR robot
author "Rex Tsai <chihchun@kalug.linux.org.tw>"
date Wed, 29 Oct 2008 12:05:36 +0800
parents ed6160630329
children b369fe3c1992
line wrap: on
line diff
--- a/Ikariam.pm	Wed Oct 29 03:20:53 2008 +0800
+++ b/Ikariam.pm	Wed Oct 29 12:05:36 2008 +0800
@@ -8,7 +8,7 @@
 use Class::DBI::AutoLoader (
     dsn       => 'dbi:SQLite:dbname=ikariam.sqlite',
     options   => { RaiseError => 1 },
-    tables    => ['cities', 'island', 'user', 'ally'],
+    tables    => ['cities', 'island', 'user', 'ally', 'report'],
     use_base  => 'Class::DBI::SQLite',
     namespace => 'Ikariam',
 );
@@ -97,6 +97,8 @@
 use HTML::TagParser;
 use XML::LibXML qw(:encoding);
 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
+# use Time::ParseDate;
+use POSIX;
 use utf8;
 
 sub new
@@ -177,15 +179,16 @@
         ]);
     my $extractor = new Ikariam::Extractor(content => $res->content);
     my $result = $extractor->{doc}->find('//table[@class="table01"][2]//tr');
+
     foreach my $tr ( @$result ) {
         my %user;
+        my $extractor = new Ikariam::Extractor(content => $tr->toString(1));
 
-        $extractor->{doc} = $tr;
         my $href = $extractor->find('//td[@class="action"]/a/@href');
         if($href =~ /index\.php\?view=sendMessage&with=(\d+)&oldView=highscore/) {
             $user{'id'} = $1;
-            # $user{'name'} = $extractor->find('//td[@class="name"]');
             $user{'name'} = $user;
+            $user{'name'} = $extractor->find('//td[@class="name"]');
 
             $user{'ally'} = $extractor->find('//td[@class="allytag"]/a/text()');
             my $allyHref = $extractor->find('//td[@class="allytag"]/a/@href');
@@ -197,6 +200,7 @@
             $users{$user{'id'}} = \%user;
         }
     }
+    # print(Dumper(\%users));
     return \%users;
 }
 
@@ -412,11 +416,22 @@
     return $out;
 }
 
-sub checkCity {
+sub plunderCity {
+    my $self = shift;
+    my $cityId = shift;
+    $self->{mech}->get(sprintf("http://%s/index.php?view=plunder&destinationCityId=%d", $self->{server}, $cityId));
+    $self->{mech}->submit_form(
+        form_number => 1,
+        fields      => {
+            cargo_army_302 => '2',
+        }
+    );
+}
+
+sub changeCity {
     my $self = shift;
     my $cityId = shift;
 
-    # search for goods
     $self->{mech}->get(sprintf("http://%s/index.php", $self->{server}));
     $self->{mech}->submit_form(
         form_number => 2,
@@ -424,6 +439,14 @@
             cityId => $cityId,
         }
     );
+}
+
+sub checkCity {
+    my $self = shift;
+    my $cityId = shift;
+
+    $self->changeCity($cityId);
+
     my $res = $self->{mech}->get(sprintf("http://%s/index.php?view=city&id=%d", $self->{server}, $cityId));
     my $extractor = new Ikariam::Extractor(content => $res->content);
 
@@ -478,102 +501,119 @@
 sub checkMilitaryAdvisorMilitaryMovements  {
     my $self = shift;
     # TODO
-    # http://%s/index.php?view=militaryAdvisorMilitaryMovements
     my $res = $self->{mech}->get(sprintf('http://%s/index.php?view=militaryAdvisorMilitaryMovements', $self->{server}));
     my $extractor = new Ikariam::Extractor(content => $res->content);
 
-    my @homeland = $extractor->find('//div[@id="homeland"]');
-    my @elsewhere = $extractor->find('//div[@id="elsewhere"]');
-    $self->{'military'}->{attacks} = $#elsewhere+1;
-    $self->{'military'}->{wars} = $#homeland+1;
+    $self->{'military'}->{wars} = 0;
+    $self->{'military'}->{attack} = 0;
+
+    foreach (qw/homeland elsewhere/) {
+        $self->{'military'}->{$_} = ();
+        my $result = $extractor->{doc}->find(sprintf('//div[@id="%s"]//ul[@id="battleReports"]/li[@class="enroute"]', $_));
+        foreach my $div ( @$result ) {
+            my $extractor = new Ikariam::Extractor(content => $div->toString(1));
+            my $f = $extractor->find('//div[@class="report"]/a[1]/@href');
+            my $t = $extractor->find('//div[@class="report"]/a[2]/@href'),
+            $f = $1 if($f =~ /\?view=island&cityId=(\d+)/);
+            $t = $1 if($t =~ /\?view=island&cityId=(\d+)/);
+
+            push @{$self->{'military'}->{$_}}, { from => $f, to => $t};
+            if($_ eq 'homeland') {
+                $self->{'military'}->{wars}++;
+            } else {
+                $self->{'military'}->{attack}++;
+            }
+        }
+    }
+    # print(Dumper($self->{'military'}));
+}
+
+sub checkMilitaryAdvisorReportView {
+    my $self = shift;
+    my $combatId = shift;
+    my $res = $self->{mech}->get(sprintf('http://%s/index.php?view=militaryAdvisorReportView&detailedCombatId=%s', $self->{server}, $combatId));
+    my $extractor = new Ikariam::Extractor(content => $res->content);
+
+    my %report;
 
-    # there are some details.
-#<div id="homeland" class="content">
-#                <ul id="battleReports">
-#                    <li class="groundfight">
-#                        <div class="type"/>
-#                        <div class="report">
-#                            <table cellspacing="0" cellpadding="0" class="repTable">
-#                                <tbody><tr>
-#                                    <th colspan="2">
-#                                        攻擊 卍严破碎虛空焱卐                                    </th>
-#                                </tr>
-#                            </tbody></table>
-#                        </div>
-#                        <br class="clearfloat"/>
-#                    </li>
-#					<li class="enroute" style="height: 52px;">
-#						<script type="text/javascript">
-#							Event.onDOMReady(function() {
-#								getCountdown({
-#									enddate: 1224863393,
-#									currentdate: 1224862910,
-#									el: "researchCountDown11396440"
-#									}, 3, " ", "", true, true);
-#								});
-#							</script>
-#                        <div class="type">
-#                            <div id="researchCountDown11396440" class="time">5分 46秒</div><div class="undefined"> Finished 23:49:23</div>
-#                        </div>
-#                        <div class="report">
-#來自 <a href="?view=island&amp;cityId=98496">松鼠城</a> 的 3 兵力正在前往 <a href="?view=island&amp;cityId=82959">卍严破碎虛空焱卐</a> 的途中。                        </div>
-#                        <div class="action">
-#                            <div class="return">
-#                                <a href="?action=transportOperations&amp;function=forceReturn&amp;actionRequest=46cc5fdb56b8cb0e65e2116ff9f61512&amp;eventId=11396440&amp;oldView=militaryAdvisorMilitaryMovements" title="返回">返回</a>
-#                            </div>
-#                        </div>
-#                        <br class="clearfloat"/>
-#                    </li>
-#		        </ul>
-#</div>
+    $report{id} = $combatId;
+    my $c = $extractor->{doc}->toString(1);
+    
+    # FIXME 城鎮  6 級)的城牆( 2 級)為防禦部隊增加了 7% 的防禦力。
+    while($c =~ /城鎮\s+(\d+)/gs) {
+        $report{cityLevel} = $1;
+        $report{wallLevel} = $2;
+    }
+    
+    $report{attacker} = $extractor->find('//div[@id="troopsReport"]//table[@id="result"]//th[@class="attackers"]');
+    $report{defender} = $extractor->find('//div[@id="troopsReport"]//table[@id="result"]//th[@class="defenders"]');
+    $report{winner} = $extractor->find('//div[@id="troopsReport"]//table[@id="result"]//td[@class="winner"]');
 
+    $report{targetCity} = $extractor->find('//div[@id="troopsReport"]/div/h3/a/text()');
+    my $href = $extractor->find('//div[@id="troopsReport"]/div/h3/a/@href');
+    if($href =~ /index\.php\?view=island&id=(\d+)&selectCity=(\d+)/) {
+       $report{island} = $1;
+       $report{city} = $2;
+    }
+    $report{gold} = $extractor->find('//div[@id="troopsReport"]//ul[@class="resources"]/li[@class="gold"]');
+    $report{wood} = $extractor->find('//div[@id="troopsReport"]//ul[@class="resources"]/li[@class="wood"]');
+    $report{crystal} = $extractor->find('//div[@id="troopsReport"]//ul[@class="resources"]/li[@class="glass"]');
+    $report{wine} = $extractor->find('//div[@id="troopsReport"]//ul[@class="resources"]/li[@class="wine"]');
+    $report{sulfur} = $extractor->find('//div[@id="troopsReport"]//ul[@class="resources"]/li[@class="sulfur"]');
 
-#    <div id="elsewhere" class="content">
-#                <ul id="battleReports">
-#                    <li class="groundfight">
-#                        <div class="type"/>
-#                        <div class="report">
-#                            <table cellspacing="0" cellpadding="0" class="repTable">
-#                                <tbody><tr>
-#                                    <th colspan="2">
-#                                        攻擊 Rex                                    </th>
-#                                </tr>
-#                            </tbody></table>
-#                        </div>
-#                        <br class="clearfloat"/>
-#                    </li>
-#                    <li class="enroute">
-#                        <script type="text/javascript">
-#												Event.onDOMReady(function() {
-#													getCountdown({
-#														enddate: 1224877160,
-#														currentdate: 1224861666,
-#														el: "researchCountDown159638"
-#														}, 3, " ", "", true, true);
-#													});
-#                        </script>
-#                        <div class="type">
-#                            <div id="researchCountDown159638" class="time">4時 17分 35秒</div>
-#                        </div>
-#                        <div class="report">
-#來自 <a href="?view=island&amp;cityId=6078">水晶交換各種資源</a> 的 3 兵力正在前往 <a href="?view=island&amp;cityId=6077">Rex</a> 的途中。                        </div>
-#                    </li>
-#		        </ul>
-#            </div>
+    foreach(qw/gold wood crystal wine sulfur attacker defender winner/) {
+        $report{$_} =~ s/^.*?:\s+//;
+        $report{$_} =~ s/\s+$//;
+        $report{$_} =~ s/,//g;
+    }
+    return \%report;
 }
 
 sub checkMilitaryAdvisorCombatReports {
     my $self = shift;
-    my $content;
-    my $res = $self->{mech}->get(sprintf('http://%s/index.php?view=militaryAdvisorCombatReports', $self->{server}));
-    gunzip \$res->content => \$content 
-        or die "gunzip failed: $GunzipError\n";
+    my $page = shift || 0;
+
+    my $res = $self->{mech}->get(sprintf('http://%s/index.php?view=militaryAdvisorCombatReports&start=%s', $self->{server}, $page));
+    my $extractor = new Ikariam::Extractor(content => $res->content);
+
+    my $result = $extractor->{doc}->find('//div[@id="troopsOverview"]//table/tr[position()<=10]');
+    foreach my $tr ( @$result ) {
+        my $trExtractor = new Ikariam::Extractor(content => $tr->toString(1));
+        my $date = $trExtractor->find('//td[@class="date"]');
+        $date =~ s/^\s+//g; $date =~ s/\s+$//g;
+
+
+        my $href = $trExtractor->find('//td/a/@href');
+        if($href =~ /index.php\?view=militaryAdvisorReportView&combatId=(\d+)/) {
+            my $report = Ikariam::Report->retrieve($1);
+            if(!$report) {
+                my $report_hash = $self->checkMilitaryAdvisorReportView($1);
+                $report = Ikariam::Report->insert($report_hash);
 
-    # TODO
+                if($date =~ /(\d+)\.(\d+)\. (\d+):(\d+)/) {
+                    my $unixtime = mktime (0, $4, $3, $1, ($2-1), '108');
+                    $report->set('date', $unixtime);
+                }
+                $report->set('time', time);
 
-    # list down reports.
-    # /index.php?view=militaryAdvisorReportView&amp;combatId=1887662
-    # //form[@id='finishedReports']//a
+                $report->update();
+            } else {
+                return;
+            }
+        } else {
+            return;
+        }
+    }
+
+    my @moreCombats = $extractor->find('//div[@id="troopsOverview"]//table/tr[position()>10]//a/@href');
+    foreach (@moreCombats){
+        last if(/^javascript/);
+        if(/\?view=militaryAdvisorCombatReports&start=(\d+)/) {
+            next if($1 le $page);
+            $self->checkMilitaryAdvisorCombatReports($1);
+            last;
+        }
+    }
 }
 
 sub checkTownHall {