Netzer.pl: Unterschied zwischen den Versionen

Aus KaroWiki
Zur Navigation springen Zur Suche springen
(Zurücksetzen)
K („Netzer.pl“ geschützt: Spambefall. Nur noch für registrierte Nutzer zugänglich. [edit=autoconfirmed:move=autoconfirmed])

Version vom 28. August 2008, 13:11 Uhr

Da die Kommunikation fuer mich das war, was mich am meisten vom Schreiben eines Bots abgehalten hat, weil ich davon einfach keine Ahnung hatte, moechte ich mein Werk jetzt hier zur Verfuegung stellen. Falls es noch jemandem so geht, dann kann er sich diesen Teil schonmal sparen, und braucht sich bloss um den eigentlichen bot zu kuemmern.

Das ganze Ding ist in perl gesschrieben, und ich bin alles andere als ein perl-Experte. Wenn ihr also in irgendeiner Form nicht damit einverstanden seid: ruhig meckern!

Die Kommunikation laeuft ueber die libwww-perl(LWP).

netzer.pl schreibt fuer jedes Spiel von der dranbin-Seite eine Datei mit Namen spielnummer.dran, der Inhalt sollte selbsterklaerend sein:

 Ich bin dran bei 3306.
 ZZZ=2, checkpoints aktiviert, crashen nicht erlaubt
 meine Position: x=29, y=65
 Die Positionen aller 1 Spieler:
 tester steht auf  x=29, y=65
 meine 8 Zugmoeglichkeiten:
 1) nach x=29, y=66 mit Vektor (0|1)
 2) nach x=29, y=67 mit Vektor (0|2)
 3) nach x=30, y=65 mit Vektor (1|0)
 4) nach x=30, y=66 mit Vektor (1|1)
 5) nach x=30, y=67 mit Vektor (1|2)
 6) nach x=31, y=65 mit Vektor (2|0)
 7) nach x=31, y=66 mit Vektor (2|1)
 8) nach x=31, y=67 mit Vektor (2|2)
 

Der eigentliche Bot sollte also diese Datei auswerten, und mit seinem Zug im Format

 
 vec 0 3
 

