From e187cd49a24da809c8c4fd732d6571bcd6093d84 Mon Sep 17 00:00:00 2001 From: funman300 Date: Wed, 12 Aug 2026 20:46:48 +0000 Subject: [PATCH] fix(fifa17): preserve versioned resourceId on the wire (no special->base collapse) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit shape_item emitted resourceId/definitionId = asset_id (base), collapsing every versioned (special) card onto its base definition on the /club and squad wire. The dev 32-card fixture is base-only (version 0), so Slice 7 never exposed it; the real profile (1531 versioned cards) did. Fifa17Identity now carries resource_id (= (version<<24)|asset_id, == asset_id for a base card). shape_item emits resourceId/definitionId from resource_id and assetId/cardassetid from asset_id — versioned and base stay distinct. The host resolver populates resource_id from the catalog's reconstructed resource_id (the catalog already parsed version; it was dropped before shaping). Regression test: versioned 117617092 (v7 of asset 176580) shapes resourceId/ definitionId=117617092, assetId/cardassetid=176580. Verified on the real staged /club: 1949 items, wire-id set exact, 0 wire->resourceId mismatches, 0 duplicate-multiplicity mismatches vs the source manifest. adapter 111 + host 24 tests green; clippy -D warnings clean. --- .../src/fut/club_response.rs | 2 + openfut-adapter-fifa17/src/fut/item.rs | 39 +++++++++++++++++-- .../src/fut/squad_projection.rs | 3 ++ .../tests/squad_projection.rs | 1 + openfut-utas-host/src/lib.rs | 1 + 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/openfut-adapter-fifa17/src/fut/club_response.rs b/openfut-adapter-fifa17/src/fut/club_response.rs index 6d39a46..311ac4f 100644 --- a/openfut-adapter-fifa17/src/fut/club_response.rs +++ b/openfut-adapter-fifa17/src/fut/club_response.rs @@ -88,6 +88,7 @@ mod tests { Fifa17Identity { item_id: 100000001, asset_id: 20801, + resource_id: 20801, }, )])); let items = vec![item( @@ -155,6 +156,7 @@ mod tests { Fifa17Identity { item_id: 100000002, asset_id: 158023, + resource_id: 158023, }, )])); // Synthetic club "Northgate United" has no FIFA team id. diff --git a/openfut-adapter-fifa17/src/fut/item.rs b/openfut-adapter-fifa17/src/fut/item.rs index 614fcad..5c1fdf5 100644 --- a/openfut-adapter-fifa17/src/fut/item.rs +++ b/openfut-adapter-fifa17/src/fut/item.rs @@ -52,7 +52,13 @@ pub struct CoreOwnedItem { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Fifa17Identity { pub item_id: u32, + /// Base FIFA player asset (low 24 bits the client resolves art/name from). pub asset_id: u32, + /// Full versioned resource id = `(version << 24) | asset_id`. Equals + /// `asset_id` for a version-0 base card. This is the wire + /// `resourceId`/`definitionId`, kept DISTINCT from `asset_id` so a versioned + /// (special) card never collapses onto its base on the wire. + pub resource_id: u32, } /// Supplies the FIFA numeric identity for a Core item. Returning `None` means @@ -80,7 +86,10 @@ fn discard_value(rating: u8) -> i64 { } } -/// Build one FIFA `_item` object (version byte 0x00 → `resourceId == assetId`). +/// Build one FIFA `_item` object. `resourceId`/`definitionId` carry the full +/// versioned resource id; `assetId`/`cardassetid` carry the base asset. For a +/// version-0 base card these coincide; for a special they differ and MUST NOT +/// be collapsed. /// /// This is the single source of truth for a player item's on-wire shape; the /// `/club` envelope and squad projection both call it, so their items are @@ -104,10 +113,10 @@ pub fn shape_item( .collect(); json!({ "id": id.item_id, - "resourceId": asset, + "resourceId": id.resource_id, "assetId": asset, "cardassetid": asset, - "definitionId": asset, + "definitionId": id.resource_id, "cardsubtypeid": 0, "itemType": "player", "rareflag": 1, @@ -162,6 +171,7 @@ mod tests { Fifa17Identity { item_id: 100000001, asset_id: 20801, + resource_id: 20801, }, &ent, ); @@ -193,6 +203,7 @@ mod tests { Fifa17Identity { item_id: 100000030, asset_id: 101490, + resource_id: 101490, }, &ent, ); @@ -201,6 +212,7 @@ mod tests { Fifa17Identity { item_id: 100000031, asset_id: 101490, + resource_id: 101490, }, &ent, ); @@ -215,4 +227,25 @@ mod tests { assert_eq!(a["id"], 100000030); assert_eq!(b["id"], 100000031); } + + #[test] + fn versioned_special_keeps_resourceid_distinct_from_assetid() { + // A versioned (special) card: resourceId/definitionId carry the full + // versioned id; assetId/cardassetid stay the base asset. They MUST NOT + // collapse. (resource 117617092 = version 7 of asset 176580.) + let ent = entities(); + let it = shape_item( + &item("oc-v", "fifa17_117617092", 92, "ST"), + Fifa17Identity { + item_id: 100000384, + asset_id: 176580, + resource_id: 117617092, + }, + &ent, + ); + assert_eq!(it["resourceId"], 117617092, "versioned resource id on the wire"); + assert_eq!(it["definitionId"], 117617092); + assert_eq!(it["assetId"], 176580, "base asset id preserved"); + assert_eq!(it["cardassetid"], 176580); + } } diff --git a/openfut-adapter-fifa17/src/fut/squad_projection.rs b/openfut-adapter-fifa17/src/fut/squad_projection.rs index 2bfc472..568796c 100644 --- a/openfut-adapter-fifa17/src/fut/squad_projection.rs +++ b/openfut-adapter-fifa17/src/fut/squad_projection.rs @@ -287,6 +287,7 @@ mod tests { Fifa17Identity { item_id: 100000042, asset_id: 20801, + resource_id: 20801, }, )])); let input = one_slot_input(&owned, SquadExtInput::Fresh(fresh_ext())); @@ -359,6 +360,7 @@ mod tests { Fifa17Identity { item_id: 100000030, asset_id: 101490, + resource_id: 101490, }, ), ( @@ -366,6 +368,7 @@ mod tests { Fifa17Identity { item_id: 100000031, asset_id: 101490, + resource_id: 101490, }, ), ])); diff --git a/openfut-adapter-fifa17/tests/squad_projection.rs b/openfut-adapter-fifa17/tests/squad_projection.rs index 97a576e..c9904ed 100644 --- a/openfut-adapter-fifa17/tests/squad_projection.rs +++ b/openfut-adapter-fifa17/tests/squad_projection.rs @@ -110,6 +110,7 @@ fn oracle_tables() -> (HashMap, TableIdentity) { Fifa17Identity { item_id: wire as u32, asset_id: asset, + resource_id: asset, }, ); } diff --git a/openfut-utas-host/src/lib.rs b/openfut-utas-host/src/lib.rs index 1198a9b..758c72d 100644 --- a/openfut-utas-host/src/lib.rs +++ b/openfut-utas-host/src/lib.rs @@ -551,6 +551,7 @@ impl ItemIdentityResolver for Fifa17IdentityResolver { // Wire ids live in 1e8..9e8 (policy) — well within u32. item_id: wire as u32, asset_id: ident.asset_id, + resource_id: ident.resource_id, }) } }