kit probe: settle the ingest question in one restart; itemType alone did NOT fix it
RESULT OF THE PREVIOUS COMMIT, recorded before anything else: sending itemType on
cardtype-7 club items did NOT make them ingest. Client relaunched, ?type=kit
answered total=2 emitted=2 with itemType="kit" on both, and afterwards there is
still no cardtype-7 record resident and the hook still traces
KITS_AVAILABLE = 0. The player/staff-vs-kit/badge/stadium correlation was real
but it is NOT the cause. The field is kept because every real EA item in the
capture corpus carries it and the two ingesting families already did, but it is
now labelled wire fidelity, not a fix.
Also already refuted, so neither is the answer: ?type=equippables answered with a
kits-only body (kits stayed undefined), and the kit ids are correct - 6300006 and
6400003 are the real fcc_kitcards carddbids for team 21 home/away with matching
category 2/3 and year 0.
This adds OPENFUT_FIFA17_KIT_PROBE (default OFF, staging armed) which appends two
synthetic kits to ?type=kit so ONE client restart discriminates the two remaining
hypotheses instead of one restart each:
6300007 MINIMAL - exactly the field set a STAFF item carries, which is known to
ingest, plus cardsubtypeid 9. If only this appears, one of the kit-only
extras (assetId, cardassetid, teamid, category, year) makes the client
discard the item.
6300008 NAMED - full kit shape plus name/localizedName/description, the three
fields the cardtype-7 parse arm is documented to copy and which OpenFUT has
never sent. If only this appears, they are required, not optional.
If NEITHER appears, ?type=kit is not the route that populates the collection
FUN_1800d73d0 scans, and the search moves to which route does.
Both ids are real team-21 carddbids, served free so they cannot disturb the
active-kit assignment, with instance ids outside Core's range. Two items in one
family: the response that crashed this client on 2026-08-05 was thirty across
five.
This commit is contained in:
@@ -2382,6 +2382,73 @@ fn club_type_filter(token: Option<&str>) -> Option<ClubTypeFilter> {
|
||||
Some(filter)
|
||||
}
|
||||
|
||||
/// DIAGNOSTIC, `OPENFUT_FIFA17_KIT_PROBE=1`, staging only, default OFF.
|
||||
///
|
||||
/// Appends two synthetic kits to `?type=kit` so one client restart can settle
|
||||
/// which of the two remaining kit-ingest hypotheses is right. It answers a
|
||||
/// question no static reading has: the client is served two kits, returns
|
||||
/// `total=2 emitted=2`, and yet NO cardtype-7 record is ever resident (measured
|
||||
/// read-only over 3.6 GB of process memory, while player and staff records from
|
||||
/// the same response family ARE resident).
|
||||
///
|
||||
/// Two shapes, because two things could be rejecting the item:
|
||||
///
|
||||
/// * `6300007` MINIMAL — exactly the field set a STAFF item carries, which is
|
||||
/// known to ingest, plus `cardsubtypeid` 9. If only this one appears, one of
|
||||
/// the kit-only extras (`assetId`, `cardassetid`, `teamid`, `category`,
|
||||
/// `year`) is what makes the client discard the item.
|
||||
/// * `6300008` NAMED — the full kit shape plus `name`/`localizedName`/
|
||||
/// `description`. The cardtype-7 parse arm is documented to copy exactly those
|
||||
/// three, and OpenFUT sends none of them. If only this one appears, they are
|
||||
/// required rather than optional.
|
||||
///
|
||||
/// If NEITHER appears, `?type=kit` is not the route that populates the
|
||||
/// collection `FUN_1800d73d0` scans, and the search moves to which route does.
|
||||
///
|
||||
/// Both ids are real `fcc_kitcards` carddbids for team 21 (`6300007` year 1972
|
||||
/// category 2, `6300008` year 0 category 5), so nothing here invents an id the
|
||||
/// client cannot resolve. They are served `free`, never active, so they cannot
|
||||
/// disturb the real active-kit assignment. Instance ids are outside Core's
|
||||
/// range so they can never collide with an owned row.
|
||||
///
|
||||
/// Deliberately small: the one response that has ever crashed this client was 30
|
||||
/// items across five families (2026-08-05). This is two items in one family.
|
||||
fn append_kit_shape_probe(label: &str, items: &mut Vec<Value>) {
|
||||
if label != "kit" || !kit_probe_enabled() {
|
||||
return;
|
||||
}
|
||||
items.push(json!({
|
||||
"id": 100009007,
|
||||
"resourceId": 6300007,
|
||||
"cardsubtypeid": 9,
|
||||
"itemType": "kit",
|
||||
"itemState": "free",
|
||||
"owners": 1,
|
||||
"untradeable": false,
|
||||
}));
|
||||
items.push(json!({
|
||||
"id": 100009008,
|
||||
"resourceId": 6300008,
|
||||
"assetId": 6300008,
|
||||
"cardassetid": 35,
|
||||
"cardsubtypeid": 9,
|
||||
"itemType": "kit",
|
||||
"itemState": "free",
|
||||
"owners": 1,
|
||||
"untradeable": false,
|
||||
"teamid": 21,
|
||||
"category": 5,
|
||||
"year": 0,
|
||||
"name": "OpenFUT Probe Kit",
|
||||
"localizedName": "OpenFUT Probe Kit",
|
||||
"description": "kit ingest probe",
|
||||
}));
|
||||
eprintln!(
|
||||
"utas-host owner=RUST route=club KIT_PROBE armed: appended 6300007 (minimal) \
|
||||
and 6300008 (named) — diagnostic only"
|
||||
);
|
||||
}
|
||||
|
||||
/// Filter already-shaped `/club` items to SPECIALS (`rareflag > 1`) and paginate
|
||||
/// the filtered set locally. Returns `(page, total_specials)`. Pure — the whole
|
||||
/// point is that "special" pagination is over the filtered set, never Core's
|
||||
@@ -2548,11 +2615,12 @@ pub fn handle_club(query: &str, deps: &ClubDeps<'_>) -> (WireResponse, ClubLog)
|
||||
};
|
||||
let (body, stats) =
|
||||
shape_club_response_with_kits(&visible, deps.entities, deps.assets, active);
|
||||
let all = body
|
||||
let mut all = body
|
||||
.get("itemData")
|
||||
.and_then(Value::as_array)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
append_kit_shape_probe(filter_arm.label, &mut all);
|
||||
let (paged, total) = if core_q.special {
|
||||
special_filter_page(&all, offset, limit)
|
||||
} else {
|
||||
@@ -5601,6 +5669,15 @@ fn equippables_enabled() -> bool {
|
||||
*ENABLED.get_or_init(|| std::env::var("OPENFUT_FIFA17_EQUIPPABLES").as_deref() == Ok("1"))
|
||||
}
|
||||
|
||||
/// Append the two diagnostic kits described on [`append_kit_shape_probe`].
|
||||
///
|
||||
/// Default OFF, staging only. Flip the env var off to revert with a restart and
|
||||
/// no rebuild.
|
||||
fn kit_probe_enabled() -> bool {
|
||||
static ENABLED: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
|
||||
*ENABLED.get_or_init(|| std::env::var("OPENFUT_FIFA17_KIT_PROBE").as_deref() == Ok("1"))
|
||||
}
|
||||
|
||||
/// A JSON response with an explicit status.
|
||||
fn json_status(status: u16, v: &Value) -> WireResponse {
|
||||
let body = serde_json::to_vec(v).unwrap_or_default();
|
||||
|
||||
Reference in New Issue
Block a user