ueberschreiben.


 #!/usr/bin/perl -w
 
 use strict;
 
 use LWP;
 use HTML::Form;
 use HTTP::Cookies;
 use Fcntl qw(:DEFAULT :flock);
 
 #
 #          parameters
 #
 
 #user
 my $username = "username";
 my $password = "passwort";
 
 # URLs
 my $URL_login   = 'http://karopapier.beididi.de/anmelden.php';
 my $URL_dranbin = 'http://karopapier.beididi.de/showgames.php?dranbin=1';
 my $URL_showmap = 'http://karopapier.beididi.de/showmap.php?GID=';
 my $URL_move    = 'http://karopapier.beididi.de/move.php?GID=';
 my $URL_mapsource='http://karopapier.beididi.de/mapsource.php?mapid=';
 my $URL_log     = 'http://karopapier.beididi.de/logs/';
 
 my $print = 1;
 my $sleep = 30;           # Zeit zwischen dranbin-abfragen in s
 my $sleep_error = 600;    # Wartezeit nach Fehler
 
 #
 #         start and login
 #
 
 # new browser
 my $browser = LWP::UserAgent->new;
 # with cookies
 $browser->cookie_jar({});
 
 
 # load login page
 my $request = HTTP::Request->new(GET => $URL_login);
 my $response;
 my $success;
 $success = 0;
 LOGIN: do {
   $response = $browser->request($request);
   if ($response->is_success) {
     #print $response->content,  "\n\n\n\n";
     if ($response -> content =~ m/Anmeldung/) {
       ;
     } else {
       print STDERR "Loginseite geladen, aber Auswertung gescheitert!\n";
       print STDERR "schlafe fuer $sleep_error Sekunden!\n";
       sleep $sleep_error;
       next LOGIN;
     }
   } else {
     print STDERR "login page problem\n";
     print STDERR $response->status_line, "\n";
     print STDERR "schlafe fuer $sleep_error Sekunden!\n";
     sleep $sleep_error;
     next LOGIN;
   }
 
   #get form
   my $form = HTML::Form->parse($response);
   #print $form->param;
 
   #login
   $form->value( "ID", $username );
   $form->value( "PWD", $password );
   $request = $form->click;
   $response = $browser->request($request);
   if ($response->is_success) {
     #print $response->content, "\n\n\n\n";
     if ($response->content =~ 
 	m/Du bist jetzt als <B>$username<\/B> angemeldet/) {
       $success = 1;
     } else {
     print STDERR "Anmeldung fehlgeschlagen!\n";
     print STDERR "schlafe fuer $sleep_error Sekunden!\n";
     sleep $sleep_error;
     next LOGIN;
     }
   } else {
     print STDERR "Anmeldung fehlgeschlagen!\n";
     print STDERR $response->status_line, "\n";
     print STDERR "schlafe fuer $sleep_error Sekunden!\n";
     sleep $sleep_error;
     next LOGIN;
   }
 } until ($success == 1);
 
 if ($print == 1) {
   print "login erfolgreich!\n";
 }
 
 #
 #        endless loop
 #
 
 ENDLESS: while() {
 
   if ($print==1) {print "------------------------------------\n";}
 
   #
   #  Spiele ermitteln
   #
 
   # get dranbin
   $request ->uri($URL_dranbin);
   $response = $browser->request($request);
   if ($response->is_success) {
     #print $response->content, "\n\n\n\n";
   } else {
     print STDERR $response->status_line, "\n";
     print STDERR "Laden der dranbin Seite fehlgeschlagen!\n";
     print STDERR "schlafe fuer $sleep_error Sekunden!\n";
     sleep $sleep_error;
     next ENDLESS;
   }
 
   my $spiel;
   my @spiele;
   foreach my $line (split(/\n/, $response->content)) {
     if ($line =~ m/showmap.php\?GID=(\d+)&pixel=10&karoborder=1>$/) {
       push @spiele, $1;
     }
   }
 
 
   if ((scalar(@spiele == 0)) && ($print == 1)) {
     print "Nix los - schlafe fuer $sleep Sekunden ... \n";
   }
 
   #
   #  Spiele abarbeiten
   #
 
  GAMES: foreach my $spiel (@spiele) {
 
     my $file = "$spiel.dran";
 
     # muss ein Auftrag erteilt werden?
     my $doit = 1;
 
     my $line;
 
     if ((-e $file) && (open (HANDLE, "<$file"))) {
 
       $line = <HANDLE>;
       if ($line =~m/(start|vec)/) {
 	
 	#
 	# Zug vorhanden
 	#
 	
 	$doit = 0;
 
 	$line =~m/(start|vec)\s+(-?\d+)\s+(-?\d+)/;
 
 	my $x = $2;
 	my $y = $3;
 	my $is_start=0;
 	if ($1 eq "start") {
 	  $is_start=1;
 	}
 	
 	if ($print == 1) {
 	  print "Zug gefunden fuer Spiel $spiel:\n";
 	  if ($is_start == 1) {
 	    print " Startzug nach ($x|$y)\n";
 	  } else {
 	    print "Vektor $x, $y\n";
 	  }
 	}
 
 	#do move
 	if ($is_start == 1) {
 	  $request->uri("$URL_move$spiel&startx=$x&starty=$y");
 	} else {
 	  $request->uri("$URL_move$spiel&xvec=$x&yvec=$y");
 	}
 	$response = $browser->request($request);
 	if ($response->is_success) {
 	  #   print $response->content, "\n\n\n\n";
 	} else {
 	  print STDERR "Zug fuer Spiel $spiel konnte nicht ausgefuehrt werden!\n";
 	  print STDERR $response->status_line, "\n";
 	  close (HANDLE);
 	  next GAMES;
 	}
 	
 	close (HANDLE);
 	open (HANDLE, ">$file");
 	print HANDLE "leer!";
 	close HANDLE;
       } elsif ($line =~ m/Ich bin dran/) {
 
 	# denkt noch!
 	if ($print ==1) {
 	  print "denker denkt noch bei Spiel $spiel...\n";
 	}
 	$doit = 0;
 	close HANDLE;
       }
 
     } # if (-e $file)...
 
     if ($doit == 1) {
 
       # ich bin dran, es liegt kein fertiger Zug vor, und es ist noch kein Suchauftrag erteilt
 
       $request->uri("$URL_showmap$spiel");
       $response = $browser->request($request);
       if ($response->is_success) {
 	# print $response->content, "\n\n\n\n";
       } else {
 	print STDERR "Laden der Seite von Spiel $spiel fehlgeschlagen!\n";
 	print STDERR $response->status_line, "\n";
 	next GAMES;
       }
 
       # is it the first move?
       my $is_start = 0;
       if ($response->content =~ m/Das Spiel fängt an: Bitte wähle Deine Startposition/) {
 	$is_start = 1;
       }
 
       my @moves;
       my $nmoves=0;
       my %position;
       my $self_found = 0;
       foreach my $line (split(/\n/, $response->content)) {
 
 	# get moves
 	if ($is_start == 0) {
 	
 	  if ($line =~ m/coords=\"(\d+),(\d+),\d+,\d+\"\s*href=\"move.php\?GID=$spiel&xvec=(-?\d+)&yvec=(-?\d+)/){
 	    $nmoves++;
 	    $moves[$nmoves]{'x'} = $1 / 11;
 	    $moves[$nmoves]{'y'} = $2 / 11;
 	    $moves[$nmoves]{'vx'} = $3;
 	    $moves[$nmoves]{'vy'} = $4;
 	  }
 	} else {
 
 	  if ($line =~ m/coords=\"(\d+),(\d+),\d+,\d+\"\s*href=\"move.php\?GID=$spiel&startx=(-?\d+)&starty=(-?\d+)/){
 	    $nmoves++;
 	    $moves[$nmoves]{'x'} = $1 / 11;
 	    $moves[$nmoves]{'y'} = $2 / 11;
 	    $moves[$nmoves]{'vx'} = 0;
 	    $moves[$nmoves]{'vy'} = 0;	
 	  }
 	}
 	
 	#get player positions
 	if ($line =~ m/coords=\"(\d+),(\d+),\d+,\d+\"\s*href=\"userinfo.php\?about=\d+\"\s*TITLE=\"(.*)\"/) {
 	  $position{$3}{'x'} = $1 / 11;
 	  $position{$3}{'y'} = $2 / 11;
 	  if ($3 eq $username) {
 	    $self_found = 1;
 	  }
 	}
 
       } # foreach $line
 
       # error?
       if (($self_found == 0) && ($is_start == 0)) {
 	print STDERR  "irgendwas laeuft schief: ich finde mich nicht, aber es geht auch nicht um Startplatzwahl!\n";
 	next GAMES;
       }
 	
       #
       # checkpoints, ZZZ, TC:
       # eigener browser ohne kekse,
       # da bei startzug nicht angezeigt wenn 'dran'
       # (bug in didis seite...)
       #
 
       # new browser
       my $browser1 = LWP::UserAgent->new;
       my $request1 = HTTP::Request->new(GET => "$URL_showmap$spiel");
       my $response1 = $browser1->request($request1);
 
       if ($response1->is_success) {
 #	print $response1->content, "\n\n\n\n";
       } else {
 	print STDERR "Laden der Seite von Spiel $spiel fehlgeschlagen!\n";
 	print STDERR $response1->status_line, "\n";
 	next GAMES;
       }
 
       my $ZZZ= 2;
       my $checkpoints = "aktiviert";;
       my $crash = "";
 
       foreach my $line (split(/\n/, $response1->content)) {
 #	print "$line\n";
 	if ($line =~ m/Spielinfos:/) {
 #	  print $line;
 	  $line =~m/ZZZ steht auf (\d+). Checkpoints sind (deaktiviert|aktiviert). Taktisches Crashen ist (<B>)?(nicht|)\s*erlaubt/;
 	  $ZZZ = $1;
 	  $checkpoints = $2;
 	  $crash = $4;
 #	  print "\n$ZZZ $checkpoints $crash\n";
 	}
       }
 
       #
       #        get map
       #
 
       my $mapID = -1;
       if ((!(-e "$spiel.map")) || ($is_start)) {
 
 	#get map ID from logfile
 
 	#get logfile
 	$request->uri("$URL_log$spiel.log");
 	# ich hab keine Ahnung warum, aber hier muss GET gesetzt 
 	# werden, sonst spuckt er.
 	$request->method('GET');
 	$response = $browser->request($request);
 	if ($response->is_success) {
 	  #   print $response->content, "\n\n\n\n";
 	} else {
 	  print STDERR "kann logfile fuer spiel $spiel nicht laden!\n";
 	  print STDERR $response->status_line, "\n";
 	  next GAMES;
 	}
 	foreach my $line (split(/\n/, $response->content)) {
 	  if ($line =~ m/.*Spiel.*Map (\d+) von .* erstellt/) {
 	    $mapID = $1;
 	  }
 	}
 	if ($mapID == -1) {
 	  print STDERR "konnte die map fuer Spiel $spiel nicht ermitteln!\n";
 	  next GAMES;
 	}
 
 	#get map
 	$request->uri("$URL_mapsource$mapID");
 	$response = $browser->request($request);
 	if ($response->is_success) {
 	  #         print $response->content, "\n\n\n\n";
 	} else {
 	  print STDERR "konnte die Karte fuer Spiel $spiel nicht laden!\n";
 	  print STDERR $response->status_line, "\n";
 	  next GAMES;
 	}
 	
 	open (HANDLE, ">$spiel.map") ||die "kann $spiel.map nicht oeffnen!\n";
 	print HANDLE $response->content;
 	close HANDLE;
       }
 
 
       # print what we got!
       if ($print == 1) {
 	print "Ich bin dran bei $spiel.\n";
 	print  "ZZZ=$ZZZ, checkpoints $checkpoints, crashen $crash erlaubt\n";
 	if ($is_start == 1) {
 	  print "Startzug!\n";
 	}
 	if ($self_found == 1) {
 	  print "meine Position: x=$position{$username}{'x'}, y=$position{$username}{'y'}\n";
 	}
 	print "Die Positionen aller ",scalar(keys(%position))," Spieler:\n";
 	foreach my $name (keys %position) {
 	  print "$name steht auf  x=$position{$name}{'x'}, y=$position{$name}{'y'}\n";
 	}
 	print "meine $#moves Zugmoeglichkeiten:\n";
 	foreach my $i (1.. $#moves) {
 	  print "$i) nach x=$moves[$i]{'x'}, y=$moves[$i]{'y'} mit Vektor ($moves[$i]{'vx'}|$moves[$i]{'vy'})\n";
 	}
       }
 
       #
       #    print to file:
       #
 
       open (HANDLE, ">$spiel.dran") ||die "kann $spiel.dran nicht oeffnen!\n";
       flock(HANDLE, LOCK_EX) ||die "kann $spiel.dran nicht locken!\n";
       select HANDLE;
       print "Ich bin dran bei $spiel.\n";
       print HANDLE "ZZZ=$ZZZ, checkpoints $checkpoints, crashen $crash erlaubt\n";
       if ($is_start == 1) {
 	print "Startzug!\n";
       }
       if ($self_found == 1) {
 	print "meine Position: x=$position{$username}{'x'}, y=$position{$username}{'y'}\n";
       }
       print "Die Positionen aller ",scalar(keys(%position))," Spieler:\n";
       foreach my $name (keys %position) {
 	print "$name steht auf  x=$position{$name}{'x'}, y=$position{$name}{'y'}\n";
       }
       print "meine $#moves Zugmoeglichkeiten:\n";
       foreach my $i (1.. $#moves) {
 	print "$i) nach x=$moves[$i]{'x'}, y=$moves[$i]{'y'} mit Vektor ($moves[$i]{'vx'}|$moves[$i]{'vy'})\n";
       }
       flock(HANDLE, LOCK_UN) ||die "kann $spiel.dran nicht unlocken!\n";
       close HANDLE;
       select STDOUT;
 
     } # if ($doit ==1)
 
   } # loop games
 
   sleep $sleep;
 
 } # end ENDLESS