Files
OpenFUT/tools/squad-exporter/export_squad.lua
T
funman300 1fb664710a 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.
2026-06-30 13:19:27 -07:00

134 lines
5.1 KiB
Lua

-- squad-exporter/export_squad.lua
-- FIFA Live Editor Lua script (v2 API).
-- Run from FLE's Lua Engine while in-game to export squad/FUT-relevant
-- database table data to JSON in the FIFA 23 Live Editor directory.
--
-- Exports:
-- players table (id, name, overall, potential, position, team)
-- teams table (id, name, league, budget)
-- fut_items table (if present in memory — only when FUT is loaded)
--
-- Output: C:\FIFA 23 Live Editor\openfut_squad_export.json
local OUT_PATH = "C:\\FIFA 23 Live Editor\\openfut_squad_export.json"
-- Minimal JSON serialiser (no external deps)
local function json_val(v)
local t = type(v)
if t == "nil" then return "null"
elseif t == "boolean" then return tostring(v)
elseif t == "number" then
if v ~= v then return "null" end -- NaN
return string.format("%.6g", v)
elseif t == "string" then
return '"' .. v:gsub('\\', '\\\\'):gsub('"', '\\"'):gsub('\n','\\n') .. '"'
elseif t == "table" then
-- array check: sequential integer keys starting at 1
local n = #v
local is_arr = n > 0
if is_arr then
local parts = {}
for i=1,n do parts[i] = json_val(v[i]) end
return "[" .. table.concat(parts, ",") .. "]"
else
local parts = {}
for k,vv in pairs(v) do
parts[#parts+1] = json_val(tostring(k)) .. ":" .. json_val(vv)
end
return "{" .. table.concat(parts, ",") .. "}"
end
end
return "null"
end
local function export_table(tbl_name, fields)
local rows = GetDBTableRows(tbl_name)
if not rows or #rows == 0 then
Log("[squad-exporter] table '" .. tbl_name .. "': empty or not found")
return {}
end
Log("[squad-exporter] table '" .. tbl_name .. "': " .. #rows .. " rows")
local out = {}
for _, row in ipairs(rows) do
local rec = {}
for _, f in ipairs(fields) do
local cell = row[f]
if cell then
rec[f] = cell.value
end
end
out[#out+1] = rec
end
return out
end
-- ── Export players ────────────────────────────────────────────────────────────
local players = export_table("players", {
"playerid", "overallrating", "potential", "preferredposition1",
"height", "weight", "birthdate", "nationality", "skillmoves",
"weakfootabilitytypecode", "attackingworkrate", "defensiveworkrate",
})
-- Enrich with names (GetPlayerName is an FLE function)
for _, p in ipairs(players) do
local pid = p.playerid
if pid then
local ok, name = pcall(GetPlayerName, math.floor(pid))
if ok and name then p.name = name end
local ok2, tid = pcall(GetTeamIdFromPlayerId, math.floor(pid))
if ok2 and tid then
p.teamid = tid
local ok3, tname = pcall(GetTeamName, tid)
if ok3 then p.teamname = tname end
end
end
end
-- ── Export teams ─────────────────────────────────────────────────────────────
local teams = export_table("teams", {
"teamid", "leagueid", "teamcolor1r", "teamcolor1g", "teamcolor1b",
"stadiumid", "domesticprestige", "internationalprestige",
"transferbudget", "wagebudget",
})
for _, t in ipairs(teams) do
local ok, name = pcall(GetTeamName, math.floor(t.teamid or 0))
if ok then t.name = name end
end
-- ── Export FUT tables if available ───────────────────────────────────────────
-- These tables are only in memory when FUT mode is active.
local fut_tables = {}
local all_table_names = GetDBTablesNames()
for _, tname in ipairs(all_table_names) do
local lower = tname:lower()
if lower:find("fut") or lower:find("club") or lower:find("pack")
or lower:find("item") or lower:find("market") then
Log("[squad-exporter] found FUT-related table: " .. tname)
fut_tables[tname] = export_table(tname, GetDBTableFields(tname) or {})
end
end
-- ── Write output ─────────────────────────────────────────────────────────────
local payload = {
exported_at = os.date("!%Y-%m-%dT%H:%M:%SZ"),
is_career_mode = IsInCM(),
player_count = #players,
team_count = #teams,
players = players,
teams = teams,
fut_tables = fut_tables,
all_db_tables = all_table_names,
}
local f = io.open(OUT_PATH, "w")
if f then
f:write(json_val(payload))
f:close()
Log("[squad-exporter] Written to " .. OUT_PATH)
MessageBox("OpenFUT Squad Export", "Done! " .. #players .. " players, "
.. #teams .. " teams.\n" .. OUT_PATH)
else
Log("[squad-exporter] ERROR: could not open " .. OUT_PATH)
MessageBox("OpenFUT Squad Export", "ERROR writing to " .. OUT_PATH)
end