From 30ee3e2b8647d80a48ce823a75ea3facf60f60af Mon Sep 17 00:00:00 2001 From: MiTHRAL Date: Sun, 30 Aug 2026 23:46:03 -0400 Subject: [PATCH] netcode-revival: force the frontend 'enter online flow' gate (sub_82703960) create-party (sub_82A1B8E0) is only reached through the frontend online flow, gated by sub_82703960 which requires: online latch 0x830670C8 == 0, frontend-mode byte obj@*(0x8306707C)+194 != 0, XamUserGetSigninInfo.unk08==1 (already), and a mode check. Force the two state inputs and log the gate inputs in the periodic dump so we can see exactly which check blocks. --- src/system/xnet_transport.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/system/xnet_transport.cpp b/src/system/xnet_transport.cpp index babadfa..6f0ac6c 100644 --- a/src/system/xnet_transport.cpp +++ b/src/system/xnet_transport.cpp @@ -186,6 +186,13 @@ void XNetTransport::ForceLiveFlag() { REXLOG_INFO("xnet trace: party state={} eaip=0x{:08X} b417={} b421={} b423={}", rd32(0x82FD98A0), rd32(0x82FD98A8), rd8(0x82FD98F1), rd8(0x82FD98F5), rd8(0x82FD98F7)); + // The frontend 'enter online flow' gate (sub_82703960) that leads to + // create-party: latch byte 0x830670C8 must be 0, and the frontend-mode + // byte at obj@*(0x8306707C)+194 must be non-zero. + uint32_t* mode_obj = REX_KERNEL_MEMORY()->TranslateVirtual(0x8306707C); + REXLOG_INFO("xnet trace: online latch={} mode_obj={} mode_byte={}", rd8(0x830670C8), + mode_obj != nullptr ? *mode_obj : 0, + (mode_obj != nullptr && *mode_obj != 0) ? rd8(*mode_obj + 194) : -1); } // The flag is the LIVE USER INDEX (not a boolean). The profile lives in // slot 0, so force 0 (any slot answers after the shim fix, but 0 is the @@ -222,6 +229,28 @@ void XNetTransport::ForceLiveFlag() { force_byte(0x82FD98F1, "party+417 (EA-Nation flag)"); force_byte(0x82FD98F5, "party+421 (online flag)"); force_byte(0x82FD98F7, "party+423 (EA connected)"); + // The frontend 'enter online flow' gate (sub_82703960) blocks the path to + // create-party unless the online latch (0x830670C8) is 0 and the + // frontend-mode byte (obj@*(0x8306707C)+194) is non-zero. Force both. + { + uint8_t* latch = REX_KERNEL_MEMORY()->TranslateVirtual(0x830670C8); + if (latch != nullptr && *latch != 0) { + if (!rate) { + REXLOG_INFO("xnet trace: forcing online latch 0x830670C8 = 0"); + } + *latch = 0; + } + uint32_t* mode_obj = REX_KERNEL_MEMORY()->TranslateVirtual(0x8306707C); + if (mode_obj != nullptr && *mode_obj != 0) { + uint8_t* mode = REX_KERNEL_MEMORY()->TranslateVirtual(*mode_obj + 194); + if (mode != nullptr && *mode == 0) { + if (!rate) { + REXLOG_INFO("xnet trace: forcing frontend mode byte = 1"); + } + *mode = 1; + } + } + } // Broadcast the Live signin-changed event a few times at startup so the // game's sign-in manager runs and designates the profile as the live user // (it only does this when it processes a real signin notification, which