changeset 0:abaee7064429

new scanning prototype.
author "Rex Tsai <chihchun@kalug.linux.org.tw>"
date Tue, 07 Oct 2008 22:24:46 +0800
parents
children f9eac5385dc0
files Ikariam.pm scan.pl
diffstat 2 files changed, 244 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Ikariam.pm	Tue Oct 07 22:24:46 2008 +0800
@@ -0,0 +1,175 @@
+#!/usr/bin/env perl
+package Ikariam;
+
+use Data::Dumper;
+use LWP;
+use LWP::Debug qw(+ -conns);
+use HTTP::Cookies;
+use WWW::Mechanize;
+use HTML::TagParser;
+use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
+
+sub new
+{
+    my ($class, $server, $user, $pass) = @_;
+
+    my $self =
+    {
+        mech => WWW::Mechanize->new(agent => "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092816 Iceweasel/3.0.1 (Debian-3.0.1-1)"),
+        server => $server,
+        user => $user,
+        pass => $pass,
+    };
+
+    $self->{mech}->cookie_jar(HTTP::Cookies->new(file => "./cookies.txt", autosave => 1));
+    $self->{mech}->default_headers->push_header('Accept-Encoding', 'deflate');
+ 
+    return bless $self, $class;
+}
+
+sub viewWorldMap
+{
+    my $self = shift;
+    my $x = shift;
+    my $y = shift;
+
+    my $res;
+    if(defined($x) && defined($y))
+    {
+        $res = $self->{mech}->post(sprintf("http://%s/index.php?view=worldmap_iso", $self->{server}), [
+            xajax => 'getMapData',
+            'xajaxargs[]' => $x,
+            'xajaxargs[]' => $y,
+            xajaxr => time,
+            ]);
+    } else {
+        $res = $self->{mech}->get(sprintf("http://%s/index.php?view=worldmap_iso", $self->{server}));
+    }
+
+    my $c;
+    my $status = gunzip \$res->content => \$c 
+        or die "gunzip failed: $GunzipError\n";
+
+    # m[50][36]=new Array(564,1,5,'Risietia', '5', 13);
+    # x = 43-57 = 6
+    # y = 27-41 = 6
+    my @islands;
+    while($c =~ /m\[(\d+)\]\[(\d+)\]=new Array\((\d+),(\d+),(\d+),'(\w+)', '(\d+)', (\d+)\);/g)
+    {
+        my %island;
+        $island{id} = $3;
+        $island{x} = $1;
+        $island{y} = $2;
+        $island{name} = $6;
+        $island{tradegood} = $4;
+        $island{wonder} = $5;
+        # $7 ?
+        $island{people} = $8;
+
+        #foreach my $i (sort(keys(%island)))
+        #{
+        #    printf ("%s %s\n", $i, $island{$i});
+        #}
+        #print("\n");
+        push @islands, \%island;
+    }
+    return @islands;
+}
+
+sub viewIsland
+{
+    my $self = shift;
+    my $island = shift;
+
+    my $res = $self->{mech}->get(sprintf("http://%s/index.php?view=island&id=%s", $self->{server}, $island));
+
+    my $c;
+    my $status = gunzip \$res->content => \$c 
+        or die "gunzip failed: $GunzipError\n";
+
+    my $html = HTML::TagParser->new($c);
+    my @elems = $html->getElementsByClassName( "cityinfo" );
+    my @cities;
+    foreach my $elem (@elems) {
+        my %info;
+
+        my @e = getElementsByTagName($elem, "li");
+        $info{'cityname'} = substr($e[0]->innerText(), 8);
+        $info{'citylevel'} = substr($e[1]->innerText(), 14);
+        $info{'owner'} = substr($e[2]->innerText(), 8);
+        $info{'ally'} = substr($e[3]->innerText(), 8);
+        @e = getElementsByAttribute($elem, "class", "messageSend");
+        if ( $e[0]->getAttribute("href") =~ /with=(\d+)&destinationCityId=(\d+)/)
+        {
+            $info{'ownerId'} = $1;
+            $info{'cityId'} = $2;
+        }
+
+        push @cities, \%info;
+        #foreach my $i (sort(keys(%info)))
+        #{
+            #    printf("%s: %s ", $i, $info{$i});
+            # }
+        # printf("\n");
+    }
+
+    return @cities;
+}
+
+sub login
+{
+    my $self = shift;
+
+    # $self->{mech}->get(sprintf('http://%s/', $self->{server}));
+    my $res = $self->{mech}->post(sprintf("http://%s/index.php?action=loginAvatar&function=login", $self->{server}), [
+        name => $self->{user},
+        password => $self->{pass},
+        ]);
+    my $c;
+    my $status = gunzip \$res->content => \$c 
+        or die "gunzip failed: $GunzipError\n";
+
+    if($c =~ /錯誤!/)
+    {
+        die ("password error\n");
+    }
+}
+
+sub getElementsByTagName {
+    my $element    = shift;
+    my $tagname = lc(shift);
+    my ( $flat, $cur ) = @$element;
+
+    my $out = [];
+    for( ; $cur <= $#$flat ; $cur++ ) {
+        next if ( $flat->[$cur]->[001] ne $tagname );
+        next if $flat->[$cur]->[000];                 # close
+        my $elem = HTML::TagParser::Element->new( $flat, $cur );
+        return $elem unless wantarray;
+        push( @$out, $elem );
+    }
+    return unless wantarray;
+    @$out;
+}
+
+sub getElementsByAttribute {
+    my $element = shift;
+    my $key  = lc(shift);
+    my $val  = shift;
+    my ( $flat, $cur ) = @$element;
+
+    my $out  = [];
+    for ( ; $cur <= $#$flat ; $cur++ ) {
+        next if $flat->[$cur]->[000];    # close
+        my $elem = HTML::TagParser::Element->new( $flat, $cur );
+        my $attr = $elem->attributes();
+        next unless exists $attr->{$key};
+        next if ( $attr->{$key} ne $val );
+        return $elem unless wantarray;
+        push( @$out, $elem );
+    }
+    return unless wantarray;
+    @$out;
+}
+
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scan.pl	Tue Oct 07 22:24:46 2008 +0800
@@ -0,0 +1,69 @@
+#!/usr/bin/perl
+use strict;
+use Ikariam;
+
+package main;
+
+use Class::DBI::AutoLoader (
+    dsn       => 'dbi:SQLite:dbname=ikariam.sqlite',
+    options   => { RaiseError => 1 },
+    tables    => ['cities', 'islands'],
+    use_base  => 'Class::DBI::SQLite',
+    namespace => 'Ikariam',
+);
+
+my $i = new Ikariam("s2.ikariam.tw", "chihchun", "c795d57d");
+$i->login;
+my @islands = $i->viewWorldMap(89, 60);
+
+foreach my $island (@islands)
+{
+    printf("checking island %d\n", $island->{id});
+    if(my $c = Ikariam::Islands->retrieve($island->{id})) {
+        foreach my $i (keys(%$island)) {
+            eval($c->$i($island->{$i}));
+        }
+    } else {
+        Ikariam::Islands->insert($island);
+    }
+
+    # scanning the island
+    my @cities = $i->viewIsland($island->{id});
+    foreach my $city (@cities)
+    {
+        $city->{island} = $island->{id};
+        printf("checking city %d\n", $city->{cityId});
+        if(my $c = Ikariam::Cities->retrieve($city->{cityId}))
+        {
+            foreach my $i (keys(%$city))
+            {
+                eval($c->$i($city->{$i}));
+                printf("%s %s ", $i, $city->{$i});
+            }
+            print ("\n");
+
+            $c->update();
+        } else {
+            Ikariam::Cities->insert($city);
+        }
+    }
+}
+
+
+# TODO
+# $i->worldmap($x, $y);
+# http://s2.ikariam.tw/index.php?view=worldmap_iso
+# xajax getMapData
+# xajaxargs[]   54
+# xajaxargs[]   30
+# xajaxr        1223302744553
+# $i->getAcount() account database.
+
+# 經濟, 軍事
+# http://s2.ikariam.tw/index.php
+# view	highscore
+# highscoreType	score
+# offset	-1
+# searchUser	chihchun
+
+# $i->getCityInfo();