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