#!/usr/bin/env python3 """Core snapshot around a consumable APPLY: coins, ownership, the source consumable's copies, and the target's mutable state. Run before and after. A player-contract apply must move EXACTLY three things: the source consumable loses one copy, the target's `contract` rises to min(99, before + grant), and nothing else — coins in particular must not move, because an apply is not an economy credit. Everything else in this snapshot is here to prove it stayed put. (Superseded for acceptance by fifa17-contract-apply-validate.py, which asserts the deltas itself; this remains the raw before/after dump for eyeballing.)""" import json import sys import urllib.request H = {"X-OpenFUT-Game": "fifa17"} SOURCE_RES = 5001004 TARGET_WIRE = 100000003 def get(p): req = urllib.request.Request("http://127.0.0.1:8299" + p, headers=H) with urllib.request.urlopen(req, timeout=30) as r: return json.loads(r.read()) snap = {} import sqlite3 con = sqlite3.connect("file:/home/alex/openfut-sold-staging/staging-core.db?mode=ro", uri=True) snap["coins"] = con.execute("SELECT coins FROM clubs LIMIT 1").fetchone()[0] snap["owned_rows"] = con.execute("SELECT COUNT(*) FROM owned_cards").fetchone()[0] snap["by_kind"] = dict(con.execute("SELECT content_kind, COUNT(*) FROM owned_cards GROUP BY 1")) con.close() cons = get("/ut/game/fifa17/club/consumables/development") stacks = cons.get("itemData") or [] snap["development_stacks"] = len(stacks) snap["development_copies"] = sum(s.get("count", 0) for s in stacks) snap["source_stack"] = next( ({"count": s.get("count"), "resourceId": s.get("resourceId")} for s in stacks if s.get("resourceId") == SOURCE_RES), None) sq = get("/ut/game/fifa17/squad/0") players = (sq.get("squad") or sq).get("players") or [] for p in players: it = p.get("itemData") or {} if it.get("id") == TARGET_WIRE: snap["target"] = { "resourceId": it.get("resourceId"), "rating": it.get("rating"), "contract": it.get("contract"), "fitness": it.get("fitness"), "injuryType": it.get("injuryType"), "training": it.get("training"), "playStyle": it.get("playStyle"), "preferredPosition": it.get("preferredPosition"), } break print(json.dumps(snap, indent=2, sort_keys=True)) if len(sys.argv) > 1: open(sys.argv[1], "w").write(json.dumps(snap, sort_keys=True))