fifa17-recon: match rewards, POW online layer, account backend, quick sell
Second session. FUT core loop, the EASFC/POW online layer, a central account
backend, and a lot of corrections. Everything risky is behind an env flag with
the default set to whatever was live-proven.
WORKING END TO END (live-verified this session):
* match loop -- POST/PUT/POST/DELETE ut/%s/match, rewards via FutDestroyMatch
(0x180121b60). Play a match, get coins, W/D/L updates.
* packs -- buy, cards land in the club, session survives (FUT_PACK_AUTOCLUB=1)
* quick sell -- POST ut/delete/%s/item was UNMAPPED and paid NOTHING; six cards
were destroyed for 0 coins. Now credits discardValue.
* POW/EASFC online -- the "EA FC servers unreachable" banner is powdll's layer,
a THIRD http api on :8094 nobody had served. Redirect needs no root: powdll
FUN_18005a460 reads FIFA_POW_URL from the same client-config store as
ROSTERUPDATE_URL. FUT_POW=1.
* account backend -- fut_account.py replaces 7 hardcoded copies of the persona
across 5 files; club/persona/online-profile editable via CLI.
CORRECTIONS TO ENDPOINT_MAP (all re-extracted from the deserializers):
* FutStoreGetPackTypes: id/packType/isPremium/quantity/saleType/purchaseLimit/
purchaseCount are NOT skipped no-ops -- all are parsed. extPrice inner objects
take externalPriceId(0x11a), not amount/currency.
* FutMoveCard 0x180128600 has NO skip handler (FUN_180135ff0 appears zero times,
unique among FUT deserializers) and parses only itemData -> dreamSquads.
* class -> deserializer resolution: the name literal is preceded by a 4-BYTE
HEADER and the factory LEA points at the header, so look up name_addr - 4.
Six attempts failed on this; now ghidra_env.class_deser(). Unlocked 11 SBC/
Draft schemas.
* live-only endpoints the request table never lists: ut/%s/squad/list,
ut/%s/user/club, ut/%s/club/stats/*, ut/%s/clientdata/<key>. The template
table is a floor, not a ceiling -- the log is the only ground truth.
* 163 RS4 call names exist; we served 17. All now served.
FIXED: club/stats/* was answering with the entire 28-item club inventory on every
poll (it fell through to the generic /club route).
UNSOLVED: the pack reveal's "Send to Club" (PUT ut/%s/item) kills the FUT session
whatever we answer -- {} included -- while its sibling quick-sell endpoint accepts
a bare {}. Seven hypotheses eliminated by live test, documented in
REBUILD_RESEARCH.md S14c so none get re-walked. FUT_PACK_AUTOCLUB routes around it.
Also unfixed: store tiles render "unknown" (displayGroup is parsed RECURSIVELY by
the same element parser; sending it FROZE the store, so FUT_STORE_GROUPS=1 is
default off).
Tests: test_fut_contract.py 380 (live, read-only) + test_match_rewards.py 51 (pure).
Note: fut_store.py carries some pre-existing uncommitted changes from before this
session (pack catalogue ids, pending-pile behaviour) that could not be separated
from this session's additions in the same file.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUT92pz6RWKih9dSr8ZpxW
This commit is contained in:
@@ -84,33 +84,48 @@ from heat2 import ( # noqa: E402
|
||||
)
|
||||
|
||||
# ================================================================== identity
|
||||
# SHARED CONSTANTS -- these MUST stay byte-identical to lsx_responder.py.
|
||||
# Source: stp-origin_emu.ini [Globals] (PersonaId / PersonaName / Language).
|
||||
# A mismatch is exactly what raises AUTH_ERR_INVALID_PERSONA (26),
|
||||
# AUTH_ERR_USER_DOES_NOT_MATCH_PERSONA and AUTH_ERR_PERSONA_NOT_FOUND.
|
||||
# SOURCED FROM fut_account.ACCOUNT -- the single source of truth shared with
|
||||
# lsx_responder_v2.py, fut_store.py, fut_seed.py and utas_server.py.
|
||||
#
|
||||
# THE CONSTRAINT IS CROSS-LAYER CONSISTENCY, NOT ANY PARTICULAR VALUE.
|
||||
# Whatever Blaze asserts here (LoginResponse.SESS.PDTL) must equal what LSX
|
||||
# asserts (GetProfileResponse) and what UTAS serves (userInfo / squad.personaId).
|
||||
# Reading them all from one module is what guarantees that.
|
||||
#
|
||||
# CORRECTION to the comment this replaces: it claimed these came from
|
||||
# stp-origin_emu.ini [Globals] and that a mismatch raises AUTH_ERR_INVALID_PERSONA
|
||||
# (26) / AUTH_ERR_USER_DOES_NOT_MATCH_PERSONA / AUTH_ERR_PERSONA_NOT_FOUND. That
|
||||
# justification is wrong twice over: those are Blaze *server* error codes and WE
|
||||
# are the server, and a byte-scan found "CAGE" and "33068179" ZERO times in
|
||||
# FIFA17.exe, CardsDLL, dbdata.dll and _fifa17.exe. 33068179 appears only inside
|
||||
# stp-origin_emu.dll, as that emu's own ini default. The client does not demand
|
||||
# these values -- they are what the currently-working stack asserts, which is
|
||||
# why they stay the defaults in fut_account.py.
|
||||
|
||||
PERSONA_ID = 33068179
|
||||
PERSONA_NAME = "CAGE"
|
||||
USER_ID = 33068179 # blazeId / userId; same value keeps BUID==UID==PID
|
||||
EXT_ID = 33068179 # XREF externalId
|
||||
EMAIL = "cage@openfut.local"
|
||||
PERSONA_NAMESPACE = "cem_ea_id" # must equal PreAuthResponse.NASP
|
||||
CLIENT_PLATFORM = 4 # Blaze::ClientPlatformType -> pc
|
||||
PERSONA_STATUS = 2 # PersonaStatus::Code -> ACTIVE (verified live: table 0x14487ad20, ACTIVE==2)
|
||||
USER_SESSION_TYPE = 0 # Blaze::UserSessionType -> normal/console user
|
||||
ACCOUNT_LOCALE_FALLBACK = 0x656E5553 # 'enUS'; overwritten by the client's own
|
||||
# PreAuthRequest LANG/LOC when we see it.
|
||||
from fut_account import ACCOUNT # noqa: E402
|
||||
|
||||
CONTENT_ID = "1027460" # FIFA 17 EA offer id (retail)
|
||||
ENTITLEMENT_TAG = "ONLINE_ACCESS" # TRIAL_ONLINE_ACCESS for FIFA17_Trial.exe
|
||||
ENTITLEMENT_GROUP = "FIFA17PCBoxContent" # was "FIFA17PC" -> matched NEITHER strstr
|
||||
PERSONA_ID = ACCOUNT.persona_id
|
||||
PERSONA_NAME = ACCOUNT.persona_name
|
||||
USER_ID = ACCOUNT.user_id # blazeId / userId; derived, keeps BUID==UID==PID
|
||||
EXT_ID = ACCOUNT.ext_id # XREF externalId; derived from persona_id
|
||||
EMAIL = ACCOUNT.email
|
||||
PERSONA_NAMESPACE = ACCOUNT.NAMESPACE # must equal PreAuthResponse.NASP
|
||||
CLIENT_PLATFORM = ACCOUNT.CLIENT_PLATFORM # Blaze::ClientPlatformType -> pc
|
||||
PERSONA_STATUS = ACCOUNT.PERSONA_STATUS # PersonaStatus::Code -> ACTIVE (live: table 0x14487ad20)
|
||||
USER_SESSION_TYPE = ACCOUNT.USER_SESSION_TYPE # Blaze::UserSessionType -> normal user
|
||||
ACCOUNT_LOCALE_FALLBACK = ACCOUNT.account_locale_int # 'enUS'; overwritten by the
|
||||
# client's own PreAuthRequest LANG/LOC.
|
||||
|
||||
CONTENT_ID = ACCOUNT.CONTENT_ID # FIFA 17 EA offer id (retail)
|
||||
ENTITLEMENT_TAG = ACCOUNT.ENTITLEMENT_TAG # TRIAL_ONLINE_ACCESS for FIFA17_Trial.exe
|
||||
ENTITLEMENT_GROUP = ACCOUNT.ENTITLEMENT_GROUP # was "FIFA17PC" -> matched NEITHER strstr
|
||||
# needle in EntitlementComponent::onListEntitlements (0x146f27440): FUT keeps an
|
||||
# entitlement only if GNAM contains "FIFA17PCBoxContent" OR "FIFA16PC" (needles
|
||||
# @0x144334030), TAG non-empty, STAT==1. "FIFA17PC" survived none -> empty store.
|
||||
|
||||
TITLE_ID = "309111"
|
||||
CLIENT_ID = "FIFA17-PC-SERVER-BLAZE"
|
||||
PLATFORM = "pc"
|
||||
TITLE_ID = ACCOUNT.TITLE_ID
|
||||
CLIENT_ID = ACCOUNT.CLIENT_ID
|
||||
PLATFORM = ACCOUNT.PLATFORM
|
||||
SERVER_VERSION = "Blaze 15.1.1.3.0 (OpenFUT)\n"
|
||||
|
||||
# ================================================================== config
|
||||
@@ -530,9 +545,36 @@ IDENTITY_PARAMS = [
|
||||
("redirect_uri", "http://127.0.0.1/success"),
|
||||
]
|
||||
|
||||
# --- POW / EASFC redirect (the "EA FC servers unreachable" gate) --------------
|
||||
# The reconnect banner comes from the EASFC layer in powdll_Win64_retail.dll, a
|
||||
# THIRD HTTP API (default host pas.gt.easfc.ea.com:8094) that nothing has ever
|
||||
# served. powdll FUN_18005a460 reads its base URLs out of THIS store -- the merged
|
||||
# '_all' section, same path that already delivers ROSTERUPDATE_URL -- via
|
||||
# cfg->vtbl[0x30] = getString(key, default, &out), and picks an http:// vs https://
|
||||
# prefix (PTR_s_http____18010aee0 / PTR_s_https____18010aee8). So pointing POW at
|
||||
# our own server needs NO /etc/hosts entry and NO root: just answer these keys.
|
||||
# POW_IS_ON (read by the same function, getBool, default TRUE) is the kill switch.
|
||||
#
|
||||
# DEFAULT IS OFF. Serving these keys sends the client somewhere it has never been
|
||||
# and pow_server.py cannot yet answer POW properly (the response schemas are not
|
||||
# reversed -- only the 58 request paths are). Enable for a CAPTURE run with
|
||||
# FUT_POW=1, which is what turns the schemas into reversing targets:
|
||||
# FUT_POW=1 ./openfut-fut.sh restart
|
||||
# and read /tmp/pow_server.log. FUT_POW=off is the instant fallback.
|
||||
POW_HOST = os.environ.get("POW_HOST", "127.0.0.1:8094")
|
||||
POW_CONTENT_HOST = os.environ.get("POW_CONTENT_HOST", "127.0.0.1:8080")
|
||||
_POW_ON = os.environ.get("FUT_POW", "").lower() in ("1", "true", "on", "yes")
|
||||
OSDK_POW = [
|
||||
("FIFA_POW_URL", "http://%s/" % POW_HOST),
|
||||
("FIFA_POW_CONTENT_SERVER_URL", "http://%s/" % POW_CONTENT_HOST),
|
||||
("FIFA_POW_NUCLEUS_PROXY_URL", "http://%s/" % POW_HOST),
|
||||
("POW_IS_ON", "1"),
|
||||
] if _POW_ON else []
|
||||
|
||||
CLIENT_CONFIGS = {
|
||||
"BlazeSDK": None, # built dynamically, see below
|
||||
"netres": OSDK_NETRES, # CFID (verified @0x143962be0)
|
||||
"OSDK_POW": OSDK_POW, # EASFC/POW redirect (opt-in, FUT_POW=1)
|
||||
"OSDK_CORE": OSDK_CORE,
|
||||
"OSDK_CLIENT": OSDK_CLIENT,
|
||||
"OSDK_NUCLEUS": OSDK_NUCLEUS,
|
||||
@@ -565,15 +607,55 @@ FUT_RS4_MODULES = [
|
||||
"TFA", "SQUADMODE", "DRAFT", "CHAMPIONS", "V2STORE", "LIVEMESSAGE",
|
||||
"ADMIN", "DEBUG", "MAINTENANCE",
|
||||
]
|
||||
FUT_RS4_CALLS_BOOT = [
|
||||
"GETSETTINGS", "AUTHENTICATION", "LOGIN", "LOGOUT", "CREATEUSER",
|
||||
"GETUSERINFO", "GETUSERDATA", "GETUSERCREDITS", "USERRELIABILITYINFO",
|
||||
"GETHUBDATA", "GETUSERMASSINFO", "LOADACTIVESQUAD", "SQUADLIST",
|
||||
"GETSQUADINFO", "GETCLUBINFO", "KEEPALIVE", "SEASONHISTORY",
|
||||
# EVERY RS4 call name in the client's table at 0x18021e250-0x18021fa60 (163 of them),
|
||||
# not just the 17 boot ones. THE CLIENT RESOLVES A PER-CALL URL KEY FIRST:
|
||||
# FUT_RS4_URL_<CALL> takes precedence over the per-module FUT_RS4_APIURL_<MODULE>.
|
||||
# Serving only the boot subset left 146 calls unresolved, so anything past boot --
|
||||
# VIEWCARDS, ASSIGNCARD, CLUBSTATS, GETCLUBUSERS, MOVECARD's follow-ups -- fell back
|
||||
# to a default (real EA) host, failed at the transport, and the client raised
|
||||
# "We are sorry but there has been an error connecting to FIFA 17 Ultimate Team."
|
||||
# That is the pack "Send to Club" kick: the move itself succeeded, the FOLLOW-UP
|
||||
# request never reached us. Live-diagnosed 2026-08-04 from the on-screen error text
|
||||
# plus GET /club never once appearing in the log.
|
||||
FUT_RS4_CALLS = [
|
||||
"AUCTIONHOUSE", "CLUB_USER", "DREAM", "SQUAD", "DELETE_SQUAD", "LBOPTIONS",
|
||||
"LBDEFAULT", "PAFPRACTICE", "USER", "DELETEUSER", "ITEMS", "ITEMS_BY_RES",
|
||||
"DELETEITEMS", "TOURNAMENT", "TOURNAMENTUSER", "TOURNAMENTQUIT", "SEASONUSER",
|
||||
"SEASONUSER_ALTER", "SEASONRESET", "FRIENDLYSEASON", "PURCHASED", "STORE", "WATCHLIST",
|
||||
"DELETEWATCHLIST", "TRADEPILE", "TRADE", "DELETETRADE", "MARKETDATA", "CLIENTDATA",
|
||||
"AUTH", "DELETE_AUTH", "PHISHING", "CAPTCHA", "SQUADMODE", "DRAFT", "CHAMPIONS",
|
||||
"V2STORE", "LIVEMESSAGE", "ADMIN", "DEBUG", "MAINTENANCE", "ISSEARCH", "ISOFFERTRADE",
|
||||
"ISSTART", "RELISTALL", "GETCLUBUSERS", "GETCLUBINFO", "CLUBSEARCH", "CLUBSTATS",
|
||||
"STAFFSTATS", "CONSUMABLESSEARCH", "DREAMSQUADSEARCH", "GETSQUADINFO",
|
||||
"UPDATESQUADNAME", "RETRIEVESQUAD", "LOADACTIVESQUAD", "DELETESQUAD", "SAVESQUAD",
|
||||
"SQUADLIST", "GETLBOPTIONS", "GETLBENTRIES", "GETLBENTRYDATA", "GETSETTINGS",
|
||||
"AUTHENTICATION", "LOGIN", "LOGOUT", "RESETUSER", "USERRELIABILITYINFO", "CREATEUSER",
|
||||
"GETUSERINFO", "SETUSERINFO", "GETHISTORICAL", "SETTUTDATA", "GETTOWDATA",
|
||||
"SETTOWDATA", "SETFAVDATA", "GETUSERCREDITS", "GETUSERDATA", "VIEWCARDS", "ASSIGNCARD",
|
||||
"APPLYCARD", "APPLYCARDBYRES", "ACTIVATECARD", "CONSUMECARD", "DISCARDCARD",
|
||||
"DISCARDCARDBYRES", "DISCARDACARD", "MOVECARD", "MOVECARDBYRES", "SWAPCARD",
|
||||
"CREATEMATCH", "MATCHREADY", "DESTROYMATCH", "PLAYGAME", "RESETMATCH", "KEEPALIVE",
|
||||
"LOADCATEGORYDETAILS", "LOADSETCHALLENGES", "STARTCHALLENGE", "LOADSQUADCHALLENGE",
|
||||
"SAVESQUADCHALLENGE", "SUBMITCHALLENGE", "TAGSETS", "SETSBCDATA", "TOURNAMENTLIST",
|
||||
"TOURNAMENTTEAMS", "GETACTIVETOURNAMENTS", "UPDATETOURNAMENT", "TOURNAMENTLOADDATA",
|
||||
"SEASONLIST", "SEASONUPDATE", "SEASONLOADDATA", "SEASONQUIT", "SEASONHISTORY",
|
||||
"PURCHASEDITEMS", "PURCHASEPACK", "PURCHASEITEMS", "STOREPACKTYPES",
|
||||
"STOREPACKQUANTITIES", "ISREMOVEWATCH", "ISWATCHTRADE", "ISWATCHLIST", "ISVIEWTRADE",
|
||||
"GETTRADEPILE", "GETAUCTIONCOUNT", "ISREMOVETRADE", "GETSUGGESTEDPRICING",
|
||||
"CHANGECLUBNAME", "GETPHISHINGQUESTION", "SETPHISHINGANSWER", "VALIDATEPHISHINGANSWER",
|
||||
"GETTRUSTEDCONSOLELIST", "GETCAPTCHA", "EXCHANGECAPTCHA", "VALIDATECAPTCHA",
|
||||
"VALIDATETFA", "UPDATEUSERACTION", "GETUSERACTION", "GETMANAGERQUESTREWARD",
|
||||
"SETMANAGERQUESTCOMPLETE", "GETHUBDATA", "GETUSERMASSINFO", "FIFAPOINTSTRANSFER",
|
||||
"FRIENDLYSEASONUPDATE", "FRIENDLYSEASONLOAD", "FRIENDLYSEASONHISTORY",
|
||||
"GETAVAILABLELOANPLAYERS", "SIGNLOANPLAYER", "GETCHEMISTRYATTR",
|
||||
"GETDRAFTCURRENTSTATE", "GETDRAFTCHOICES", "GETDRAFTSTATS", "GETDRAFTAWARD",
|
||||
"PURCHASEDRAFTMODE", "PICKDRAFTCHOICE", "PICKDRAFTAUTOCHOICE", "GETSTORYMODEREWARD",
|
||||
"CHAMPIONSHUB", "CHAMPIONSTOPX", "CHAMPIONSRANK", "CHAMPIONSFRIENDS",
|
||||
"GRANTPRIZECHAMPIONUSER", "REGISTERCHAMPIONSLEAGUE"
|
||||
]
|
||||
FUT_RS4_CONFIG = (
|
||||
[("FUT_RS4_APIURL_%s" % m, UTAS_BASE) for m in FUT_RS4_MODULES]
|
||||
+ [("FUT_RS4_URL_%s" % c, UTAS_BASE) for c in FUT_RS4_CALLS_BOOT]
|
||||
+ [("FUT_RS4_URL_%s" % c, UTAS_BASE) for c in FUT_RS4_CALLS]
|
||||
+ [("FUT_RS4_BASE_URL", UTAS_BASE)]
|
||||
# STORE gate: FIFA shows "store not available" unless these config flags are
|
||||
# true. The store-screen entitlement checks (CardsDLL 0x18001749d vtable+0x138 /
|
||||
@@ -604,9 +686,14 @@ def client_config_for(cfid: str) -> list:
|
||||
still wrap in a present CONF field -- never an empty frame).
|
||||
FUT_RS4_* base-URL keys ride on EVERY CFID (merged '_all' store; which section
|
||||
CardsDLL reads is unproven, so serve them everywhere)."""
|
||||
# OSDK_POW rides on EVERY CFID for the same reason FUT_RS4_* does: powdll's
|
||||
# FUN_18005a460 reads FIFA_POW_URL out of the merged '_all' store, and which
|
||||
# section it happens to read is unproven. Empty list when FUT_POW is unset, so
|
||||
# this is a no-op by default. (Putting the keys ONLY under a hypothetical
|
||||
# "OSDK_POW" CFID would be dead code -- nothing is known to request that name.)
|
||||
if cfid == "BlazeSDK":
|
||||
return sorted(blazesdk_config() + FUT_RS4_CONFIG)
|
||||
return sorted((CLIENT_CONFIGS.get(cfid) or []) + FUT_RS4_CONFIG)
|
||||
return sorted(blazesdk_config() + FUT_RS4_CONFIG + OSDK_POW)
|
||||
return sorted((CLIENT_CONFIGS.get(cfid) or []) + FUT_RS4_CONFIG + OSDK_POW)
|
||||
|
||||
|
||||
def fetch_config_response_fields(cfid: str) -> "OrderedDict":
|
||||
@@ -691,9 +778,13 @@ def ping_response_fields() -> "OrderedDict":
|
||||
def persona_details_fields(now: int) -> "OrderedDict":
|
||||
"""Blaze::Authentication::PersonaDetails @0x14487cab0 -- 6 members."""
|
||||
return OrderedDict([
|
||||
("DSNM", (STRING, PERSONA_NAME)), # displayName MUST be "CAGE"
|
||||
# DSNM/PID: no particular value is demanded by the client (see the
|
||||
# identity block at the top). What IS required is that they equal LSX
|
||||
# GetProfileResponse Persona/PersonaId and UTAS userInfo.personaId --
|
||||
# hence fut_account.ACCOUNT.
|
||||
("DSNM", (STRING, PERSONA_NAME)), # displayName == LSX Persona
|
||||
("LAST", (INT, now)), # lastAuthenticated uint32
|
||||
("PID", (INT, PERSONA_ID)), # personaId int64 MUST be 33068179
|
||||
("PID", (INT, PERSONA_ID)), # personaId int64 == LSX PersonaId
|
||||
("PLAT", (INT, CLIENT_PLATFORM)), # clientPlatform enum -> pc
|
||||
("STAS", (INT, PERSONA_STATUS)), # PersonaStatus::Code -> ACTIVE
|
||||
("XREF", (INT, EXT_ID)), # extId uint64
|
||||
@@ -748,7 +839,7 @@ def login_response_fields(sess: Session) -> "OrderedDict":
|
||||
# LN MAIL PML RC STAS STAT TPOT UDU UID. IDENTITY: MAIL/UID/ASRC MUST byte-match
|
||||
# LoginResponse.SESS.MAIL/UID and PreAuthResponse.NASP. Empty request.
|
||||
|
||||
ACCOUNT_LOCALE_STR = "en_US" # AccountInfo.LN (language)
|
||||
ACCOUNT_LOCALE_STR = ACCOUNT.locale # AccountInfo.LN (language); "en_US" default
|
||||
|
||||
|
||||
def account_info_fields(sess: "Session", now: int) -> "OrderedDict":
|
||||
@@ -1556,6 +1647,13 @@ def _selftest() -> None:
|
||||
print("blaze_responder_v3 selftest")
|
||||
print("=" * 72)
|
||||
|
||||
# ---- 0. identity is sourced from the shared account, not local literals
|
||||
assert PERSONA_ID == ACCOUNT.persona_id and PERSONA_NAME == ACCOUNT.persona_name
|
||||
assert USER_ID == EXT_ID == ACCOUNT.persona_id, "BUID/UID/XREF are derived"
|
||||
assert PERSONA_NAMESPACE == ACCOUNT.NAMESPACE == "cem_ea_id"
|
||||
assert EMAIL == ACCOUNT.email and ACCOUNT_LOCALE_STR == ACCOUNT.locale
|
||||
print("[ok] identity from fut_account %r" % (ACCOUNT,))
|
||||
|
||||
sess = Session()
|
||||
sess.session_key = "0540000031e5dde8_OPENFUTselftestkeyOPENFUTselftestkeyOPENFUT0"
|
||||
sess.account_locale = 0x656E5553
|
||||
@@ -1602,8 +1700,10 @@ def _selftest() -> None:
|
||||
d = s["PDTL"][1]
|
||||
assert list(d.keys()) == ["DSNM", "LAST", "PID", "PLAT", "STAS", "XREF"], \
|
||||
list(d.keys())
|
||||
assert d["PID"][1] == PERSONA_ID == 33068179
|
||||
assert d["DSNM"][1] == PERSONA_NAME == "CAGE"
|
||||
# Identity is now configurable (fut_account.ACCOUNT), so assert CONSISTENCY
|
||||
# with the shared account rather than the old hardcoded 33068179/"CAGE".
|
||||
assert d["PID"][1] == PERSONA_ID == ACCOUNT.persona_id
|
||||
assert d["DSNM"][1] == PERSONA_NAME == ACCOUNT.persona_name
|
||||
assert back["ANON"][1] == 0 and back["UNDR"][1] == 0 and back["NTOS"][1] == 0
|
||||
lfr = fire2(COMP_AUTH, CMD_LOGIN, 7, REPLY, lp)
|
||||
lh = parse_fire2_header(lfr)
|
||||
|
||||
Reference in New Issue
Block a user