docs: add FLE bridge direction pivot and squad-injection test tooling

Adds the app-centric FLE bridge direction (direction.md) replacing the
Blaze-backend route as primary plan, plus a corrected foundational test
procedure and snapshot/diff/apply tooling for reverse-engineering FLE's
Freeze Lineup write mechanism. Also picks up prior untracked research docs
(status-review, fut-integration-options, fifa23-startup-flow, track-c) and
existing capture/export tooling that hadn't been committed yet.
This commit is contained in:
funman300
2026-06-30 13:19:27 -07:00
parent cbb9ea49ab
commit 1fb664710a
15 changed files with 2060 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""Diff two openfut_snapshot_*.json files from snapshot_lineup_tables.lua.
Usage: diff_snapshots.py before.json after.json
Reports, per table, which rows changed and which fields differed —
this is how the real DB write behind FLE's "Freeze Lineup" GUI feature
gets discovered (see docs/foundational-xi-injection-test.md).
"""
import json
import sys
def row_key(row):
for candidate in ("playerid", "player_id", "id", "rowid"):
if candidate in row:
return row[candidate]
return json.dumps(row, sort_keys=True)
def diff_table(name, before, after):
before_rows = {row_key(r): r for r in before.get("rows", [])}
after_rows = {row_key(r): r for r in after.get("rows", [])}
changes = []
for key, after_row in after_rows.items():
before_row = before_rows.get(key)
if before_row is None:
changes.append({"row": key, "type": "added", "row_data": after_row})
continue
field_diffs = {}
for field in set(before_row) | set(after_row):
bval = before_row.get(field)
aval = after_row.get(field)
if bval != aval:
field_diffs[field] = {"before": bval, "after": aval}
if field_diffs:
changes.append({"row": key, "type": "modified", "fields": field_diffs})
for key in before_rows:
if key not in after_rows:
changes.append({"row": key, "type": "removed"})
if changes:
print(f"\n=== {name}: {len(changes)} changed row(s) ===")
for c in changes:
print(json.dumps(c, indent=2))
def main():
if len(sys.argv) != 3:
print(__doc__)
sys.exit(1)
with open(sys.argv[1]) as f:
before = json.load(f)
with open(sys.argv[2]) as f:
after = json.load(f)
table_names = set(before.get("tables", {})) | set(after.get("tables", {}))
any_changes = False
for name in sorted(table_names):
b = before.get("tables", {}).get(name, {"rows": []})
a = after.get("tables", {}).get(name, {"rows": []})
before_len = len(b.get("rows", []))
after_len = len(a.get("rows", []))
if before_len != after_len:
print(f"{name}: row count changed {before_len} -> {after_len}")
any_changes = True
diff_table(name, b, a)
if not any_changes:
print("(row-count-only check found no differences; per-field diffs above are authoritative)")
if __name__ == "__main__":
main()