Fix sending clients from lobby to game when lobby and game are on same server

In the current case (only "direct" lobby backend, i.e. connect to a
server directly), lobby and game are always on the same server anyway..

It used to send the IP of the first network interface.. that kinda works
on Windows and FreeBSD in LANs (i.e. not over the internet or even
behind a NAT), but not at all on Linux, because the first device seems
to be the loopback device there (at least on my machine)..
Now it sends net_ip (so it should even work behind NAT) or, if net_ip is
set to "localhost" (the default), 0.0.0.0 is sent, which the client
interprets as "just use the IP of the lobby you're already connected to"
This commit is contained in:
Daniel Gibson 2013-03-16 02:29:56 +01:00
parent 6e6703b93f
commit b38aff8995
4 changed files with 26 additions and 7 deletions

View file

@ -339,7 +339,7 @@ void idLobby::Shutdown( bool retainMigrationInfo, bool skipGoodbye )
idLobby::HandlePacket
========================
*/
// FIXME: remoteAddress const?
// TODO: remoteAddress const?
void idLobby::HandlePacket( lobbyAddress_t& remoteAddress, idBitMsg fragMsg, idPacketProcessor::sessionId_t sessionID )
{
SCOPED_PROFILE_EVENT( "HandlePacket" );
@ -590,7 +590,7 @@ void idLobby::HandlePacket( lobbyAddress_t& remoteAddress, idBitMsg fragMsg, idP
idBitMsg reliableMsg( reliableData, reliableSize );
reliableMsg.SetSize( reliableSize );
HandleReliableMsg( peerNum, reliableMsg );
HandleReliableMsg( peerNum, reliableMsg, &remoteAddress );
}
if( peerNum == -1 || !peers[ peerNum ].IsConnected() )
@ -2766,13 +2766,13 @@ const char* idLobby::GetPeerName( int peerNum ) const
idLobby::HandleReliableMsg
========================
*/
void idLobby::HandleReliableMsg( int p, idBitMsg& msg )
void idLobby::HandleReliableMsg( int p, idBitMsg& msg, const lobbyAddress_t* remoteAddress /* = NULL */ )
{
peer_t& peer = peers[p];
int reliableType = msg.ReadByte();
//idLib::Printf(" Received reliable msg: %i \n", reliableType );
NET_VERBOSE_PRINT( " Received reliable msg: %i \n", reliableType );
const lobbyType_t actingGameStateLobbyType = GetActingGameStateLobbyType();
@ -3022,8 +3022,17 @@ void idLobby::HandleReliableMsg( int p, idBitMsg& msg )
// Get connection info
lobbyConnectInfo_t connectInfo;
connectInfo.ReadFromMsg( msg );
// DG: if connectInfo.ip = 0.0.0.0 just use remoteAddress
// i.e. the IP used to connect to the lobby
if( remoteAddress && *( ( int* )connectInfo.netAddr.ip ) == 0 )
{
connectInfo.netAddr = remoteAddress->netAddr;
}
// DG end
const lobbyType_t destLobbyType = ( lobbyType_t )msg.ReadByte();
const bool waitForMembers = msg.ReadBool();

View file

@ -624,7 +624,7 @@ public: // Turning this on for now, for the sake of getting this up and running
const char* GetPeerName( int peerNum ) const;
virtual const char* GetHostUserName() const;
void HandleReliableMsg( int p, idBitMsg& msg );
void HandleReliableMsg( int p, idBitMsg& msg, const lobbyAddress_t* remoteAddress = NULL );
// Bandwidth / Qos / Throttling
void BeginBandwidthTest();

View file

@ -31,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#include "sys_lobby_backend_direct.h"
extern idCVar net_port;
extern idCVar net_ip;
extern idLobbyToSessionCB* lobbyToSessionCB;
@ -101,6 +102,7 @@ void idLobbyBackendDirect::JoinFromConnectInfo( const lobbyConnectInfo_t& connec
{
if( lobbyToSessionCB->CanJoinLocalHost() )
{
// TODO: "CanJoinLocalHost" == *must* join LocalHost ?!
Sys_StringToNetAdr( "localhost", &address, true );
address.port = net_port.GetInteger();
NET_VERBOSE_PRINT( "NET: idLobbyBackendDirect::JoinFromConnectInfo(): canJoinLocalHost\n" );
@ -178,7 +180,16 @@ lobbyConnectInfo_t idLobbyBackendDirect::GetConnectInfo()
if( IsHost() )
{
// If we are the host, give them our ip address
const char* ip = Sys_GetLocalIP( 0 ); // XXX: ohweiha.
// DG: always using the first IP doesn't work, because on linux that's 127.0.0.1
// and even if not, this causes trouble with NAT.
// So either use net_ip or, if it's not set ("localhost"), use 0.0.0.0 which is
// a special case the client will treat as "just use the IP I used for the lobby"
// (which is the right behavior for the Direct backend, I guess).
// the client special case is in idLobby::HandleReliableMsg
const char* ip = net_ip.GetString();
if( ip == NULL || idStr::Length( ip ) == 0 || idStr::Icmp( ip, "localhost" ) == 0 )
ip = "0.0.0.0";
// DG end
Sys_StringToNetAdr( ip, &address, false );
address.port = net_port.GetInteger();
}

View file

@ -1128,7 +1128,6 @@ bool idSessionLocal::State_Create_And_Move_To_Game_Lobby()
// Now that we've created our game lobby, send our own party users to it
// NOTE - We pass in false to wait on party members since we are the host, and we know they can connect to us
// TODO: special handling of ourselves here?
GetPartyLobby().SendMembersToLobby( GetGameLobby(), false );
return true;
}