Wer in Path of Exile 2 ernsthaft handelt, landet früher oder später bei einer Browser-Erweiterung für die Trade-Seite. Better Trading, TradeUX und ein Dutzend andere bringen Lesezeichen, Verlauf, Preise in Divine und eine bessere Ansicht. Fast alle gibt es nur für Chrome. Ich benutze Firefox und hatte keine Lust, für das Handeln den Browser zu wechseln. Also habe ich mir das Ganze als Userscript gebaut: PoE2 Trade Monkey. Es läuft in Violentmonkey und damit in jedem Browser, der Erweiterungen kann.

Was es kann
Rechts sitzt eine Seitenleiste im Look der Trade-Seite. Darin liegen Lesezeichen in Ordnern mit Währungs- oder Aszendenz-Icons, ein Verlauf der letzten Suchen und angepinnte Items. Im Formular gibt es eine Schnellfilter-Leiste für die Dinge, die man ständig braucht: verderbt, brüchig, entweiht, Gegenstandsstufe, Qualität, Seltenheit. Sie bleibt zusammen mit Suchen und Leeren unten am Bildschirm kleben, während man durch die Filter scrollt.
In den Ergebnissen werden die Mods hervorgehoben, nach denen man filtert. Neben jeder Mod gibt es ein Plus und ein Minus, die sie als Filter übernehmen oder ausschließen. Gleiche Angebote vom selben Verkäufer zum selben Preis werden zusammengefasst, und unter jedem Preis steht der Gegenwert in Divine oder Exalted, gerechnet mit den Kursen von poe.ninja. Jede Funktion lässt sich einzeln abschalten.

Lesezeichen, die in jeder neuen Liga funktionieren
Der eigentliche Grund für das Projekt: Ich will meine Suchen einmal anlegen und in der nächsten Liga einfach wieder anklicken. Bei Better Trading verfielen gespeicherte Suchen nach ein paar Wochen, weil sich die Erweiterung nur eine kurze Such-ID merkte, die GGG irgendwann wegräumt.
Beim Untersuchen der Seite stellte sich heraus, dass trade2 das inzwischen anders macht. Die Such-ID in der URL ist die komplette Suche selbst: das JSON der Anfrage, gzip-komprimiert und base64-kodiert. Die Liga steckt nicht drin. Dieselbe ID öffnet in Standard, in Runes of Aldur oder in Forbidden Rites exakt dieselbe Suche. Ein Lesezeichen speichert deshalb nur noch Typ und ID, und beim Öffnen setzt das Skript die Liga ein, in der man gerade spielt. Weil sich die Suche aus der ID zurückrechnen lässt, kann es außerdem prüfen, ob alle Stats der Suche in der aktuellen Liga noch existieren.

Gepinnte Items merken sich ebenfalls ihre Suche. Wer nach dem Anpinnen weitergesucht hat, kommt über einen Klick zurück zu der Suche, aus der das Item stammt.

Wie es unter der Haube aussieht
Die Trade-Seite besteht aus zwei Welten. Das Suchformular ist eine Vue-2-App mit Vuex, die Ergebnisliste eine eigene Vue-3-App. Ein Userscript läuft in einer Sandbox und kommt an den Zustand der Seite nur über Umwege heran, in Firefox zusätzlich hinter sogenannten Xray-Wrappern. Deshalb schleust das Skript beim Laden ein kleines Stück Code direkt in die Seite. Das hört mit, welche Suchen die Seite abschickt und welche Ergebnisse sie lädt, und kann Vuex-Mutationen ausführen. Wenn das Plus an einer Mod einen Filter setzt, passiert das über genau die Mutation, die auch das Formular selbst benutzt. Das ist unabhängig von der Sprache der Seite und robuster als in Dropdowns zu tippen.
Wichtig war mir, dass das Skript nichts tut, was man nicht selbst getan hätte. Es schickt keine eigenen Suchen ab, fragt die Trade-API nicht im Hintergrund ab und klickt nie auf Flüstern oder "Travel to Hideout". Es arbeitet nur mit den Daten, die die Seite sowieso lädt.
Gebaut mit Agenten, getestet ohne Cloudflare
Gebaut habe ich es an einem Tag zusammen mit Claude Code. Am Anfang standen vier Recherche-Agenten, die Better Trading, TradeUX, alle anderen Trade-Tools und die Technik der Seite auseinandergenommen haben. Danach habe ich das Fundament selbst festgelegt und die dreizehn Funktionen in zwei Wellen von je fünf Agenten bauen lassen, jeder in seinem eigenen Ordner, damit sich niemand gegenseitig die Dateien überschreibt.
Die größte Hürde war nicht der Code, sondern Cloudflare. Die Trade-Seite braucht einen Login und blockt automatisierte Browser. Ich habe deshalb ein normales Chrome mit eigenem Profil gestartet, mich eingeloggt und Playwright nur per Debug-Port angehängt. Das ging gut, bis ich nach zu vielen Neuladern in kurzer Zeit in einer immer längeren Cloudflare-Prüfung festhing. Seitdem läuft fast alles gegen einen Nachbau der Seite: die echten API-Antworten und das echte CSS vom CDN, nur der Server fehlt. Darauf laufen die Playwright-Tests und die Screenshots für Design-Änderungen, die echte Seite brauche ich nur noch für einen kurzen Durchgang zum Schluss.
Installieren
Violentmonkey für Firefox installieren, dann das Skript öffnen und bestätigen. Updates kommen von allein. Der Code liegt unter MIT-Lizenz auf GitHub.
Für die Kampagne habe ich übrigens auch etwas gebaut: Der PoE2-Speedrun-Guide ist eine Checkliste für das Tablet neben dem Spiel, mit Akt-Zeiten, allen Quests und einem Nachschlage-Teil.