Für ein paar meiner AzerothCore-Module brauche ich Client-Patches. Wenn ich zum Beispiel neue Rasse/Klasse-Kombinationen wie Gnom-Priester freischalte, akzeptiert der Server sie zwar, aber der 3.3.5a-Client bietet sie im Charakter-Erstellungs-Bildschirm nur an, wenn ich ihm eine gepatchte CharBaseInfo.dbc unterschiebe. So ein Patch ist ein MPQ-Archiv, patch-*.MPQ, mit ein paar DBC-Dateien drin.
Das Reviewen von so einem Patch war jedes Mal die gleiche Fummelei: MPQ runterladen, mit einem Tool auspacken, die DBC in einen Viewer laden, von Hand mit der Standard-Version vergleichen. Für eine geänderte Zeile viel zu viel Handarbeit.
Was in so einem Patch steckt
MPQ ist Blizzards altes Archivformat, im Grunde ein Container mit Hash-Table und Block-Table. Interessant ist, was drin liegt: DBC-Dateien. Eine DBC ist eine simple Binär-Tabelle, fester Header, feste Record-Größe, ein String-Block am Ende. Kein Schema in der Datei selbst, man muss die Spalten kennen.
Die spannendste ist CharBaseInfo.dbc: eine winzige Tabelle aus Rasse-Byte und Klasse-Byte, die dem Client sagt, welche Kombinationen er zur Auswahl anbietet. CharStartOutfit.dbc hält die Startausrüstung pro Rasse, Klasse und Geschlecht. SkillRaceClassInfo.dbc ist die Tabelle hinter dem klassischen "Untoter Paladin kann keine Schwerter führen", sie vergibt Waffen- und Rüstungs-Skills je nach Rasse und Klasse.
Die Action
Also hab ich mir eine GitHub Action gebaut, die genau diesen Weg automatisiert. Sie schaut, welche .MPQ-Dateien ein Pull Request ändert, öffnet sie, liest das Datei-Manifest und decodiert die bekannten DBCs. Das Ergebnis kommt als Markdown-Sticky-Kommentar zurück an den PR.
Der Trick, der es nützlich macht, ist der Diff: die decodierte CharBaseInfo wird gegen die Standard-WotLK-Matrix gehalten, neu freigeschaltete Kombos werden also direkt hervorgehoben, statt dass ich hundert Zeilen von Hand vergleiche. Item-IDs aus dem StartOutfit verlinken auf Wowhead, damit man sofort sieht, was da als Startgear rauskommt.
So bindet man es ein
Man legt eine Workflow-Datei ins Repo, das die MPQ-Patches bekommt:
name: Inspect MPQ patches on: pull_request_target: types: [opened, synchronize, reopened] paths: ["**/*.MPQ", "**/*.mpq"] permissions: contents: read pull-requests: write jobs: inspect: runs-on: ubuntu-latest steps: - uses: maluramichael/mpq-inspect-action@main with: pr-number: ${{ github.event.pull_request.number }}
Kein actions/checkout nötig, die Action zieht sich nur die geänderten MPQ-Blobs über die GitHub-API. pull_request_target statt pull_request deshalb, weil Fork-PRs sonst nur ein Read-only-Token bekommen und die Action gar nicht kommentieren könnte. Sicher ist das hier, weil nie Code aus dem PR ausgecheckt oder ausgeführt wird, es werden ausschließlich die .MPQ-Dateien als Daten geparst.
Liegt auf dem GitHub Marketplace, Code und Projekt-Seite gibt es unter mpq-inspect-action.