FreewarWiki:Bot/Skripts/maplist.php: Unterschied zwischen den Versionen

aus FreewarWiki, der Referenz für Freewar
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „{{Scriptquelltextverwendung}} Das Skript ist semantisch identisch zu FreewarWiki:Bot/Skripts/maplist.pl mit dem Unterschied, dass es die Informationen aus …“)
 
(fixed passages, tested changes, minor clean up, autoformat)
 
(10 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
{{Scriptquelltextverwendung}}
{{Scriptquelltextverwendung}}
Das Skript ist semantisch identisch zu [[FreewarWiki:Bot/Skripts/maplist.pl]] mit dem Unterschied, dass es die Informationen aus [[:Kategorie:Felder]] holt und daher keine Angaben über Passagen machen kann.
 
Letzte Änderungen:
* Ermittlung unbegehbarer Felder aus makemap.php hier eingebaut. --[[Benutzer:Count Ypsilon|Count Ypsilon]] ([[Benutzer Diskussion:Count Ypsilon|Diskussion]]) 23:30, 14. Feb. 2019 (CET)
 
<pre>
<pre>
<?php
<?php
// Ausgabeformat: Gebiet;Betretbar;X-Position;Y-Position;Slash/separierte/NPC-Liste;Bild-URL;Passage
// wobei Passage Komma-separierte X,Y Koordinaten sind bzw. ein Komma ohne Koordinaten zeigt eine Zufallspassage an (ohne festen Zielort)
header('Content-Type: text/plain; charset=utf-8;');
header('Content-Type: text/plain; charset=utf-8;');
error_reporting(E_ALL ^ E_NOTICE);
error_reporting(E_ALL ^ E_NOTICE);


function is_obsolete($wiki_text) {
define('TEMPLATE_GET_KEY', 1);
define('TEMPLATE_GET_VALUE', 2);
define('WIKIURL', 'https://fwwiki.de');
define("BERGFELD", 'http://welt1.freewar.de/freewar/images/map/std.jpg');
 
function is_obsolete($wiki_text)
{
     // Veraltetes Feld=none liefert true!
     // Veraltetes Feld=none liefert true!
     return (bool)preg_match('/Veraltetes Feld=[^}]+/', $wiki_text);
     return (bool)preg_match('/Veraltetes Feld=[^}]+/', $wiki_text);
}
}


function get_areas($url, $prefix) {
// Zerlegt eine Seite so, dass jedes Resultat mit der angegebenen
    preg_match_all("/>$prefix:([^<]+)</", file_get_contents($url), $areas);
// Vorlage beginnt (kann danach aber noch Müll enthalten)


     return $areas[1];
function get_templates($template, $wiki_text)
{
    $pattern = '/\{\{(Vorlage:)?' . preg_quote($template, '/') . '/';
    $templates = preg_split($pattern, $wiki_text);
     return array_slice($templates, 1);
}
}


function parse_field_article($area, $host) {
// Liest zu einem angegebenen Gebiet die Felder aus dem "Felder:XXX"-Artikel.
// Die unbetretbaren Felder um das Gebiet herum sind nicht mit dabei, dafür
// aber Details zu NPCs usw.
 
function parse_field_article($area)
{
 
     $fields = array();
     $fields = array();
 
     // Artikel fetchen
     // Artikel fetchen
     $field_url = "$host/index.php/Felder:" . str_replace(' ', '%20', $area).
     $field_url = WIKIURL . "/index.php/Felder:" . rawurlencode($area) . "?action=raw";
                "?action=edit";
     $html = file_get_contents($field_url);
     $html = file_get_contents($field_url);
   
 
     if (is_obsolete($html) === true) { // veraltet
     if (is_obsolete($html) === true) { // veraltet
         return array();
         return array();
     } else {
     } else {
         // Layout Vorlagen matchen
         // Layout Vorlagen matchen
         $pattern_template = "/\{\{(Vorlage:)?Feldzusammenfassung\/Layout([^}]+)\}\}/";
         $field_templates = get_templates('Feldzusammenfassung/Layout', $html);
        preg_match_all($pattern_template, $html, $matches);
 
   
         // Layout Vorlagen durchlaufen
         // Layout Vorlage durchlaufen
         foreach ($field_templates as $field_template) {
         foreach ($matches[2] as $field_template) {
             // init und parsen
             // init und parsen
             $field = array_merge(array('area' => $area), parse_field_template($field_template));
             $field = array_merge(array('area' => $area), parse_field_template($field_template));
Zeile 40: Zeile 61:
             $fields[] = $field;
             $fields[] = $field;
         }
         }
 
         return $fields;
         return $fields;
     }
     }
}
}


function parse_field_template($wiki_text) {
// Liest zu einem angegebenen Gebiet die unbetretbaren Felder aus dem
     // Vorlagen als Array: Parameter => Wert
// "Karte:XXX"-Artikel.
     $template = array();
 
function parse_map_article($area)
{
     // Artikel fetchen
    $field_url = WIKIURL . "/index.php/Karte:" . rawurlencode($area) . "?action=raw";
    echo "$field_url\n";
    $raw = file_get_contents($field_url);
    return array_map(function ($template_text) use ($area) {
        if (!preg_match("/^\|(-?\d+)\|(-?\d+)(\|([^}|]+))?/", $template_text, $values)) return [];
        return [
            'area' => $area,
            'accessible' => 0,
            'pos_x' => $values[1],
            'pos_y' => $values[2],
            'npc' => NULL,
            'url' => isset($values[4]) ? $values[4] : BERGFELD,
            'passages' => NULL
        ];
     }, array_merge(get_templates("Karte/Unbetretbar", $raw), get_templates("Karte/Rahmenfeld", $raw)));
}
 
// Verarbeitet Feld-Templates
 
function parse_field_template($wiki_text)
{
 
     // Standard-Werte
     // Standard-Werte
     $field = array(
     $field = array(
         'accessible' => 1,
         'accessible' => 1,
         'pos_x'     => -10,
         'pos_x' => -10,
         'pos_y'     => -9,
         'pos_y' => -9,
         'npc'     => array(),
         'npc' => array(),
         'url'       => '',
         'url' => '',
         'passages'   => array()
         'passages' => array()
     );
     );


     // Key-Value Paare spliten
     // Vorlage als Array: Parameter => Wert
    $lines = array_filter(explode('|', $wiki_text));
     $template = parse_template($wiki_text);
     foreach ($lines as $line) {
        // Key/Value trennen
        $keyval = explode('=', $line, 2);
        // und entsprechend ins Array eintragen
        $template[$keyval[0]] = trim($keyval[1]); // 'Parameter=' wirft undefined offset 1
    }


     // Vorlagewerte maschinenlesbar machen
     // Vorlagewerte maschinenlesbar machen
     $field['pos_x'] = (int)$template['X'];
     $field['pos_x'] = (int)$template['X'];
     $field['pos_y'] = (int)$template['Y'];
     $field['pos_y'] = (int)$template['Y'];
     $field['url']   = $template['Bild'];
     $field['url'] = $template['Bild'];
 
    // Passagen lesen
    $passage_templates = get_templates('Feldzusammenfassung/Passage', $wiki_text);
 
    // Passagen durchlaufen
    foreach ($passage_templates as $passage_template) {
        $passage = parse_template($passage_template);
 
        // keine Koordinaten gesetzt
        if (strcasecmp($passage['Nach'], 'zufall') && !isset($passage['X'], $passage['Y'])) {
            /* Warnung deaktiviert - Es gibt einige Passagen in denen das beabsichtigt ist (Buran), solange nicht speziell gefiltert wird stört die Meldung nur
                trigger_error('Keine Koordinatenangabe in Passage von '.
                    $template['Name'] . ' nach ' . $passage['Nach'], E_USER_WARNING);
            */
        } else {
            $field['passages'][] = $passage['X'] . ',' . $passage['Y'];
        }
    }


     // npcs lesen
     // npcs lesen
     preg_match_all('/\[\[([^]]+)\]\]/', $template['NPC'], $npc_matches);
     preg_match_all('/\[\[([^]]+)]]/', $template['NPC'], $npc_matches, PREG_PATTERN_ORDER);
     $field['npc'] = $npc_matches[1];
     $field['npc'] = $npc_matches[1];
   
 
     return $field;
     return $field;
}
}


$host            = 'http://fwwiki.de';
function parse_template($text)
$prefix          = 'Felder';                           // Wiki-Namespace
{
$parser_function = 'parse_field_article';             // Parser Funktion des Skripts
    $template = array();
$category_url    = "$host/index.php/Kategorie:Felder"; // Gebietskategorie
 
    /* nicht kompatibel mit verschachtelten Vorlagen
    // Key-Value Paare spliten
    $lines = array_filter(explode('|', $template_text));
 
    foreach ($lines as $line) {
        // Key/Value trennen
        $keyval = explode('=', $line, 2);
        // und entsprechend ins Array eintragen
        $template[$keyval[0]] = trim($keyval[1]); // 'Parameter=' wirft undefined offset 1
    }//*/
 
    $key = '';
    $mode = TEMPLATE_GET_KEY;
    $depth = 0;
 
    for ($i = 1, $length = strlen($text); $i < $length; ++$i) {
        if ($text[$i] === '{' && $text[$i + 1] === '{') { // weitere Vorlage
            ++$depth;
            ++$i;
            $template[$key] .= '{';
        } else if ($text[$i] === '}' && $text[$i + 1] === '}') { // geschlossene Vorlage
 
            if ($depth === 0) {
                break;
            } else {
                --$depth;
                ++$i;
                $template[$key] .= '}';
            }
        } else if ($text[$i] === '[' && $text[$i + 1] === '[') { // geöffneter Link
            ++$depth;
            ++$i;
            $template[$key] .= '[';
        } else if ($text[$i] === ']' && $text[$i + 1] === ']') { // geschlossener Link


// init
            if ($depth === 0) {
$fields = array();
                break;
            } else {
                --$depth;
                ++$i;
                $template[$key] .= ']';
            }
        }


// Gebiete fetchen
        if ($text[$i] === '=' && $depth === 0) { // Wertzuweisung beginnt
$areas = get_areas($category_url, $prefix);
            $mode = TEMPLATE_GET_VALUE;
            $depth = 0;
            $template[$key] = '';
        } else if ($text[$i] === '|' && $depth === 0) { // Parameter Sparierung
            $mode = TEMPLATE_GET_KEY;
            $key = '';
        } else if ($mode === TEMPLATE_GET_KEY) {
            $key .= $text[$i];
        } else if ($mode === TEMPLATE_GET_VALUE) { // Wert wird geschrieben
            $template[$key] .= $text[$i];
        }
    }


// durchlaufen
     return array_map('trim', $template);
foreach ($areas as $area) {
     $fields = array_merge($fields, $parser_function($area, $host));
}
}


// und ausgeben
// Liste aller Gebiete aus "Katgorie:Felder" bestimmen
$delimiter = ';';


// head
preg_match_all("/>Felder:([^<]+)</",
#echo implode($delimiter, array_keys($fields[0])) . "\n";
    file_get_contents(WIKIURL . '/index.php/Kategorie:Felder'), $areas);
 
// Für jedes Gebiet die Felder und die Randfelder ermitteln,
// und alles in ein großes Array werfen
 
$fields = array();
foreach ($areas[1] as $area) {
    $fields = array_merge($fields, parse_field_article($area));
    $fields = array_merge($fields, parse_map_article($area));
}
 
// Ausgabe


// body
foreach ($fields as $field) {
foreach ($fields as $field) {
     // output wie maplist.pl
     // output wie maplist.pl
     $field['npc'] = implode('/', $field['npc']);
     printf("%s;%d;%d;%d;%s;%s;%s\n",
    $field['passages'] = implode('/', $field['passages']);
        $field['area'],
   
        $field['accessible'],
    echo implode($delimiter, $field) . "\n";
        $field['pos_x'],
        $field['pos_y'],
        is_null($field['npc']) ? "" : implode('/', $field['npc']),
        $field['url'],
        is_null($field['passages']) ? "" : implode('/', $field['passages']));
}
}
</pre>
</pre>

Aktuelle Version vom 30. Mai 2020, 15:03 Uhr

Dieses Script ist hier lediglich archiviert und nicht direkt lauffähig. Wenn Du es benutzen möchtest, musst Du es lokal abspeichern und mit einem geeigneten Interpreter ausführen lassen. Zum Übernehmen solltest Du nicht den unten angezeigten Text verwenden, sondern den Quelltext des Wiki-Artikels: Dazu wählst Du Bearbeiten und kopierst den (meist zwischen PRE-Tags eingefassten) Scripttext.

Sofern Du die Scripte dauerhaft lokal abgespeichert hältst, solltest Du sie vor der nächsten Ausführung darauf prüfen, ob sie noch aktuell sind.

Letzter Bearbeiter: 91.65.141.33 — Zuletzt bearbeitet: 30.05.2020

Letzte Änderungen:

  • Ermittlung unbegehbarer Felder aus makemap.php hier eingebaut. --Count Ypsilon (Diskussion) 23:30, 14. Feb. 2019 (CET)
<?php

// Ausgabeformat: Gebiet;Betretbar;X-Position;Y-Position;Slash/separierte/NPC-Liste;Bild-URL;Passage
// wobei Passage Komma-separierte X,Y Koordinaten sind bzw. ein Komma ohne Koordinaten zeigt eine Zufallspassage an (ohne festen Zielort)

header('Content-Type: text/plain; charset=utf-8;');
error_reporting(E_ALL ^ E_NOTICE);

define('TEMPLATE_GET_KEY', 1);
define('TEMPLATE_GET_VALUE', 2);
define('WIKIURL', 'https://fwwiki.de');
define("BERGFELD", 'http://welt1.freewar.de/freewar/images/map/std.jpg');

function is_obsolete($wiki_text)
{
    // Veraltetes Feld=none liefert true!
    return (bool)preg_match('/Veraltetes Feld=[^}]+/', $wiki_text);
}

// Zerlegt eine Seite so, dass jedes Resultat mit der angegebenen
// Vorlage beginnt (kann danach aber noch Müll enthalten)

function get_templates($template, $wiki_text)
{
    $pattern = '/\{\{(Vorlage:)?' . preg_quote($template, '/') . '/';
    $templates = preg_split($pattern, $wiki_text);
    return array_slice($templates, 1);
}

// Liest zu einem angegebenen Gebiet die Felder aus dem "Felder:XXX"-Artikel.
// Die unbetretbaren Felder um das Gebiet herum sind nicht mit dabei, dafür
// aber Details zu NPCs usw.

function parse_field_article($area)
{

    $fields = array();

    // Artikel fetchen
    $field_url = WIKIURL . "/index.php/Felder:" . rawurlencode($area) . "?action=raw";
    $html = file_get_contents($field_url);

    if (is_obsolete($html) === true) { // veraltet
        return array();
    } else {
        // Layout Vorlagen matchen
        $field_templates = get_templates('Feldzusammenfassung/Layout', $html);

        // Layout Vorlagen durchlaufen
        foreach ($field_templates as $field_template) {
            // init und parsen
            $field = array_merge(array('area' => $area), parse_field_template($field_template));

            // push
            $fields[] = $field;
        }

        return $fields;
    }
}

// Liest zu einem angegebenen Gebiet die unbetretbaren Felder aus dem
// "Karte:XXX"-Artikel.

function parse_map_article($area)
{
    // Artikel fetchen
    $field_url = WIKIURL . "/index.php/Karte:" . rawurlencode($area) . "?action=raw";
    echo "$field_url\n";
    $raw = file_get_contents($field_url);
    return array_map(function ($template_text) use ($area) {
        if (!preg_match("/^\|(-?\d+)\|(-?\d+)(\|([^}|]+))?/", $template_text, $values)) return [];
        return [
            'area' => $area,
            'accessible' => 0,
            'pos_x' => $values[1],
            'pos_y' => $values[2],
            'npc' => NULL,
            'url' => isset($values[4]) ? $values[4] : BERGFELD,
            'passages' => NULL
        ];
    }, array_merge(get_templates("Karte/Unbetretbar", $raw), get_templates("Karte/Rahmenfeld", $raw)));
}

// Verarbeitet Feld-Templates

function parse_field_template($wiki_text)
{

    // Standard-Werte
    $field = array(
        'accessible' => 1,
        'pos_x' => -10,
        'pos_y' => -9,
        'npc' => array(),
        'url' => '',
        'passages' => array()
    );

    // Vorlage als Array: Parameter => Wert
    $template = parse_template($wiki_text);

    // Vorlagewerte maschinenlesbar machen
    $field['pos_x'] = (int)$template['X'];
    $field['pos_y'] = (int)$template['Y'];
    $field['url'] = $template['Bild'];

    // Passagen lesen
    $passage_templates = get_templates('Feldzusammenfassung/Passage', $wiki_text);

    // Passagen durchlaufen
    foreach ($passage_templates as $passage_template) {
        $passage = parse_template($passage_template);

        // keine Koordinaten gesetzt
        if (strcasecmp($passage['Nach'], 'zufall') && !isset($passage['X'], $passage['Y'])) {
            /* Warnung deaktiviert - Es gibt einige Passagen in denen das beabsichtigt ist (Buran), solange nicht speziell gefiltert wird stört die Meldung nur
                trigger_error('Keine Koordinatenangabe in Passage von '.
                    $template['Name'] . ' nach ' . $passage['Nach'], E_USER_WARNING);
            */
        } else {
            $field['passages'][] = $passage['X'] . ',' . $passage['Y'];
        }
    }

    // npcs lesen
    preg_match_all('/\[\[([^]]+)]]/', $template['NPC'], $npc_matches, PREG_PATTERN_ORDER);
    $field['npc'] = $npc_matches[1];

    return $field;
}

function parse_template($text)
{
    $template = array();

    /* nicht kompatibel mit verschachtelten Vorlagen
    // Key-Value Paare spliten
    $lines = array_filter(explode('|', $template_text));

    foreach ($lines as $line) {
        // Key/Value trennen
        $keyval = explode('=', $line, 2);
        // und entsprechend ins Array eintragen
        $template[$keyval[0]] = trim($keyval[1]); // 'Parameter=' wirft undefined offset 1
    }//*/

    $key = '';
    $mode = TEMPLATE_GET_KEY;
    $depth = 0;

    for ($i = 1, $length = strlen($text); $i < $length; ++$i) {
        if ($text[$i] === '{' && $text[$i + 1] === '{') { // weitere Vorlage
            ++$depth;
            ++$i;
            $template[$key] .= '{';
        } else if ($text[$i] === '}' && $text[$i + 1] === '}') { // geschlossene Vorlage

            if ($depth === 0) {
                break;
            } else {
                --$depth;
                ++$i;
                $template[$key] .= '}';
            }
        } else if ($text[$i] === '[' && $text[$i + 1] === '[') { // geöffneter Link
            ++$depth;
            ++$i;
            $template[$key] .= '[';
        } else if ($text[$i] === ']' && $text[$i + 1] === ']') { // geschlossener Link

            if ($depth === 0) {
                break;
            } else {
                --$depth;
                ++$i;
                $template[$key] .= ']';
            }
        }

        if ($text[$i] === '=' && $depth === 0) { // Wertzuweisung beginnt
            $mode = TEMPLATE_GET_VALUE;
            $depth = 0;
            $template[$key] = '';
        } else if ($text[$i] === '|' && $depth === 0) { // Parameter Sparierung
            $mode = TEMPLATE_GET_KEY;
            $key = '';
        } else if ($mode === TEMPLATE_GET_KEY) {
            $key .= $text[$i];
        } else if ($mode === TEMPLATE_GET_VALUE) { // Wert wird geschrieben
            $template[$key] .= $text[$i];
        }
    }

    return array_map('trim', $template);
}

// Liste aller Gebiete aus "Katgorie:Felder" bestimmen

preg_match_all("/>Felder:([^<]+)</",
    file_get_contents(WIKIURL . '/index.php/Kategorie:Felder'), $areas);

// Für jedes Gebiet die Felder und die Randfelder ermitteln,
// und alles in ein großes Array werfen

$fields = array();
foreach ($areas[1] as $area) {
    $fields = array_merge($fields, parse_field_article($area));
    $fields = array_merge($fields, parse_map_article($area));
}

// Ausgabe

foreach ($fields as $field) {
    // output wie maplist.pl
    printf("%s;%d;%d;%d;%s;%s;%s\n",
        $field['area'],
        $field['accessible'],
        $field['pos_x'],
        $field['pos_y'],
        is_null($field['npc']) ? "" : implode('/', $field['npc']),
        $field['url'],
        is_null($field['passages']) ? "" : implode('/', $field['passages']));
}