Files
OpenFUT/fifa17-recon/tools/fifadrive.sh
T
funman300 6ddd5e9d47 fifa17-recon: offline FUT squad-shell working + full card-system RE
Milestone: FIFA 17 Ultimate Team boots end-to-end on our offline backend
past every EA gate into the hub and a live Squads editor (correct 4-4-2,
5-star squad, no freezes).

Key findings this session:
- userMassInfo MUST stay {} (any content desyncs the massinfo parser
  0x180174630 -> tokenizer busy-loop freeze). Deliver the squad via
  GET /squad/0 (fetched on Squads-tab entry) instead.
- Player cards render generic because the card view-model (0x1800d7920)
  reads identity/rating/face from a resolved record at item+0x10, filled
  by a lookup (0x18011cca0) in the FUT item-definition std::map at
  CardsDb+0x160c0 -- which is EMPTY offline -> default blank record.
- Version advertising (itemDbVersion/checkServerDbVersion) is proven inert
  (JSON fields routed to the skip handler). Owned items don't auto-trigger
  a definition fetch. In-place map overwrite is dead (map stays empty).
- Definition-serving endpoints (item/resource, defid, item?idList) built +
  ready; the fetch trigger lives in the packed FIFA17.exe.

New: docs/CARD_SYSTEM.md (findings + ordered next-steps plan for real
player cards: patch-POC, dbdata extractor, drive FIFA17.exe fetch, or
live-memory store injection). Plus tools: fut_seed.py (squad ladder +
definition serving), fifadrive.sh, vgamepad.py, and the login-RE toolset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PN5bmpDVQR1aXgefyWAt7o
2026-08-01 20:24:30 -07:00

70 lines
3.3 KiB
Bash

#!/usr/bin/env bash
# ============================================================================
# fifadrive.sh — drive & observe FIFA 17's menu from a shell (OpenFUT recon)
#
# FIFA 17 runs under Proton as an XWayland client. XWayland accepts X11
# synthetic input (XTEST, via xdotool) and per-window capture (XGetImage, via
# ImageMagick `import`). So we can navigate the menus and screenshot the result
# entirely headless — no manual relaunch/navigation per test.
#
# ./fifadrive.sh wid print the FIFA window id (empty if not up)
# ./fifadrive.sh focus raise + focus the FIFA window
# ./fifadrive.sh shot [name] capture FIFA window -> screens/<name>.png (print path)
# ./fifadrive.sh key <keys...> focus, then send key(s) e.g. key Right Right Return
# ./fifadrive.sh hold <key> <ms> press-and-hold a key for <ms> (menus that need a beat)
# ./fifadrive.sh type <text...> focus, then type literal text (e.g. security answer)
# ./fifadrive.sh launch (re)launch FIFA via ~/Desktop/launch-fifa17.sh
# ./fifadrive.sh wait <secs> poll until the FIFA window appears (after launch)
#
# XTEST injects to the FOCUSED window, so every input auto-focuses FIFA first.
# The higher-level "read the screenshot and decide the next key" step is done by
# the operator (Claude Reads the PNG) — this script only provides the primitives.
# ============================================================================
set -uo pipefail
export DISPLAY="${DISPLAY:-:0}"
HERE="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
SCREENS="${FIFADRIVE_SCREENS:-$HERE/../.screens}"
TITLE='^FIFA 17$'
LAUNCH="$HOME/Desktop/launch-fifa17.sh"
wid() { xdotool search --name "$TITLE" 2>/dev/null | head -1; }
need_wid() {
local w; w=$(wid)
[ -n "$w" ] || { echo "!! FIFA window not found (is the game running?)" >&2; exit 3; }
printf '%s' "$w"
}
focus() {
local w; w=$(need_wid)
xdotool windowactivate --sync "$w" 2>/dev/null
# tiny settle so the compositor finishes the focus switch before we inject
perl -e 'select(undef,undef,undef,0.20)' 2>/dev/null || sleep 1
}
shot() {
local w name out; w=$(need_wid); name="${1:-shot}"
mkdir -p "$SCREENS"
out="$SCREENS/${name}.png"
import -window "$w" "$out" 2>/dev/null || { echo "!! capture failed" >&2; exit 4; }
echo "$out"
}
case "${1:-}" in
wid) wid; echo ;;
focus) focus; echo "focused: $(xdotool getactivewindow getwindowname 2>/dev/null)" ;;
shot) shift; shot "${1:-shot}" ;;
key) shift; focus; xdotool key --clearmodifiers "$@"; echo "sent: $*" ;;
hold) shift; focus; k="$1"; ms="${2:-300}"
xdotool keydown --clearmodifiers "$k"; perl -e "select(undef,undef,undef,$ms/1000)" 2>/dev/null || sleep 1
xdotool keyup --clearmodifiers "$k"; echo "held: $k ${ms}ms" ;;
type) shift; focus; xdotool type --clearmodifiers -- "$*"; echo "typed: $*" ;;
launch) [ -x "$LAUNCH" ] || { echo "!! no launch script at $LAUNCH" >&2; exit 5; }
setsid bash -c "exec '$LAUNCH'" </dev/null >/tmp/fifa_launch.log 2>&1 & disown
echo "launched (log: /tmp/fifa_launch.log)" ;;
wait) shift; secs="${1:-60}"; i=0
while [ $i -lt "$secs" ]; do [ -n "$(wid)" ] && { echo "FIFA window up (${i}s)"; exit 0; }; sleep 1; i=$((i+1)); done
echo "!! FIFA window did not appear in ${secs}s" >&2; exit 6 ;;
*) sed -n '2,32p' "$0"; exit 1 ;;
esac