# HG changeset patch # User "Rex Tsai " # Date 1225794846 -28800 # Node ID 8e9f2848f8cd0b5faed81a9b63825f2283dc6403 # Parent 60c3ab6983509bdc645dfaa773a67d2ca01ec9a0# Parent 51a8a81d0bb63791602ec5a2923bb9ba5de82b49 merged. diff -r 51a8a81d0bb6 -r 8e9f2848f8cd .hgignore --- a/.hgignore Sun Nov 02 11:58:02 2008 +0800 +++ b/.hgignore Tue Nov 04 18:34:06 2008 +0800 @@ -7,6 +7,7 @@ *.html *.sh *.txt +*-dump.yaml excel perl samples diff -r 51a8a81d0bb6 -r 8e9f2848f8cd Ikariam.pm --- a/Ikariam.pm Sun Nov 02 11:58:02 2008 +0800 +++ b/Ikariam.pm Tue Nov 04 18:34:06 2008 +0800 @@ -116,33 +116,11 @@ user => $user, pass => $pass, debug => undef, - buildingIDs => { - townHall => 0, - townhall => 0, - port => 3, - academy => 4, - shipyard => 5, - barracks => 6, - warehouse => 7, - wall => 8, - tavern => 9, - museum => 10, - palace => 11, - embassy => 12, - branchOffice => 13, - workshop => 15, - 'workshop-army' => 15, - 'workshop-fleet' => 15, - safehouse => 16, - palaceColony => 17, - resource => 1, - tradegood => 2 - } }; # if debug - # LWP::Debug::level('+trace'); + LWP::Debug::level('+trace'); $self->{mech}->cookie_jar(HTTP::Cookies->new(file => "/tmp/ikariam-cookies.txt", autosave => 1)); $self->{mech}->default_headers->push_header('Accept-Encoding', 'deflate'); @@ -312,23 +290,18 @@ delete($info{'ally'}) } else { my $href = $extractor->find(sprintf('//li[@id="cityLocation%s"]//li[@class="ally"]/a/@href', $i)); - # http://s2.ikariam.tw/index.php?view=allyPage&allyId=264&oldView=island&id=569 if($href =~ /&allyId=(\d+)&/) { $info{'allyId'} = $1; } } # Ally Id - my $href = $extractor->find(sprintf('//li[@id="cityLocation%s"]//a[@class="messageSend"]/@href', $i)); - # ?view=sendMessage&type=0&with=20204&destinationCityId=64165&oldView=island if ($href =~ /with=(\d+)&destinationCityId=(\d+)/) { $info{'user'} = $1; $info{'cityId'} = $2; - # ?view=sendAllyMessage&allyId=1192&oldView=island&id=721 } else { - # 聯盟 - # this is me. + # 聯盟 this is me. my $id = $extractor->find(sprintf('//li[@id="cityLocation%s"]/a/@id', $i)); if($id =~ /city_(\d+)/) { $info{'user'} = undef; # FIXME @@ -372,6 +345,7 @@ } } + # for tavern only sub set { my $self = shift; @@ -391,13 +365,171 @@ $self->{mech}->submit_form( form_number => 1, fields => { - amount => $self->{'cities'}->{$cityId}->{$type}->{maxValue}, - } + amount => $self->{'cities'}->{$cityId}->{$type}->{maxValue}, + } ); } } +sub is_shipyard_upgrading { + my $self = shift; + my $cityId = shift; + my $type = "shipyard"; + + my $position = -1; + my @locations = @{$self->{'cities'}->{$cityId}->{locations}}; + foreach (1..2) { + $position = $_ if($locations[$_] eq $type); + } + + if($position != -1) { + my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); + if(defined(Ikariam::Extractor->new(content => $res->content)->find('//div[@class="isUpgrading"]'))) { + return 1; + } else { + return 0; + } + } + return 0; +} + +sub is_navy_trainning { + my $self = shift; + my $cityId = shift; + my $type = "shipyard"; + + my $position = -1; + my @locations = @{$self->{'cities'}->{$cityId}->{locations}}; + foreach (1..2) { + $position = $_ if($locations[$_] eq $type); + } + + if($position != -1) { + my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); + if(defined(Ikariam::Extractor->new(content => $res->content)->find('//div[@id="unitConstructionList"]//h4'))) { + return 1; + } else { + return 0; + } + } + # FIXME we can not found the shipyard + return 0; +} + +sub buildShips { + my $self = shift; + my $shipType = shift; + my $cityId = shift; + my $type = 'shipyard'; + + warn("buildShips $shipType"); + my $position = -1; + my @locations = @{$self->{'cities'}->{$cityId}->{locations}}; + foreach (1..2) { + $position = $_ if($locations[$_] eq $type); + } + + if($position != -1) { + my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); + $self->{mech}->submit_form( + form_number => 1, + fields => { + $shipType => 1, + } + ); + } +} + +sub is_army_trainning { + my $self = shift; + my $cityId = shift; + my $type = "barracks"; + + my $position = -1; + my @locations = @{$self->{'cities'}->{$cityId}->{locations}}; + foreach (2..$#locations) { + $position = $_ if($locations[$_] eq $type); + } + + if($position != -1) { + my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); + if(defined(Ikariam::Extractor->new(content => $res->content)->find('//div[@id="unitConstructionList"]//h4'))) { + return 1; + } else { + return 0; + } + } + # FIXME we can not found the shipyard + return 0; +} + +sub is_barracks_upgrading { + my $self = shift; + my $cityId = shift; + my $type = 'barracks'; + + my $position = -1; + my @locations = @{$self->{'cities'}->{$cityId}->{locations}}; + foreach (2..$#locations) { + $position = $_ if($locations[$_] eq $type); + } + + if($position != -1) { + my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); + if(defined(Ikariam::Extractor->new(content => $res->content)->find('//div[@class="isUpgrading"]'))) { + return 1; + } else { + return 0; + } + } + return 0; +} + +sub buildUnits { + my $self = shift; + my $unitType = shift; + my $cityId = shift; + my $type = 'barracks'; + + warn("buildShips $unitType"); + my $position = -1; + my @locations = @{$self->{'cities'}->{$cityId}->{locations}}; + foreach (2..$#locations) { + $position = $_ if($locations[$_] eq $type); + } + + if($position != -1) { + my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); + $self->{mech}->submit_form( + form_number => 1, + fields => { + $unitType => 1, + } + ); + } +} + +sub buildSpy { + my $self = shift; + my $unitType = shift; + my $cityId = shift; + my $type = 'safehouse'; + + my $position = -1; + my @locations = @{$self->{'cities'}->{$cityId}->{locations}}; + foreach (2..$#locations) { + $position = $_ if($locations[$_] eq $type); + } + + if($position != -1) { + my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); + my $url = + Ikariam::Extractor->new(content => $res->content)->find(sprintf('//div[@class="forminput"]/a/@href')); + $self->{mech}->get($url) if(defined($url)); + } +} + sub build { my $self = shift; my $type = shift; @@ -412,16 +544,27 @@ } if($position == -1) { - foreach (0..$#locations) { - # XXX - next if($_ <= 2 && ($self->{buildingIDs}->{$type} ne "workshop-fleet" && - $self->{buildingIDs}->{$type} ne "shipyard")); - if($locations[$_] eq undef) { - my $res = $self->{mech}->get(sprintf('http://%s/index.php?action=CityScreen&function=build&id=%s&position=%s&building=%d', - $self->{server}, $cityId, $_, $self->{buildingIDs}->{$type} )); - last; + my $targetPosition = undef; + if($type eq "wall") { + # 14 is wall. + $targetPosition = 14; + } else { + foreach (0..13) { + next if($_ <= 2 && ($type ne "workshop-fleet" && + $type ne "shipyard")); + + if($locations[$_] eq undef) { + $targetPosition = $_; + last; + } } } + + my $res = $self->{mech}->get(sprintf('http://%s/index.php?view=buildingGround&id=%s&position=%s', + $self->{server}, $cityId, $targetPosition)); + my $url = + Ikariam::Extractor->new(content => $res->content)->find(sprintf('//li[@class="building %s"]//a/@href', $type)); + $self->{mech}->get($url) if(defined($url)); } else { my $res = $self->{mech}->get (sprintf("http://%s/index.php?view=%s&id=%s&position=%d", $self->{server}, $type, $cityId, $position)); my $url = Ikariam::Extractor->new(content => $res->content)->find('//a[@title="升級建築物"]/@href'); @@ -433,7 +576,7 @@ my $self = shift; my $param = shift; # defense. - die("run $param not implemented yet."); + warn ("run $param not implemented yet."); } sub research @@ -474,11 +617,19 @@ $self->{mech}->submit_form( form_number => 1, fields => { - cargo_army_302 => '2', - } + cargo_army_302 => '3', # 劍士 + } ); } else { - warn ($treaty); + # put the id in the friends.txt file. + Ikariam::Cities->has_a(user => 'Ikariam::User'); + my $city = Ikariam::Cities->retrieve($cityId); + my $sheep = $city->user; + + open(OUT, ">>friends.txt") or Carp::carp("can not open friends.txt"); + print OUT $sheep->name . "\n"; + close(OUT); + Carp::carp($treaty); } } @@ -607,7 +758,6 @@ } } } - # print(Dumper($self->{'military'})); } sub checkMilitaryAdvisorReportView { @@ -619,7 +769,7 @@ my %report; $report{id} = $combatId; - my $c = $extractor->{doc}->toString(1); + my $c = $extractor->{doc}->toString(0); # FIXME 城鎮 6 級)的城牆( 2 級)為防禦部隊增加了 7% 的防禦力。 while($c =~ /城鎮\s+(\d+)/gs) { @@ -846,6 +996,7 @@ $self->checkArmies($cityId); $self->checkTavern($cityId); } + # $self->checkFriends(); return $self->{'cities'}; } @@ -895,30 +1046,29 @@ # o 最佳軍營等級 # a 攻擊力 # d 防守力 - # A - # D + # A 攻擊力加成 + # D 防守力加成 # s 耐力 # c 種類 - # v speed - # x 加成 Assault, Resistance - Slinger => {n=>"Slinger",p=>1,w=>40,b=>"12m",u=>8,m=>1,o=>4,a=>7,d=>6,A=>2,D=>2,s=>10,c=>"Human",v=>20}, - Swordsman => {n=>"Swordsman",p=>2,w=>47,S=>16,b=>"17m",u=>16,m=>3,o=>5,a=>18,d=>14,A=>4,D=>3,s=>12,c=>"Human",v=>20,x=>"Assault"}, - Phalanx => {n=>"Phalanx",p=>4,w=>104,S=>64,b=>"40m",u=>24,m=>4,o=>7,a=>24,d=>40,A=>6,D=>10,s=>14,c=>"Human",v=>20,x=>"Resistance"}, - Ram => {n=>"Ram",p=>8,w=>198,S=>128,b=>"42m",u=>52,m=>5,o=>8,a=>14,d=>18,A=>3,D=>4,s=>16,c=>"Machina",v=>20,x=>"Ram"}, - Archer => {n=>"Archer",p=>4,w=>172,S=>86,b=>"49m",u=>32,m=>7,o=>10,a=>40,d=>40,A=>10,D=>10,s=>12,c=>"Human",v=>20}, - Catapult => {n=>"Catapult",p=>10,w=>342,S=>232,b=>"49m",u=>72,m=>10,o=>14,a=>36,d=>28,A=>9,D=>7,s=>16,c=>"Machina",v=>20,x=>"Ram"}, - Gunsman => {n=>"Gunsman",i=>"marksman",p=>7,w=>355,S=>154,b=>"1h 23m",u=>58,m=>14,o=>18,a=>80,d=>64,A=>18,D=>14,s=>10,c=>"Human",v=>20}, - Mortar => {n=>"Mortar",p=>12,w=>1325,S=>938,b=>"1h 53m",u=>128,m=>19,o=>21,a=>64,d=>64,A=>15,D=>15,s=>16,c=>"Machina",v=>20,x=>"Ram"}, - SteamGiant => {n=>"SteamGiant",i=>"steamgiant",p=>6,w=>1150,S=>716,b=>"1h 45m",u=>68,m=>16,o=>20,a=>100,d=>140,A=>20,D=>30,s=>14,c=>"Machina",v=>20,x=>"Resistance"}, - Gyrocopter => {n=>"Gyrocopter",p=>8,w=>1250,S=>670,b=>"1h 2m",u=>97,m=>12,o=>16,a=>112,d=>112,A=>25,D=>25,s=>12,c=>"Machina",v=>20}, - Bombardier => {n=>"Bombardier",p=>24,w=>2270,S=>878,b=>"2h 10m",u=>228,m=>22,o=>24,a=>200,d=>165,A=>45,D=>35,s=>14,c=>"Machina",v=>20,x=>"Assault"}, - Doctor => {n=>"Doctor",i=>"medic",p=>6,w=>640,C=>361,b=>"1h 2m",u=>244,m=>11,o=>12,a=>4,d=>28,A=>0,D=>0,s=>14,c=>"Human",v=>20,x=>"Healer"}, - Cook => {n=>"Cook",p=>4,w=>520,W=>103,b=>"38m",u=>138,m=>8,o=>8,a=>6,d=>26,A=>0,D=>0,s=>16,c=>"Human",v=>20,x=>"Regeneration"} + # v Speed + # x 攻防加成 Assault, Resistance + Slinger => {n => "Slinger", p => 1, w => 40, b => "12m", u => 8, m => 1, o => 4, a => 7, d => 6, A => 2, D => 2, s => 10, c => "Human", v => 20}, + Swordsman => {n => "Swordsman", p => 2, w => 47, S => 16, b => "17m", u => 16, m => 3, o => 5, a => 18, d => 14, A => 4, D => 3, s => 12, c => "Human", v => 20, x => "Assault"}, + Phalanx => {n => "Phalanx", p => 4, w => 104, S => 64, b => "40m", u => 24, m => 4, o => 7, a => 24, d => 40, A => 6, D => 10, s => 14, c => "Human", v => 20, x => "Resistance"}, + Ram => {n => "Ram", p => 8, w => 198, S => 128, b => "42m", u => 52, m => 5, o => 8, a => 14, d => 18, A => 3, D => 4, s => 16, c => "Machina", v => 20, x => "Ram"}, + Archer => {n => "Archer", p => 4, w => 172, S => 86, b => "49m", u => 32, m => 7, o => 10, a => 40, d => 40, A => 10, D => 10, s => 12, c => "Human", v => 20}, + Catapult => {n => "Catapult", p => 10, w => 342, S => 232, b => "49m", u => 72, m => 10, o => 14, a => 36, d => 28, A => 9, D => 7, s => 16, c => "Machina", v => 20, x => "Ram"}, + Gunsman => {n => "Gunsman", i => "marksman", p => 7, w => 355, S => 154, b => "1h 23m", u => 58, m => 14, o => 18, a => 80, d => 64, A => 18, D => 14, s => 10, c => "Human", v => 20}, + Mortar => {n => "Mortar", p => 12, w => 1325, S => 938, b => "1h 53m", u => 128, m => 19, o => 21, a => 64, d => 64, A => 15, D => 15, s => 16, c => "Machina", v => 20, x => "Ram"}, + SteamGiant => {n => "SteamGiant", i => "steamgiant", p => 6, w => 1150, S => 716, b => "1h 45m", u => 68, m => 16, o => 20, a => 100, d => 140, A => 20, D => 30, s => 14, c => "Machina", v => 20, x => "Resistance"}, + Gyrocopter => {n => "Gyrocopter", p => 8, w => 1250, S => 670, b => "1h 2m", u => 97, m => 12, o => 16, a => 112, d => 112, A => 25, D => 25, s => 12, c => "Machina", v => 20}, + Bombardier => {n => "Bombardier", p => 24, w => 2270, S => 878, b => "2h 10m", u => 228, m => 22, o => 24, a => 200, d => 165, A => 45, D => 35, s => 14, c => "Machina", v => 20, x => "Assault"}, + Doctor => {n => "Doctor", i => "medic", p => 6, w => 640, C => 361, b => "1h 2m", u => 244, m => 11, o => 12, a => 4, d => 28, A => 0, D => 0, s => 14, c => "Human", v => 20, x => "Healer"}, + Cook => {n => "Cook", p => 4, w => 520, W => 103, b => "38m", u => 138, m => 8, o => 8, a => 6, d => 26, A => 0, D => 0, s => 16, c => "Human", v => 20, x => "Regeneration"} }; my $cost = 0; foreach(keys(%{$cities->{$cityId}->{army}})) { - # printf("%s %d = %d\n", $_, $cities->{$cityId}->{army}->{$_}, $cities->{$cityId}->{army}->{$_} * $troops->{$_}->{u}); $cost += $cities->{$cityId}->{army}->{$_} * $troops->{$_}->{u}; } return $cost; @@ -1002,6 +1152,7 @@ } foreach(@cities) { $self->{'cities'}->{$_} = {}; + $self->{'cities'}->{$_}->{id} = $_; } } diff -r 51a8a81d0bb6 -r 8e9f2848f8cd agent.pl --- a/agent.pl Sun Nov 02 11:58:02 2008 +0800 +++ b/agent.pl Tue Nov 04 18:34:06 2008 +0800 @@ -36,17 +36,70 @@ return ($city->{buildings}->{wall} >= $city->{buildings}->{townHall} ? 1 : 0); } +sub is_academy_enough { + my ($self, $city) = @_; + return ($city->{buildings}->{academy} >= 6 ? 1 : 0); +} + +sub is_embassy_enough { + my ($self, $city) = @_; + return ($city->{buildings}->{embassy} >= 6 ? 1 : 0); +} + +sub is_museum_enough { + my ($self, $city) = @_; + return ($city->{buildings}->{museum} >= 2 ? 1 : 0); +} + sub is_space_enough { my ($self, $city) = @_; # The maximum town hall is level 20, then we build new town return 1 if($city->{buildings}->{townHall} >= 20); # TODO 應該以 成長率 * 升級所需時間計算 # 6 hours earlier, we upgrade the twonHall. - return ($city->{space}->{total} <= ($city->{space}->{occupied} + ($city->{growth}*6)) ? 0 : 1) + return ($city->{space}->{total} <= ($city->{space}->{occupied} + ($city->{growth}*8)) ? 0 : 1) +} + +sub is_safehouse_enough { + my ($self, $city) = @_; + return 0 if(!defined($city->{buildings}->{safehouse})); + return (($city->{buildings}->{townHall} <= ($city->{buildings}->{safehouse} + 4)) ? 0 : 1); +} + +sub is_warehouse_enough { + my ($self, $city) = @_; + my @warehouse = (qw/undef undef 0 4 9 16 18 19 20 21 22 23 24 25/); + my @cities = keys(%{$self->{ikariam}->{cities}}); + my $nextCities = ($#cities + 1) + 1; + + Carp::carp(sprintf("Required warehouse level %s for next city (%s), current is %s\n", $warehouse[$nextCities], $nextCities, $city->{buildings}->{warehouse})); + return 0 if(!defined($city->{buildings}->{warehouse})); + return ($city->{buildings}->{warehouse} >= $warehouse[$nextCities]) ? 1 : 0; +} + + +sub is_warehouse_enougn_for_governorsresidence { + my ($self, $city) = @_; + my @warehouse = (qw/undef undef 0 4 9 16 18 19 20 21 22 23 24 25/); + my @cities = keys(%{$self->{ikariam}->{cities}}); + my $citiesNumber = $#cities + 1; + + Carp::carp(sprintf("Required warehouse level %s for %s cities, current is %s\n", $warehouse[$citiesNumber], $citiesNumber, $city->{buildings}->{warehouse})); + return 0 if(!defined($city->{buildings}->{warehouse})); + return ($city->{buildings}->{warehouse} >= $warehouse[$citiesNumber]) ? 1 : 0; } sub is_corruption { my ($self, $city) = @_; + return ($city->{corruption} > 0) ? 1 : 0; +} + +sub is_any_corruption { + my ($self, $city) = @_; + + foreach (keys(%{$self->{ikariam}->{cities}})) { + return 1 if ($self->{ikariam}->{cities}->{$_}->{corruption} > 0); + } return 0; } @@ -71,24 +124,6 @@ return ($city->{tavern}->{maxValue} == $city->{tavern}->{iniValue} ? 1 : 0); } -sub is_warehouse_enough { - my ($self, $city) = @_; - # TODO 以速率計算容納率 - return 1; -} - -sub is_risk { - my ($self, $city) = @_; - # TODO 計算可搶劫比例, 城牆防護, 軍事分數 - # - # my $capture = $city->{buildings}->{townHall} * ($city->{buildings}->{townHall} - 1) * $city->{resource}->gold / 10000; - # 計算軍人消耗 - # 方陣兵, 1.58 軍分, 24 維護費 - # 劍士, 4.64 軍分, 16 維護費 - # army_score_main > (occupied * 0.3) - return 0; -} - sub is_gold_enoughforcargo { my ($self, $city) = @_; my @cargoCost = qw/160 244 396 812 1240 1272 1832 1888 3848 3972 5204 5384 6868 7120 8864 9200 11268 11712 14108 14680 23320 24288 28664 29880 34956 36468 42348 44212 51024 53308 61236 64024 73096 76468 87020 91088 103224 116524 122072 137432 180060 202132 211964 237444 249108 278276 292076 306623 321963 338138 355198 373191 392171 412195 433320 455612 479135 503962 530166 557828 587031 617863 650420 684802 721113 759466 799981 842783 888005 935790 986286 1039654 1096062 1155689 1218724 1285369 1355837 1430353 1509159 1592508 1680670 1773932 1872597 1976989 2087448 2204338 2328045 2458976 2597567 2744276 2899594 3064040 3238163 3422550 3617820 3824635 4043693 4275738 4521561 4782000 5057946 5350345 5660202 5988585 6336630 6705540 7096598 7511164 7950683 8416694 8910828 9434823 9990523 10579889 11205006 11868090 12571498 13317734 14109462 14949514/; @@ -119,7 +154,7 @@ return (defined($self->{'ikariam'}->{research}->{1030}) ? 1 : 0); } -sub is_culturalexchange_researched { +sub is_foreigncultures_researched { my ($self) = @_; return (defined($self->{'ikariam'}->{research}->{1040}) ? 1 : 0); } @@ -129,6 +164,11 @@ return (defined($self->{'ikariam'}->{research}->{1060}) ? 1 : 0); } +sub is_conservation_researched { + my ($self) = @_; + return (defined($self->{'ikariam'}->{research}->{2010}) ? 1 : 0); +} + sub is_wealth_researched { my ($self) = @_; return (defined($self->{'ikariam'}->{research}->{2030}) ? 1 : 0); @@ -172,35 +212,83 @@ sub is_barracks_level_enough { my ($self, $city) = @_; return 0 if(!defined($city->{buildings}->{barracks})); - # 方陣兵需要 level 4 - # optimum is 5 - return ($city->{buildings}->{barracks} >= 4 ? 1 : 0); + if($city->{buildings}->{townHall} >= 10) { + # optimum is 5 + return ($city->{buildings}->{barracks} >= 5 ? 1 : 0); + } else { + # 方陣兵需要 level 4 + return ($city->{buildings}->{barracks} >= 4 ? 1 : 0); + } } sub is_shipyard_level_enough { my ($self, $city) = @_; return 0 if(!defined($city->{buildings}->{shipyard})); - # optimum is 5 - return ($city->{buildings}->{shipyard} >= 3 ? 1 : 0); - return 0; + if ($self->is_greekfire_researched() eq 1) { + return ($city->{buildings}->{shipyard} >= 5 ? 1 : 0); + } else { + return ($city->{buildings}->{shipyard} >= 3 ? 1 : 0); + } +} + +sub is_shipyard_upgrading { + my ($self, $city) = @_; + return $self->{'ikariam'}->is_shipyard_upgrading($city->{id}); +} + +sub is_navy_trainning { + my ($self, $city) = @_; + return $self->{'ikariam'}->is_navy_trainning($city->{id}); } -sub rule_engagement -{ +sub train_navy { my ($self, $city) = @_; - # TODO - # 計算距離, 可搶劫比例, 是否有聯盟, 軍事分數 (win rate) + my $cityId = $city->{id}; + # TODO, 依照升級比例算 CP 值最高 + if($self->is_greekfire_researched() eq 1 && $city->{buildings}->{shipyard} >= 5) { + # ok, we can build Flamethrower. + if(defined($city->{'fleet'}->{Flamethrower}) && ($city->{'fleet'}->{Flamethrower} > 0) + && ($city->{'fleet'}->{BallistaShip} / $city->{'fleet'}->{Flamethrower}) <= (1.5/1)) { + return 213; # 強弩船 + } else { + return 211; # 噴火船 + } + } else { + return 213; # 強弩船 + } } -sub rule_resource -{ - # TODO +sub is_barracks_upgrading { + my ($self, $city) = @_; + return $self->{ikariam}->is_barracks_upgrading($city->{id}); +} + +sub is_army_trainning { + my ($self, $city) = @_; + return $self->{ikariam}->is_army_trainning($city->{id}); +} +sub train_army { + my ($self, $city) = @_; + my $cityId = $city->{id}; + + # TODO, 依照升級比例算 CP 值最高 + my $assault = 'Swordsman'; + my $resistance = 'Phalanx'; + + # ok, we can build Flamethrower. + if(($city->{'army'}->{$assault} / $city->{'army'}->{$resistance}) <= (2/1)) { + return 302; # Swordsman + } else { + return 303; # Phalanx + } } # navy -sub rule_navyExpenditure +sub is_navyExpenditure_available { - my ($self, $cityId) = @_; + my ($self, $city) = @_; + my $cityId = $city->{id}; + # move this to somewhere else. my $workersRatio = { 'citizens' => 0.4, @@ -212,19 +300,23 @@ my $netincome = $self->{'ikariam'}->getNetIncome($cityId); # 軍費為 兩成 淨收入 - # 陸軍佔用 0.8 - # 海軍佔用 0.2 - my $militaryExpenditure = int($netincome * 0.2 * 0.2); + # 陸軍佔用 0.3 + # 海軍佔用 0.7 + my $militaryExpenditure = int($netincome * 0.2 * 0.7); if($currentCost < $militaryExpenditure) { printf("Current navy expenditure total=%s, affordable %s\n", $currentCost, $militaryExpenditure); + return 1; } + return 0; } # army -sub rule_milityExpenditure +sub is_milityExpenditure_available { - my ($self, $cityId) = @_; + my ($self, $city) = @_; + my $cityId = $city->{id}; + # move this to somewhere else. my $workersRatio = { 'citizens' => 0.4, @@ -236,14 +328,18 @@ my $netincome = $self->{'ikariam'}->getNetIncome($cityId); # 軍費為 兩成 淨收入 - # 陸軍佔用 0.8 - # 海軍佔用 0.2 - my $militaryExpenditure = int($netincome * 0.2 * 0.8); + # 陸軍佔用 0.3 + # 海軍佔用 0.7 + + my $militaryExpenditure = int($netincome * 0.2 * 0.3); if($currentCost < $militaryExpenditure) { - printf("Current army expenditure total=%s, affordable %s\n", $currentCost, $militaryExpenditure); + Carp::carp("Current army expenditure total=%s, affordable %s\n", $currentCost, $militaryExpenditure); + return 1; } + return 0; } + 1; @@ -258,9 +354,7 @@ my $rules = Ikariam::Cities::Rules->new($i); # blanace resources, arrange defance my $tree = LoadFile('overall.yaml'); -my $decision; -$decision->{parse_path} = []; -$decision->{parse_answer} = undef; +my $decision; $decision->{parse_path} = []; $decision->{parse_answer} = undef; my $action = ParseTree($tree, $rules, $decision); triggerAction($action, (keys(%$cities))[0]) if(defined($action)); # print STDERR Dump($decision) if(defined($verbose)); @@ -270,8 +364,7 @@ printf("%s http://%s/index.php?view=city&id=%d\n", $cities->{$cityId}->{name}, $::server, $cityId); printf("construction: %s\n", $cities->{$cityId}->{construction}); - - # foreach my $thing (qw/resources space wars buildings citizens army fleet/) { + foreach my $thing (qw/resources space buildings citizens army fleet/) { printf("<%s>\n", uc($thing)); foreach my $i (keys(%{$cities->{$cityId}->{$thing}})) { @@ -283,25 +376,30 @@ # maybe this should be moved to Rules. $i->blanceHurmanResource($cityId); - # milityExpenditure - $rules->rule_milityExpenditure($cityId); - $rules->rule_navyExpenditure($cityId); + + # build spy + $i->buildSpy('spy', $cityId); + + # build military! + $tree = LoadFile('military.yaml'); + $cities->{$cityId}->{parse_path} = []; + $cities->{$cityId}->{parse_answer} = undef; + if (my $action = ParseTree($tree, $rules, $cities->{$cityId})) { + triggerAction($action, $cityId); + } + DumpFile("military-$cityId-dump.yaml", $cities->{$cityId}); # build and upgrade for cities $tree = LoadFile('city.yaml'); $cities->{$cityId}->{parse_path} = []; $cities->{$cityId}->{parse_answer} = undef; - while (my $action = ParseTree($tree, $rules, $cities->{$cityId})) { + if (my $action = ParseTree($tree, $rules, $cities->{$cityId})) { triggerAction($action, $cityId); - last; } - # Debug - # print(Dump($cities->{$cityId}->{parse_path})) if(defined($verbose)); + DumpFile("city-$cityId-dump.yaml", $cities->{$cityId}); } -# print(Dump($cities)) if(defined($verbose)); -DumpFile("cities-dump.yaml", $cities); DumpFile("research-dump.yaml", $i->{'research'}); -DumpFile("military-dump.yaml", $i->{'military'}); +DumpFile("wares-dump.yaml", $i->{'military'}); $i->logout; diff -r 51a8a81d0bb6 -r 8e9f2848f8cd city.yaml --- a/city.yaml Sun Nov 02 11:58:02 2008 +0800 +++ b/city.yaml Tue Nov 04 18:34:06 2008 +0800 @@ -1,3 +1,4 @@ +# TODO adjust human resources --- # city level # 基本建設規則 @@ -5,63 +6,64 @@ - is_attacked: # we are in Peace :D 0: - # adjust human resources - is_constructing: 0: - # XXX: 這樣會一口氣買同等城市數量的船耶 + # FIXME: 這樣會一口氣買同等城市數量的船耶, 應拉出至全國金錢考量 # - is_gold_enoughforcargo: # 1: increaseTransporter - - is_space_enough: + - is_corruption: + 1: + - is_warehouse_enougn_for_governorsresidence: + 0: build_warehouse + 1: build_palaceColony + - is_any_corruption: 0: - - is_resource_enoghforHall: - 1: build_townHall - - is_wall_enough: - 0: build_wall - - is_corruption: - 1: build_governorsresidence - # 倉庫庫存量 - - is_warehouse_enough: - 0: build_warehouse - - is_happiness: - 0: - - is_winepress_researched: - 1: - - is_tavern_available: - 0: build_tavern - 1: - - is_bacchanal: - 0: set_tavern - 1: build_tavern - # TODO - # http://ikariam.wikia.com/wiki/List_of_buildings - # http://ikariam.wikia.com/wiki/Technology_Tree - # is_conservation_researched - # -build_warehouse - # build_academy - # build_palace (Expansion, Capital only) - # build_embassy (副城, 不建) - - is_risk: - 1: - - is_professionalarmy_researched: - 1: - - is_shipyard_level_enough: - 0: build_shipyard - - is_barracks_level_enough: - 0: build_barracks + - is_space_enough: + 0: + - is_resource_enoghforHall: + 1: build_townHall + - is_wall_enough: + 0: build_wall + - is_happiness: + 0: + - is_winepress_researched: + 1: + - is_tavern_available: + 0: build_tavern + 1: + - is_bacchanal: + 0: set_tavern + 1: build_tavern - is_shipyard_level_enough: - 0: - - is_drydock_researched: - # requireed more army ? + 0: + - is_professionalarmy_researched: 1: build_shipyard - # - build one boat -# 應該把 Barracks 建到最佳等級 - # 要蓋到何種程度? - # is_invention_researched - # 1: - # - build_workshop - # is_espionage_researched - # 1: - # - build_hideout - # is_culturalexchange_resaerched - # 1: - # - build_museum + - is_barracks_level_enough: + 0: + - is_professionalarmy_researched: + 1: build_barracks + - is_safehouse_enough: + 0: + - is_espionage_researched: + 1: build_safehouse + - is_warehouse_enough: + 0: + - is_conservation_researched: + 1: build_warehouse + 0: build_academy + - is_academy_enough: + 0: build_academy + # 大使館 + - is_embassy_enough: + 0: + - is_foreigncultures_researched: + 1: build_embassy + - is_museum_enough: + 0: + - is_culturalexchange_resaerched: + 1: build_museum + +# 水晶島應該建設 +# is_invention_researched +# 1: +# - build_workshop diff -r 51a8a81d0bb6 -r 8e9f2848f8cd freeland.pl --- a/freeland.pl Sun Nov 02 11:58:02 2008 +0800 +++ b/freeland.pl Tue Nov 04 18:34:06 2008 +0800 @@ -7,10 +7,10 @@ my @tradegoodText = qw/NULL 葡萄酒 大理石 水晶 硫磺/; my @wonderText = qw/NULL 赫菲斯拓斯的熔爐 蓋亞的神殿 狄奧尼索斯的花園 雅典娜的神殿 赫秘士的神殿 阿瑞斯的要塞 波賽頓的神殿 克羅瑟斯的神殿/; -if($#ARGV != 1) { - die("Usage: $0 x y\n"); +if($#ARGV != 2) { + die("Usage: $0 x y tradegood (1 葡萄酒, 2 大理石, 3 水晶, 4 硫磺/)\n"); } -my ($x, $y) = @ARGV; +my ($x, $y, $tradegood) = @ARGV; my @location = (($x + 6), ($x - 6), ($y + 6), ($y - 6)); @@ -27,7 +27,7 @@ # my @islands = Ikariam::Island->retrieve_from_sql(qq{ - tradegood == 2 + tradegood == $tradegood AND people < 16 AND x <= $location[0] AND x >= $location[1] diff -r 51a8a81d0bb6 -r 8e9f2848f8cd military.yaml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/military.yaml Tue Nov 04 18:34:06 2008 +0800 @@ -0,0 +1,54 @@ +--- +- is_attacked: + 0: + - is_navyExpenditure_available: + 1: + - is_professionalarmy_researched: + 1: + - is_shipyard_level_enough: + 0: + - is_constructing: + 0: + - is_any_corruption: + 0: build_shipyard + 1: + - is_shipyard_upgrading: + 0: + - is_navy_trainning: + 0: + - train_navy: + 211: buildShips_211 + 212: buildShips_212 + 213: buildShips_213 + 214: buildShips_214 + 215: buildShips_215 + 216: buildShips_216 + - is_milityExpenditure_available: + 1: + - is_professionalarmy_researched: + 1: + - is_barracks_level_enough: + 0: + - is_constructing: + 0: + - is_any_corruption: + 0: build_barracks + 1: + - is_barracks_upgrading: + 0: + - is_army_trainning: + 0: + - train_army: + 301: buildUnits_301 + 302: buildUnits_302 + 303: buildUnits_303 + 304: buildUnits_304 + 305: buildUnits_305 + 306: buildUnits_306 + 307: buildUnits_307 + 308: buildUnits_308 + 309: buildUnits_309 + 310: buildUnits_310 + 311: buildUnits_311 + 312: buildUnits_312 + 313: buildUnits_313 diff -r 51a8a81d0bb6 -r 8e9f2848f8cd overall.yaml --- a/overall.yaml Sun Nov 02 11:58:02 2008 +0800 +++ b/overall.yaml Tue Nov 04 18:34:06 2008 +0800 @@ -30,4 +30,3 @@ 0: research_seafaring 1: run_defence - # we are being attacked!!!!!!!!!!!!! diff -r 51a8a81d0bb6 -r 8e9f2848f8cd pyikriam/buildings.py --- a/pyikriam/buildings.py Sun Nov 02 11:58:02 2008 +0800 +++ b/pyikriam/buildings.py Tue Nov 04 18:34:06 2008 +0800 @@ -1,6 +1,9 @@ from lazy.www import c from lxml import etree from StringIO import StringIO +from sync_utils import sync_tagclass, sync_tagvalue +from sync_utils import sync_tagcount, sync_tagclass_start_appear +from sync_utils import ikariam_zh_timeval class position(object): def __init__(self, build_type, city_id, idx, baseurl): @@ -16,30 +19,238 @@ def get_page(self): page = c(self._baseurl).get(self._params).get_content() return page + + def sync(self): + page = self.get_page() + parser = etree.HTMLParser(encoding='utf8') + page_dom = etree.parse(StringIO(page), parser) + + self._sync(page_dom) + pass pass -class townhall(position): - xpath_patterns = { - 'level': 'div[@class=\'buildingLevel\']/text()' +## \brief Base class of all building class. +# +# This class extract information from page of building. That are +# information all buildings have. +# +class building(position): + class_patterns = { + 'level': 'buildingLevel' + } + appear_patterns = { + 'is_upgrading': 'isUpgrading' + } + upgrade_res_patterns = { + 'wood': 'wood', + 'marble': 'marble', + 'crystal': 'glass' } + def _sync(self, page_dom): + sync_tagclass(self, building.class_patterns, page_dom) + + sync_tagclass_start_appear(self, building.appear_patterns, page_dom) + + xpath_upgrade = '/descendant::ul[@class=\'actions\']/li[@class=\'upgrade\']/a' + anodes = page_dom.xpath(xpath_upgrade) + if len(anodes) == 1: + anode = anodes[0] + self._upgrade_uri = anode.get('href') + else: + self._upgrade_uri = None + pass + + self.upgrade_wood = 0 + self.upgrade_marble = 0 + self.upgrade_crystal = 0 + self.upgrade_time = 0 + self.upgrade_countdown = 0 + + if self.is_upgrading: + xpath_countdown = '/descendant::div[@id=\'upgradeCountDown\']/text()' + value = page_dom.xpath(xpath_countdown)[0] + self.upgrade_countdown = ikariam_zh_timeval(value) + else: + xpath_res = '/descendant::div[@class=\'content\']/ul[@class=\'resources\']/li[starts-with(@class, \'%s\')]/text()' + + for resname, clzname in building.upgrade_res_patterns.items(): + xpath = xpath_res % (clzname) + txts = page_dom.xpath(xpath) + if len(txts) == 1: + value = txts[0].strip() + setattr(self, 'upgrade_' + resname, int(value)) + pass + pass + + xpath_time = xpath_res % ('time') + txts = page_dom.xpath(xpath_time) + if len(txts) == 1: + value = txts[0].strip() + self.upgrade_time = ikariam_zh_timeval(value) + pass + pass + pass + + def upgrade(self): + url = self._baseurl + self._upgrade_uri + page = c(url).get().get_content() + pass + pass + +class townhall(building): + class_patterns = { + 'occupied': 'value occupied', + 'rooms': 'value total', + } + value_patterns = { + 'growth': 'growth', + 'happiness': 'happiness', + 'interest_base': 'base', + 'interest_research': 'research1', + 'interest_capital': 'capital', + 'overpopulation': 'cat overpopulation' + } + count_patterns = { + 'pop_citizens': 'citizens', + 'pop_woodworkers': 'woodworkers', + 'pop_specialworkers': 'specialworkers', + 'pop_scientists': 'scientists' + } + def __init__(self, city_id, idx, baseurl): super(townhall, self).__init__('townhall', city_id, idx, baseurl) pass - def _sync(self, page): - parser = etree.HTMLParser(encoding='utf8') - page_dom = etree.parse(StringIO(page), parser) - xpath_building = '/html/body/descendant::' - for name, ptn in self.xpath_patterns.items(): - path = xpath_building + ptn - value = page_dom.xpath(path)[0] - setattr(self, name, value) + def _sync(self, page_dom): + sync_tagclass(self, townhall.class_patterns, page_dom) + + sync_tagvalue(self, townhall.value_patterns, page_dom) + + sync_tagcount(self, townhall.count_patterns, page_dom) + + super(townhall, self)._sync(page_dom) + pass + pass + +class academy(building): + def __init__(self, city_id, idx, baseurl): + super(academy, self).__init__('academy', city_id, idx, baseurl) + pass + + def _sync(self, page_dom): + xpath_research_name = '/descendant::*[@class=\'researchName\']/a' + anodes = page_dom.xpath(xpath_research_name) + if len(anodes) == 1: + anode = anodes[0] + self.researching = anode.get('title') + xpath_countdown = '/descendant::div[@id=\'researchCountDown\']/text()' + txtnodes = page_dom.xpath(xpath_countdown) + self.researching_countdown = ikariam_zh_timeval(txtnodes[0]) + else: + self.researching = None + self.researching_countdown = None + pass + + super(academy, self)._sync(page_dom) + pass + pass + +class warehouse(building): + def __init__(self, city_id, idx, baseurl): + super(warehouse, self).__init__('warehouse', city_id, idx, baseurl) + pass + pass + +class barracks(building): + def __init__(self, city_id, idx, baseurl): + super(barracks, self).__init__('barracks', city_id, idx, baseurl) + pass + pass + +class branchoffice(building): + def __init__(self, city_id, idx, baseurl): + super(branchoffice, self).__init__('branchoffice', city_id, idx, baseurl) + pass + pass + +class port(building): + def __init__(self, city_id, idx, baseurl): + super(port, self).__init__('port', city_id, idx, baseurl) + pass + pass + +class wall(building): + def __init__(self, city_id, idx, baseurl): + super(wall, self).__init__('wall', city_id, idx, baseurl) + pass + pass + +class shipyard(building): + def __init__(self, city_id, idx, baseurl): + super(shipyard, self).__init__('shipyard', city_id, idx, baseurl) + pass + pass + +class empty_pos(position): + res_patterns = { + 'wood': 'wood', + 'marble': 'marble', + 'crystal': 'glass' + } + + def _sync(self, page_dom): + self.building_info = None + self.res_wood = 0 + self.res_marble = 0 + self.res_crystal = 0 + self.building_time = 0 + self._building_uri = None + + xpath_building = '/descendant::div[@class=\'buildinginfo\']/h4/text()' + buildings = page_dom.xpath(xpath_building) + if len(buildings) == 1: + self.building_info = buildings[0] + pass + + xpath_costs = '/descendant::div[@class=\'costs\']/ul/li[@class=\'%s\']/text()' + for res, ptn in empty_pos.res_patterns.items(): + xpath = xpath_costs % (ptn) + txts = page_dom.xpath(xpath) + if len(txts) == 1: + value = int(txts[0]) + setattr(self, 'res_' + res, value) + pass + pass + + xpath = xpath_costs % ('time') + txts = page_dom.xpath(xpath) + if len(txts) == 1: + value = ikariam_zh_timeval(txts[0]) + self.building_time = value + pass + + xpath_button = '/descendant::a[@class=\'button build\']' + anodes = page_dom.xpath(xpath_button) + if len(anodes) == 1: + self._building_uri = anodes[0].get('href') pass pass - def sync(self): - page = self.get_page() - self._sync(page) + def build(self): + url = self._baseurl + self._building_uri + page = c(url).get().get_content() pass pass + +class land(empty_pos): + def __init__(self, city_id, idx, baseurl): + super(land, self).__init__('land', city_id, idx, baseurl) + pass + pass + +class shore(empty_pos): + def __init__(self, city_id, idx, baseurl): + super(shore, self).__init__('shore', city_id, idx, baseurl) + pass + pass diff -r 51a8a81d0bb6 -r 8e9f2848f8cd pyikriam/createAccount.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyikriam/createAccount.py Tue Nov 04 18:34:06 2008 +0800 @@ -0,0 +1,47 @@ +import urllib2,urllib + +from ikariam import fake_moz +from lazy.www import c + +class CreateAccount: + """ + For create sheep to cheat. take care of the ip address & email check by yourself. + """ + def __init__(self,account,email,password,server): + self.account=account + self.password=password + self.server=server + self.email=email + headers=[('Referer','http://'+self.server[self.server.find('.')+1:]+'/register.php')] + self.browser = fake_moz(headers) + urllib2.install_opener(self.browser) + pass + + def ca(self): + self.baseurl='http://'+self.server + params = { + "function":"createAvatar",\ + "name":self.account,\ + "email":self.email,\ + "password":self.password,\ + "agb":"on"} + self.ret=c(self.baseurl+'/index.php?action=newPlayer').get(params).get_content() + pass + +class confirme: + def __init__(self,confirmeurl): + self.confirmeurl=confirmeurl + self.browser = fake_moz() + urllib2.install_opener(self.browser) + pass + + def run(self): + self.ret=c(self.confirmeurl).get().get_content() + pass + +""" +ikariamca=CreateAccount('someac','kevin@butyshop.com','contest123','s2.ikariam.tw') +a=ikariamca.ca() +confirme("http://s2.ikariam.tw/index.php?action=newPlayer&function=validateEmail&hash=c239c92a94690066078ca95c993d348b&id=70997").run() +""" + diff -r 51a8a81d0bb6 -r 8e9f2848f8cd pyikriam/example.py --- a/pyikriam/example.py Sun Nov 02 11:58:02 2008 +0800 +++ b/pyikriam/example.py Tue Nov 04 18:34:06 2008 +0800 @@ -1,4 +1,5 @@ import sys +import buildings from ikariam import Ikariam if len(sys.argv) != 2: @@ -21,7 +22,16 @@ print 'marble is ' + city.marble print 'crystal is ' + city.crystal print 'sulfur is ' + city.sulfur -print 'positions ' + repr(city.positions) -city.positions[0].sync() -print 'positions[0] level is ' + str(city.positions[0].level) +for idx, pos in enumerate(city.positions): + if not isinstance(pos, buildings.position): + continue + pos.sync() + building_attrs = filter(lambda attr: not attr[0].startswith('_'), + pos.__dict__.items()) + building_attrs.sort(key=lambda x: x[0]) + print + print 'positions[%d]' % (idx) + for building_attr, value in building_attrs: + print '\t%s: %s' % (building_attr, repr(value)) + pass diff -r 51a8a81d0bb6 -r 8e9f2848f8cd pyikriam/ikariam.py --- a/pyikriam/ikariam.py Sun Nov 02 11:58:02 2008 +0800 +++ b/pyikriam/ikariam.py Tue Nov 04 18:34:06 2008 +0800 @@ -11,34 +11,34 @@ class fake_moz(object): __metaclass__ = decorator - def __init__(self): + def __init__(self,headers=0): + fakeheaders=[('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.12pre) Gecko/20071220 BonEcho/2.0.0.12pre')] + if headers: + fakeheaders=fakeheaders+headers super(fake_moz, self).__init__() cookie_jar = cookielib.LWPCookieJar() cookie_proc = urllib2.HTTPCookieProcessor(cookie_jar) opener = urllib2.build_opener(cookie_proc) - opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.12pre) Gecko/20071220 BonEcho/2.0.0.12pre')] + opener.addheaders = fakeheaders fake_moz.set_backend(self, opener) self.cookie_jar = cookie_jar pass pass - class Ikariam: cities = {} COOKIEFILE = '/tmp/ikariam.lwp' def __init__(self): - browser = fake_moz() - self.browser = browser - self._cookie_jar = browser.cookie_jar + self.browser = fake_moz() + self._cookie_jar = self.browser.cookie_jar if os.path.isfile(self.COOKIEFILE): self._cookie_jar.load(self.COOKIEFILE) pass - urllib2.install_opener(browser) - + urllib2.install_opener(self.browser) self.confdata=LoadConfigfile().cd self.baseurl='http://'+self.confdata['server'] diff -r 51a8a81d0bb6 -r 8e9f2848f8cd pyikriam/sync_utils.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyikriam/sync_utils.py Tue Nov 04 18:34:06 2008 +0800 @@ -0,0 +1,72 @@ +## \file +# \brief Sync information of objects with DOM trees of respective pages. +# + +import re as _re + +def sync_tagclass(obj, patterns, page_dom): + xpath_building = '/html/body/descendant::*[@class=\'%s\']/text()' + for name, clzname in patterns.items(): + path = xpath_building % (clzname) + value = float(page_dom.xpath(path)[0]) + setattr(obj, name, value) + pass + pass + +def sync_tagvalue(obj, patterns, page_dom): + xpath_value = '/html/body/descendant::*[starts-with(@class,\'%s\')]/descendant::*[@class=\'value\']/text()' + for name, clzname in patterns.items(): + path = xpath_value % (clzname) + value = float(page_dom.xpath(path)[0]) + setattr(obj, name, value) + pass + pass + +def sync_tagcount(obj, patterns, page_dom): + xpath_count = '/html/body/descendant::*[starts-with(@class,\'%s\')]/descendant::*[@class=\'count\']/text()' + for name, clzname in patterns.items(): + path = xpath_count % (clzname) + value = int(page_dom.xpath(path)[0]) + setattr(obj, name, value) + pass + pass + +def sync_tagclass_start_appear(obj, patterns, page_dom): + xpath_appear = '/html/body/descendant::*[starts-with(@class,\'%s\')]' + for name, clzname in patterns.items(): + path = xpath_appear % (clzname) + cnt = len(page_dom.xpath(path)) + if cnt != 0: + setattr(obj, name, True) + else: + setattr(obj, name, False) + pass + pass + pass + +_reo_tv = _re.compile(u'(([0-9]+)\u6642)? ?(([0-9]+)\u5206)? ?(([0-9]+)\u79d2)?') +## \brief Translate timeval in Chinese text format to integer seconds. +# +def ikariam_zh_timeval(tv_str): + tmo = _reo_tv.match(tv_str) + if not tmo: + raise SyntaxError, \ + '%s is an invalid time interval string' % (repr(tv_str)) + tv = 0 + + value = tmo.group(2) # hour + if value: + tv = tv + int(value) * 3600 + pass + + value = tmo.group(4) # minute + if value: + tv = tv + int(value) * 60 + pass + + value = tmo.group(6) # second + if value: + tv = tv + int(value) + pass + + return tv diff -r 51a8a81d0bb6 -r 8e9f2848f8cd scan.pl --- a/scan.pl Sun Nov 02 11:58:02 2008 +0800 +++ b/scan.pl Tue Nov 04 18:34:06 2008 +0800 @@ -28,7 +28,7 @@ $c->update(); my $user = Ikariam::User->retrieve($h_city->{'user'}); - next if (defined($user) && defined($user->time) && $user->time le (time - 60*60*1)); + next if (defined($user) && defined($user->time) && $user->time le (time - 30*60*1)); saveUser($h_city->{owner}); } @@ -65,7 +65,7 @@ # Save for member of ally my $ally = Ikariam::Ally->retrieve($allyId); - if(!defined($ally) || $ally->time le (time - 60*60*1)) { + if(!defined($ally) || $ally->time le (time - 30*60*1)) { my $h_ally = $::i->viewAlly($allyId); $h_ally->{'time'} = time; if(defined($ally)) { @@ -107,7 +107,7 @@ foreach my $h_island (@islands) { - printf("checking island %d\n", $h_island->{id}); + # printf("checking island %d\n", $h_island->{id}); my $island; if($island = Ikariam::Island->retrieve($h_island->{id})) { @@ -119,7 +119,7 @@ } # scanning the island - if($island->time le (time - 60*60*6)) + if($island->time le (time - 30*60*6)) { my @cities = $i->viewIsland($h_island->{id}); saveCities($h_island->{id}, @cities); diff -r 51a8a81d0bb6 -r 8e9f2848f8cd warfare.pl --- a/warfare.pl Sun Nov 02 11:58:02 2008 +0800 +++ b/warfare.pl Tue Nov 04 18:34:06 2008 +0800 @@ -50,7 +50,16 @@ sub is_transporters_available { my ($self, $city) = @_; - return ($city->{transporters}->{avail} > 0) ? 1 : 0; + # we keep 10 transporters for prize + return ($city->{transporters}->{avail} > 10) ? 1 : 0; +} + +sub is_port_available { + my ($self, $city) = @_; + foreach(1..2) { + return 1 if($city->{locations}[$_] eq 'port'); + } + return 0; } sub is_army_available { @@ -101,8 +110,10 @@ # we attack one city maximum 4 times a day. next if($c >= 4); + my $capture = $city->citylevel * ($city->citylevel - 1) * $sheep->trader_score_secondary / 10000; + next if($capture < 1500); + # { - my $capture = $city->citylevel * ($city->citylevel - 1) * $sheep->trader_score_secondary / 10000; my $line = sprintf("%d %s [%d,%d] %s (%d) %s Attacked %d", $capture, $city->status, $island->x, $island->y, @@ -135,6 +146,7 @@ $i->login; my $cities = $i->check; $i->checkMilitaryAdvisorCombatReports(); +$i->checkFriends(); foreach my $cityId (keys(%$cities)) { print Dump($i->{'military'}); diff -r 51a8a81d0bb6 -r 8e9f2848f8cd warfare.yaml --- a/warfare.yaml Sun Nov 02 11:58:02 2008 +0800 +++ b/warfare.yaml Tue Nov 04 18:34:06 2008 +0800 @@ -5,5 +5,7 @@ 1: - is_transporters_available: 1: - - is_army_available: - 1: engagement + - is_port_available: + 1: + - is_army_available: + 1: engagement