Files
OpenFUT/fifa17-recon/docker/fifa17-python/tools/fut_accounts.py
T
root 70a64e3709 fifa17-python: commit working FUT backend deployment (client/server split)
Freeze the running offline FUT backend into version control as
fifa17-recon/docker/fifa17-python/ - declarative and rebuildable from a
fresh checkout:

* OPENFUT_BIND / OPENFUT_ADVERTISE client/server split in the responders
  (lsx, blaze, roster, utas, pow) + entrypoint.sh; OPENFUT_ADVERTISE is
  required for remote mode (compose and entrypoint fail without it)
* docker-compose.yml reproducing the frozen baseline container exactly
  (env, ports incl. the 8085->8080 POW-content remap, /state bind, restart)
* .env.example / .env for site config - the LAN IP is never hardcoded in source
* tools/ + data/ staged from openfut-fut-backend:python-baseline-2026-08-10,
  verified byte-identical to the running container at freeze time
* client_arm.sh (the 105 client-side arming counterpart)
* Dockerfile bakes /app/SHA256SUMS.txt so any image is self-identifying
* docs/BASELINE-python-2026-08-10.md: frozen image/container/hash record,
  restore instructions and rebuild-equivalence procedure

Secrets (redir key/cert, .env) and runtime state (docker/state) stay gitignored.
The live container is untouched pending the .105 launcher audit.
2026-08-10 23:54:04 +00:00

71 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Launcher-to-server active-account selection for the single-player stack."""
import json
import os
from fut_account import ACCOUNT
from fut_store import STORE, profile_path_for
def _existing_identity(persona_id):
path = profile_path_for(persona_id)
try:
with open(path) as f:
profile = json.load(f)
except (OSError, ValueError):
return {}
if not isinstance(profile, dict):
return {}
return {
"club_name": profile.get("clubName"),
"club_abbr": profile.get("clubAbbr"),
"established": profile.get("established"),
"pow_level": profile.get("powLevel"),
"pow_exp": profile.get("powExp"),
"pow_exp_max": profile.get("powExpMax"),
"pow_funds": profile.get("powFunds"),
"pow_funds_cap": profile.get("powFundsCap"),
}
def activate(payload):
"""Select/create one persistent profile and publish it to all responders."""
if not isinstance(payload, dict):
raise ValueError("account payload must be an object")
try:
persona_id = int(payload.get("personaId"))
except (TypeError, ValueError):
raise ValueError("personaId must be a positive integer") from None
persona_name = payload.get("personaName")
if persona_id <= 0 or not isinstance(persona_name, str) or not persona_name.strip():
raise ValueError("personaId must be positive and personaName must not be empty")
values = _existing_identity(persona_id)
values.update(persona_id=persona_id, persona_name=persona_name.strip())
for wire, field in (("clubName", "club_name"), ("clubAbbr", "club_abbr"),
("established", "established"), ("squadName", "squad_name"),
("level", "pow_level"), ("experience", "pow_exp"),
("experienceMax", "pow_exp_max"), ("accountFunds", "pow_funds"),
("accountFundsCap", "pow_funds_cap")):
if payload.get(wire) not in (None, ""):
values[field] = payload[wire]
ACCOUNT.replace(values)
ACCOUNT.set_online_profile()
ACCOUNT.save()
profile = STORE.select_account(persona_id)
STORE.ensure_security_question()
return {
"personaId": ACCOUNT.persona_id,
"personaName": ACCOUNT.persona_name,
"clubName": ACCOUNT.club_name,
"clubAbbr": ACCOUNT.club_abbr,
"level": ACCOUNT.pow_level,
"experience": ACCOUNT.pow_exp,
"experienceMax": ACCOUNT.pow_exp_max,
"accountFunds": ACCOUNT.pow_funds,
"accountFundsCap": ACCOUNT.pow_funds_cap,
"profilePath": os.path.relpath(STORE.path, os.path.dirname(ACCOUNT.path)),
"coins": profile.get("coins", 0),
"unopenedPacks": len(profile.get("unopenedPackIds", [])),
}