d71234b03d
AGENTS.md is the new canonical AI-agent entry point (FIFA17 active target, repo map, FIFA23->FIFA17 pivot history). README/CLAUDE/setup.sh get stale banners pointing to it. Retained pre-existing WIP brought forward.
164 lines
9.7 KiB
Markdown
164 lines
9.7 KiB
Markdown
# AGENTS.md — OpenFUT
|
|
|
|
**Read this first.** It is the entry point for AI-assisted work on OpenFUT. It supersedes the
|
|
root `README.md` and `CLAUDE.md`, which are **stale** (they describe an earlier FIFA 23 plan).
|
|
|
|
## Project
|
|
|
|
OpenFUT is a preservation / private-server project that restores **offline, single-player FIFA
|
|
Ultimate Team (FUT)** after EA retired the online servers. You must own the game legitimately; the
|
|
project does not bypass ownership checks — it only re-serves the dead online services locally.
|
|
|
|
**Current active target: FIFA 17 (PC).** A clean-room emulation of the full online + FUT stack
|
|
was proven working end-to-end on **2026-08-01** (auth → Blaze login → device-trust → FUT hub).
|
|
This lives in `fifa17-recon/`. The FIFA 17 work is explicitly the **Rosetta Stone for FIFA 23**
|
|
(identical Blaze/LSX/UTAS wire format), so FIFA 23 remains the eventual second target.
|
|
|
|
Three moving parts, kept strictly separate:
|
|
- **The FIFA client** — the retail game (FIFA 17 now). Unmodified except live cert-verify patches.
|
|
- **The emulation layer** — Python responders in `fifa17-recon/tools/` (LSX, Blaze, UTAS, roster)
|
|
that impersonate EA's online services on localhost. This is where all reverse engineering lives.
|
|
- **OpenFUT Core** — a game-independent REST FUT economy backend (`openfut-core/`), feature-complete
|
|
and tested. Knows nothing about FIFA. Intended to eventually back the emulation layer's FUT data.
|
|
|
|
> The emulation layer and Core are **not yet wired together.** The FIFA 17 UTAS server currently
|
|
> serves its own hardcoded/JSON payloads, not Core's API. See `docs/PROJECT_STATE.md`.
|
|
|
|
## Repository map
|
|
|
|
Monorepo. `openfut-core`, `openfut-bridge`, `openfut-launcher`, `fifa-blaze` are **git submodules**
|
|
(each with independent history — use `tea`/Gitea, not `gh`). `fifa17-recon/` is a plain directory.
|
|
|
|
| Path | What it is | Status |
|
|
|---|---|---|
|
|
| `fifa17-recon/` | **The live path.** FIFA 17 offline FUT emulation: Python responders, cert patcher, runbook, RE write-ups. | Working |
|
|
| `openfut-core/` | Rust (Axum + SQLite) FUT economy backend. Game-independent REST API. | Working, tested |
|
|
| `openfut-bridge/` | Rust FIFA 23 in-process hook / proxy RE effort. | Blocked (see below) |
|
|
| `fifa-blaze/` | Rust Blaze protocol emulator scaffold for FIFA 23 (capture stub). | Milestone 1 stub |
|
|
| `openfut-launcher/` | Rust egui/eframe desktop launcher (targets FIFA 23 hook flow). | Legacy plan |
|
|
| `docs/` | **Mirrors** of the vault (`OpenFUT-Vault`), which is canonical. Direction pivots + context. | — |
|
|
| `tools/` | Host-side RE helpers (file-watch-diff, exporters, squad-injector) from the FLE-bridge idea. | Legacy plan |
|
|
| `setup.sh` | FIFA 23 full-stack orchestrator (core+bridge). | Legacy plan |
|
|
|
|
**Legacy vs live:** the project pivoted twice — (1) FIFA 23 Blaze backend → (2) FIFA 23 as a match
|
|
renderer driven by an FLE Lua bridge (`docs/direction.md`) → (3) **FIFA 17 full online emulation,
|
|
which succeeded and is now the primary path** (`fifa17-recon/`). Treat `openfut-bridge`,
|
|
`openfut-launcher`, `fifa-blaze`, `tools/`, `setup.sh`, and `docs/direction.md` as historical unless
|
|
a task explicitly targets the FIFA 23 port.
|
|
|
|
## Architecture (live path)
|
|
|
|
```
|
|
FIFA 17 client (Wine/Proton, base 0x140000000)
|
|
│ autopatch.py NOPs two ProtoSSL cert-verify gates in /proc/PID/mem
|
|
├─ LSX 127.0.0.1:4216 → lsx_responder_v2.py (Origin login/profile/authcode)
|
|
├─ TLS 127.0.0.1:42127 → blaze_responder_v3b.py (Blaze redirector, via DNAT of 159.153.51.20)
|
|
├─ Blaze 42130 / Nucleus 42131 → blaze_responder_v3b.py (Fire2/Heat2 binary + login)
|
|
├─ easw.easports.com (→127.0.0.1) :8099 → utas_server.py (UTAS/RS4 FUT API + device-trust)
|
|
└─ roster :8081 → roster_server.py (FUT roster-update XML)
|
|
|
|
OpenFUT Core (openfut-core, :8080) ── clean REST FUT economy ── NOT YET CONNECTED to the above
|
|
```
|
|
|
|
Host arming (`root_arm.sh` via `pkexec`, volatile across reboot): `ptrace_scope=0`,
|
|
`route_localnet=1`, iptables DNAT `159.153.51.20→127.0.0.1:42127`, `/etc/hosts easw.easports.com`.
|
|
|
|
## Development commands (verified)
|
|
|
|
**FIFA 17 emulation** (from `fifa17-recon/tools/`):
|
|
- Start everything (idempotent; re-run after reboot): `./openfut-fut.sh start`
|
|
- Status / stop / restart: `./openfut-fut.sh status | stop | restart`
|
|
- Then launch the game fresh (`~/Desktop/launch-fifa17.sh`) and pick Ultimate Team.
|
|
- Logs: `/tmp/{lsx,blaze,roster,utas,autopatch}.log`
|
|
- Full procedure + gate-ladder troubleshooting: `fifa17-recon/FUT-RUNBOOK.md`
|
|
|
|
**OpenFUT Core** (from `openfut-core/`): `cargo run` (creates `openfut.db`) · `cargo test`
|
|
(full in-memory integration suite; requires `data/`) · `cargo test <name>` for one ·
|
|
`cargo clippy -- -D warnings` · `cargo fmt`. Env: `LISTEN_ADDR` (127.0.0.1:8080), `DATABASE_URL`
|
|
(sqlite://openfut.db), `DATA_DIR` (data).
|
|
|
|
**Other Rust crates** (`openfut-bridge`, `fifa-blaze`, `openfut-launcher`): standard
|
|
`cargo run/build/test/clippy/fmt` from within each. `fifa-blaze` is a workspace (`--bin blaze-server`).
|
|
|
|
**CI:** only `openfut-core` has it (`.gitea/workflows/ci.yml`): `fmt --check`, `clippy -D warnings`,
|
|
`build --locked`, `test --locked` on push/PR to main. No CI on the other crates or the recon dir.
|
|
|
|
There is **no install step, no Docker, no JS/TS frontend, no typecheck** in this repo. Do not invent them.
|
|
|
|
## Coding conventions
|
|
|
|
- **Rust (Core):** Axum 0.7 + SQLx 0.7 (SQLite, compile-time-checked queries). Strict layering —
|
|
`routes/` (handlers, extract state, call services) → `services/` (own **all** DB access + logic)
|
|
→ `models/` (pure `Serde`/`FromRow` data). Errors via `AppError` (`src/error.rs`) with
|
|
`IntoResponse`. One file per domain across `routes/`, `services/`, `models/`. **Single-profile
|
|
design:** every service reads "the active profile" as the first DB row — intentional, don't
|
|
parameterize it. Content is data-driven: JSON under `data/` loaded at startup into Arc registries
|
|
in `AppState`. Add content by dropping JSON files, not code. Migrations are numbered SQL in
|
|
`migrations/`. Keep `clippy -D warnings` and `fmt` clean (CI enforces).
|
|
- **Python (recon):** stdlib-only servers, no framework. Each responder is a standalone script with
|
|
the reverse-engineered contract documented in its module docstring (byte offsets, VAs, symbol
|
|
names). When changing a responder, preserve byte-exactness — the client is the oracle.
|
|
- **Clean-room, always.** Every finding derives from binaries we own + live observation. **Never**
|
|
use, reference, or reproduce leaked EA source. If a task seems to need it, stop and say so.
|
|
|
|
## AI-agent rules
|
|
|
|
1. Read this file before exploring the repo.
|
|
2. Read the vault file relevant to the task (`../OpenFUT-Vault/`), not the whole tree. Repo
|
|
`docs/` files are mirrors of the vault — consult them for the same content, but treat the
|
|
vault as canonical.
|
|
3. Don't scan the whole repository unless the knowledge base is clearly stale — if you find it
|
|
stale, update the vault, then its repo `docs/` mirror.
|
|
4. Search the specific directory (`fifa17-recon/`, `openfut-core/src/<layer>/`) before a repo-wide search.
|
|
5. Update the vault when architecture materially changes (and sync the matching `docs/` mirror).
|
|
6. Don't refactor or rewrite unrelated working code.
|
|
7. Prefer small, testable changes; run the narrowest relevant test first (`cargo test <name>`).
|
|
8. **Never invent EA/FIFA/Blaze protocol behavior.** Values you don't know are `TODO/CONFIRM`, not
|
|
confident guesses. The live client is the only oracle for whether a gate is satisfied.
|
|
9. Clearly separate discovered behavior from hypotheses; record findings in
|
|
`../OpenFUT-Vault/02 Reverse Engineering/FIFA 17/Protocol Findings.md` under the right confidence
|
|
tier — never silently promote a hypothesis to a fact.
|
|
10. Root `README.md` / `CLAUDE.md` and `openfut-bridge/CLAUDE.md` describe superseded FIFA 23 plans;
|
|
prefer vault + repository evidence over them when they conflict.
|
|
|
|
## AI Session Bootstrap
|
|
|
|
Future agents should start with:
|
|
1. Read `AGENTS.md`.
|
|
2. Read the vault README (`../OpenFUT-Vault/README.md`) to locate the canonical files.
|
|
3. Identify the subsystem the task affects and read the corresponding vault file: Architecture,
|
|
Project State, Roadmap/Current Priorities, or Protocol Findings.
|
|
4. Inspect only the relevant source directories.
|
|
5. Check `../OpenFUT-Vault/02 Reverse Engineering/FIFA 17/Protocol Findings.md` before assuming
|
|
anything about FIFA/EA behavior.
|
|
6. Check `../OpenFUT-Vault/06 Agent Memory/Project State.md` before assuming a feature exists.
|
|
7. Implement the smallest coherent change.
|
|
8. Run the narrowest relevant tests.
|
|
9. Update the vault (and its repo `docs/` mirror) only if the change makes existing knowledge
|
|
inaccurate.
|
|
|
|
Do not reread the entire repository during every session.
|
|
|
|
## OpenFUT Knowledge Base
|
|
|
|
**The OpenFUT Vault is the canonical project knowledge base.** Repo `docs/` files mirror it; the
|
|
vault wins on any disagreement. Consult it before starting substantial work and update it after
|
|
durable discoveries.
|
|
|
|
Vault location: `../OpenFUT-Vault/` — start at `../OpenFUT-Vault/README.md`.
|
|
|
|
Canonical files:
|
|
- Dashboard: `00 Dashboard/OpenFUT.md`
|
|
- Architecture: `01 Architecture/Architecture.md` (repo mirror `docs/ARCHITECTURE.md`)
|
|
- RE findings: `02 Reverse Engineering/FIFA 17/Protocol Findings.md`
|
|
(repo mirror `docs/research/KNOWN_FINDINGS.md`)
|
|
- Direction history: `04 Decisions/Direction History.md`
|
|
- Project State: `06 Agent Memory/Project State.md` (repo mirror `docs/PROJECT_STATE.md`)
|
|
- Current Priorities: `06 Agent Memory/Current Priorities.md`
|
|
- Known Issues: `06 Agent Memory/Known Issues.md`
|
|
- Important Discoveries: `06 Agent Memory/Important Discoveries.md`
|
|
- Roadmap: `08 Roadmap/Roadmap.md` (repo mirror `docs/ROADMAP.md`)
|
|
|
|
When editing knowledge that exists in both places, edit the vault first, then update the matching
|
|
`docs/` mirror so they stay in sync.
|