From dbe8afaa5730e6fc8964c5e3fe54dc1012b07b5f Mon Sep 17 00:00:00 2001 From: MiTHRAL Date: Fri, 28 Aug 2026 02:25:31 -0400 Subject: [PATCH] netcode-revival: ghost client feeds the game's netcode transport (Phase 1c) - SendJoin carries the machine's virtual IP (v5) so the relay can route the game's UDP and answer session queries. - While the public relay is connected, keep rexglue's XNetTransport on the same relay + room (idempotent; reconnects on any change), so the game's RakNet netcode follows the room the player joined. --- src/native/skate3_native_ghost.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/native/skate3_native_ghost.cpp b/src/native/skate3_native_ghost.cpp index 5eb4a6e..a158e56 100644 --- a/src/native/skate3_native_ghost.cpp +++ b/src/native/skate3_native_ghost.cpp @@ -27,6 +27,7 @@ #include #include +#include #if defined(_WIN32) #include @@ -363,6 +364,10 @@ void SendJoin(GhostSock sock, const GhostAddr& to, bool ping) { std::memcpy(jp.room, g_room, g_room_len); jp.room_len = g_room_len; } + // v5: the machine's virtual IP (10.80.0.x) so the relay can route the + // game's own netcode and answer session queries. Mirrors the XNet layer's + // identity (single source of truth in the rexglue transport). + jp.virtual_ip = rex::system::XNetTransport::LocalVirtualIp(); // Display name: JOIN carries it so the relay can echo it in the roster; // the LAN discovery PING carries it too (a host can tag probes). CurrentDisplayName(jp.name, &jp.name_len); @@ -781,6 +786,14 @@ void GhostNetworkLoop() { // keeps the roster/name labels current as members join and leave), and // reconnect when the HELLO stream goes quiet. if (g_peer_public.configured) { + // netcode-revival: keep the game's own netcode transport on the same + // relay + room (idempotent; reconnect happens on any change). + char active_room[kGhostMaxRoomLen] = {}; + { + std::lock_guard lock(g_mu); + std::memcpy(active_room, g_room, g_room_len); + } + rex::system::XNetTransport::Instance().SetRelay(server.c_str(), port, active_room); if (now - g_peer_public.last_join >= kJoinIntervalSec) { SendJoin(sock, g_peer_public.addr, /*ping=*/false); g_peer_public.last_join = now;