#!/usr/bin/perl # vim: ts=4 sw=4 use strict; use Time::Local; use LWP::UserAgent; my $base = "http://80.237.205.38/gw03/"; my $login_page = "login.php"; my $uebersicht_page = "uebersicht.php"; my $navbar_page = "n/navbar.php"; my $produktion_page = "produktion.php"; my $gap_time = 30; my $normal_wait_time = 60*60*2; my $job_file = "./jobs"; my $log_file = "./log"; # Create a user agent object my $ua = LWP::UserAgent->new; $ua->agent("galaxywars/0.1 "); my $id = $ARGV[0]; my @attacks = (); my @rohstoffe = (0, 0, 0, 0); my %ships = ( 'p1' => { 'name' => 'schakal', 'kosten' => [250, 0, 0, 75]}, 'p2' => { 'name' => 'recycler', 'kosten' => [850, 850, 100, 0]}, 'p3' => { 'name' => 'spionagesonde', 'kosten' => [0, 150, 0, 0]}, 'p4' => { 'name' => 'renegade', 'kosten' => [1000, 0, 0, 0]}, 'p12' => { 'name' => 'kleines handelsschiff', 'kosten' => [2000, 2000, 0, 0] } ); my @production = (258, 165, 10, 14); sub get_best_build { my @res = @_; my @build = (); my $count = &can_build(\@res, $ships{'p1'}->{'kosten'}, 3); if ($count) { $build[++$#build] = ['p1',$count]; $count = 0; } $count = &can_build(\@res, $ships{'p2'}->{'kosten'}, 2); if ($count) { $build[++$#build] = ['p2',$count]; $count = 0; } $count = &can_build(\@res, $ships{'p12'}->{'kosten'}, 4); if ($count) { $build[++$#build] = ['p12',$count]; $count = 0; } $count = &can_build(\@res, $ships{'p4'}->{'kosten'}, 0); if ($count) { $build[++$#build] = ['p4',$count]; $count = 0; } $count = &can_build(\@res, $ships{'p3'}->{'kosten'}, 1); if ($count) { $build[++$#build] = ['p3',$count]; $count = 0; } return \@build; } sub can_build { my ($res, $cost, $which) = @_; $res->[4] = 3000; my @others = (0 .. 3); delete $others[$which]; my $count = 0; while ($res->[$which] > 2000 and not grep { $res->[$_] < $cost->[$_]; } @others) { for ((0 .. 3)) { $res->[$_] -= $cost->[$_]; } $count ++; } delete $res->[4]; return $count; } sub insert { my ($arr, $i, $elem) = @_; for ((@$arr .. $i+1)) { $arr->[$_] = $arr->[$_-1]; } $arr->[$i] = $elem; }; sub read_jobs { my @ret = (); my $item; if (open (IN, '<', $job_file)) { while() { chomp; if (m/\[(\d+)\]/) { $item = ($ret[++$#ret] = {'time'=>$1, 'build'=>[]}); } elsif (m/(.+?) ?= ?(\d+)/) { $item->{'build'}->[@{$item->{'build'}}] = [$1,$2]; } } close (IN); } print "Read Jobs: ".scalar @ret."\n"; return \@ret; } sub write_jobs { my $jobs = shift; print "Jobs: ".scalar @$jobs."\n"; if (open (OUT, '>', $job_file)) { foreach my $job (@$jobs) { print OUT '['.$job->{'time'}.'] '.scalar localtime ($job->{'time'})."\n"; for (@{$job->{'build'}}) { print OUT $_->[0].'='.$_->[1].' '.$ships{$_->[0]}->{'name'}."\n"; } print OUT "\n"; } close (OUT); } } sub plan_jobs { my ($jobs, $ts, $tstr) = @_; my ($min_ts, $max_ts) = ($ts - 5, $ts + 5); my ($item, @res); if (@$jobs) { for ((0 .. $#$jobs)) { if ($jobs->[$_]->{'time'} > $max_ts) { &insert ($jobs, $_, {'time'=>$ts,'build'=>[]}); $item = $jobs->[$_]; last; } if ($jobs->[$_]->{'time'} > $min_ts and $jobs->[$_]->{'time'} < $max_ts) { $item = $jobs->[$_]; last; } } } unless ($item) { $jobs->[@$jobs] = {'time'=>$ts, 'build'=>[]}; $item = $jobs->[$#$jobs]; } for ((0 .. 3)) { $res[$_] = $rohstoffe[$_]+($production[$_]*(($ts-time())/3600)); } $item->{'build'} = &get_best_build (@res); } sub get_next_job { my ($jobs) = @_; return shift (@$jobs); } sub do_job { my ($job) = @_; print "Starting to build\n"; &get_http ("POST", $base.$produktion_page, "u=$id&a=y&".join('&', map { $_->[0].'='.$_->[1]; } @{$job->{'build'}})); sleep 2*$gap_time; print "Removing ships\n"; for ((1 .. @{$job->{'build'}})) { &get_http ("GET", $base.$produktion_page, "u=$id&auftr=1&dm=delete"); } } sub get_http { my ($method, $url, $content, $referer) = @_; if ($method == "GET") { $url .= '?'.$content; $content = ""; #print $url."\n"; } # Create a request my $req = HTTP::Request->new($method => $url); if ($referer) { $req->header("Referer: $referer"); } $req->content_type('application/x-www-form-urlencoded'); $req->content($content); # Pass request to the user agent and get a response back my $res = $ua->request($req); # Check the outcome of the response if ($res->is_success) { if ($res->content =~ m/Fehler<\/font>/i) { print "Fetching new id\n"; $id = &get_id (); $_[2] =~ s/((^|&)u=).*?(&|$)/$1$id$3/i; print "Trying with ".join(':',@_)."\n"; return &get_http (@_); } return $res->content; } else { print $res->status_line, "\n"; return ""; } } sub get_id { my $html = &get_http("POST",$base.$login_page,'i=y&name=&pw='); unless ($html =~ m/uebersicht\.php\?U=(.*?)"/i) { die "Konnte mich nicht anmelden"; } return $1; } while (1) { my $wait_time = $normal_wait_time; my $jobs = &read_jobs(); #$html = &get_http("GET",$base.$navbar_page,"u=$id&p1=1x296x10&c=1x296x10"); my $html = &get_http("GET",$base.$uebersicht_page,"U=$id"); for ((0 .. 3)) { $html =~ m/([\d\.]*)<\/td>/ig; $rohstoffe[$_] = $1; $rohstoffe[$_] =~ s/\.//g; } my $attack; while ($html =~ m/.*?.*?(.*?)<\/font>/ig) { my ($timestr, $secs, $msg) = ($1, $2, $3); $msg =~ s/<.*?>//g; #$time =~ m/(\d{1,2})\.(\d{1,2})\.(\d{4}) - (\d{2}):(\d{2}):(\d{2})/; #$timestamp = timelocal ($6, $5, $4, $1, $2, $3); print $timestr.": ".$msg."\n"; if ($msg =~ m/greift.*an/) { &plan_jobs($jobs, time()+$secs, $timestr); if ($secs < $wait_time) { if ($secs < $gap_time + 5) { $attack = &get_next_job($jobs) unless ($attack); } else { $wait_time = $secs - $gap_time; } } } } &write_jobs ($jobs); if ($attack) { &do_job ($attack); $attack = ''; next; } #print &get_http ("GET", $base.$produktion_page, "u=$id&auftr=1&dm=delete"); #$html = &get_http("GET",$base.$produktion_page,"u=$id"); #print $html; print "Going to wait for $wait_time seconds...\n"; sleep $wait_time; }