diff --git a/MUNGA_L4/L4STEAMTRANSPORT.cpp b/MUNGA_L4/L4STEAMTRANSPORT.cpp index a718140..0d19d3b 100644 --- a/MUNGA_L4/L4STEAMTRANSPORT.cpp +++ b/MUNGA_L4/L4STEAMTRANSPORT.cpp @@ -65,6 +65,7 @@ namespace unsigned long fakeIP; // host order unsigned short fakeConsolePort; // host order unsigned short fakeGamePort; // host order + unsigned __int64 steamID; // identity -> global FakeIP on accept }; // engine-side port convention (lobby default; game port is +1) @@ -500,14 +501,38 @@ namespace } --listener->pendingCount; - // the remote engine port is the same engine port we accept - // on: all pods share the -net convention under Steam + // + // The remote engine port is the same engine port we accept + // on (all pods share the -net convention under Steam). The + // caller's address: Steam reports incoming connections + // under a locally-allocated ALIAS FakeIP, so resolve the + // caller's identity through the peer table to the GLOBAL + // FakeIP the egg's [pilots] list promised - the engine's + // mesh identity checks compare against that. + // unsigned long remote_ip_net = 0; - SteamNetworkingIPAddr remote_fake; - if (SteamNetworkingSockets()->GetRemoteFakeIPForConnection( - handle, &remote_fake) == k_EResultOK) + SteamNetConnectionInfo_t info; + if (SteamNetworkingSockets()->GetConnectionInfo(handle, &info)) { - remote_ip_net = htonl(remote_fake.GetIPv4()); + unsigned __int64 caller_id = info.m_identityRemote.GetSteamID64(); + for (int p = 0; p < gPeerCount; ++p) + { + if (gPeers[p].steamID != 0 && gPeers[p].steamID == caller_id) + { + remote_ip_net = htonl(gPeers[p].fakeIP); + break; + } + } + } + if (remote_ip_net == 0) + { + // unregistered caller: fall back to the alias address + SteamNetworkingIPAddr remote_fake; + if (SteamNetworkingSockets()->GetRemoteFakeIPForConnection( + handle, &remote_fake) == k_EResultOK) + { + remote_ip_net = htonl(remote_fake.GetIPv4()); + } } ConnectionRecord *record = AddConnection( handle, remote_ip_net, htons(listener->enginePort)); @@ -676,6 +701,16 @@ Logical SteamNetworkingUtils()->InitRelayNetworkAccess(); + // + // Mission load stalls the game thread for 10-30s with nothing + // pumping - Steam's default 10s connected-timeout would shear + // every connection mid-load (seen live: end reason 4001 with rx + // ages right at load duration). TCP never timed out idle arcade + // links; 90s keeps that spirit. + // + SteamNetworkingUtils()->SetGlobalConfigValueInt32( + k_ESteamNetworkingConfig_TimeoutConnected, 90 * 1000); + if (!SteamNetworkingSockets()->BeginAsyncRequestFakeIP(2)) { DEBUG_STREAM << "SteamNetTransport: BeginAsyncRequestFakeIP failed - staying on TCP\n" << std::flush; @@ -734,7 +769,8 @@ Logical { DEBUG_STREAM << "SteamNetTransport: SELF TEST starting\n" << std::flush; SteamNetTransport_RegisterPeer( - gLocalFakeAddressString, gLocalFakePorts[0], gLocalFakePorts[1]); + gLocalFakeAddressString, gLocalFakePorts[0], gLocalFakePorts[1], + SteamUser()->GetSteamID().ConvertToUint64()); NetTransport *transport = &gSteamTransport; NetTransport::Connection listener = transport->Listen(1501, 1); @@ -833,7 +869,8 @@ void SteamNetTransport_RegisterPeer( const char *fake_ip, int fake_console_port, - int fake_game_port + int fake_game_port, + unsigned __int64 steam_id ) { SteamNetworkingIPAddr parsed; @@ -847,6 +884,7 @@ void { gPeers[i].fakeConsolePort = (unsigned short) fake_console_port; gPeers[i].fakeGamePort = (unsigned short) fake_game_port; + gPeers[i].steamID = steam_id; return; } } @@ -857,10 +895,11 @@ void gPeers[gPeerCount].fakeIP = parsed.GetIPv4(); gPeers[gPeerCount].fakeConsolePort = (unsigned short) fake_console_port; gPeers[gPeerCount].fakeGamePort = (unsigned short) fake_game_port; + gPeers[gPeerCount].steamID = steam_id; ++gPeerCount; DEBUG_STREAM << "SteamNetTransport: peer registered: " << fake_ip << " (console " << fake_console_port << ", game " - << fake_game_port << ")\n" << std::flush; + << fake_game_port << ", id " << steam_id << ")\n" << std::flush; } #endif // RP412_STEAM diff --git a/MUNGA_L4/L4STEAMTRANSPORT.h b/MUNGA_L4/L4STEAMTRANSPORT.h index f6f3b8a..0a333bc 100644 --- a/MUNGA_L4/L4STEAMTRANSPORT.h +++ b/MUNGA_L4/L4STEAMTRANSPORT.h @@ -81,13 +81,17 @@ int void SteamNetTransport_SetEnginePorts(int console_port); -// The lobby feeds every member's FakeIP + fake ports here before -// anything dials out. Registering is idempotent per IP. +// The lobby feeds every member's FakeIP + fake ports + SteamID here +// before anything dials out. The SteamID matters on accept: Steam +// reports incoming callers under locally-allocated alias addresses, +// so the transport maps the caller's identity back to the global +// FakeIP the egg promised. Registering is idempotent per IP. void SteamNetTransport_RegisterPeer( const char *fake_ip, int fake_console_port, - int fake_game_port + int fake_game_port, + unsigned __int64 steam_id ); #endif // RP412_STEAM diff --git a/RP_L4/RPL4LOBBY.cpp b/RP_L4/RPL4LOBBY.cpp index cbbc42b..929e871 100644 --- a/RP_L4/RPL4LOBBY.cpp +++ b/RP_L4/RPL4LOBBY.cpp @@ -205,7 +205,8 @@ namespace if (members[i].published) { SteamNetTransport_RegisterPeer( - members[i].ip, members[i].consolePort, members[i].gamePort); + members[i].ip, members[i].consolePort, members[i].gamePort, + members[i].id.ConvertToUint64()); } } } @@ -513,13 +514,14 @@ namespace if (all_published && room.memberCount >= 1) { ++gLastGoNonce; - char go[600]; + char go[800]; sprintf(go, "%d:", gLastGoNonce); for (int i = 0; i < room.memberCount; ++i) { - char entry[64]; - sprintf(entry, "%s|%d|%d;", room.members[i].ip, - room.members[i].consolePort, room.members[i].gamePort); + char entry[96]; + sprintf(entry, "%s|%d|%d|%I64u;", room.members[i].ip, + room.members[i].consolePort, room.members[i].gamePort, + room.members[i].id.ConvertToUint64()); if (strlen(go) + strlen(entry) < sizeof(go)) { strcat(go, entry); @@ -554,6 +556,7 @@ namespace { char ip[32]; int console_port = 0, game_port = 0; + unsigned __int64 steam_id = 0; int n = 0; while (cursor[n] != '\0' && cursor[n] != '|' && n < (int) sizeof(ip) - 1) @@ -571,13 +574,19 @@ namespace if (*cursor == '|') { game_port = atoi(++cursor); + while (*cursor != '\0' && *cursor != '|' && *cursor != ';') ++cursor; + } + if (*cursor == '|') + { + steam_id = _strtoui64(++cursor, NULL, 10); } while (*cursor != '\0' && *cursor != ';') ++cursor; if (*cursor == ';') ++cursor; if (ip[0] != '\0' && console_port > 0 && game_port > 0) { - SteamNetTransport_RegisterPeer(ip, console_port, game_port); + SteamNetTransport_RegisterPeer( + ip, console_port, game_port, steam_id); } } outcome = LobbyLaunchMember;