4.1 KiB
Einheiten: backend/tft/matches/extract.py
stand: f41ac76b57
backend/tft/matches/extract.py::patch_of
beschreibung: Leitet den zweistelligen Versions-Patch (z. B. „16.14") aus einem beliebigen game_version-String ab.
input: Ein game_version-String mit beliebigen Präfixen oder Trennzeichen.
output: Der Patch-Anteil als String der Form „x.y".
entscheidungen:
- Iteriert über Tokens statt blind zu splitten, um an einen tatsächlichen
x.y-Token zu gelangen. beleg: "for token in game_version.replace("(", " ").split():" - Übernimmt nur die ersten beiden Punkt-Segmente und ignoriert alles dahinter. beleg: "return ".".join(digits.split(".")[:2])"
- Bevorzugt ein gefundes numerisches Token gegenüber dem Fallback auf das letzte whitespace-getrennte Wort. beleg: "digits = token" kanten:
- wird-genutzt-von: backend/tft/matches/extract.py::extract_match
backend/tft/matches/extract.py::extract_match
beschreibung: Überführt ein einzelnes rohes Match-Diktat in eine Liste von Endboard-Zeilen, indem es pro Teilnehmer die relevanten Felder in ein Tupel schreibt.
input: Ein match-Dictionary gemäß Riot-Match-Schema.
output: Eine Liste von Tupeln mit Match-ID, PUUID, Set-Nummer, Patch, Platzierung, Level, letzter Runde, Restgold und JSON-serialisierten Units/Traits/Augments.
entscheidungen:
- Serialisiert verschachtelte Strukturen (Units, Traits, Augments) vor dem Schreiben als JSON-String, um eine flache Tupel-Form zu behalten. beleg: "json.dumps(p["units"]),"
- Liefert bei fehlendem
augments-Feld eine leere Liste statt einen Fehler. beleg: "json.dumps(p.get("augments", []))," - Bezieht den Patch je Match zentral aus
infound nicht pro Teilnehmer neu berechnet. beleg: "patch = patch_of(info["game_version"])" kanten: - ruft-auf: backend/tft/matches/extract.py::patch_of
- wird-genutzt-von: backend/tft/matches/extract.py::extract_all
backend/tft/matches/extract.py::validate_ids
beschreibung: Zählt in den Endboard-Zeilen IDs (Units, Items, Traits, Augments), die nicht in den statischen Daten vorkommen, als Patch-Drift-Kanarienvogel.
input: Eine Liste von Endboard-Zeilen-Tupeln und ein static-Dictionary mit bekannten IDs.
output: Ein Counter mit Präfix-Schlüsseln unit:, item:, trait: und augment:, das unbekannte IDs samt Häufigkeit führt.
entscheidungen:
- Filtert Unit-Drift um erwartbar unbekannte Beschwörungen/PvE-Einheiten anhand von Namenshinweisen heraus. beleg: "if not any(h in api.lower() for h in BENIGN_UNIT_HINTS):"
- Vereinigt Items und Augments zu einem einzigen
known_items-Set, um Doppellookups zu vermeiden. beleg: "known_items = set(static["items"]) | set(static["augments"])" - Zählt bei Items nur Drift, wenn das Item dem aktuellen Set oder dem generischen
TFT_Item_-Schema angehört. beleg: "if item.startswith("TFT_Item_") or item.startswith(set_prefix):" kanten: - nutzt: backend/tft/matches/extract.py::BENIGN_UNIT_HINTS
- wird-genutzt-von: backend/tft/matches/extract.py::extract_all
backend/tft/matches/extract.py::extract_all
beschreibung: Liest alle noch nicht verarbeiteten Roh-Matches aus der Datenbank, extrahiert ihre Endboard-Zeilen, prüft sie gegen die statischen Daten und schreibt sie persistent in die endboards-Tabelle.
input: Eine geöffnete DB-connection mit Schema matches/endboards und ein static-Dictionary mit bekannten IDs.
output: Ein Tupel (n, total_unknown) mit Anzahl geschriebener Zeilen und aggregiertem Drift-Counter.
entscheidungen:
- Selektiert nur Matches, deren
match_idnoch nicht inendboardsvorkommt, um Doppelverarbeitung zu vermeiden. beleg: "SELECT raw FROM matches WHERE match_id NOT IN (SELECT DISTINCT match_id FROM endboards)" - Verwendet
INSERT OR IGNORE, damit Wiederholungsläufe keine Duplikatfehler erzeugen. beleg: ""INSERT OR IGNORE INTO endboards VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"" - Sammelt Drift in einem einzigen Counter statt pro Match, damit das Endergebnis meldbar bleibt. beleg: "total_unknown.update(validate_ids(rows, static))" kanten:
- ruft-auf: backend/tft/matches/extract.py::extract_match
- ruft-auf: backend/tft/matches/extract.py::validate_ids