Kategorien
FreewarWiki:Bot/Skripts/makemap.php
< FreewarWiki:Bot | Skripts
<?php header('Content-Type: text/plain; charset=utf-8;'); // Bergfeld url define("BERGFELD", 'http://welt1.freewar.de/freewar/images/map/std.jpg'); $host = 'http://www.fwwiki.de'; $prefix = 'Karte'; // Wiki-Namespace // pfad zu maplist.txt $maplist = 'maplist.txt'; // Pfad zur Ausgabedatei $mapfile = './Gesamtkarte (automatisch generiert).jpg'; // pfad zu map_cache $map_cache = './map_cache'; # Bereich angeben. Alles ausserhalb wird ignoriert. Die Karte wird aber # immer nur so gross, wie tatsaechlich Felder da sind, nicht so gross, # wie man hier angibt. # (nicht mit 1,1 starten, sonst kriegt man den Dummyplace mit) $min_x = 2; $min_y = 2; $max_x = 170; # oestlicher Rand, damit Itolos und Belpharia-Inseln draussen bleiben $max_y = 400; # Hintergrundfarbe fuer Karte $bgcolor = "ffffff"; # auf z.b. 5 setzen, wenn felder mit luecken gewuenscht $cellspacing = 0; # auf 1 setzen, wenn alle 5 zeilen/spalten linie gewuenscht $draw_grid = 1; // ab hier nichts ändern ohne Kenntnisse über Funktionsweise des Skripts function get_templates($template, $wiki_text) { $pattern = '/\{\{(Vorlage:)?' . preg_quote($template, '/') . '/'; $templates = preg_split($pattern, $wiki_text); return array_slice($templates, 1); } // cacht mapfile function cache_mapfile($url, $map_cache) { $cache_file = "$map_cache/" . md5($url); if (!file_exists($cache_file)) { file_put_contents($cache_file, file_get_contents($url)); } return $cache_file; } $parser_function = 'parse_card_article'; // Parser Funktion des Skripts $api_url = "$host/api.php?format=json"; // trennzeichen für positionsschlüssel $pos_delimiter = '|'; // Rahmen $min_x_found = $max_x; $min_y_found = $max_y; $max_x_found = $min_x; $max_y_found = $min_y; // zusätzliche Felder, die nicht von Feld-Artikeln erfasst werden $additional_fields = []; // Bergfeld cachen cache_mapfile(BERGFELD, $map_cache); // Karten holen $api_query_url = "$api_url&action=query&list=categorymembers". "&cmtitle=Kategorie:Karten&cmtype=page". "&cmprop=ids|sortkeyprefix|title&cmlimit=50"; $api_query_url_continue = $api_query_url; // pageids der karten $map_pageids = []; // kategorieeinträge durchlaufen while (true) { $json = json_decode(file_get_contents($api_query_url_continue), true); // pageids hinzufügen $map_pageids = array_merge($map_pageids, array_filter(array_map(function ($row) { // keine ! kategorieeinträge return ($row['sortkeyprefix'][0] == '!') ? null : $row['pageid']; }, $json['query']['categorymembers']))); // continue url if (isset($json['continue'])) { $api_query_url_continue = "$api_query_url&cmcontinue={$json['continue']['cmcontinue']}"; } else { break; } } // karten durchlaufen $rvlimit = 10; foreach (array_chunk($map_pageids, $rvlimit) as $pageids) { $api_query_url = "$api_url&action=query&prop=revisions". "&rvprop=content&pageids=". implode("|", $pageids); $json = json_decode(file_get_contents($api_query_url), true); foreach ($json['query']['pages'] as $pageid => $prop) { $raw = $prop['revisions'][0]['*']; // unbetretbare und rahmenfelder erfassen, durchlaufen und an maplist format anpassen $additional_fields = array_merge($additional_fields, array_map(function ($template_text) { preg_match("/([0-9\-]+)\|([0-9\-]+)(\|([^}\|]+))?/", $template_text, $values); if (!isset($values[1])) { return []; } return [ // array keys entsprechend format in maplist.txt 2 => $values[1], 3 => $values[2], 5 => isset($values[3]) ? $values[4] : BERGFELD ]; }, array_merge(get_templates("Karte/Unbetretbar", $raw), get_templates("Karte/Rahmenfeld", $raw)))); } } // zusätzliche Felder geholt // eigentliche maplist holen und mit zusätzlichen zusammenführen $field_rows = array_merge(array_map(function ($line) { return str_getcsv($line, ";"); }, explode("\n", file_get_contents($maplist))), $additional_fields); // felder in `position` => `url` format überführen $fields = []; foreach ($field_rows as $field) { # Koordinaten-Check if ($field[2] < $min_x || $field[2] > $max_x || $field[3] < $min_y || $field[3] > $max_y) { continue; } if ($field[2] < $min_x_found) { $min_x_found = $field[2] ; } if ($field[3] < $min_y_found) { $min_y_found = $field[3]; } if ($field[2] > $max_x_found) { $max_x_found = $field[2] ; } if ($field[3] > $max_y_found) { $max_y_found = $field[3]; } // und gleich bilddatein holen $cache_file = cache_mapfile($field[5], $map_cache); // kein Feldtitel oder `Feldtitel Pensal (brennend)` if (!isset($field[1]) || strpos($field[1], ' (brennend)') === false) { $fields["{$field[2]}$pos_delimiter{$field[3]}"] = [ 'x' => $field[2], 'y' => $field[3], 'file' => $cache_file ]; } } // Randfelder einfügen foreach ($fields as $field) { // Randfelder for ($diff_x = -1; $diff_x <= 1; ++$diff_x) { for ($diff_y = -1; $diff_y <= 1; ++$diff_y) { $edge = ($field['x'] + $diff_x) . $pos_delimiter . ($field['y'] + $diff_y); if (!isset($fields[$edge])) { $fields[$edge] = [ 'x' => $field['x'] + $diff_x, 'y' => $field['y'] + $diff_y, 'file' => "$map_cache/" . md5(BERGFELD) ]; } } } } # Groesse eines Kartenfelds feststellen list($tilewidth, $tileheight) = getimagesize($cache_file); echo "tile size: $tilewidth x $tileheight\n"; # Leeres Kartenbild erstellen $mapwidth = ($max_x_found - $min_x_found + 3) * $tilewidth + ($max_x_found - $min_x_found + 2) * $cellspacing; $mapheight = ($max_y_found - $min_y_found + 3) * $tileheight + ($max_y_found - $min_y_found + 2) * $cellspacing; $mapimage = imagecreatetruecolor($mapwidth, $mapheight); echo "x_min: $min_x_found; x_max: $max_x_found; y_min: $min_y_found; y_max: $max_y_found;"; echo "map size: $mapwidth x $mapheight\n"; // hintergrundfarbe imagefill($mapimage, 0, 0, imagecolorallocate($mapimage, hexdec(substr($bgcolor, 0, 2)), hexdec(substr($bgcolor, 2, 2)), hexdec(substr($bgcolor, 4, 2)))); // Gitter malen, wenn angefordert if ($draw_grid) { for ($x = $min_x_found; $x <= $max_x_found; $x++) { if ($x%5 == 0) { $mpx = ($x - $min_x_found + 1) * ($tilewidth + $cellspacing) + $cellspacing + $tilewidth/2; imageline($mapimage, $mpx, 0, $mpx, $mapheight, 0); } } for ($y = $min_y_found; $y <= $max_y_found; $y++) { if ($y%5 == 0) { $mpy = ($y - $min_y_found + 1) * ($tileheight + $cellspacing) + $cellspacing + $tileheight/2; imageline($mapimage, 0, $mpy, $mapwidth, $mpy, 0); } } } // Felder einzeichnen foreach ($fields as $key => $data) { // bild in map einfügen imagecopy($mapimage, imagecreatefromjpeg($data['file']), ($data['x'] - $min_x_found + 1) * ($tilewidth + $cellspacing) + $cellspacing, ($data['y'] - $min_y_found + 1) * ($tileheight + $cellspacing) + $cellspacing, 0, 0, $tilewidth, $tileheight); } // ausgabe imagejpeg($mapimage, $mapfile); imagedestroy($mapimage);