Enforce reloadable AdventureBot area and travel access policies

This commit is contained in:
Nico committed 2026-10-29 09:44:49 +01:00
1 parent 0173a434f4
commit 321a28640c
31 files changed
+4869 -21

No files matched your search

+158
View File
@@ -0,0 +1,158 @@
# Veränderbarer Gebietskatalog der AdventureBots
Der Katalog liegt in der **World-Datenbank**, nicht in C++ oder in den Nodes.
Migration: `sql/custom/world/2026_10_29_02_adventure_area_catalog.sql`.
Sie setzt die bestehende Migration `2026_10_29_00_adventure_population.sql`
mit `vcore_adventure_zone` voraus. Erneutes Einspielen erhält vorhandene Einträge.
## Stand und Geltungsbereich
Die Regeln sind in Tagesplanung, TravelGraph und Bewegungsausführung angebunden.
`clientless adventure reload` lädt Gebiets- und Nodefreigaben sowie Location- und
TravelGraph-Kataloge im laufenden Betrieb neu. Spätere Änderungen benötigen
keinen Build, keine Installation und keinen Neustart. Ungültige Gebietskataloge
(z.B. Elternzyklen oder unzulässige Masken) werden vor Austausch des aktiven
Snapshots abgewiesen.
Neue Tagespläne wählen nur zulässige Locations. Bestehende Tagespläne werden
beim Einloggen und nach erfolgreichem Reload geprüft: Unzulässige Ziele werden
ersetzt und gespeichert; Intents und Stunden bleiben erhalten. Sind keine
zulässigen Ziele vorhanden, bleibt das Ziel leer, statt eine Sperre zu umgehen.
Die aktuelle Mikroaktion oder ein bereits gestarteter nativer Transport wird
nicht mitten in einer Bewegung gewaltsam abgebrochen. Neue Reiseabschnitte
werden erneut geprüft. Ein bereits in einem gesperrten Gebiet stehender Bot wird
nicht automatisch teleportiert; diese Regeln ersetzen keine eigene Bergungslogik.
Die Regeln betreffen ausschließlich autonome AdventureBots. Sie sperren keine
Gebiete für menschliche Spieler und verändern weder DBC noch NPC-Fraktionen.
## Inhalt
`vcore_adventure_map_catalog` enthält Karten-ID, Anzeigename, Kartentyp und
Erweiterung. Kartentyp 255 markiert alte Gebiete ohne vorhandenen Map.dbc-Eintrag.
Solche Gebiete sind ausdrücklich gesperrt. Dungeon-/Raid-/Schlachtfeldkarten
bleiben gekennzeichnet und werden nicht als normale offene Welt behandelt.
`vcore_adventure_area_catalog` enthält alle Gebiete und Untergebiete aus der
lokalen Cataclysm-4.3.4-AreaTable.dbc, mit Namen, Karten-ID und Elterngebiet.
Die Namen sind hier deutsch; die stabile Referenz ist immer die numerische ID.
| Spalte | Bedeutung |
| --- | --- |
| `area_id` | Native AreaTable-ID, auch für übergeordnete Zonen |
| `parent_area_id` | Übergeordnetes Gebiet; 0 bedeutet Wurzelgebiet |
| `allowed_factions` | NULL: erben; 0: gesperrt; 1: Allianz; 2: Horde; 3: beide |
| `min_level`, `max_level` | Empfohlener Levelbereich; NULL: erben/unbekannt |
| `max_level_gap` | Erlaubter Abstand unter der Mindeststufe; NULL: erben, Standard 5 |
| `prefer_flight` | NULL: erben; 0: normale Reisegewichtung; 1: erlaubte Flüge bevorzugen |
| `notes` | Frei bearbeitbare Begründung/Notiz |
Die Mindeststufe ist eine untere Zugangsgrenze mit der angegebenen Toleranz.
`max_level` sperrt höherstufige Bots nicht aus ihren Heimatgebieten aus.
Die vorhandenen, manuell gepflegten Levelbereiche aus `vcore_adventure_zone`
werden beim Import übernommen. Unbekannte Bereiche bleiben NULL, statt einen
nicht belegten sicheren Levelbereich vorzutäuschen. Unbekannte Freilandbereiche sind unter Stufe85 gesperrt.
## Verbindliche Hierarchie
Alle Vorfahren eines Gebiets sind zu berücksichtigen. Fraktionsfreigaben werden
geschnitten: Ein Kind mit Freigabe 3 kann einen gesperrten Elternbereich nicht
freigeben. Dasselbe gilt anschließend für einen neutralen Node in einem
fraktionsgesperrten Gebiet. Ein Node darf zusätzliche Einschränkungen besitzen,
aber die Gebietsfreigabe nicht erweitern. Die geltende Reihenfolge ist
**Karte vorhanden → Gebiet samt Vorfahren → Node → Verbindung/Transport**.
NULL bedeutet Vererbung, ausdrücklich 0 bedeutet bei Fraktionen Sperre und bei
Flugpräferenz normale Gewichtung. Flugpräferenzen ersetzen keine Reitfähigkeit,
Fluglizenzen, nativen Flugverbote oder Kollisionsprüfung. Sichere Endpunkte
allein reichen nicht für sichere Wege: Zwischengebiete müssen ebenfalls geprüft
werden. Ein bereits in einem gesperrten Gebiet stehender Bot braucht einen
gesonderten sicheren Ausweg, statt die Sperre für reguläre Reisen aufzuheben.
## Voreinstellungen
- Rassische Startregionen und Hauptstädte haben Fraktionsfreigaben. Darunter
Dun Morogh/Elwynn/Teldrassil/Azur- und Blutmythosinseln/Gilneas für Allianz
sowie Durotar/Tirisfal/Mulgore/Immersangwald/Geisterlande/Kezan/Verlorene Inseln
für Horde. Die zugehörigen Hauptstädte sind ebenfalls eingetragen.
- Vashj'ir (5146) ist für alle gesperrt. Tang'tharwald (4815), Schimmernde Weiten
(5144) und Abyssische Tiefen (5145) erben diese Sperre über die echte DBC-Hierarchie.
- Die Scherbenweltgebiete einschließlich Shattrath, Nordend sowie Hyjal,
Tiefenheim, Uldum, Schattenhochland und Tol Barad bevorzugen erlaubtes Fliegen.
Native Flugverbote haben stets Vorrang. Karte 530 wird bewusst nicht pauschal
als Scherbenwelt behandelt: Sie enthält auch die Blutelfen-/Draenei-Startgebiete.
Tiefenbahn und Schiff Sturmwind–Rut'theran haben explizite Allianz-Nodefreigaben.
Hauptstadtportale werden über ihre Zielgebiete gesperrt; auch neutrale Quellnodes
können diese Sperre nicht umgehen.
## Nodefreigaben
Migration: `sql/custom/world/2026_10_29_03_adventure_node_access.sql`.
`vcore_clientless_node_access` erlaubt für jeden Node eine zusätzliche
`allowed_factions`-Maske mit gleicher Bedeutung wie bei Gebieten. NULL bedeutet
keine manuelle Einschränkung. Neue Nodes können über INSERT ergänzt werden.
Die Tabelle enthält initial alle vorhandenen Nodekeys.
Flugknoten werden bei jedem Reload automatisch einem Flugmeister im Umkreis von
100 Yards zugeordnet. Maßgeblich sind die Fraktionsvorlagen der NPCs und ihre
Feindseligkeit gegenüber Allianz/Horde; neutrale Flugmeister erlauben beide.
Unklare Zuordnungen bleiben gesperrt. `flightmaster_spawn_id` ermöglicht eine
explizite Zuordnung zu einem bestimmten NPC-Spawn innerhalb dieses Umkreises.
Manuelle Masken können native NPC-Freigaben weiter einschränken, nicht erweitern.
Die tatsächlich berechnete Maske ist im Diagnosebefehl als `nodeMask` sichtbar.
```sql
UPDATE vcore_clientless_node_access SET allowed_factions=1
WHERE node_key='mein_node';
```
Nach einer Änderung an Gebieten oder Nodes in der Serverkonsole:
```text
clientless adventure reload
clientless adventure area 26 taxi_11
```
Die Diagnose zeigt für den angegebenen Online-Bot das aufgelöste Gebiet,
Fraktionsmaske, Levelgrenze, Flugpräferenz, Nodefreigabe und Gesamterlaubnis.
Ohne Nodekey wird die aktuelle Position geprüft. Die Zahl26 ist hier nur ein
Beispiel für Arthoran; der Befehl funktioniert mit jedem Online-AdventureBot.
Gespeicherte Bodenwege und lokale MMAP-Wege werden an ihren Wegpunkten und
zusätzlich mit maximal40Yards Abstand geprüft. Flugtaxiwege berücksichtigen ihre
nativen Wegpunkte, freie Flüge ihre geplanten und tatsächlich gestarteten
Abschnitte. Virtuelle Graphverbindungen verwenden dieselben Prüfungen, auch bei
zwischengespeicherter Weggeometrie. Diese räumliche Abtastung ist keine mathematisch
lückenlose Prüfung jedes einzelnen Grenzpunkts. Schiffs-/Tiefenbahnfahrten prüfen
beide Haltestellen und Nodefreigaben statt einen Bodenweg quer durch das Meer.
## Bearbeitung ohne Neukompilierung
Beispiel: Gebiet und seine unmittelbar untergeordneten Gebiete ansehen:
```sql
SELECT * FROM vcore_adventure_area_catalog
WHERE area_id=5146 OR parent_area_id=5146;
```
Beispiel: Flugpräferenz und Leveltoleranz eines Gebiets bearbeiten:
```sql
UPDATE vcore_adventure_area_catalog
SET prefer_flight=1, max_level_gap=5, notes='Flugreisen bevorzugen'
WHERE area_id=616;
```
Nicht die generierte SQL-Datei erneut einspielen, um vorhandene Zeilen zu ändern:
`INSERT IGNORE` bewahrt absichtlich Betreiberanpassungen. Stattdessen gezielte
UPDATEs verwenden. Die alte Leveltabelle dient nur noch als Importquelle; der laufende Server
verwendet die Levelbereiche dieses Katalogs. Änderungen der alten Tabelle
werden nicht automatisch in diesen Katalog kopiert.
Die Ausgangsdaten lassen sich ohne DB-Verbindung reproduzieren:
```bash
python3 contrib/clientless/export_area_catalog.py /pfad/zu/dbc/deDE /tmp/area-catalog.sql
```