Netzer.pl: Unterschied zwischen den Versionen
Jody (Diskussion | Beiträge) K (re) |
K |
||
(4 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | Da die Kommunikation | + | == Hintergrund == |
+ | Da die Kommunikation für mich ({{Benutzer|quabla}}) das war, was mich am meisten vom Schreiben eines Bots abgehalten hat, weil ich davon einfach keine Ahnung hatte, möchte ich mein Werk jetzt hier zur Verfügung stellen. Falls es noch jemandem so geht, dann kann er sich diesen Teil schonmal sparen, und braucht sich bloß um den eigentlichen [[Bot]] zu kümmern. | ||
− | Das ganze Ding ist in perl | + | Das ganze Ding ist in perl geschrieben, und ich bin alles andere als ein perl-Experte. Wenn ihr also in irgendeiner Form nicht damit einverstanden seid: ruhig meckern! |
− | Die Kommunikation | + | Die Kommunikation läuft über die [http://search.cpan.org/~gaas/libwww-perl/ libwww-perl(LWP)]. |
− | netzer.pl schreibt | + | == Netzer-Logik == |
+ | |||
+ | netzer.pl schreibt für jedes Spiel von der dranbin-Seite eine Datei mit Namen spielnummer.dran, der Inhalt sollte selbsterklärend sein: | ||
<nowiki> | <nowiki> | ||
Zeile 24: | Zeile 27: | ||
</nowiki> | </nowiki> | ||
− | Der eigentliche Bot sollte also diese Datei auswerten, und mit seinem Zug | + | Der eigentliche Bot sollte also diese Datei auswerten, und mit seinem Zug im Format |
<nowiki> | <nowiki> | ||
Zeile 30: | Zeile 33: | ||
</nowiki> | </nowiki> | ||
− | + | überschreiben. | |
− | |||
+ | == netzer.pl == | ||
<nowiki> | <nowiki> |
Aktuelle Version vom 7. Dezember 2018, 15:22 Uhr
Hintergrund
Da die Kommunikation für mich (quabla) das war, was mich am meisten vom Schreiben eines Bots abgehalten hat, weil ich davon einfach keine Ahnung hatte, möchte ich mein Werk jetzt hier zur Verfügung stellen. Falls es noch jemandem so geht, dann kann er sich diesen Teil schonmal sparen, und braucht sich bloß um den eigentlichen Bot zu kümmern.
Das ganze Ding ist in perl geschrieben, und ich bin alles andere als ein perl-Experte. Wenn ihr also in irgendeiner Form nicht damit einverstanden seid: ruhig meckern!
Die Kommunikation läuft über die libwww-perl(LWP).
Netzer-Logik
netzer.pl schreibt für jedes Spiel von der dranbin-Seite eine Datei mit Namen spielnummer.dran, der Inhalt sollte selbsterklärend 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
überschreiben.
netzer.pl
#!/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