netcode-revival: fix the live-flag address + force the live-user cache flags
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run

The live-flag address was wrong: sub_8263E788's lis r11,-32003 gives
r11 = -2097348608 = 0x82FD0000 (recompiler value + 2^32), so the flag is at
0x82FC8851, not 0x83028851 (an arithmetic slip mis-multiplied 0x82FD0000).
We were forcing/reading an unrelated mapped byte, so the gate never saw the
forced value. Also force the game's cached 'live user exists' flags the
frontend online-access controllers check: 0x8308396C (14700) and 0x83084690
(18064).
This commit is contained in:
MiTHRAL 2026-08-28 22:08:51 -04:00
parent aa8cda81a8
commit 3016f14fe8

View file

@ -160,8 +160,8 @@ void XNetTransport::ForceLiveFlag() {
// with no real Live the flag never becomes non-zero. Force it here. // with no real Live the flag never becomes non-zero. Force it here.
// Address from the game: sub_8263E788 does lis r11,-32003 -> r11 = // Address from the game: sub_8263E788 does lis r11,-32003 -> r11 =
// 0x83030000 (recompiler's -2097348608) then lbz at -30639 => // 0x83030000 (recompiler's -2097348608) then lbz at -30639 =>
// 0x83028851. (Fragile: tied to this title's build; revival only.) // 0x82FC8851. (Fragile: tied to this title's build; revival only.)
uint8_t* flag = REX_KERNEL_MEMORY()->TranslateVirtual<uint8_t*>(0x83028851); uint8_t* flag = REX_KERNEL_MEMORY()->TranslateVirtual<uint8_t*>(0x82FC8851);
// Rate-limited status so we can SEE whether the address maps and its value. // Rate-limited status so we can SEE whether the address maps and its value.
static double last_log = 0.0; static double last_log = 0.0;
const double now = const double now =
@ -169,7 +169,7 @@ void XNetTransport::ForceLiveFlag() {
const bool rate = now - last_log >= 2.0; const bool rate = now - last_log >= 2.0;
if (rate) { if (rate) {
last_log = now; last_log = now;
REXLOG_INFO("xnet trace: live flag 0x83028851 {} value={}", REXLOG_INFO("xnet trace: live flag 0x82FC8851 {} value={}",
flag != nullptr ? "mapped" : "NOT MAPPED", flag != nullptr ? "mapped" : "NOT MAPPED",
flag != nullptr ? int(*flag) : -1); flag != nullptr ? int(*flag) : -1);
} }
@ -178,15 +178,31 @@ void XNetTransport::ForceLiveFlag() {
// safest for index-into-live-array readers). // safest for index-into-live-array readers).
if (flag != nullptr && *flag != 0) { if (flag != nullptr && *flag != 0) {
if (!rate) { if (!rate) {
REXLOG_INFO("xnet trace: forcing game live flag 0x83028851 = 0"); REXLOG_INFO("xnet trace: forcing game live flag 0x82FC8851 = 0");
} }
*flag = 0; *flag = 0;
} }
// The game also caches "live user exists" flags from its sign-in manager
// (set only when it processes a real signin notification, which never
// happens with no Live): 0x8308396C (=14700, 'live user exists') and
// 0x83084690 (=18064, checked by the frontend online-access controllers
// sub_826147C8 / sub_82614F38). Force both so Party Play ungreys.
const auto force_byte = [rate](uint32_t addr, const char* what) {
uint8_t* p = REX_KERNEL_MEMORY()->TranslateVirtual<uint8_t*>(addr);
if (p != nullptr && *p == 0) {
if (!rate) {
REXLOG_INFO("xnet trace: forcing game live cache {} = 1", what);
}
*p = 1;
}
};
force_byte(0x8308396C, "0x8308396C (live user exists)");
force_byte(0x83084690, "0x83084690 (online access)");
} }
XNetTransport::GateStatus XNetTransport::GetGateStatus() const { XNetTransport::GateStatus XNetTransport::GetGateStatus() const {
GateStatus gs; GateStatus gs;
uint8_t* flag = REX_KERNEL_MEMORY()->TranslateVirtual<uint8_t*>(0x83028851); uint8_t* flag = REX_KERNEL_MEMORY()->TranslateVirtual<uint8_t*>(0x82FC8851);
gs.live_flag_mapped = flag != nullptr; gs.live_flag_mapped = flag != nullptr;
gs.live_flag_value = flag != nullptr ? *flag : 0; gs.live_flag_value = flag != nullptr ? *flag : 0;
const uint32_t state = REX_KERNEL_STATE()->user_profile()->signin_state(); const uint32_t state = REX_KERNEL_STATE()->user_profile()->signin_state();