diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index f3803d45..43262e73 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -16,9 +16,14 @@ #include "master.h" #include "proto_oob.h" #include "host.h" +#include "eiface.h" +#include "server.h" +extern ConVar sv_tags; extern ConVar sv_lan; +#define S2A_EXTRA_DATA_HAS_GAMETAG_DATA 0x01 // Next bytes are the game tag string + //----------------------------------------------------------------------------- // Purpose: List of master servers and some state info about them //----------------------------------------------------------------------------- @@ -65,6 +70,8 @@ public: void RunFrame(); void RequestServersInfo(); + void ReplyInfo( const netadr_t &adr ); + newgameserver_t &ProcessInfo( bf_read &buf ); // SeversInfo void RequestInternetServerList( const char *gamedir, IServerListResponse *response ); @@ -116,6 +123,79 @@ void CMaster::RunFrame() CheckHeartbeat(); } +void CMaster::ReplyInfo( const netadr_t &adr ) +{ + static char gamedir[MAX_OSPATH]; + Q_FileBase( com_gamedir, gamedir, sizeof( gamedir ) ); + + CUtlBuffer buf; + buf.EnsureCapacity( 2048 ); + + buf.PutUnsignedInt( LittleDWord( CONNECTIONLESS_HEADER ) ); + buf.PutUnsignedChar( S2C_INFOREPLY ); + + buf.PutUnsignedChar( PROTOCOL_VERSION ); // Hardcoded protocol version number + buf.PutString( sv.GetName() ); + buf.PutString( sv.GetMapName() ); + buf.PutString( gamedir ); + buf.PutString( serverGameDLL->GetGameDescription() ); + + // player info + buf.PutUnsignedChar( sv.GetNumClients() ); + buf.PutUnsignedChar( sv.GetMaxClients() ); + buf.PutUnsignedChar( sv.GetNumFakeClients() ); + + // Password? + buf.PutUnsignedChar( sv.GetPassword() != NULL ? 1 : 0 ); + + // Write a byte with some flags that describe what is to follow. + const char *pchTags = sv_tags.GetString(); + int nFlags = 0; + + if ( pchTags && pchTags[0] != '\0' ) + nFlags |= S2A_EXTRA_DATA_HAS_GAMETAG_DATA; + + buf.PutUnsignedInt( nFlags ); + + if ( nFlags & S2A_EXTRA_DATA_HAS_GAMETAG_DATA ) + { + buf.PutString( pchTags ); + } + + NET_SendPacket( NULL, NS_SERVER, adr, (unsigned char *)buf.Base(), buf.TellPut() ); +} + +newgameserver_t &CMaster::ProcessInfo(bf_read &buf) +{ + static newgameserver_t s; + memset( &s, 0, sizeof(s) ); + + s.m_nProtocolVersion = buf.ReadByte(); + + buf.ReadString( s.m_szServerName, sizeof(s.m_szServerName) ); + buf.ReadString( s.m_szMap, sizeof(s.m_szMap) ); + buf.ReadString( s.m_szGameDir, sizeof(s.m_szGameDir) ); + + buf.ReadString( s.m_szGameDescription, sizeof(s.m_szGameDescription) ); + + // player info + s.m_nPlayers = buf.ReadByte(); + s.m_nMaxPlayers = buf.ReadByte(); + s.m_nBotPlayers = buf.ReadByte(); + + // Password? + s.m_bPassword = buf.ReadByte(); + + s.m_iFlags = buf.ReadLong(); + + if( s.m_iFlags & S2A_EXTRA_DATA_HAS_GAMETAG_DATA ) + { + buf.ReadString( s.m_szGameTags, sizeof(s.m_szGameTags) ); + } + + return s; +} + void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) { static ALIGN4 char string[2048] ALIGN4_POST; // Buffer for sending heartbeat @@ -158,27 +238,24 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) } case C2S_INFOREQUEST: { - bf_write p(string, sizeof(string)); - p.WriteLong(CONNECTIONLESS_HEADER); - p.WriteByte(S2C_INFOREPLY); - p.WriteString(sv.GetName()); - - NET_SendPacket(NULL, NS_SERVER, packet->from, p.GetData(), p.GetNumBytesWritten()); - + ReplyInfo(packet->from); break; } case S2C_INFOREPLY: { - char hostname[1024]; - msg.ReadString(hostname, sizeof(hostname)); + newgameserver_t &s = ProcessInfo( msg ); + Msg("hostname = %s\nplayers: %d/%d\nbots: %d\n", s.m_szServerName, s.m_nPlayers, s.m_nMaxPlayers, s.m_nBotPlayers); - newgameserver_t s; s.m_NetAdr = packet->from; - s.SetName( hostname ); - m_serverListResponse->ServerResponded( s ); break; } + case A2A_PING: + { + const char p = A2A_ACK; + NET_SendPacket( NULL, NS_SERVER, packet->from, (unsigned char*)&p, 1); + break; + } } } diff --git a/public/engine/iserversinfo.h b/public/engine/iserversinfo.h index 8e80d0c4..e2fd07de 100644 --- a/public/engine/iserversinfo.h +++ b/public/engine/iserversinfo.h @@ -25,25 +25,23 @@ class newgameserver_t public: newgameserver_t() = default; - const char* GetName() const { return m_szServerName; } - void SetName( const char *pName ) - { - strncpy( m_szServerName, pName, sizeof(m_szServerName) ); - } - netadr_t m_NetAdr; ///< IP/Query Port/Connection Port for this server int m_nPing; ///< current ping time in milliseconds + int m_nProtocolVersion; bool m_bHadSuccessfulResponse; ///< server has responded successfully in the past bool m_bDoNotRefresh; ///< server is marked as not responding and should no longer be refreshed char m_szGameDir[MAX_PATH]; ///< current game directory char m_szMap[MAX_PATH]; ///< current map + char m_szGameTags[MAX_PATH]; char m_szGameDescription[MAX_GAME_DESCRIPTION]; ///< game description int m_nPlayers; int m_nMaxPlayers; ///< Maximum players that can join this server int m_nBotPlayers; ///< Number of bots (i.e simulated players) on this server bool m_bPassword; ///< true if this server needs a password to join -private: + + int m_iFlags; + /// Game server name char m_szServerName[MAX_SERVER_NAME]; }; diff --git a/serverbrowser/BaseGamesPage.cpp b/serverbrowser/BaseGamesPage.cpp index 6bdba32f..5f76f78d 100644 --- a/serverbrowser/BaseGamesPage.cpp +++ b/serverbrowser/BaseGamesPage.cpp @@ -2203,8 +2203,6 @@ const char *CBaseGamesPage::GetConnectCode() void CBaseGamesPage::ServerResponded( newgameserver_t &server ) { - Msg("Serverbrowser: hostname %s\n", server.GetName()); - Assert( server.m_NetAdr.GetIPHostByteOrder() != 0 ); newgameserver_t *pServerItem = &server; @@ -2232,7 +2230,7 @@ void CBaseGamesPage::ServerResponded( newgameserver_t &server ) // new entry KeyValues *kv = new KeyValues("Server"); - kv->SetString("name", pServerItem->GetName()); + kv->SetString("name", pServerItem->m_szServerName); kv->SetString("map", pServerItem->m_szMap); kv->SetString("GameDir", pServerItem->m_szGameDir); kv->SetString("GameDesc", pServerItem->m_szGameDescription); @@ -2278,15 +2276,6 @@ void CBaseGamesPage::ServerResponded( newgameserver_t &server ) } }*/ -// if ( pServer->m_bDoNotRefresh ) - { - // clear out the vars - kv->SetString("Ping", ""); - kv->SetWString("GameDesc", g_pVGuiLocalize->Find("#ServerBrowser_NotResponding")); - kv->SetString("Players", ""); - kv->SetString("map", ""); - } - int iServerIndex = m_serversInfo.AddToTail( server ); //if ( !m_pGameList->IsValidItemID( pServer->m_iListID ) ) diff --git a/serverbrowser/InternetGames.cpp b/serverbrowser/InternetGames.cpp index afe94f90..2e77e0ab 100644 --- a/serverbrowser/InternetGames.cpp +++ b/serverbrowser/InternetGames.cpp @@ -127,7 +127,6 @@ void CInternetGames::OnTick() void CInternetGames::ServerResponded( newgameserver_t &server ) { m_bDirty = true; - Msg("InternetGames::ServerResponded hostname = %s\n", server.GetName()); BaseClass::ServerResponded( server ); m_bAnyServersRespondedToQuery = true;