#!/usr/bin/env python3 """The card pool packs draw from. Replaces the 18-entry curated list that lived in fut_store.py, whose own TODO asked for "a full dbdata.dll extract (~18k players)". WHY THIS IS NOT THAT EXTRACT, and why it does not need to be yet ---------------------------------------------------------------- `dbdata.dll` is a real PE with a single export, `getTableData`, and its 2.5MB payload sits in a section named `.xdata` that disassembles as obfuscated code rather than a table directory. So the base player DB is not statically extractable without either running that export under Wine or defeating the obfuscation. Neither is cheap. More importantly it would not currently change anything on screen. Per docs/CARD_SYSTEM.md, the card view-model at 0x1800d7920 reads EVERY rendered field (rating +0xb4, position +0x146, nation +0x148, teamid +0x94, six attributes +0x98..0xac, name +0xdd) from a player-definition record resolved at `item+0x10`, and NEVER from our item JSON. That record comes from the client's own CardsDb map at `CardsDb_obj+0x160c0`, keyed by resourceId, and OFFLINE THAT MAP IS EMPTY: every lookup misses and a blank default record is emitted. So no assetId we send, real or invented, can currently produce a named card. Fixing that is a separate and much larger job (options A/B/C in CARD_SYSTEM.md) and it is about populating the client's map, not about our pool. WHAT THE POOL DOES CONTROL, and why widening it is worth doing now ------------------------------------------------------------------ Everything the SERVER is the source of truth for: * rating, which drives the gold/silver/bronze split. The old pool was 18 players rated 85 to 94, so every pack produced gold rares and the bronze pack was a lie. * leagueId / nation / teamid, which are exactly what the club-stats drill-down screens read. Those screens now work (REBUILD_RESEARCH S20) and were being fed from 5 leagues and 13 nations. * preferredPosition, which decides whether a squad can actually be filled. A pool with no goalkeepers below 87 makes a bronze squad impossible. * the six attributes, which feed the market's attribute filters. ON THE ASSET IDS ---------------- Ids marked (real) are genuine FIFA 17 player ids and were already in use here or are well established. The remainder are structural: they occupy a valid-looking id space so the pool has breadth. Because the CardsDb map is empty offline, an id being wrong has NO user-visible effect today: every card renders generic either way. If the identity work ever lands, this table is the thing to correct, and `verified` marks which rows can be trusted. Do not present the unverified ones as real players. Tuple layout matches fut_store._item: (assetId, rating, position, nation, leagueId, teamid, [6 attributes]) """ # League ids seen in live traffic and in the seed: 4, 13, 16, 19, 53. LEAGUES = { 13: "Premier League", 16: "Ligue 1", 19: "Bundesliga", 31: "Serie A", 53: "LaLiga", 4: "Eredivisie", 14: "EFL Championship", } # Nation ids used below, from the seed's own data. NATIONS = { 7: "Belgium", 14: "England", 18: "France", 21: "Germany", 27: "Netherlands", 34: "Croatia", 37: "Poland", 38: "Portugal", 39: "Rep. Ireland", 40: "Austria", 44: "Slovenia", 45: "Spain", 52: "Argentina", 54: "Brazil", 60: "Uruguay", 95: "Colombia", 117: "Ghana", 25: "Italy", 36: "Norway", 46: "Sweden", } # --- GOLD, 75+ --------------------------------------------------------------- # The eight below were in the previous pool and are (real). GOLD = [ (20801, 94, "LW", 38, 53, 243, [90, 93, 82, 91, 33, 80]), # (real) Ronaldo (158023, 93, "RW", 52, 53, 241, [89, 90, 86, 96, 26, 61]), # (real) Messi (176580, 92, "ST", 60, 53, 241, [83, 90, 79, 87, 42, 80]), # (real) Suarez (167495, 90, "GK", 21, 19, 21, [86, 88, 52, 88, 22, 88]), # (real) Neuer (183907, 90, "CB", 21, 19, 21, [80, 58, 70, 71, 89, 85]), # (real) Boateng (155862, 89, "CB", 45, 53, 243, [77, 62, 72, 74, 87, 84]), # (real) Ramos (188545, 89, "ST", 37, 19, 21, [77, 88, 75, 82, 42, 82]), # (real) Lewandowski (182521, 88, "CM", 21, 19, 21, [61, 79, 89, 82, 72, 74]), # (real) Kroos (183277, 88, "LM", 7, 13, 5, [89, 80, 82, 92, 37, 62]), # (real) Hazard (177003, 88, "CM", 34, 53, 243, [65, 78, 88, 79, 71, 66]), # (real) Modric (192985, 88, "RM", 7, 13, 10, [80, 82, 85, 85, 63, 68]), # (real) De Bruyne (190871, 87, "LW", 54, 16, 73, [90, 78, 80, 88, 36, 61]), # (real) Neymar (200389, 87, "GK", 44, 53, 240, [86, 88, 47, 88, 25, 86]), # (real) Oblak (197445, 87, "LB", 40, 19, 21, [86, 68, 79, 82, 82, 79]), # (real) Alaba (202126, 86, "ST", 14, 13, 5, [79, 84, 74, 82, 45, 79]), # (real) Kane (189332, 86, "LB", 45, 53, 241, [92, 66, 78, 84, 80, 71]), # (real) Alba (169193, 87, "CDM", 45, 19, 21, [70, 66, 80, 78, 82, 84]), # (real) Alonso (184941, 85, "CB", 14, 4, 5, [72, 40, 55, 60, 86, 85]), # (real) # structural, gold tier, spread across the remaining leagues and positions (201153, 85, "CAM", 18, 16, 73, [82, 79, 84, 86, 45, 62]), (204485, 84, "RB", 45, 31, 44, [84, 55, 74, 76, 80, 74]), (198710, 84, "CDM", 25, 31, 47, [66, 62, 79, 74, 83, 80]), (193080, 83, "GK", 14, 13, 11, [82, 84, 45, 83, 24, 82]), (192119, 83, "ST", 95, 13, 18, [83, 84, 71, 81, 38, 74]), (186345, 82, "CM", 27, 4, 10, [70, 71, 82, 79, 70, 72]), (207439, 82, "RW", 54, 31, 45, [88, 76, 77, 85, 34, 60]), (178603, 81, "CB", 46, 19, 175, [70, 48, 62, 63, 82, 83]), (199304, 81, "LM", 36, 13, 9, [85, 72, 76, 80, 45, 66]), (210035, 80, "CAM", 39, 14, 15, [76, 74, 81, 80, 48, 63]), (194765, 80, "ST", 117, 16, 66, [80, 81, 68, 76, 40, 78]), (205452, 79, "RB", 34, 31, 48, [82, 52, 71, 73, 77, 72]), (212188, 79, "GK", 18, 16, 73, [80, 82, 43, 80, 22, 79]), (196889, 78, "CDM", 21, 19, 175, [64, 60, 76, 71, 79, 78]), (203551, 78, "LW", 95, 53, 481, [86, 73, 74, 82, 32, 58]), (209331, 77, "CB", 25, 31, 47, [66, 45, 58, 61, 79, 80]), (191043, 77, "CM", 14, 13, 11, [68, 70, 78, 75, 68, 71]), (213345, 76, "RM", 54, 4, 10, [84, 70, 73, 79, 40, 60]), (188350, 76, "ST", 46, 14, 15, [74, 78, 65, 72, 36, 76]), (206113, 75, "LB", 38, 53, 481, [83, 58, 70, 73, 74, 70]), (215316, 75, "GK", 52, 31, 44, [78, 79, 41, 77, 21, 76]), ] # --- SILVER, 65 to 74 -------------------------------------------------------- SILVER = [ (214119, 74, "ST", 14, 14, 15, [76, 74, 63, 70, 34, 74]), (208618, 74, "CM", 18, 16, 66, [70, 66, 74, 72, 66, 68]), (211029, 73, "CB", 27, 4, 10, [64, 44, 55, 58, 75, 76]), (216543, 73, "RW", 95, 31, 48, [82, 68, 68, 75, 32, 58]), (205781, 72, "GK", 46, 19, 175, [74, 75, 40, 73, 20, 73]), (219877, 72, "LM", 39, 14, 15, [80, 65, 68, 73, 38, 60]), (207112, 71, "CDM", 25, 31, 47, [62, 55, 70, 66, 73, 74]), (218455, 71, "ST", 36, 13, 9, [73, 72, 60, 68, 32, 72]), (210998, 70, "RB", 21, 19, 175, [76, 48, 65, 67, 70, 68]), (222301, 70, "CAM", 54, 4, 10, [78, 66, 71, 74, 38, 58]), (213776, 69, "CB", 45, 53, 481, [62, 42, 52, 56, 71, 73]), (220144, 69, "LW", 18, 16, 66, [81, 64, 66, 72, 30, 56]), (217650, 68, "CM", 14, 14, 15, [66, 62, 69, 67, 63, 65]), (223089, 68, "GK", 34, 31, 48, [70, 71, 38, 69, 19, 70]), (211934, 67, "ST", 117, 16, 66, [74, 70, 58, 66, 30, 71]), (224512, 67, "LB", 46, 4, 10, [78, 50, 63, 66, 66, 64]), (215008, 66, "RM", 39, 13, 9, [79, 62, 65, 70, 34, 57]), (225367, 66, "CDM", 27, 31, 47, [60, 52, 66, 63, 68, 70]), (218902, 65, "CB", 36, 19, 175, [60, 40, 50, 54, 68, 70]), (226118, 65, "CAM", 95, 14, 15, [74, 63, 67, 70, 36, 55]), ] # --- BRONZE, under 65 -------------------------------------------------------- BRONZE = [ (227403, 64, "ST", 14, 14, 15, [70, 66, 55, 62, 28, 68]), (228156, 64, "GK", 39, 13, 9, [66, 67, 35, 65, 18, 66]), (229011, 63, "CB", 46, 4, 10, [58, 38, 48, 52, 65, 67]), (230245, 63, "LM", 95, 16, 66, [76, 58, 61, 66, 30, 52]), (231088, 62, "CM", 27, 31, 47, [60, 56, 63, 61, 58, 60]), (232517, 62, "RB", 36, 19, 175, [72, 44, 58, 60, 62, 61]), (233402, 61, "ST", 117, 14, 15, [70, 64, 52, 59, 26, 66]), (234199, 61, "CAM", 18, 16, 66, [70, 58, 63, 65, 32, 51]), (235066, 60, "GK", 34, 31, 48, [62, 63, 33, 61, 17, 62]), (236743, 60, "LB", 45, 53, 481, [72, 42, 56, 58, 60, 58]), (237510, 59, "CB", 25, 4, 10, [56, 36, 46, 50, 62, 64]), (238228, 59, "RW", 54, 13, 9, [76, 58, 58, 64, 26, 50]), (239104, 58, "CDM", 21, 19, 175, [56, 48, 60, 57, 63, 65]), (240377, 58, "ST", 36, 14, 15, [68, 62, 50, 57, 24, 64]), (241255, 57, "RM", 39, 16, 66, [74, 55, 58, 62, 28, 49]), (242018, 57, "CB", 46, 31, 47, [54, 34, 44, 48, 60, 62]), (243390, 56, "GK", 27, 13, 9, [60, 61, 31, 59, 16, 60]), (244107, 56, "CM", 95, 4, 10, [58, 52, 59, 57, 55, 57]), (245266, 55, "LW", 117, 53, 481, [74, 54, 55, 60, 24, 48]), (246013, 55, "LB", 25, 19, 175, [70, 40, 54, 56, 58, 56]), ] POOL = GOLD + SILVER + BRONZE # Rows whose assetId is a genuine FIFA 17 player id. Everything else is structural, # see the module docstring. Kept as data so a future dbdata extract can diff against it. VERIFIED_ASSET_IDS = { 20801, 158023, 176580, 167495, 183907, 155862, 188545, 182521, 183277, 177003, 192985, 190871, 200389, 197445, 202126, 189332, 169193, 184941, } def tier(rating): return "gold" if rating >= 75 else "silver" if rating >= 65 else "bronze" def pool_for(tier_name): """Players of one tier. Falls back to the whole pool rather than returning [].""" sel = [p for p in POOL if tier(p[1]) == tier_name] return sel or POOL if __name__ == "__main__": import collections print("pool: %d players (%d verified asset ids)" % (len(POOL), len(VERIFIED_ASSET_IDS))) for name in ("gold", "silver", "bronze"): sel = pool_for(name) print(" %-7s %3d ratings %d-%d" % (name, len(sel), min(p[1] for p in sel), max(p[1] for p in sel))) print(" leagues %2d %s" % (len({p[4] for p in POOL}), sorted({p[4] for p in POOL}))) print(" nations %2d" % len({p[3] for p in POOL})) print(" teams %2d" % len({p[5] for p in POOL})) print(" positions %s" % sorted({p[2] for p in POOL})) dupes = [a for a, n in collections.Counter(p[0] for p in POOL).items() if n > 1] print(" duplicate asset ids: %s" % (dupes or "none"))