#!/usr/bin/perl
# vim: ts=4 sw=4
$base = "http://80.237.205.38/gw03/";
$login_page = "login.php";
$uebersicht_page = "uebersicht.php";
$navbar_page = "n/navbar.php";
$produktion_page = "produktion.php";
$gap_time = 30;
$normal_wait_time = 60*60*2;
$job_file = "./jobs";
$log_file = "./log";
use Time::Local;
# Create a user agent object
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$ua->agent("galaxywars/0.1 ");
$id = $ARGV[0];
%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] }
);
@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 {
@ret = ();
if (open (IN, '<', $job_file)) {
while(<IN>) {
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 $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/<font color="#FF0000" size="\+1">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 {
$html = &get_http("POST",$base.$login_page,'i=y&name=<Benutzername>&pw=<Passwort>');
unless ($html =~ m/uebersicht\.php\?U=(.*?)"/i) {
die "Konnte mich nicht anmelden";
}
return $1;
}
@attacks = ();
@rohstoffe = (0, 0, 0, 0);
while (1) {
$wait_time = $normal_wait_time;
$jobs = &read_jobs();
#$html = &get_http("GET",$base.$navbar_page,"u=$id&p1=1x296x10&c=1x296x10");
$html = &get_http("GET",$base.$uebersicht_page,"U=$id");
for ((0 .. 3)) {
$html =~ m/<td.*?class="g">([\d\.]*)<\/td>/ig;
$rohstoffe[$_] = $1;
$rohstoffe[$_] =~ s/\.//g;
}
while ($html =~ m/<a title="(.*?)">.*?<div.*?title="(.*?)">.*?<font.*?>(.*?)<\/font>/ig)
{
($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;
}