From 9e300e14bc5e15af1f6c94708e480d48949c1dcf Mon Sep 17 00:00:00 2001 From: MiTHRAL Date: Fri, 28 Aug 2026 14:13:10 -0400 Subject: [PATCH] netcode-revival: report online title address + active link The game's party state machine (57.cpp sub_82A1B310 state 1) freezes on 'connecting to EA Nation' because it gates on (XNetGetTitleXnAddr status & 0x60) == online AND XNetGetEthernetLinkStatus() != 0 to pick the online EA server. rexglue returned STATIC (1) + link 0, so the state machine never advanced. Now: - XNetGetTitleXnAddr returns status 0x60 (the game's online bits; it checks (status & 0x60) in the EA resolver and session join) and populates inaOnline with the virtual IP. - XNetGetEthernetLinkStatus returns active+100Mbps. With the ONLINE status the party machine proceeds to CreateKey/RegisterKey, the sign-in gate, XNetConnect and the session-ready state. --- src/kernel/xam/xam_net.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/kernel/xam/xam_net.cpp b/src/kernel/xam/xam_net.cpp index b365eac..050600a 100644 --- a/src/kernel/xam/xam_net.cpp +++ b/src/kernel/xam/xam_net.cpp @@ -486,16 +486,19 @@ struct XnAddrStatus { }; u32 NetDll_XNetGetTitleXnAddr_entry(u32 caller, ppc_ptr_t addr_ptr) { - // netcode-revival: return this machine's stable virtual identity (10.80.0.x - // + a unique abEnet) so RakNet gets a non-zero, per-machine GUID seed and - // the game's address resolution has a consistent LAN-class address. + // netcode-revival: report this machine as ONLINE so the game's party + // state machine advances (Skate 3 maps status bit 0x60 = online: the + // EA-Nation resolver and session-join both gate on it). Also expose the + // online address so online-address paths have a valid inaOnline. const XnetIdentity& id = XnetLocalIdentity(); addr_ptr->ina.s_addr = htonl(id.virtual_ip); - addr_ptr->inaOnline.s_addr = 0; + addr_ptr->inaOnline.s_addr = htonl(id.virtual_ip); addr_ptr->wPortOnline = 0; std::memcpy(addr_ptr->abEnet, id.ab_enet, 6); std::memset(addr_ptr->abOnline, 0, 20); - return XnAddrStatus::XNET_GET_XNADDR_STATIC; + // 0x60 = the game's "online" status bits (not the standard 0-3 enum; the + // game checks (status & 0x60) everywhere it means "connected to LIVE"). + return 0x60; } u32 NetDll_XNetGetDebugXnAddr_entry(u32 caller, ppc_ptr_t addr_ptr) { @@ -569,7 +572,12 @@ struct XEthernetStatus { }; u32 NetDll_XNetGetEthernetLinkStatus_entry(u32 caller) { - return 0; + // netcode-revival: report an active 100Mbps link. The game's party state + // machine only reaches the EA-Nation/online path when the link is up + // (sub_82A1AAE8 returns the online server IP only if this is non-zero), + // so returning 0 left it frozen on "connecting to EA Nation" forever. + return XEthernetStatus::XNET_ETHERNET_LINK_ACTIVE | + XEthernetStatus::XNET_ETHERNET_LINK_100MBPS; } u32 NetDll_XNetDnsLookup_entry(u32 caller, mapped_string host, u32 event_handle, mapped_u32 pdns) {