# HG changeset patch # User "Rex Tsai " # Date 1223389486 -28800 # Node ID abaee70644290715a05d1f08fbb5fd93096db894 new scanning prototype. diff -r 000000000000 -r abaee7064429 Ikariam.pm --- /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; diff -r 000000000000 -r abaee7064429 scan.pl --- /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();