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.
This commit is contained in:
MiTHRAL 2026-08-28 02:25:31 -04:00
parent 7e86b8563a
commit dbe8afaa57

View file

@ -27,6 +27,7 @@
#include <rex/cvar.h> #include <rex/cvar.h>
#include <rex/logging.h> #include <rex/logging.h>
#include <rex/system/xnet_transport.h>
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h> #include <windows.h>
@ -363,6 +364,10 @@ void SendJoin(GhostSock sock, const GhostAddr& to, bool ping) {
std::memcpy(jp.room, g_room, g_room_len); std::memcpy(jp.room, g_room, g_room_len);
jp.room_len = 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; // 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). // the LAN discovery PING carries it too (a host can tag probes).
CurrentDisplayName(jp.name, &jp.name_len); CurrentDisplayName(jp.name, &jp.name_len);
@ -781,6 +786,14 @@ void GhostNetworkLoop() {
// keeps the roster/name labels current as members join and leave), and // keeps the roster/name labels current as members join and leave), and
// reconnect when the HELLO stream goes quiet. // reconnect when the HELLO stream goes quiet.
if (g_peer_public.configured) { 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<std::mutex> 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) { if (now - g_peer_public.last_join >= kJoinIntervalSec) {
SendJoin(sock, g_peer_public.addr, /*ping=*/false); SendJoin(sock, g_peer_public.addr, /*ping=*/false);
g_peer_public.last_join = now; g_peer_public.last_join = now;