From 0df7838ee197d93e1c58c59f3d9e3018267cb647 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 28 Jan 2023 05:29:26 +0300 Subject: [PATCH 01/17] WIP: initial masterserver client implementation --- common/proto_oob.h | 24 +- engine/baseclientstate.cpp | 3 + engine/baseserver.cpp | 3 + engine/host.cpp | 5 +- engine/master.h | 63 +++++ engine/masterserver.cpp | 502 +++++++++++++++++++++++++++++++++++ engine/net_chan.cpp | 5 + engine/net_ws.cpp | 14 +- engine/sv_steamauth.cpp | 2 +- engine/wscript | 3 +- public/engine/iserversinfo.h | 97 +++++++ 11 files changed, 703 insertions(+), 18 deletions(-) create mode 100644 engine/master.h create mode 100644 engine/masterserver.cpp create mode 100644 public/engine/iserversinfo.h diff --git a/common/proto_oob.h b/common/proto_oob.h index dbeeb60f..a6c70152 100644 --- a/common/proto_oob.h +++ b/common/proto_oob.h @@ -16,6 +16,8 @@ // This is used, unless overridden in the registry #define VALVE_MASTER_ADDRESS "207.173.177.10:27011" +#define HB_TIMEOUT 15 + #define PORT_RCON 27015 // defualt RCON port, TCP #define PORT_MASTER 27011 // Default master port, UDP #define PORT_CLIENT 27005 // Default client port, UDP/TCP @@ -29,6 +31,8 @@ #endif // ENABLE_RPT #define PORT_REPLAY 27040 // Default replay port +#define PORT_SERVERSINFO 27069 // Default matchmaking port + // out of band message id bytes // M = master, S = server, C = client, A = any @@ -80,16 +84,17 @@ // A user is requesting the list of master servers, auth servers, and titan dir servers from the Client Master server -#define A2M_GETMASTERSERVERS 'v' // + byte (type of request, TYPE_CLIENT_MASTER or TYPE_SERVER_MASTER) // Master server list response -#define M2A_MASTERSERVERS 'w' // + byte type + 6 byte IP/Port List +#define S2M_GETCHALLENGE 'w' // + dword challenge +#define S2M_HEARTBEAT 'y' +#define S2M_SHUTDOWN 'z' // Master peering message +#define M2S_CHALLENGE 'x' // + dword challenge +#define M2C_QUERY 'J' // request module from master +#define C2M_CLIENTQUERY '1' // New style server query -#define A2M_GETACTIVEMODS 'x' // + string Request to master to provide mod statistics ( current usage ). "1" for first mod. - -#define M2A_ACTIVEMODS 'y' // response: modname\r\nusers\r\nservers - -#define M2M_MSG 'z' // Master peering message +#define C2S_INFOREQUEST 'v' +#define S2C_INFOREPLY 'K' // SERVER TO CLIENT/ANY @@ -106,9 +111,6 @@ #define S2A_INFO_SRC 'I' // + Address, hostname, map, gamedir, gamedescription, active players, maxplayers, protocol #define S2A_INFO_GOLDSRC 'm' // Reserved for use by goldsrc servers -#define S2M_GETFILE 'J' // request module from master -#define M2S_SENDFILE 'K' // send module to server - #define S2C_REDIRECT 'L' // + IP x.x.x.x:port, redirect client to other server/proxy #define C2M_CHECKMD5 'M' // player client asks secure master if Module MD5 is valid @@ -133,8 +135,6 @@ #define A2S_KEY_STRING "Source Engine Query" // required postfix to a A2S_INFO query -#define A2M_GET_SERVERS_BATCH2 '1' // New style server query - #define A2M_GETACTIVEMODS2 '2' // New style mod info query #define C2S_AUTHREQUEST1 '3' // diff --git a/engine/baseclientstate.cpp b/engine/baseclientstate.cpp index bb0d3de3..ed001afd 100644 --- a/engine/baseclientstate.cpp +++ b/engine/baseclientstate.cpp @@ -37,6 +37,7 @@ #include "sv_plugin.h" #include "sys_dll.h" #include "host.h" +#include "master.h" #if defined( REPLAY_ENABLED ) #include "replay_internal.h" #include "replayserver.h" @@ -875,6 +876,8 @@ bool CBaseClientState::ProcessConnectionlessPacket( netpacket_t *packet ) Assert( packet ); + master->ProcessConnectionlessPacket( packet ); + bf_read &msg = packet->message; // handy shortcut int c = msg.ReadByte(); diff --git a/engine/baseserver.cpp b/engine/baseserver.cpp index b0acee7c..d9c61a96 100644 --- a/engine/baseserver.cpp +++ b/engine/baseserver.cpp @@ -56,6 +56,7 @@ #include "sv_ipratelimit.h" #include "cl_steamauth.h" #include "sv_filter.h" +#include "master.h" #if defined( _X360 ) #include "xbox/xbox_win32stubs.h" @@ -663,6 +664,8 @@ bool CBaseServer::ValidInfoChallenge( netadr_t & adr, const char *nugget ) bool CBaseServer::ProcessConnectionlessPacket(netpacket_t * packet) { + master->ProcessConnectionlessPacket( packet ); + bf_read msg = packet->message; // handy shortcut char c = msg.ReadChar(); diff --git a/engine/host.cpp b/engine/host.cpp index 9ebdc928..2e22474f 100644 --- a/engine/host.cpp +++ b/engine/host.cpp @@ -40,6 +40,7 @@ #include "steam/steam_api.h" #include "LoadScreenUpdate.h" #include "datacache/idatacache.h" +#include "master.h" #if !defined SWDS #include "voice.h" @@ -1820,6 +1821,8 @@ void Host_ShutdownServer( void ) if ( !sv.IsActive() ) return; + master->ShutdownConnection(); + Host_AllowQueuedMaterialSystem( false ); // clear structures #if !defined( SWDS ) @@ -4951,7 +4954,7 @@ void Host_Shutdown(void) TRACESHUTDOWN( HLTV_Shutdown() ); TRACESHUTDOWN( g_Log.Shutdown() ); - + TRACESHUTDOWN( g_GameEventManager.Shutdown() ); TRACESHUTDOWN( sv.Shutdown() ); diff --git a/engine/master.h b/engine/master.h new file mode 100644 index 00000000..eddb39e0 --- /dev/null +++ b/engine/master.h @@ -0,0 +1,63 @@ +//======== (C) Copyright 1999, 2000 Valve, L.L.C. All rights reserved. ======== +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//============================================================================= +#ifndef MASTER_H +#define MASTER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "engine/iserversinfo.h" + +#define DEFAULT_MASTER_ADDRESS "185.192.97.130:27010" + +//----------------------------------------------------------------------------- +// Purpose: Implements a master server interface. +//----------------------------------------------------------------------------- +class IMaster +{ +public: + // Allow master server to register cvars/commands + virtual void Init( void ) = 0; + // System is shutting down + virtual void Shutdown( void ) = 0; + // Server is shutting down + virtual void ShutdownConnection( void ) = 0; + // Sends the actual heartbeat to the master ( after challenge value is parsed ) + virtual void SendHeartbeat( struct adrlist_s *p ) = 0; + // Add server to global master list + virtual void AddServer( struct netadr_s *adr ) = 0; + // If parsing for server, etc. fails, always have at least one server around to use. + virtual void UseDefault ( void ) = 0; + // See if it's time to send the next heartbeat + virtual void CheckHeartbeat( void ) = 0; + // Master sent back a challenge value, read it and send the actual heartbeat + virtual void RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ) = 0; + // Console command to set/remove master server + virtual void SetMaster_f( void ) = 0; + // Force a heartbeat to be issued right away + virtual void Heartbeat_f( void ) = 0; + + virtual void ProcessConnectionlessPacket( netpacket_t *packet ) = 0; + + virtual void RunFrame( void ) = 0; +}; + +extern IMaster *master; +extern IServersInfo *g_pServersInfo; + +#endif // MASTER_H diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp new file mode 100644 index 00000000..62d7e614 --- /dev/null +++ b/engine/masterserver.cpp @@ -0,0 +1,502 @@ +//======177== (C) Copyright 1999, 2000 Valve, L.L.C. All rights reserved. ======== +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//============================================================================= +#include "quakedef.h" +#include "server.h" +#include "master.h" +#include "proto_oob.h" +#include "host.h" + +extern ConVar sv_lan; + +//----------------------------------------------------------------------------- +// Purpose: List of master servers and some state info about them +//----------------------------------------------------------------------------- +typedef struct adrlist_s +{ + // Next master in chain + struct adrlist_s *next; + // Challenge request sent to master + qboolean heartbeatwaiting; + // Challenge request send time + float heartbeatwaitingtime; + // Last one is Main master + int heartbeatchallenge; + // Time we sent last heartbeat + double last_heartbeat; + // Master server address + netadr_t adr; +} adrlist_t; + +//----------------------------------------------------------------------------- +// Purpose: Implements the master server interface +//----------------------------------------------------------------------------- +class CMaster : public IMaster, public IServersInfo +{ +public: + CMaster( void ); + virtual ~CMaster( void ); + + // Heartbeat functions. + void Init( void ); + void Shutdown( void ); + // Sets up master address + void ShutdownConnection(void); + void SendHeartbeat( struct adrlist_s *p ); + void AddServer( struct netadr_s *adr ); + void UseDefault ( void ); + void CheckHeartbeat (void); + void RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ); + + void ProcessConnectionlessPacket( netpacket_t *packet ); + + void SetMaster_f( void ); + void Heartbeat_f( void ); + + void RunFrame(); + void RequestServersInfo(); + + // SeversInfo + void RequestInternetServerList( const char *gamedir, IServerListResponse *response ); + void RequestLANServerList( const char *gamedir, IServerListResponse *response ); + void AddServerAddresses( netadr_t **adr, int count ); +private: + // List of known master servers + adrlist_t *m_pMasterAddresses; + + bool m_bInitialized; + + // If nomaster is true, the server will not send heartbeats to the master server + bool m_bNoMasters; + + CUtlLinkedList m_serverAddresses; +}; + +static CMaster s_MasterServer; +IMaster *master = (IMaster *)&s_MasterServer; + +IServersInfo *g_pServersInfo = (IServersInfo*)&s_MasterServer; + +#define HEARTBEAT_SECONDS 140.0 + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CMaster::CMaster( void ) +{ + m_pMasterAddresses = NULL; + m_bNoMasters = false; + m_bInitialized = false; + Init(); +} + +CMaster::~CMaster( void ) +{ +} + +void CMaster::RunFrame() +{ + CheckHeartbeat(); +} + +void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) +{ + static ALIGN4 char string[2048] ALIGN4_POST; // Buffer for sending heartbeat + + uint ip; uint16 port; + + bf_read msg = packet->message; + char c = msg.ReadChar(); + + if ( c == 0 ) + return; + + switch( c ) + { + case M2S_CHALLENGE: + { + RespondToHeartbeatChallenge( packet->from, msg ); + break; + } + case M2C_QUERY: + { + if( m_serverAddresses.Count() > 0 ) + m_serverAddresses.RemoveAll(); + + ip = msg.ReadLong(); + port = msg.ReadShort(); + + while( ip != 0 && port != 0 ) + { + netadr_t adr(ip, port); + + m_serverAddresses.AddToHead(adr); + + ip = msg.ReadLong(); + port = msg.ReadShort(); + } + + RequestServersInfo(); + break; + } + 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()); + + break; + } + case S2C_INFOREPLY: + { + char hostname[1024]; + msg.ReadString(hostname, sizeof(hostname)); + + break; + } + } +} + +void CMaster::RequestServersInfo() +{ + static ALIGN4 char string[256] ALIGN4_POST; // Buffer for sending heartbeat + + bf_write msg( string, sizeof(string) ); + + FOR_EACH_LL( m_serverAddresses, i ) + { + const netadr_t adr = m_serverAddresses[i]; + + msg.WriteLong( CONNECTIONLESS_HEADER ); + msg.WriteByte( C2S_INFOREQUEST ); + + NET_SendPacket( NULL, NS_CLIENT, adr, msg.GetData(), msg.GetNumBytesWritten() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Sends a heartbeat to the master server +// Input : *p - x00\x00\x00\x00\x00\x00 +//----------------------------------------------------------------------------- +void CMaster::SendHeartbeat ( adrlist_t *p ) +{ + static ALIGN4 char string[256] ALIGN4_POST; // Buffer for sending heartbeat + char szGD[ MAX_OSPATH ]; + + if ( !p ) + return; + + // Still waiting on challenge response? + if ( p->heartbeatwaiting ) + return; + + // Waited too long + if ( (realtime - p->heartbeatwaitingtime ) >= HB_TIMEOUT ) + return; + + // Send to master + // TODO(nillerusr): send engine version in this packet + Q_FileBase( com_gamedir, szGD, sizeof( szGD ) ); + + bf_write buf( string, sizeof(string) ); + buf.WriteByte( S2M_HEARTBEAT ); + buf.WriteLong( p->heartbeatchallenge ); + buf.WriteShort( PROTOCOL_VERSION ); + buf.WriteString( szGD ); + + NET_SendPacket( NULL, NS_SERVER, p->adr, buf.GetData(), buf.GetNumBytesWritten() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Requests a challenge so we can then send a heartbeat +//----------------------------------------------------------------------------- +void CMaster::CheckHeartbeat (void) +{ + adrlist_t *p; + ALIGN4 char buf[256] ALIGN4_POST; + + if ( m_bNoMasters || // We are ignoring heartbeats + sv_lan.GetInt() || // Lan servers don't heartbeat + (sv.GetMaxClients() <= 1) || // not a multiplayer server. + !sv.IsActive() ) // only heartbeat if a server is running. + return; + + p = m_pMasterAddresses; + while ( p ) + { + // Time for another try? + if ( ( realtime - p->last_heartbeat) < HEARTBEAT_SECONDS) // not time to send yet + { + p = p->next; + continue; + } + + // Should we resend challenge request? + if ( p->heartbeatwaiting && + ( ( realtime - p->heartbeatwaitingtime ) < HB_TIMEOUT ) ) + { + p = p->next; + continue; + } + + int32 challenge = RandomInt( 0, INT_MAX ); + + p->heartbeatwaiting = true; + p->heartbeatwaitingtime = realtime; + + p->last_heartbeat = realtime; // Flag at start so we don't just keep trying for hb's when + p->heartbeatchallenge = challenge; + + bf_write msg("Master Join", buf, sizeof(buf)); + + msg.WriteByte( S2M_GETCHALLENGE ); + msg.WriteLong( challenge ); + + // Send to master asking for a challenge # + NET_SendPacket( NULL, NS_SERVER, p->adr, msg.GetData(), msg.GetNumBytesWritten() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Server is shutting down, unload master servers list, tell masters that we are closing the server +//----------------------------------------------------------------------------- +void CMaster::ShutdownConnection( void ) +{ + adrlist_t *p; + + if ( !host_initialized ) + return; + + if ( m_bNoMasters || // We are ignoring heartbeats + sv_lan.GetInt() || // Lan servers don't heartbeat + (sv.GetMaxClients() <= 1) ) // not a multiplayer server. + return; + + const char packet = S2M_SHUTDOWN; + + p = m_pMasterAddresses; + while ( p ) + { + NET_SendPacket( NULL, NS_SERVER, p->adr, (unsigned char*)&packet, 1); + p->last_heartbeat = -99999.0; + p = p->next; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Add server to the master list +// Input : *adr - +//----------------------------------------------------------------------------- +void CMaster::AddServer( netadr_t *adr ) +{ + adrlist_t *n; + + // See if it's there + n = m_pMasterAddresses; + while ( n ) + { + if ( n->adr.CompareAdr( *adr ) ) + break; + n = n->next; + } + + // Found it in the list. + if ( n ) + return; + + n = ( adrlist_t * ) malloc ( sizeof( adrlist_t ) ); + if ( !n ) + Sys_Error( "Error allocating %i bytes for master address.", sizeof( adrlist_t ) ); + + memset( n, 0, sizeof( adrlist_t ) ); + + n->adr = *adr; + + // Queue up a full heartbeat to all master servers. + n->last_heartbeat = -99999.0; + + // Link it in. + n->next = m_pMasterAddresses; + m_pMasterAddresses = n; +} + +//----------------------------------------------------------------------------- +// Purpose: Add built-in default master if woncomm.lst doesn't parse +//----------------------------------------------------------------------------- +void CMaster::UseDefault ( void ) +{ + netadr_t adr; + + // Convert to netadr_t + if ( NET_StringToAdr ( DEFAULT_MASTER_ADDRESS, &adr ) ) + { + // Add to master list + AddServer( &adr ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMaster::RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ) +{ + adrlist_t *p; + uint challenge, challenge2; + + // No masters, just ignore. + if ( !m_pMasterAddresses ) + return; + + p = m_pMasterAddresses; + while ( p ) + { + if ( from.CompareAdr( p->adr ) ) + break; + + p = p->next; + } + + // Not a known master server. + if ( !p ) + return; + + challenge = msg.ReadLong(); + challenge2 = msg.ReadLong(); + + if( p->heartbeatchallenge != challenge2 ) + { + Warning("unexpected master server info query packet (wrong challenge!)\n"); + return; + } + + // Kill timer + p->heartbeatwaiting = false; + p->heartbeatchallenge = challenge; + + // Send the actual heartbeat request to this master server. + SendHeartbeat( p ); +} + +//----------------------------------------------------------------------------- +// Purpose: Add/remove master servers +//----------------------------------------------------------------------------- +void CMaster::SetMaster_f (void) +{ + +} + + +//----------------------------------------------------------------------------- +// Purpose: Send a new heartbeat to the master +//----------------------------------------------------------------------------- +void CMaster::Heartbeat_f (void) +{ + adrlist_t *p; + + p = m_pMasterAddresses; + while ( p ) + { + // Queue up a full hearbeat + p->last_heartbeat = -9999.0; + p->heartbeatwaitingtime = -9999.0; + p = p->next; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void SetMaster_f( void ) +{ + master->SetMaster_f(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void Heartbeat1_f( void ) +{ + master->Heartbeat_f(); +} + +static ConCommand setmaster("setmaster", SetMaster_f ); +static ConCommand heartbeat("heartbeat", Heartbeat1_f, "Force heartbeat of master servers" ); + +//----------------------------------------------------------------------------- +// Purpose: Adds master server console commands +//----------------------------------------------------------------------------- +void CMaster::Init( void ) +{ + // Already able to initialize at least once? + if ( m_bInitialized ) + return; + + // So we don't do this a send time.sv_mas + m_bInitialized = true; + + UseDefault(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMaster::Shutdown(void) +{ + adrlist_t *p, *n; + + // Free the master list now. + p = m_pMasterAddresses; + while ( p ) + { + n = p->next; + free( p ); + p = n; + } + + m_pMasterAddresses = NULL; +} + +// ServersInfo +void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse *response) +{ + if( m_bNoMasters ) return; + + ALIGN4 char buf[256] ALIGN4_POST; + bf_write msg(buf, sizeof(buf)); + + msg.WriteByte( C2M_CLIENTQUERY ); + msg.WriteString(gamedir); + + // TODO(nillerusr): add switching between masters? + NET_SendPacket(NULL, NS_CLIENT, m_pMasterAddresses->adr, msg.GetData(), msg.GetNumBytesWritten() ); +} + +void CMaster::RequestLANServerList(const char *gamedir, IServerListResponse *response) +{ + +} + +void CMaster::AddServerAddresses( netadr_t **adr, int count ) +{ + +} + +void Master_Request_f() +{ + g_pServersInfo->RequestInternetServerList("cstrike", NULL); +} + +ConCommand master_request( "master_request", Master_Request_f ); diff --git a/engine/net_chan.cpp b/engine/net_chan.cpp index bccf0073..e722bc02 100644 --- a/engine/net_chan.cpp +++ b/engine/net_chan.cpp @@ -64,10 +64,15 @@ extern int NET_ReceiveStream( int nSock, char * buf, int len, int flags ); // We only need to checksum packets on the PC and only when we're actually sending them over the network. static bool ShouldChecksumPackets() { + // nillerusr: temporary solution for testing + return false; + +#if 0 if ( !IsPC() ) return false; return NET_IsMultiplayer(); +#endif } bool CNetChan::IsLoopback() const diff --git a/engine/net_ws.cpp b/engine/net_ws.cpp index ba3a791e..b2680f1a 100644 --- a/engine/net_ws.cpp +++ b/engine/net_ws.cpp @@ -13,6 +13,7 @@ #include "net_ws_headers.h" #include "net_ws_queued_packet_sender.h" #include "fmtstr.h" +#include "master.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1644,7 +1645,7 @@ netpacket_t *NET_GetPacket (int sock, byte *scratch ) // Check loopback first if ( !NET_GetLoopPacket( &inpacket ) ) { - if ( !NET_IsMultiplayer() ) + if ( !NET_IsMultiplayer() && sock != NS_CLIENT ) { return NULL; } @@ -2351,7 +2352,7 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns Msg("UDP -> %s: sz=%i OOB '%c'\n", to.ToString(), length, data[4] ); } - if ( !NET_IsMultiplayer() || to.type == NA_LOOPBACK || ( to.IsLocalhost() && !net_usesocketsforloopback.GetBool() ) ) + if ( (!NET_IsMultiplayer() && sock != NS_CLIENT) || to.type == NA_LOOPBACK || ( to.IsLocalhost() && !net_usesocketsforloopback.GetBool() ) ) { Assert( !pVoicePayload ); @@ -2988,6 +2989,8 @@ void NET_RunFrame( double flRealtime ) #endif // SWDS + master->RunFrame(); + #ifdef _X360 if ( net_logserver.GetInt() ) { @@ -3110,7 +3113,7 @@ void NET_ListenSocket( int sock, bool bListen ) NET_CloseSocket( netsock->hTCP, sock ); } - if ( !NET_IsMultiplayer() || net_notcp ) + if ( (!NET_IsMultiplayer() && sock != NS_CLIENT) || net_notcp ) return; if ( bListen ) @@ -3296,6 +3299,11 @@ void NET_Init( bool bIsDedicated ) ipname.SetValue( ip ); // update the cvar right now, this will get overwritten by "stuffcmds" later } + const int nProtocol = X360SecureNetwork() ? IPPROTO_VDP : IPPROTO_UDP; + + // open client socket for masterserver + OpenSocketInternal( NS_CLIENT, clientport.GetInt(), PORT_SERVER, "client", nProtocol, true ); + if ( bIsDedicated ) { // set dedicated MP mode diff --git a/engine/sv_steamauth.cpp b/engine/sv_steamauth.cpp index 144ae775..caa14cea 100644 --- a/engine/sv_steamauth.cpp +++ b/engine/sv_steamauth.cpp @@ -1005,7 +1005,7 @@ void Heartbeat_f() } } -static ConCommand heartbeat( "heartbeat", Heartbeat_f, "Force heartbeat of master servers", 0 ); +//static ConCommand heartbeat( "heartbeat", Heartbeat_f, "Force heartbeat of master servers", 0 ); //----------------------------------------------------------------------------- diff --git a/engine/wscript b/engine/wscript index 6ef0bc77..81456630 100755 --- a/engine/wscript +++ b/engine/wscript @@ -329,7 +329,8 @@ def build(bld): 'vgui_texturebudgetpanel.cpp', 'vgui_vprofgraphpanel.cpp', 'vgui_vprofpanel.cpp', - 'toolframework.cpp' + 'toolframework.cpp', + 'masterserver.cpp', ] if bld.env.DEST_OS != 'win32': diff --git a/public/engine/iserversinfo.h b/public/engine/iserversinfo.h new file mode 100644 index 00000000..663feb75 --- /dev/null +++ b/public/engine/iserversinfo.h @@ -0,0 +1,97 @@ +//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. ======= +// +// Purpose: interface to steam managing game server/client match making +// +//============================================================================= + +#ifndef ISERVERSINFO_H +#define ISERVERSINFO_H +#ifdef _WIN32 +#pragma once +#endif + +#define MAX_GAME_DESCRIPTION 8192 +#define MAX_SERVER_NAME 2048 + +enum ServerResponse +{ + ServerResponded = 0, + ServerFailedToRespond, + NoServersListedOnMasterServer, +}; + +class newgameserver_t +{ +public: + newgameserver_t() = default; + + const char* GetName() const; + void SetName( const char *pName ); + + netadr_t m_NetAdr; ///< IP/Query Port/Connection Port for this server + int m_nPing; ///< current ping time in milliseconds + 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_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: + /// Game server name + char m_szServerName[MAX_SERVER_NAME]; +}; + +class IServerListResponse +{ +public: + // Server has responded ok with updated data + virtual void ServerResponded( newgameserver_t &server ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Callback interface for receiving responses after pinging an individual server +// +class IServerPingResponse +{ +public: + // Server has responded successfully and has updated data + virtual void ServerResponded( newgameserver_t &server ) = 0; +}; +//----------------------------------------------------------------------------- +// Purpose: Callback interface for receiving responses after requesting details on +// who is playing on a particular server. +// +class IServerPlayersResponse +{ +public: + // Got data on a new player on the server -- you'll get this callback once per player + // on the server which you have requested player data on. + virtual void AddPlayerToList( const char *pchName, int nScore, float flTimePlayed ) = 0; + + // The server failed to respond to the request for player details + virtual void PlayersFailedToRespond() = 0; + + // The server has finished responding to the player details request + virtual void PlayersRefreshComplete() = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Functions for match making services for clients to get to game lists and details +//----------------------------------------------------------------------------- +class IServersInfo +{ +public: + virtual void RequestInternetServerList( const char *gamedir, IServerListResponse *response ) = 0; + virtual void RequestLANServerList( const char *gamedir, IServerListResponse *response ) = 0; + + //virtual HServerQuery PingServer( uint32 unIP, uint16 usPort, ISteamMatchmakingPingResponse *pRequestServersResponse ) = 0; + //virtual HServerQuery PlayerDetails( uint32 unIP, uint16 usPort, ISteamMatchmakingPlayersResponse *pRequestServersResponse ) = 0; + +}; +#define SERVERLIST_INTERFACE_VERSION "ServerList001" + +#endif // ISERVERSINFO_H From 548be38a0b564c5624eff521c1e88bfe1062f4bb Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 28 Jan 2023 05:36:57 +0300 Subject: [PATCH 02/17] engine: restore checksum check --- engine/net_chan.cpp | 8 -------- engine/wscript | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/engine/net_chan.cpp b/engine/net_chan.cpp index e722bc02..080c727c 100644 --- a/engine/net_chan.cpp +++ b/engine/net_chan.cpp @@ -64,15 +64,7 @@ extern int NET_ReceiveStream( int nSock, char * buf, int len, int flags ); // We only need to checksum packets on the PC and only when we're actually sending them over the network. static bool ShouldChecksumPackets() { - // nillerusr: temporary solution for testing - return false; - -#if 0 - if ( !IsPC() ) - return false; - return NET_IsMultiplayer(); -#endif } bool CNetChan::IsLoopback() const diff --git a/engine/wscript b/engine/wscript index 81456630..54ffdc4e 100755 --- a/engine/wscript +++ b/engine/wscript @@ -196,6 +196,7 @@ def build(bld): 'EngineSoundServer.cpp', 'audio/voice_wavefile.cpp', 'audio/vox.cpp', + 'masterserver.cpp', #'audio/snd_dev_xaudio.cpp',[$X360] #'audio/snd_wave_mixer_xma.cpp', [$X360] @@ -330,7 +331,6 @@ def build(bld): 'vgui_vprofgraphpanel.cpp', 'vgui_vprofpanel.cpp', 'toolframework.cpp', - 'masterserver.cpp', ] if bld.env.DEST_OS != 'win32': From 41aa50e66ef1c832e0b9f3a9da83575e00e12e1c Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sun, 29 Jan 2023 19:26:04 +0300 Subject: [PATCH 03/17] WIP: Begin rewriting serverbrowser --- engine/masterserver.cpp | 16 ++ serverbrowser/BaseGamesPage.cpp | 243 ++++++++++++------ serverbrowser/BaseGamesPage.h | 28 +- serverbrowser/DialogAddServer.cpp | 20 -- serverbrowser/DialogAddServer.h | 14 - serverbrowser/DialogGameInfo.cpp | 30 +-- serverbrowser/FavoriteGames.cpp | 4 +- serverbrowser/FavoriteGames.h | 2 +- serverbrowser/HistoryGames.cpp | 20 +- serverbrowser/HistoryGames.h | 2 +- serverbrowser/InternetGames.cpp | 23 +- serverbrowser/InternetGames.h | 6 +- serverbrowser/LanGames.cpp | 4 +- serverbrowser/LanGames.h | 2 +- serverbrowser/ServerBrowser.cpp | 14 +- serverbrowser/ServerBrowserDialog.cpp | 141 ++-------- serverbrowser/ServerBrowserDialog.h | 15 +- serverbrowser/pch_serverbrowser.h | 6 +- .../{ => unused}/BlacklistedServers.cpp | 0 .../{ => unused}/BlacklistedServers.h | 0 serverbrowser/{ => unused}/CustomGames.cpp | 0 serverbrowser/{ => unused}/CustomGames.h | 0 serverbrowser/{ => unused}/FriendsGames.cpp | 0 serverbrowser/{ => unused}/FriendsGames.h | 0 serverbrowser/{ => unused}/SpectateGames.cpp | 0 serverbrowser/{ => unused}/SpectateGames.h | 0 serverbrowser/wscript | 8 +- 27 files changed, 265 insertions(+), 333 deletions(-) rename serverbrowser/{ => unused}/BlacklistedServers.cpp (100%) rename serverbrowser/{ => unused}/BlacklistedServers.h (100%) rename serverbrowser/{ => unused}/CustomGames.cpp (100%) rename serverbrowser/{ => unused}/CustomGames.h (100%) rename serverbrowser/{ => unused}/FriendsGames.cpp (100%) rename serverbrowser/{ => unused}/FriendsGames.h (100%) rename serverbrowser/{ => unused}/SpectateGames.cpp (100%) rename serverbrowser/{ => unused}/SpectateGames.h (100%) diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index 62d7e614..f3803d45 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -80,6 +80,8 @@ private: bool m_bNoMasters; CUtlLinkedList m_serverAddresses; + + IServerListResponse *m_serverListResponse; }; static CMaster s_MasterServer; @@ -87,6 +89,8 @@ IMaster *master = (IMaster *)&s_MasterServer; IServersInfo *g_pServersInfo = (IServersInfo*)&s_MasterServer; +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CMaster, IServersInfo, SERVERLIST_INTERFACE_VERSION, s_MasterServer ); + #define HEARTBEAT_SECONDS 140.0 //----------------------------------------------------------------------------- @@ -97,6 +101,9 @@ CMaster::CMaster( void ) m_pMasterAddresses = NULL; m_bNoMasters = false; m_bInitialized = false; + + m_serverListResponse = NULL; + Init(); } @@ -165,6 +172,11 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) char hostname[1024]; msg.ReadString(hostname, sizeof(hostname)); + newgameserver_t s; + s.m_NetAdr = packet->from; + s.SetName( hostname ); + + m_serverListResponse->ServerResponded( s ); break; } } @@ -180,6 +192,8 @@ void CMaster::RequestServersInfo() { const netadr_t adr = m_serverAddresses[i]; + Msg("Request server info %s\n", adr.ToString()); + msg.WriteLong( CONNECTIONLESS_HEADER ); msg.WriteByte( C2S_INFOREQUEST ); @@ -474,6 +488,8 @@ void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse { if( m_bNoMasters ) return; + m_serverListResponse = response; + ALIGN4 char buf[256] ALIGN4_POST; bf_write msg(buf, sizeof(buf)); diff --git a/serverbrowser/BaseGamesPage.cpp b/serverbrowser/BaseGamesPage.cpp index 6cef8827..e0f80b63 100644 --- a/serverbrowser/BaseGamesPage.cpp +++ b/serverbrowser/BaseGamesPage.cpp @@ -322,7 +322,7 @@ void CBaseGamesPage::PerformLayout() m_pRefreshQuick->SetEnabled(false); } - if ( !steamapicontext->SteamMatchmakingServers() || !steamapicontext->SteamMatchmaking() ) +/* if ( !steamapicontext->SteamMatchmakingServers() || !steamapicontext->SteamMatchmaking() ) { m_pAddCurrentServer->SetVisible( false ); m_pRefreshQuick->SetEnabled( false ); @@ -331,7 +331,7 @@ void CBaseGamesPage::PerformLayout() m_pRefreshAll->SetEnabled( false ); m_pAddToFavoritesButton->SetEnabled( false ); m_pGameList->SetEmptyListText( "#ServerBrowser_SteamRunning" ); - } + }*/ Repaint(); } @@ -797,19 +797,19 @@ void CBaseGamesPage::UpdateGameFilter() // Purpose: Handles incoming server refresh data // updates the server browser with the refreshed information from the server itself //----------------------------------------------------------------------------- -void CBaseGamesPage::ServerResponded( gameserveritem_t &server ) +/*void CBaseGamesPage::ServerResponded( gameserveritem_t &server ) { int nIndex = -1; // start at -1 and work backwards to find the next free slot for this adhoc query while ( m_mapServers.Find( nIndex ) != m_mapServers.InvalidIndex() ) nIndex--; ServerResponded( nIndex, &server ); -} +}*/ //----------------------------------------------------------------------------- // Purpose: Callback for ISteamMatchmakingServerListResponse //----------------------------------------------------------------------------- -void CBaseGamesPage::ServerResponded( HServerListRequest hReq, int iServer ) +/*void CBaseGamesPage::ServerResponded( HServerListRequest hReq, int iServer ) { gameserveritem_t *pServerItem = steamapicontext->SteamMatchmakingServers()->GetServerDetails( hReq, iServer ); if ( !pServerItem ) @@ -825,15 +825,17 @@ void CBaseGamesPage::ServerResponded( HServerListRequest hReq, int iServer ) pServerItem->m_nMaxPlayers = (uint8)(int8)pServerItem->m_nMaxPlayers; ServerResponded( iServer, pServerItem ); -} +}*/ //----------------------------------------------------------------------------- // Purpose: Handles incoming server refresh data // updates the server browser with the refreshed information from the server itself //----------------------------------------------------------------------------- + void CBaseGamesPage::ServerResponded( int iServer, gameserveritem_t *pServerItem ) { +#if 0 int iServerMap = m_mapServers.Find( iServer ); if ( iServerMap == m_mapServers.InvalidIndex() ) { @@ -988,6 +990,7 @@ void CBaseGamesPage::ServerResponded( int iServer, gameserveritem_t *pServerItem PrepareQuickListMap( pServerItem->m_szMap, pServer->m_iListID ); UpdateStatus(); m_iServerRefreshCount++; +#endif } //----------------------------------------------------------------------------- @@ -1143,11 +1146,10 @@ void CBaseGamesPage::OnTextChanged(Panel *panel, const char *text) //----------------------------------------------------------------------------- void CBaseGamesPage::ApplyGameFilters() { +#if 0 if ( !steamapicontext->SteamMatchmakingServers() ) return; - m_iServersBlacklisted = 0; - // loop through all the servers checking filters FOR_EACH_MAP_FAST( m_mapServers, i ) { @@ -1215,6 +1217,7 @@ void CBaseGamesPage::ApplyGameFilters() m_pGameList->SortList(); InvalidateLayout(); Repaint(); +#endif } //----------------------------------------------------------------------------- @@ -1224,14 +1227,10 @@ void CBaseGamesPage::UpdateStatus() { if (m_pGameList->GetItemCount() > 1) { - wchar_t header[256]; - wchar_t count[128]; - wchar_t blacklistcount[128]; + wchar_t msg[256]; - _snwprintf( count, Q_ARRAYSIZE(count), L"%d", m_pGameList->GetItemCount() ); - _snwprintf( blacklistcount, Q_ARRAYSIZE(blacklistcount), L"%d", m_iServersBlacklisted ); - g_pVGuiLocalize->ConstructString( header, sizeof( header ), g_pVGuiLocalize->Find( "#ServerBrowser_ServersCountWithBlacklist"), 2, count, blacklistcount ); - m_pGameList->SetColumnHeaderText( k_nColumn_Name, header); + _snwprintf( msg, Q_ARRAYSIZE(msg), L"%S( %d )", g_pVGuiLocalize->Find( "#ServerBrowser_Servers"), m_pGameList->GetItemCount() ); + m_pGameList->SetColumnHeaderText( k_nColumn_Name, msg); } else { @@ -1529,19 +1528,12 @@ void CBaseGamesPage::RecalculateFilterString() // Purpose: Checks to see if the server passes the primary filters // if the server fails the filters, it will not be refreshed again //----------------------------------------------------------------------------- -bool CBaseGamesPage::CheckPrimaryFilters( gameserveritem_t &server ) +bool CBaseGamesPage::CheckPrimaryFilters( newgameserver_t &server ) { - if (m_szGameFilter[0] && ( server.m_szGameDir[0] || server.m_nPing ) && Q_stricmp(m_szGameFilter, server.m_szGameDir ) ) + if (m_szGameFilter[0] && server.m_szGameDir[0] && Q_stricmp(m_szGameFilter, server.m_szGameDir ) ) { return false; } - - // If it's blacklisted, we ignore it too - if ( ServerBrowserDialog().IsServerBlacklisted( server ) ) - { - m_iServersBlacklisted++; - return false; - } return true; } @@ -1551,7 +1543,7 @@ bool CBaseGamesPage::CheckPrimaryFilters( gameserveritem_t &server ) // server will be continued to be pinged if it fails the filter, since // the relvent server data is dynamic //----------------------------------------------------------------------------- -bool CBaseGamesPage::CheckSecondaryFilters( gameserveritem_t &server ) +bool CBaseGamesPage::CheckSecondaryFilters( newgameserver_t &server ) { bool bFilterNoEmpty = m_bFilterNoEmptyServers; bool bFilterNoFull = m_bFilterNoFullServers; @@ -1595,7 +1587,7 @@ bool CBaseGamesPage::CheckSecondaryFilters( gameserveritem_t &server ) return false; } - if ( iFilterSecure == FILTER_SECURESERVERSONLY && !server.m_bSecure ) + /*if ( iFilterSecure == FILTER_SECURESERVERSONLY && !server.m_bSecure ) { return false; } @@ -1608,7 +1600,7 @@ bool CBaseGamesPage::CheckSecondaryFilters( gameserveritem_t &server ) if ( m_bFilterReplayServers && !IsReplayServer( server ) ) { return false; - } + }*/ if ( m_pQuickList->IsVisible() == false ) { @@ -1787,37 +1779,15 @@ void CBaseGamesPage::OnAddToFavorites() } } -//----------------------------------------------------------------------------- -// Purpose: adds a server to the blacklist -//----------------------------------------------------------------------------- -void CBaseGamesPage::OnAddToBlacklist() -{ - if ( !steamapicontext->SteamMatchmakingServers() ) - return; - - // loop through all the selected favorites - for (int i = 0; i < m_pGameList->GetSelectedItemsCount(); i++) - { - int serverID = m_pGameList->GetItemUserData(m_pGameList->GetSelectedItem(i)); - - gameserveritem_t *pServer = steamapicontext->SteamMatchmakingServers()->GetServerDetails( m_hRequest, serverID ); - if ( pServer ) - { - ServerBrowserDialog().AddServerToBlacklist(*pServer); - } - } - ServerBrowserDialog().BlacklistsChanged(); -} - - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- +#if 0 void CBaseGamesPage::ServerFailedToRespond( HServerListRequest hReq, int iServer ) { ServerResponded( hReq, iServer ); } - +#endif //----------------------------------------------------------------------------- // Purpose: removes the server from the UI list @@ -1864,41 +1834,37 @@ void CBaseGamesPage::OnRefreshServer( int serverID ) //----------------------------------------------------------------------------- void CBaseGamesPage::StartRefresh() { - if ( !steamapicontext->SteamMatchmakingServers() ) - return; - ClearServerList(); MatchMakingKeyValuePair_t *pFilters; int nFilters = GetServerFilters( &pFilters ); - if ( m_hRequest ) +/* if ( m_hRequest ) { steamapicontext->SteamMatchmakingServers()->ReleaseRequest( m_hRequest ); m_hRequest = NULL; - } + }*/ switch ( m_eMatchMakingType ) { - case eFavoritesServer: +/* case eFavoritesServer: m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestFavoritesServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); break; case eHistoryServer: m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestHistoryServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); - break; + break;*/ case eInternetServer: - m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestInternetServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); + Msg("RequestInternetServerList\n"); + g_pServersInfo->RequestInternetServerList(COM_GetModDirectory(), this); + //m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestInternetServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); break; - case eSpectatorServer: +/* case eSpectatorServer: m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestSpectatorServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); break; - case eFriendsServer: - m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestFriendsServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); - break; case eLANServer: m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestLANServerList( GetFilterAppID().AppID(), this ); break; default: Assert( !"Unknown server type" ); - break; + break;*/ } SetRefreshing( true ); @@ -1936,7 +1902,6 @@ void CBaseGamesPage::ClearServerList() m_mapServers.RemoveAll(); m_mapServerIP.RemoveAll(); m_pGameList->RemoveAll(); - m_iServersBlacklisted = 0; ClearQuickList(); } @@ -1964,7 +1929,7 @@ void CBaseGamesPage::StopRefresh() steamapicontext->SteamMatchmakingServers()->CancelQuery( m_hRequest ); // update UI - RefreshComplete( m_hRequest, eServerResponded ); + RefreshComplete( nServerResponded ); // apply settings ApplyGameFilters(); @@ -1973,7 +1938,7 @@ void CBaseGamesPage::StopRefresh() //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CBaseGamesPage::RefreshComplete( HServerListRequest hRequest, EMatchMakingServerResponse response ) +void CBaseGamesPage::RefreshComplete( NServerResponse response ) { SelectQuickListServers(); } @@ -2116,7 +2081,7 @@ void CDialogServerWarning::OnCommand(const char *command) PostMessage(this, new KeyValues("Close")); // join the game - ServerBrowserDialog().JoinGame( m_pGameList, m_iServerID ); + //ServerBrowserDialog().JoinGame( m_pGameList, m_iServerID ); } else { @@ -2142,16 +2107,16 @@ void CDialogServerWarning::OnButtonToggled(Panel *panel, int state) void CBaseGamesPage::OnBeginConnect() { KeyValues *pKV = NULL; - int serverID = GetSelectedServerID( &pKV ); + int iServerIndex = GetSelectedServerID( &pKV ); - if ( serverID == -1 ) + if ( iServerIndex == -1 ) return; // Stop the current refresh StopRefresh(); ConVarRef sb_dontshow_maxplayer_warning( "sb_dontshow_maxplayer_warning", true ); - if ( sb_dontshow_maxplayer_warning.IsValid() ) +/* if ( sb_dontshow_maxplayer_warning.IsValid() ) { // If the server is above the suggested maxplayers, warn the player int iMaxP = sb_mod_suggested_maxplayers.GetInt(); @@ -2177,10 +2142,10 @@ void CBaseGamesPage::OnBeginConnect() return; } } - } + }*/ // join the game - ServerBrowserDialog().JoinGame(this, serverID); + ServerBrowserDialog().JoinGame(this, &m_serversInfo[iServerIndex]); } //----------------------------------------------------------------------------- @@ -2197,7 +2162,7 @@ void CBaseGamesPage::OnViewGameInfo() StopRefresh(); // join the game - ServerBrowserDialog().OpenGameInfoDialog(this, serverID); + //ServerBrowserDialog().OpenGameInfoDialog(this, serverID); } //----------------------------------------------------------------------------- @@ -2222,9 +2187,6 @@ const char *CBaseGamesPage::GetConnectCode() case eLANServer: pszConnectCode = "serverbrowser_lan"; break; - case eFriendsServer: - pszConnectCode = "serverbrowser_friends"; - break; case eFavoritesServer: pszConnectCode = "serverbrowser_favorites"; break; @@ -2239,6 +2201,119 @@ const char *CBaseGamesPage::GetConnectCode() return pszConnectCode; } +void CBaseGamesPage::ServerResponded( newgameserver_t &server ) +{ + Msg("Serverbrowser: hostname %s\n", server.GetName()); + + Assert( server.m_NetAdr.GetIP() != 0 ); + + newgameserver_t *pServerItem = &server; + + // check filters + bool removeItem = false; +#if 0 + if ( !CheckPrimaryFilters( server ) ) + { + // server has been filtered at a primary level + // remove from lists + //pServer->m_bDoNotRefresh = true; + + // remove from UI list + //removeItem = true; + return; + } + else if (!CheckSecondaryFilters( server )) + { + // we still ping this server in the future; however it is removed from UI list + return; + } +#endif + + // new entry + KeyValues *kv = new KeyValues("Server"); + + kv->SetString("name", pServerItem->GetName()); + kv->SetString("map", pServerItem->m_szMap); + kv->SetString("GameDir", pServerItem->m_szGameDir); + kv->SetString("GameDesc", pServerItem->m_szGameDescription); + kv->SetInt("password", pServerItem->m_bPassword ? m_nImageIndexPassword : 0); + + if ( pServerItem->m_nBotPlayers > 0 ) + kv->SetInt("bots", pServerItem->m_nBotPlayers); + else + kv->SetString("bots", ""); + + + kv->SetInt("secure", 0); + + kv->SetString( "IPAddr", pServerItem->m_NetAdr.ToString() ); + + int nAdjustedForBotsPlayers = max( 0, pServerItem->m_nPlayers - pServerItem->m_nBotPlayers ); + + char buf[32]; + Q_snprintf(buf, sizeof(buf), "%d / %d", nAdjustedForBotsPlayers, pServerItem->m_nMaxPlayers ); + kv->SetString("Players", buf); + + kv->SetInt("PlayerCount", nAdjustedForBotsPlayers ); + kv->SetInt("MaxPlayerCount", pServerItem->m_nMaxPlayers ); + + kv->SetInt("Ping", pServerItem->m_nPing); + + kv->SetString("Tags", ""); + + kv->SetInt("Replay", 0); + +/* if ( pServerItem->m_ulTimeLastPlayed ) + { + // construct a time string for last played time + struct tm *now; + now = localtime( (time_t*)&pServerItem->m_ulTimeLastPlayed ); + + if ( now ) + { + char buf[64]; + strftime(buf, sizeof(buf), "%a %d %b %I:%M%p", now); + Q_strlower(buf + strlen(buf) - 4); + kv->SetString("LastPlayed", buf); + } + }*/ + +// 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 ) ) + + // new server, add to list + int iListID = m_pGameList->AddItem(kv, iServerIndex, false, false); + /*if ( m_bAutoSelectFirstItemInGameList && m_pGameList->GetItemCount() == 1 ) + { + m_pGameList->AddSelectedItem( pServer->m_iListID ); + }*/ + + m_pGameList->SetItemVisible( iListID, true ); + + kv->deleteThis(); + +/* else + { + // tell the list that we've changed the data + m_pGameList->ApplyItemChanges( pServer->m_iListID ); + m_pGameList->SetItemVisible( pServer->m_iListID, !removeItem ); + }*/ + + PrepareQuickListMap( pServerItem->m_szMap, iListID ); + UpdateStatus(); + m_iServerRefreshCount++; + +} //----------------------------------------------------------------------------- // Purpose: Refresh if our favorites list changed @@ -2252,8 +2327,6 @@ void CBaseGamesPage::OnFavoritesMsg( FavoritesListChanged_t *pFavListChanged ) case eInternetServer: case eLANServer: case eSpectatorServer: - case eFriendsServer: - return; case eFavoritesServer: case eHistoryServer: // check containing property sheet to see if the page is visible. @@ -2276,8 +2349,6 @@ void CBaseGamesPage::OnFavoritesMsg( FavoritesListChanged_t *pFavListChanged ) case eInternetServer: case eLANServer: case eSpectatorServer: - case eFriendsServer: - break; case eFavoritesServer: case eHistoryServer: { @@ -2286,8 +2357,10 @@ void CBaseGamesPage::OnFavoritesMsg( FavoritesListChanged_t *pFavListChanged ) { if ( pFavListChanged->m_bAdd ) { - if ( steamapicontext->SteamMatchmakingServers() ) - steamapicontext->SteamMatchmakingServers()->PingServer( pFavListChanged->m_nIP, pFavListChanged->m_nQueryPort, this ); + + // TODO(nillerusr): implement this + // if ( steamapicontext->SteamMatchmakingServers() ) + // steamapicontext->SteamMatchmakingServers()->PingServer( pFavListChanged->m_nIP, pFavListChanged->m_nQueryPort, this ); } // ignore deletes of fav's we didn't have } @@ -2295,8 +2368,8 @@ void CBaseGamesPage::OnFavoritesMsg( FavoritesListChanged_t *pFavListChanged ) { if ( pFavListChanged->m_bAdd ) { - if ( m_mapServerIP[ iIPServer ] > 0 ) - ServerResponded( m_hRequest, m_mapServerIP[ iIPServer ] ); + // if ( m_mapServerIP[ iIPServer ] > 0 ) + // ServerResponded( m_hRequest, m_mapServerIP[ iIPServer ] ); } else { diff --git a/serverbrowser/BaseGamesPage.h b/serverbrowser/BaseGamesPage.h index 2d69b1d1..fca73685 100644 --- a/serverbrowser/BaseGamesPage.h +++ b/serverbrowser/BaseGamesPage.h @@ -12,6 +12,7 @@ #endif #include "tier1/utldict.h" +#include "engine/iserversinfo.h" class CBaseGamesPage; @@ -82,7 +83,7 @@ struct gametypes_t //----------------------------------------------------------------------------- // Purpose: Base property page for all the games lists (internet/favorites/lan/etc.) //----------------------------------------------------------------------------- -class CBaseGamesPage : public vgui::PropertyPage, public IGameList, public ISteamMatchmakingServerListResponse, public ISteamMatchmakingPingResponse +class CBaseGamesPage : public vgui::PropertyPage, public IGameList, public IServerListResponse //, public ISteamMatchmakingPingResponse { DECLARE_CLASS_SIMPLE( CBaseGamesPage, vgui::PropertyPage ); @@ -138,7 +139,6 @@ public: // adds a server to the favorites MESSAGE_FUNC( OnAddToFavorites, "AddToFavorites" ); - MESSAGE_FUNC( OnAddToBlacklist, "AddToBlacklist" ); virtual void StartRefresh(); @@ -173,14 +173,14 @@ protected: void UpdateStatus(); // ISteamMatchmakingServerListResponse callbacks - virtual void ServerResponded( HServerListRequest hReq, int iServer ); - virtual void ServerResponded( int iServer, gameserveritem_t *pServerItem ); - virtual void ServerFailedToRespond( HServerListRequest hReq, int iServer ); - virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ) = 0; + virtual void ServerResponded( newgameserver_t &server ); + virtual void RefreshComplete( NServerResponse response ); // ISteamMatchmakingPingResponse callbacks - virtual void ServerResponded( gameserveritem_t &server ); - virtual void ServerFailedToRespond() {} + //virtual void ServerResponded( gameserveritem_t &server ); + //virtual void ServerFailedToRespond() {} + + virtual void ServerResponded( int iServer, gameserveritem_t *pServerItem ); // Removes server from list void RemoveServer( serverdisplay_t &server ); @@ -190,10 +190,10 @@ protected: // filtering methods // returns true if filters passed; false if failed - virtual bool CheckPrimaryFilters( gameserveritem_t &server); - virtual bool CheckSecondaryFilters( gameserveritem_t &server ); - virtual bool CheckTagFilter( gameserveritem_t &server ) { return true; } - virtual bool CheckWorkshopFilter( gameserveritem_t &server ) { return true; } + virtual bool CheckPrimaryFilters( newgameserver_t &server); + virtual bool CheckSecondaryFilters( newgameserver_t &server ); + virtual bool CheckTagFilter( newgameserver_t &server ) { return true; } + virtual bool CheckWorkshopFilter( newgameserver_t &server ) { return true; } virtual int GetInvalidServerListID(); virtual void OnSaveFilter(KeyValues *filter); @@ -236,6 +236,9 @@ protected: CUtlMap m_mapGamesFilterItem; CUtlMap m_mapServers; CUtlMap m_mapServerIP; + + CUtlVector m_serversInfo; + CUtlVector m_vecServerFilters; CUtlDict< CQuickListMapServerList, int > m_quicklistserverlist; int m_iServerRefreshCount; @@ -316,7 +319,6 @@ private: bool m_bFilterNoEmptyServers; bool m_bFilterNoPasswordedServers; int m_iSecureFilter; - int m_iServersBlacklisted; bool m_bFilterReplayServers; CGameID m_iLimitToAppID; diff --git a/serverbrowser/DialogAddServer.cpp b/serverbrowser/DialogAddServer.cpp index cbba58eb..5dbc9ed5 100644 --- a/serverbrowser/DialogAddServer.cpp +++ b/serverbrowser/DialogAddServer.cpp @@ -370,23 +370,3 @@ void CDialogAddServer::FinishAddServer( gameserveritem_t &pServer ) { ServerBrowserDialog().AddServerToFavorites( pServer ); } - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CDialogAddBlacklistedServer::FinishAddServer( gameserveritem_t &pServer ) -{ - ServerBrowserDialog().AddServerToBlacklist( pServer ); - ServerBrowserDialog().BlacklistsChanged(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CDialogAddBlacklistedServer::ApplySchemeSettings( vgui::IScheme *pScheme ) -{ - BaseClass::ApplySchemeSettings( pScheme ); - - m_pAddServerButton->SetText( "#ServerBrowser_AddAddressToBlacklist" ); - m_pAddSelectedServerButton->SetText( "#ServerBrowser_AddSelectedToBlacklist" ); -} diff --git a/serverbrowser/DialogAddServer.h b/serverbrowser/DialogAddServer.h index 7abaee1a..c340904b 100644 --- a/serverbrowser/DialogAddServer.h +++ b/serverbrowser/DialogAddServer.h @@ -58,18 +58,4 @@ protected: CUtlVector m_Queries; }; -class CDialogAddBlacklistedServer : public CDialogAddServer -{ - DECLARE_CLASS_SIMPLE( CDialogAddBlacklistedServer, CDialogAddServer ); -public: - CDialogAddBlacklistedServer( vgui::Panel *parent, IGameList *gameList) : - CDialogAddServer( parent, gameList ) - { - } - - virtual void FinishAddServer( gameserveritem_t &pServer ); - void ApplySchemeSettings( vgui::IScheme *pScheme ); - virtual bool AllowInvalidIPs( void ) { return true; } -}; - #endif // DIALOGADDSERVER_H diff --git a/serverbrowser/DialogGameInfo.cpp b/serverbrowser/DialogGameInfo.cpp index fc0ed36c..ce54f477 100644 --- a/serverbrowser/DialogGameInfo.cpp +++ b/serverbrowser/DialogGameInfo.cpp @@ -293,7 +293,10 @@ void CDialogGameInfo::PerformLayout() } SetControlString("PlayersText", buf); - if ( m_Server.m_NetAdr.GetIP() && m_Server.m_NetAdr.GetQueryPort() ) + SetControlString("ServerIPText", m_Server.m_NetAdr.GetConnectionAddressString() ); + m_pConnectButton->SetEnabled(true); + +/* if ( m_Server.m_NetAdr.GetIP() && m_Server.m_NetAdr.GetQueryPort() ) { SetControlString("ServerIPText", m_Server.m_NetAdr.GetConnectionAddressString() ); m_pConnectButton->SetEnabled(true); @@ -312,7 +315,7 @@ void CDialogGameInfo::PerformLayout() { SetControlString("ServerIPText", ""); m_pConnectButton->SetEnabled(false); - } + }*/ if ( m_Server.m_bHadSuccessfulResponse ) { @@ -405,7 +408,11 @@ void CDialogGameInfo::OnConnect() // need to refresh server before attempting to connect, to make sure there is enough room on the server m_iRequestRetry = 0; - RequestInfo(); + + ConnectToServer(); + + //TODO(nillerusr): restore this later + //RequestInfo(); } //----------------------------------------------------------------------------- @@ -633,17 +640,6 @@ void CDialogGameInfo::ConnectToServer() { m_bConnecting = false; - // check VAC status - if ( m_Server.m_bSecure && ServerBrowser().IsVACBannedFromGame( m_Server.m_nAppID ) ) - { - // refuse the user - CVACBannedConnRefusedDialog *pDlg = new CVACBannedConnRefusedDialog( GetVParent(), "VACBannedConnRefusedDialog" ); - pDlg->Activate(); - Close(); - return; - } - - // check to see if we need a password if ( m_Server.m_bPassword && !m_szPassword[0] ) { @@ -654,7 +650,9 @@ void CDialogGameInfo::ConnectToServer() } // check the player count - if ( m_Server.m_nPlayers >= m_Server.m_nMaxPlayers ) + + // nillerusr + /*if ( m_Server.m_nPlayers >= m_Server.m_nMaxPlayers ) { // mark why we cannot connect m_bServerFull = true; @@ -662,7 +660,7 @@ void CDialogGameInfo::ConnectToServer() m_bShowAutoRetryToggle = true; InvalidateLayout(); return; - } + }*/ // tell the engine to connect const char *gameDir = m_Server.m_szGameDir; diff --git a/serverbrowser/FavoriteGames.cpp b/serverbrowser/FavoriteGames.cpp index 0149baf1..a9306cc2 100644 --- a/serverbrowser/FavoriteGames.cpp +++ b/serverbrowser/FavoriteGames.cpp @@ -73,7 +73,7 @@ bool CFavoriteGames::SupportsItem(InterfaceItem_e item) //----------------------------------------------------------------------------- // Purpose: called when the current refresh list is complete //----------------------------------------------------------------------------- -void CFavoriteGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ) +void CFavoriteGames::RefreshComplete( NServerResponse response ) { SetRefreshing(false); if ( steamapicontext->SteamMatchmaking() && steamapicontext->SteamMatchmaking()->GetFavoriteGameCount() == 0 ) @@ -88,7 +88,7 @@ void CFavoriteGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServe } m_pGameList->SortList(); - BaseClass::RefreshComplete( hReq, response ); + BaseClass::RefreshComplete( response ); } //----------------------------------------------------------------------------- diff --git a/serverbrowser/FavoriteGames.h b/serverbrowser/FavoriteGames.h index 8355005a..242670ea 100644 --- a/serverbrowser/FavoriteGames.h +++ b/serverbrowser/FavoriteGames.h @@ -30,7 +30,7 @@ public: virtual bool SupportsItem(InterfaceItem_e item); // called when the current refresh list is complete - virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ); + virtual void RefreshComplete( NServerResponse response ); // passed from main server browser window instead of messages void OnConnectToGame(); diff --git a/serverbrowser/HistoryGames.cpp b/serverbrowser/HistoryGames.cpp index 565c313e..ad93e3da 100644 --- a/serverbrowser/HistoryGames.cpp +++ b/serverbrowser/HistoryGames.cpp @@ -18,16 +18,6 @@ CHistoryGames::CHistoryGames(vgui::Panel *parent) : m_pGameList->AddColumnHeader(10, "LastPlayed", "#ServerBrowser_LastPlayed", 100); m_pGameList->SetSortFunc(10, LastPlayedCompare); m_pGameList->SetSortColumn(10); - - if ( !IsSteamGameServerBrowsingEnabled() ) - { - m_pGameList->SetEmptyListText("#ServerBrowser_OfflineMode"); - m_pConnect->SetEnabled( false ); - m_pRefreshAll->SetEnabled( false ); - m_pRefreshQuick->SetEnabled( false ); - m_pAddServer->SetEnabled( false ); - m_pFilter->SetEnabled( false ); - } } //----------------------------------------------------------------------------- @@ -42,12 +32,6 @@ CHistoryGames::~CHistoryGames() //----------------------------------------------------------------------------- void CHistoryGames::LoadHistoryList() { - if ( IsSteamGameServerBrowsingEnabled() ) - { - // set empty message - m_pGameList->SetEmptyListText("#ServerBrowser_NoServersPlayed"); - } - if ( m_bRefreshOnListReload ) { m_bRefreshOnListReload = false; @@ -77,13 +61,13 @@ bool CHistoryGames::SupportsItem(InterfaceItem_e item) //----------------------------------------------------------------------------- // Purpose: called when the current refresh list is complete //----------------------------------------------------------------------------- -void CHistoryGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ) +void CHistoryGames::RefreshComplete( NServerResponse response ) { SetRefreshing(false); m_pGameList->SetEmptyListText("#ServerBrowser_NoServersPlayed"); m_pGameList->SortList(); - BaseClass::RefreshComplete( hReq, response ); + BaseClass::RefreshComplete( response ); } //----------------------------------------------------------------------------- diff --git a/serverbrowser/HistoryGames.h b/serverbrowser/HistoryGames.h index 6dbbf447..14af807c 100644 --- a/serverbrowser/HistoryGames.h +++ b/serverbrowser/HistoryGames.h @@ -30,7 +30,7 @@ public: virtual bool SupportsItem(InterfaceItem_e item); // called when the current refresh list is complete - virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ); + virtual void RefreshComplete( NServerResponse response ); void SetRefreshOnReload() { m_bRefreshOnListReload = true; } diff --git a/serverbrowser/InternetGames.cpp b/serverbrowser/InternetGames.cpp index 208bea45..afe94f90 100644 --- a/serverbrowser/InternetGames.cpp +++ b/serverbrowser/InternetGames.cpp @@ -23,7 +23,7 @@ CInternetGames::CInternetGames(vgui::Panel *parent, const char *panelName, EPage m_fLastSort = 0.0f; m_bDirty = false; m_bRequireUpdate = true; - m_bOfflineMode = !IsSteamGameServerBrowsingEnabled(); + m_bOfflineMode = false; //ro!IsSteamGameServerBrowsingEnabled(); m_bAnyServersRetrievedFromMaster = false; m_bNoServersListedOnMaster = false; @@ -124,19 +124,20 @@ void CInternetGames::OnTick() // Purpose: Handles incoming server refresh data // updates the server browser with the refreshed information from the server itself //----------------------------------------------------------------------------- -void CInternetGames::ServerResponded( HServerListRequest hReq, int iServer ) +void CInternetGames::ServerResponded( newgameserver_t &server ) { m_bDirty = true; - BaseClass::ServerResponded( hReq, iServer ); + Msg("InternetGames::ServerResponded hostname = %s\n", server.GetName()); + + BaseClass::ServerResponded( server ); m_bAnyServersRespondedToQuery = true; m_bAnyServersRetrievedFromMaster = true; } - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CInternetGames::ServerFailedToRespond( HServerListRequest hReq, int iServer ) +/*void CInternetGames::ServerFailedToRespond( HServerListRequest hReq, int iServer ) { m_bDirty = true; gameserveritem_t *pServer = steamapicontext->SteamMatchmakingServers()->GetServerDetails( hReq, iServer ); @@ -145,7 +146,7 @@ void CInternetGames::ServerFailedToRespond( HServerListRequest hReq, int iServer if ( pServer->m_bHadSuccessfulResponse ) { // if it's had a successful response in the past, leave it on - ServerResponded( hReq, iServer ); + //ServerResponded( hReq, iServer ); } else { @@ -155,24 +156,24 @@ void CInternetGames::ServerFailedToRespond( HServerListRequest hReq, int iServer // we've never had a good response from this server, remove it from the list m_iServerRefreshCount++; } -} +}*/ //----------------------------------------------------------------------------- // Purpose: Called when server refresh has been completed //----------------------------------------------------------------------------- -void CInternetGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ) +void CInternetGames::RefreshComplete( NServerResponse response ) { SetRefreshing(false); UpdateFilterSettings(); - if ( response != eServerFailedToRespond ) + if ( response != nServerFailedToRespond ) { if ( m_bAnyServersRespondedToQuery ) { m_pGameList->SetEmptyListText( GetStringNoUnfilteredServers() ); } - else if ( response == eNoServersListedOnMasterServer ) + else if ( response == nNoServersListedOnMasterServer ) { m_pGameList->SetEmptyListText( GetStringNoUnfilteredServersOnMaster() ); } @@ -196,7 +197,7 @@ void CInternetGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServe UpdateStatus(); - BaseClass::RefreshComplete( hReq, response ); + BaseClass::RefreshComplete( response ); } diff --git a/serverbrowser/InternetGames.h b/serverbrowser/InternetGames.h index 8779d1f2..3f17d296 100644 --- a/serverbrowser/InternetGames.h +++ b/serverbrowser/InternetGames.h @@ -35,9 +35,9 @@ public: MESSAGE_FUNC( GetNewServerList, "GetNewServerList" ); // serverlist refresh responses - virtual void ServerResponded( HServerListRequest hReq, int iServer ); - virtual void ServerFailedToRespond( HServerListRequest hReq, int iServer ); - virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ); + virtual void ServerResponded( newgameserver_t &server ); + //virtual void ServerFailedToRespond( HServerListRequest hReq, int iServer ); + virtual void RefreshComplete( NServerResponse response ); MESSAGE_FUNC_INT( OnRefreshServer, "RefreshServer", serverID ); virtual int GetRegionCodeToFilter(); diff --git a/serverbrowser/LanGames.cpp b/serverbrowser/LanGames.cpp index c375845d..131869cb 100644 --- a/serverbrowser/LanGames.cpp +++ b/serverbrowser/LanGames.cpp @@ -127,7 +127,7 @@ void CLanGames::ServerFailedToRespond( HServerListRequest hReq, int iServer ) //----------------------------------------------------------------------------- // Purpose: called when the current refresh list is complete //----------------------------------------------------------------------------- -void CLanGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ) +void CLanGames::RefreshComplete( NServerResponse response ) { SetRefreshing( false ); m_pGameList->SortList(); @@ -135,7 +135,7 @@ void CLanGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResp m_pGameList->SetEmptyListText("#ServerBrowser_NoLanServers"); SetEmptyListText(); - BaseClass::RefreshComplete( hReq, response ); + BaseClass::RefreshComplete( response ); } void CLanGames::SetEmptyListText() diff --git a/serverbrowser/LanGames.h b/serverbrowser/LanGames.h index f1e3afaa..8ff2233d 100644 --- a/serverbrowser/LanGames.h +++ b/serverbrowser/LanGames.h @@ -49,7 +49,7 @@ public: virtual void ServerFailedToRespond( HServerListRequest hReq, int iServer ); // called when the current refresh list is complete - virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ); + virtual void RefreshComplete( NServerResponse response ); // Tell the game list what to put in there when there are no games found. virtual void SetEmptyListText(); diff --git a/serverbrowser/ServerBrowser.cpp b/serverbrowser/ServerBrowser.cpp index ff66bbbf..20268a2f 100644 --- a/serverbrowser/ServerBrowser.cpp +++ b/serverbrowser/ServerBrowser.cpp @@ -19,6 +19,7 @@ CServerBrowser &ServerBrowser() } IRunGameEngine *g_pRunGameEngine = NULL; +IServersInfo *g_pServersInfo = NULL; static CSteamAPIContext g_SteamAPIContext; CSteamAPIContext *steamapicontext = &g_SteamAPIContext; @@ -79,11 +80,12 @@ bool CServerBrowser::Initialize(CreateInterfaceFn *factorylist, int factoryCount for ( int i = 0; i < factoryCount; ++i ) { if ( !g_pEngineReplay ) - { g_pEngineReplay = ( IEngineReplay * )factorylist[ i ]( ENGINE_REPLAY_INTERFACE_VERSION, NULL ); - } + if( !g_pServersInfo ) + g_pServersInfo = ( IServersInfo * )factorylist[ i ]( SERVERLIST_INTERFACE_VERSION, NULL ); } + SteamAPI_InitSafe(); SteamAPI_SetTryCatchCallbacks( false ); // We don't use exceptions, so tell steam not to use try/catch in callback handlers steamapicontext->Init(); @@ -304,7 +306,7 @@ void CServerBrowser::Shutdown() //----------------------------------------------------------------------------- bool CServerBrowser::OpenGameInfoDialog( uint64 ulSteamIDFriend, const char *pszConnectCode ) { -#if !defined( _X360 ) // X360TBD: SteamFriends() +#if 0 if ( m_hInternetDlg.Get() ) { // activate an already-existing dialog @@ -337,11 +339,11 @@ bool CServerBrowser::OpenGameInfoDialog( uint64 ulSteamIDFriend, const char *psz //----------------------------------------------------------------------------- bool CServerBrowser::JoinGame( uint64 ulSteamIDFriend, const char *pszConnectCode ) { - if ( OpenGameInfoDialog( ulSteamIDFriend, pszConnectCode ) ) +/* if ( OpenGameInfoDialog( ulSteamIDFriend, pszConnectCode ) ) { CDialogGameInfo *pDialogGameInfo = m_hInternetDlg->GetDialogGameInfoForFriend( ulSteamIDFriend ); pDialogGameInfo->Connect(); - } + }*/ return false; } @@ -362,11 +364,13 @@ bool CServerBrowser::JoinGame( uint32 unGameIP, uint16 usGamePort, const char *p //----------------------------------------------------------------------------- void CServerBrowser::CloseGameInfoDialog( uint64 ulSteamIDFriend ) { +#if 0 CDialogGameInfo *pDialogGameInfo = m_hInternetDlg->GetDialogGameInfoForFriend( ulSteamIDFriend ); if ( pDialogGameInfo ) { pDialogGameInfo->Close(); } +#endif } diff --git a/serverbrowser/ServerBrowserDialog.cpp b/serverbrowser/ServerBrowserDialog.cpp index dc2ca162..b3e9738b 100644 --- a/serverbrowser/ServerBrowserDialog.cpp +++ b/serverbrowser/ServerBrowserDialog.cpp @@ -66,20 +66,17 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, m_pSavedData = NULL; m_pFilterData = NULL; m_pFavorites = NULL; - m_pBlacklist = NULL; m_pHistory = NULL; - // Do this before LoadUserData() so it loads the blacklist file properly - m_pBlacklist = new CBlacklistedServers(this); - LoadUserData(); - m_pInternetGames = new CCustomGames(this); + m_pInternetGames = new CInternetGames(this); m_pFavorites = new CFavoriteGames(this); m_pHistory = new CHistoryGames(this); - m_pSpectateGames = new CSpectateGames(this); + + // TODO(nillerusr): implement spectate games without steam + //m_pSpectateGames = new CSpectateGames(this); m_pLanGames = new CLanGames(this); - m_pFriendsGames = new CFriendsGames(this); SetMinimumSize( 640, 384 ); SetSize( 640, 384 ); @@ -94,13 +91,9 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, m_pTabPanel->AddPage(m_pInternetGames, "#ServerBrowser_InternetTab"); m_pTabPanel->AddPage(m_pFavorites, "#ServerBrowser_FavoritesTab"); m_pTabPanel->AddPage(m_pHistory, "#ServerBrowser_HistoryTab"); - m_pTabPanel->AddPage(m_pSpectateGames, "#ServerBrowser_SpectateTab"); + //m_pTabPanel->AddPage(m_pSpectateGames, "#ServerBrowser_SpectateTab"); m_pTabPanel->AddPage(m_pLanGames, "#ServerBrowser_LanTab"); - m_pTabPanel->AddPage(m_pFriendsGames, "#ServerBrowser_FriendsTab"); - if ( m_pBlacklist ) - { - m_pTabPanel->AddPage(m_pBlacklist, "#ServerBrowser_BlacklistTab"); - } + m_pTabPanel->AddActionSignalTarget(this); m_pStatusLabel = new Label(this, "StatusLabel", ""); @@ -112,11 +105,12 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, // load current tab const char *gameList = m_pSavedData->GetString("GameList"); - if (!Q_stricmp(gameList, "spectate")) +/* if (!Q_stricmp(gameList, "spectate")) { m_pTabPanel->SetActivePage(m_pSpectateGames); } - else if (!Q_stricmp(gameList, "favorites")) + else */ + if (!Q_stricmp(gameList, "favorites")) { m_pTabPanel->SetActivePage(m_pFavorites); } @@ -128,14 +122,6 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, { m_pTabPanel->SetActivePage(m_pLanGames); } - else if (!Q_stricmp(gameList, "friends")) - { - m_pTabPanel->SetActivePage(m_pFriendsGames); - } - else if (!Q_stricmp(gameList, "blacklist")) - { - m_pTabPanel->SetActivePage(m_pBlacklist); - } else { m_pTabPanel->SetActivePage(m_pInternetGames); @@ -254,11 +240,6 @@ void CServerBrowserDialog::LoadUserData() m_pFavorites->StartRefresh(); } - if ( m_pBlacklist ) - { - m_pBlacklist->LoadBlacklistedList(); - } - InvalidateLayout(); Repaint(); } @@ -272,11 +253,12 @@ void CServerBrowserDialog::SaveUserData() m_pSavedData->LoadFromFile( g_pFullFileSystem, "ServerBrowser.vdf", "CONFIG"); // set the current tab - if (m_pGameList == m_pSpectateGames) + /*if (m_pGameList == m_pSpectateGames) { m_pSavedData->SetString("GameList", "spectate"); } - else if (m_pGameList == m_pFavorites) + else */ + if (m_pGameList == m_pFavorites) { m_pSavedData->SetString("GameList", "favorites"); } @@ -284,10 +266,6 @@ void CServerBrowserDialog::SaveUserData() { m_pSavedData->SetString("GameList", "lan"); } - else if (m_pGameList == m_pFriendsGames) - { - m_pSavedData->SetString("GameList", "friends"); - } else if (m_pGameList == m_pHistory) { m_pSavedData->SetString("GameList", "history"); @@ -301,11 +279,6 @@ void CServerBrowserDialog::SaveUserData() m_pSavedData->AddSubKey( m_pFilterData->MakeCopy() ); m_pSavedData->SaveToFile( g_pFullFileSystem, "ServerBrowser.vdf", "CONFIG"); - if ( m_pBlacklist ) - { - m_pBlacklist->SaveBlacklistedList(); - } - // save per-page config SaveUserConfig(); } @@ -321,14 +294,6 @@ void CServerBrowserDialog::RefreshCurrentPage() } } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CServerBrowserDialog::BlacklistsChanged() -{ - m_pInternetGames->ApplyGameFilters(); -} - //----------------------------------------------------------------------------- // Purpose: Updates status test at bottom of window //----------------------------------------------------------------------------- @@ -409,38 +374,9 @@ void CServerBrowserDialog::AddServerToFavorites(gameserveritem_t &server) server.m_NetAdr.GetQueryPort(), k_unFavoriteFlagFavorite, time( NULL ) ); - - if ( GameSupportsReplay() ) - { - // send command to propagate to the client so the client can send it on to the GC - char command[ 256 ]; - Q_snprintf( command, Q_ARRAYSIZE( command ), "rfgc %s\n", server.m_NetAdr.GetConnectionAddressString() ); - g_pRunGameEngine->AddTextCommand( command ); - } } } -//----------------------------------------------------------------------------- -// Purpose: Adds a server to our list of blacklisted servers -//----------------------------------------------------------------------------- -void CServerBrowserDialog::AddServerToBlacklist(gameserveritem_t &server) -{ - if ( m_pBlacklist ) - { - m_pBlacklist->AddServer( server ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CServerBrowserDialog::IsServerBlacklisted(gameserveritem_t &server) -{ - if ( m_pBlacklist ) - return m_pBlacklist->IsServerBlacklisted( server ); - return false; -} - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -469,10 +405,10 @@ CServerContextMenu *CServerBrowserDialog::GetContextMenu(vgui::Panel *pPanel) // Purpose: begins the process of joining a server from a game list // the game info dialog it opens will also update the game list //----------------------------------------------------------------------------- -CDialogGameInfo *CServerBrowserDialog::JoinGame(IGameList *gameList, unsigned int serverIndex) +CDialogGameInfo *CServerBrowserDialog::JoinGame(IGameList *gameList, newgameserver_t *pServer) { // open the game info dialog, then mark it to attempt to connect right away - CDialogGameInfo *gameDialog = OpenGameInfoDialog(gameList, serverIndex); + CDialogGameInfo *gameDialog = OpenGameInfoDialog(gameList, pServer); // set the dialog name to be the server name gameDialog->Connect(); @@ -497,16 +433,12 @@ CDialogGameInfo *CServerBrowserDialog::JoinGame(int serverIP, int serverPort, co //----------------------------------------------------------------------------- // Purpose: opens a game info dialog from a game list //----------------------------------------------------------------------------- -CDialogGameInfo *CServerBrowserDialog::OpenGameInfoDialog( IGameList *gameList, unsigned int serverIndex ) +CDialogGameInfo *CServerBrowserDialog::OpenGameInfoDialog( IGameList *gameList, newgameserver_t *pServer ) { - gameserveritem_t *pServer = gameList->GetServer( serverIndex ); - if ( !pServer ) - return NULL; - - CDialogGameInfo *gameDialog = new CDialogGameInfo( NULL, pServer->m_NetAdr.GetIP(), pServer->m_NetAdr.GetQueryPort(), pServer->m_NetAdr.GetConnectionPort(), gameList->GetConnectCode() ); + CDialogGameInfo *gameDialog = new CDialogGameInfo( NULL, pServer->m_NetAdr.GetIPHostByteOrder(), 0, pServer->m_NetAdr.GetPort(), gameList->GetConnectCode() ); gameDialog->SetParent(GetVParent()); gameDialog->AddActionSignalTarget(this); - gameDialog->Run( pServer->GetName() ); + gameDialog->Run( "Test" /*pServer->GetName()*/ ); int i = m_GameInfoDialogs.AddToTail(); m_GameInfoDialogs[i] = gameDialog; return gameDialog; @@ -541,23 +473,6 @@ void CServerBrowserDialog::CloseAllGameInfoDialogs() } } - -//----------------------------------------------------------------------------- -// Purpose: finds a dialog -//----------------------------------------------------------------------------- -CDialogGameInfo *CServerBrowserDialog::GetDialogGameInfoForFriend( uint64 ulSteamIDFriend ) -{ - FOR_EACH_VEC( m_GameInfoDialogs, i ) - { - CDialogGameInfo *pDlg = m_GameInfoDialogs[i]; - if ( pDlg && pDlg->GetAssociatedFriend() == ulSteamIDFriend ) - { - return pDlg; - } - } - return NULL; -} - //----------------------------------------------------------------------------- // Purpose: accessor to the filter save data //----------------------------------------------------------------------------- @@ -612,10 +527,9 @@ void CServerBrowserDialog::OnActiveGameName( KeyValues *pKV ) void CServerBrowserDialog::ReloadFilterSettings() { m_pInternetGames->LoadFilterSettings(); - m_pSpectateGames->LoadFilterSettings(); + //m_pSpectateGames->LoadFilterSettings(); m_pFavorites->LoadFilterSettings(); m_pLanGames->LoadFilterSettings(); - m_pFriendsGames->LoadFilterSettings(); m_pHistory->LoadFilterSettings(); } @@ -659,27 +573,19 @@ void CServerBrowserDialog::OnConnectToGame( KeyValues *pMessageValues ) // forward to favorites m_pFavorites->OnConnectToGame(); - if ( m_pBlacklist ) - { - m_pBlacklist->OnConnectToGame(); - } m_bCurrentlyConnected = true; // Now we want to track which tabs have the quick list button checked int iQuickListBitField = 0; - if ( m_pFriendsGames && m_pFriendsGames->IsQuickListButtonChecked() ) - { - iQuickListBitField |= ( 1 << 0 ); - } if ( m_pLanGames && m_pLanGames->IsQuickListButtonChecked() ) { iQuickListBitField |= ( 1 << 1 ); } - if ( m_pSpectateGames && m_pSpectateGames->IsQuickListButtonChecked() ) +/* if ( m_pSpectateGames && m_pSpectateGames->IsQuickListButtonChecked() ) { iQuickListBitField |= ( 1 << 2 ); - } + }*/ if ( m_pHistory && m_pHistory->IsQuickListButtonChecked() ) { iQuickListBitField |= ( 1 << 3 ); @@ -720,10 +626,6 @@ void CServerBrowserDialog::OnDisconnectFromGame( void ) // forward to favorites m_pFavorites->OnDisconnectFromGame(); - if ( m_pBlacklist ) - { - m_pBlacklist->OnDisconnectFromGame(); - } } //----------------------------------------------------------------------------- @@ -732,10 +634,9 @@ void CServerBrowserDialog::OnDisconnectFromGame( void ) void CServerBrowserDialog::OnLoadingStarted( void ) { m_pInternetGames->OnLoadingStarted(); - m_pSpectateGames->OnLoadingStarted(); +// m_pSpectateGames->OnLoadingStarted(); m_pFavorites->OnLoadingStarted(); m_pLanGames->OnLoadingStarted(); - m_pFriendsGames->OnLoadingStarted(); m_pHistory->OnLoadingStarted(); } diff --git a/serverbrowser/ServerBrowserDialog.h b/serverbrowser/ServerBrowserDialog.h index 2b251867..8180a9f1 100644 --- a/serverbrowser/ServerBrowserDialog.h +++ b/serverbrowser/ServerBrowserDialog.h @@ -50,26 +50,22 @@ public: // Adds a server to the list of favorites void AddServerToFavorites(gameserveritem_t &server); - // Adds a server to our list of blacklisted servers - void AddServerToBlacklist(gameserveritem_t &server); - bool IsServerBlacklisted(gameserveritem_t &server); // begins the process of joining a server from a game list // the game info dialog it opens will also update the game list - CDialogGameInfo *JoinGame(IGameList *gameList, unsigned int serverIndex); + CDialogGameInfo *JoinGame(IGameList *gameList, newgameserver_t *pServer); // joins a game by a specified IP, not attached to any game list CDialogGameInfo *JoinGame(int serverIP, int serverPort, const char *pszConnectCode); // opens a game info dialog from a game list - CDialogGameInfo *OpenGameInfoDialog(IGameList *gameList, unsigned int serverIndex); + CDialogGameInfo *OpenGameInfoDialog(IGameList *gameList, newgameserver_t *pServer); // opens a game info dialog by a specified IP, not attached to any game list CDialogGameInfo *OpenGameInfoDialog( int serverIP, uint16 connPort, uint16 queryPort, const char *pszConnectCode ); // closes all the game info dialogs void CloseAllGameInfoDialogs(); - CDialogGameInfo *GetDialogGameInfoForFriend( uint64 ulSteamIDFriend ); // accessor to the filter save data KeyValues *GetFilterSaveData(const char *filterSet); @@ -91,9 +87,6 @@ public: return &m_CurrentConnection; } - void BlacklistsChanged(); - CBlacklistedServers *GetBlacklistPage( void ) { return m_pBlacklist; } - private: // current game list change @@ -126,12 +119,10 @@ private: // property sheet vgui::PropertySheet *m_pTabPanel; CFavoriteGames *m_pFavorites; - CBlacklistedServers *m_pBlacklist; CHistoryGames *m_pHistory; CInternetGames *m_pInternetGames; - CSpectateGames *m_pSpectateGames; + //CSpectateGames *m_pSpectateGames; CLanGames *m_pLanGames; - CFriendsGames *m_pFriendsGames; KeyValues *m_pSavedData; KeyValues *m_pFilterData; diff --git a/serverbrowser/pch_serverbrowser.h b/serverbrowser/pch_serverbrowser.h index 575382e4..8e44f2ba 100644 --- a/serverbrowser/pch_serverbrowser.h +++ b/serverbrowser/pch_serverbrowser.h @@ -57,15 +57,11 @@ // game list #include "BaseGamesPage.h" -#include "BlacklistedServers.h" #include "InternetGames.h" #include "FavoriteGames.h" -#include "SpectateGames.h" +//#include "SpectateGames.h" #include "LanGames.h" -#include "FriendsGames.h" #include "HistoryGames.h" -#include "SpectateGames.h" -#include "CustomGames.h" #include "ServerBrowserDialog.h" #include "QuickListPanel.h" #include "vgui_controls/PanelListPanel.h" diff --git a/serverbrowser/BlacklistedServers.cpp b/serverbrowser/unused/BlacklistedServers.cpp similarity index 100% rename from serverbrowser/BlacklistedServers.cpp rename to serverbrowser/unused/BlacklistedServers.cpp diff --git a/serverbrowser/BlacklistedServers.h b/serverbrowser/unused/BlacklistedServers.h similarity index 100% rename from serverbrowser/BlacklistedServers.h rename to serverbrowser/unused/BlacklistedServers.h diff --git a/serverbrowser/CustomGames.cpp b/serverbrowser/unused/CustomGames.cpp similarity index 100% rename from serverbrowser/CustomGames.cpp rename to serverbrowser/unused/CustomGames.cpp diff --git a/serverbrowser/CustomGames.h b/serverbrowser/unused/CustomGames.h similarity index 100% rename from serverbrowser/CustomGames.h rename to serverbrowser/unused/CustomGames.h diff --git a/serverbrowser/FriendsGames.cpp b/serverbrowser/unused/FriendsGames.cpp similarity index 100% rename from serverbrowser/FriendsGames.cpp rename to serverbrowser/unused/FriendsGames.cpp diff --git a/serverbrowser/FriendsGames.h b/serverbrowser/unused/FriendsGames.h similarity index 100% rename from serverbrowser/FriendsGames.h rename to serverbrowser/unused/FriendsGames.h diff --git a/serverbrowser/SpectateGames.cpp b/serverbrowser/unused/SpectateGames.cpp similarity index 100% rename from serverbrowser/SpectateGames.cpp rename to serverbrowser/unused/SpectateGames.cpp diff --git a/serverbrowser/SpectateGames.h b/serverbrowser/unused/SpectateGames.h similarity index 100% rename from serverbrowser/SpectateGames.h rename to serverbrowser/unused/SpectateGames.h diff --git a/serverbrowser/wscript b/serverbrowser/wscript index 755ae062..abeb6297 100755 --- a/serverbrowser/wscript +++ b/serverbrowser/wscript @@ -21,13 +21,13 @@ def configure(conf): def build(bld): source = [ 'BaseGamesPage.cpp', - 'BlacklistedServers.cpp', - 'CustomGames.cpp', +# 'BlacklistedServers.cpp', +# 'CustomGames.cpp', 'DialogAddServer.cpp', 'DialogGameInfo.cpp', 'DialogServerPassword.cpp', 'FavoriteGames.cpp', - 'FriendsGames.cpp', +# 'FriendsGames.cpp', 'HistoryGames.cpp', 'InternetGames.cpp', 'LanGames.cpp', @@ -36,7 +36,7 @@ def build(bld): 'ServerBrowserDialog.cpp', 'ServerContextMenu.cpp', 'ServerListCompare.cpp', - 'SpectateGames.cpp', +# 'SpectateGames.cpp', 'VACBannedConnRefusedDialog.cpp', 'QuickListPanel.cpp', '../public/vgui_controls/vgui_controls.cpp', From c4b93b30d7baa4747fa2f2e84c6967a3070d9d28 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sun, 29 Jan 2023 20:57:04 +0300 Subject: [PATCH 04/17] WIP(serverbrowser): update IServersInfo interface --- public/engine/iserversinfo.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/public/engine/iserversinfo.h b/public/engine/iserversinfo.h index 663feb75..8e80d0c4 100644 --- a/public/engine/iserversinfo.h +++ b/public/engine/iserversinfo.h @@ -13,11 +13,11 @@ #define MAX_GAME_DESCRIPTION 8192 #define MAX_SERVER_NAME 2048 -enum ServerResponse +enum NServerResponse { - ServerResponded = 0, - ServerFailedToRespond, - NoServersListedOnMasterServer, + nServerResponded = 0, + nServerFailedToRespond, + nNoServersListedOnMasterServer, }; class newgameserver_t @@ -25,8 +25,11 @@ class newgameserver_t public: newgameserver_t() = default; - const char* GetName() const; - void SetName( const char *pName ); + 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 @@ -50,6 +53,7 @@ class IServerListResponse public: // Server has responded ok with updated data virtual void ServerResponded( newgameserver_t &server ) = 0; + virtual void RefreshComplete( NServerResponse response ) = 0; }; //----------------------------------------------------------------------------- @@ -94,4 +98,6 @@ public: }; #define SERVERLIST_INTERFACE_VERSION "ServerList001" +extern IServersInfo *g_pServersInfo; + #endif // ISERVERSINFO_H From 64f7bf9f96070ee91ffd9ac7fbfb1b270d2b655e Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sun, 29 Jan 2023 21:48:36 +0300 Subject: [PATCH 05/17] vgui_controls: fix SetParent function --- serverbrowser/BaseGamesPage.cpp | 2 +- vgui2/vgui_controls/Panel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/serverbrowser/BaseGamesPage.cpp b/serverbrowser/BaseGamesPage.cpp index e0f80b63..6bdba32f 100644 --- a/serverbrowser/BaseGamesPage.cpp +++ b/serverbrowser/BaseGamesPage.cpp @@ -2205,7 +2205,7 @@ void CBaseGamesPage::ServerResponded( newgameserver_t &server ) { Msg("Serverbrowser: hostname %s\n", server.GetName()); - Assert( server.m_NetAdr.GetIP() != 0 ); + Assert( server.m_NetAdr.GetIPHostByteOrder() != 0 ); newgameserver_t *pServerItem = &server; diff --git a/vgui2/vgui_controls/Panel.cpp b/vgui2/vgui_controls/Panel.cpp index 3adbf7ed..ec2c5653 100644 --- a/vgui2/vgui_controls/Panel.cpp +++ b/vgui2/vgui_controls/Panel.cpp @@ -1465,7 +1465,7 @@ void Panel::SetParent(VPANEL newParent) if( ipanel()->IsProportional(GetVParent()) ) SetProportional(true); - if( IsPopup() ) + if( !IsPopup() ) { // most of the time KBInput == parents kbinput if (ipanel()->IsKeyBoardInputEnabled(GetVParent()) != IsKeyBoardInputEnabled()) From a08b6ae7bf12093ce7cb5fe0b94b02f99cf29cb5 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Mon, 30 Jan 2023 22:16:48 +0300 Subject: [PATCH 06/17] engine: update server info reply --- engine/masterserver.cpp | 101 ++++++++++++++++++++++++++++---- public/engine/iserversinfo.h | 12 ++-- serverbrowser/BaseGamesPage.cpp | 13 +--- serverbrowser/InternetGames.cpp | 1 - 4 files changed, 95 insertions(+), 32 deletions(-) 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; From 12716fd07f089fc25b4da5eb3be24c9f9a067365 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Fri, 10 Feb 2023 22:45:36 +0300 Subject: [PATCH 07/17] engine(masterserver): Add sequence for requesting server info, implement StopRefresh and use it on timeout --- engine/masterserver.cpp | 104 +++++++++++++++++++++++++++++------ public/engine/iserversinfo.h | 1 + public/tier0/threadtools.h | 44 ++------------- public/tier1/memhelpers.h | 16 ++++-- tier0/threadtools.cpp | 53 ++++++++++++++++++ vstdlib/jobthread.cpp | 20 +++++-- 6 files changed, 171 insertions(+), 67 deletions(-) diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index 43262e73..e7580773 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -18,11 +18,14 @@ #include "host.h" #include "eiface.h" #include "server.h" +#include "utlmap.h" extern ConVar sv_tags; extern ConVar sv_lan; #define S2A_EXTRA_DATA_HAS_GAMETAG_DATA 0x01 // Next bytes are the game tag string +#define RETRY_INFO_REQUEST_TIME 0.4 // seconds +#define INFO_REQUEST_TIMEOUT 5.0 // seconds //----------------------------------------------------------------------------- // Purpose: List of master servers and some state info about them @@ -62,6 +65,7 @@ public: void UseDefault ( void ); void CheckHeartbeat (void); void RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ); + void PingServer( netadr_t &svadr ); void ProcessConnectionlessPacket( netpacket_t *packet ); @@ -70,23 +74,35 @@ public: void RunFrame(); void RequestServersInfo(); - void ReplyInfo( const netadr_t &adr ); + + void ReplyInfo( const netadr_t &adr, uint sequence ); newgameserver_t &ProcessInfo( bf_read &buf ); // SeversInfo void RequestInternetServerList( const char *gamedir, IServerListResponse *response ); void RequestLANServerList( const char *gamedir, IServerListResponse *response ); void AddServerAddresses( netadr_t **adr, int count ); + void StopRefresh(); + private: // List of known master servers adrlist_t *m_pMasterAddresses; bool m_bInitialized; + bool m_bWaitingForReplys; + + int m_iServersResponded; + + double m_flStartRequestTime; + double m_flRetryRequestTime; + + uint m_iInfoSequence; // If nomaster is true, the server will not send heartbeats to the master server bool m_bNoMasters; - CUtlLinkedList m_serverAddresses; + CUtlMap m_serverAddresses; + CUtlMap m_serversRequestTime; IServerListResponse *m_serverListResponse; }; @@ -108,8 +124,13 @@ CMaster::CMaster( void ) m_pMasterAddresses = NULL; m_bNoMasters = false; m_bInitialized = false; + m_iServersResponded = 0; m_serverListResponse = NULL; + SetDefLessFunc( m_serverAddresses ); + SetDefLessFunc( m_serversRequestTime ); + m_bWaitingForReplys = false; + m_iInfoSequence = 0; Init(); } @@ -121,9 +142,34 @@ CMaster::~CMaster( void ) void CMaster::RunFrame() { CheckHeartbeat(); + + if( !m_bWaitingForReplys ) + return; + + if( m_serverListResponse && + m_flStartRequestTime < Plat_FloatTime()-INFO_REQUEST_TIMEOUT ) + { + m_serverListResponse->RefreshComplete( NServerResponse::nServerFailedToRespond ); + m_bWaitingForReplys = false; + } + + if( m_flRetryRequestTime < Plat_FloatTime() - RETRY_INFO_REQUEST_TIME ) + { + m_flRetryRequestTime = Plat_FloatTime(); + + if( m_iServersResponded < m_serverAddresses.Count() ) + RequestServersInfo(); + } } -void CMaster::ReplyInfo( const netadr_t &adr ) +void CMaster::StopRefresh() +{ + m_bWaitingForReplys = false; + m_serverAddresses.RemoveAll(); + m_serversRequestTime.RemoveAll(); +} + +void CMaster::ReplyInfo( const netadr_t &adr, uint sequence ) { static char gamedir[MAX_OSPATH]; Q_FileBase( com_gamedir, gamedir, sizeof( gamedir ) ); @@ -134,6 +180,7 @@ void CMaster::ReplyInfo( const netadr_t &adr ) buf.PutUnsignedInt( LittleDWord( CONNECTIONLESS_HEADER ) ); buf.PutUnsignedChar( S2C_INFOREPLY ); + buf.PutUnsignedInt(sequence); buf.PutUnsignedChar( PROTOCOL_VERSION ); // Hardcoded protocol version number buf.PutString( sv.GetName() ); buf.PutString( sv.GetMapName() ); @@ -217,8 +264,7 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) } case M2C_QUERY: { - if( m_serverAddresses.Count() > 0 ) - m_serverAddresses.RemoveAll(); + m_serverAddresses.RemoveAll(); ip = msg.ReadLong(); port = msg.ReadShort(); @@ -227,33 +273,48 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) { netadr_t adr(ip, port); - m_serverAddresses.AddToHead(adr); + m_serverAddresses.Insert(adr, false); ip = msg.ReadLong(); port = msg.ReadShort(); } + m_iServersResponded = 0; RequestServersInfo(); + m_flRetryRequestTime = m_flStartRequestTime = Plat_FloatTime(); break; } case C2S_INFOREQUEST: { - ReplyInfo(packet->from); + ReplyInfo(packet->from, msg.ReadLong()); break; } case S2C_INFOREPLY: { + uint sequence = msg.ReadLong(); 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); + unsigned short index = m_serverAddresses.Find(packet->from); + unsigned short rindex = m_serversRequestTime.Find(sequence); + + if( index == m_serverAddresses.InvalidIndex() || + rindex == m_serversRequestTime.InvalidIndex() ) + break; + + double requestTime = m_serversRequestTime[rindex]; + + m_serverAddresses[index] = true; + s.m_nPing = (packet->received-requestTime)*1000.0; s.m_NetAdr = packet->from; m_serverListResponse->ServerResponded( s ); - break; - } - case A2A_PING: - { - const char p = A2A_ACK; - NET_SendPacket( NULL, NS_SERVER, packet->from, (unsigned char*)&p, 1); + + m_iServersResponded++; + + if( m_iServersResponded >= m_serverAddresses.Count() ) + { + StopRefresh(); + m_serverListResponse->RefreshComplete( NServerResponse::nServerResponded ); + } break; } } @@ -265,17 +326,24 @@ void CMaster::RequestServersInfo() bf_write msg( string, sizeof(string) ); - FOR_EACH_LL( m_serverAddresses, i ) + FOR_EACH_MAP_FAST( m_serverAddresses, i ) { - const netadr_t adr = m_serverAddresses[i]; + bool bResponded = m_serverAddresses.Element(i); + if( bResponded ) + continue; - Msg("Request server info %s\n", adr.ToString()); + const netadr_t adr = m_serverAddresses.Key(i); msg.WriteLong( CONNECTIONLESS_HEADER ); msg.WriteByte( C2S_INFOREQUEST ); + msg.WriteLong( m_iInfoSequence ); + m_serversRequestTime.Insert(m_iInfoSequence, net_time); + m_iInfoSequence++; NET_SendPacket( NULL, NS_CLIENT, adr, msg.GetData(), msg.GetNumBytesWritten() ); } + + m_bWaitingForReplys = true; } //----------------------------------------------------------------------------- @@ -410,7 +478,7 @@ void CMaster::AddServer( netadr_t *adr ) n = ( adrlist_t * ) malloc ( sizeof( adrlist_t ) ); if ( !n ) - Sys_Error( "Error allocating %i bytes for master address.", sizeof( adrlist_t ) ); + Sys_Error( "Error allocating %zd bytes for master address.", sizeof( adrlist_t ) ); memset( n, 0, sizeof( adrlist_t ) ); diff --git a/public/engine/iserversinfo.h b/public/engine/iserversinfo.h index e2fd07de..d892cf2c 100644 --- a/public/engine/iserversinfo.h +++ b/public/engine/iserversinfo.h @@ -89,6 +89,7 @@ class IServersInfo public: virtual void RequestInternetServerList( const char *gamedir, IServerListResponse *response ) = 0; virtual void RequestLANServerList( const char *gamedir, IServerListResponse *response ) = 0; + virtual void StopRefresh() = 0; //virtual HServerQuery PingServer( uint32 unIP, uint16 usPort, ISteamMatchmakingPingResponse *pRequestServersResponse ) = 0; //virtual HServerQuery PlayerDetails( uint32 unIP, uint16 usPort, ISteamMatchmakingPlayersResponse *pRequestServersResponse ) = 0; diff --git a/public/tier0/threadtools.h b/public/tier0/threadtools.h index b7216193..2b18dda7 100644 --- a/public/tier0/threadtools.h +++ b/public/tier0/threadtools.h @@ -52,12 +52,6 @@ #pragma once #pragma warning(push) #pragma warning(disable:4251) - -extern "C" -{ - void __declspec(dllimport) __stdcall Sleep( unsigned long ); -} - #endif #ifdef COMPILER_MSVC64 @@ -200,6 +194,8 @@ PLATFORM_INTERFACE bool ReleaseThreadHandle( ThreadHandle_t ); //----------------------------------------------------------------------------- +PLATFORM_INTERFACE void ThreadSleep(unsigned duration = 0); +PLATFORM_INTERFACE void ThreadNanoSleep(unsigned ns); PLATFORM_INTERFACE ThreadId_t ThreadGetCurrentId(); PLATFORM_INTERFACE ThreadHandle_t ThreadGetCurrentHandle(); PLATFORM_INTERFACE int ThreadGetPriority( ThreadHandle_t hThread = NULL ); @@ -233,10 +229,10 @@ inline void ThreadPause() { #if defined( COMPILER_PS3 ) __db16cyc(); -#elif defined( COMPILER_GCC ) && (defined( __i386__ ) || defined( __x86_64__ )) - __asm __volatile( "pause" ); -#elif defined( POSIX ) +#elif defined(__arm__) || defined(__aarch64__) sched_yield(); +#elif defined( COMPILER_GCC ) + __asm __volatile( "pause" ); #elif defined ( COMPILER_MSVC64 ) _mm_pause(); #elif defined( COMPILER_MSVC32 ) @@ -251,36 +247,6 @@ inline void ThreadPause() #endif } -inline void ThreadSleep(unsigned nMilliseconds = 0) -{ - if( nMilliseconds == 0 ) - { - ThreadPause(); - return; - } - -#ifdef _WIN32 - -#ifdef _WIN32_PC - static bool bInitialized = false; - if ( !bInitialized ) - { - bInitialized = true; - // Set the timer resolution to 1 ms (default is 10.0, 15.6, 2.5, 1.0 or - // some other value depending on hardware and software) so that we can - // use Sleep( 1 ) to avoid wasting CPU time without missing our frame - // rate. - timeBeginPeriod( 1 ); - } -#endif - Sleep( nMilliseconds ); -#elif PS3 - sys_timer_usleep( nMilliseconds * 1000 ); -#elif defined(POSIX) - usleep( nMilliseconds * 1000 ); -#endif -} - PLATFORM_INTERFACE bool ThreadJoin( ThreadHandle_t, unsigned timeout = TT_INFINITE ); PLATFORM_INTERFACE void ThreadSetDebugName( ThreadHandle_t hThread, const char *pszName ); diff --git a/public/tier1/memhelpers.h b/public/tier1/memhelpers.h index 35cd513e..898cafb2 100644 --- a/public/tier1/memhelpers.h +++ b/public/tier1/memhelpers.h @@ -11,15 +11,21 @@ namespace memutils template inline void copy( T *dest, const T *src, size_t n ) { - for(; n; n--) - *(dest++) = *(src++); + do + { + --n; + *(dest+n) = *(src+n); + } while( n ); } template - inline void set( T *dest, const T& value, size_t n ) + inline void set( T *dest, T value, size_t n ) { - for(; n; n--) - *(dest++) = value; + do + { + --n; + *(dest+n) = value; + } while( n ); } } diff --git a/tier0/threadtools.cpp b/tier0/threadtools.cpp index 06c8296f..b0dbb645 100644 --- a/tier0/threadtools.cpp +++ b/tier0/threadtools.cpp @@ -485,6 +485,59 @@ bool ReleaseThreadHandle( ThreadHandle_t hThread ) // //----------------------------------------------------------------------------- +void ThreadSleep(unsigned nMilliseconds) +{ +#ifdef _WIN32 + +#ifdef _WIN32_PC + static bool bInitialized = false; + if ( !bInitialized ) + { + bInitialized = true; + // Set the timer resolution to 1 ms (default is 10.0, 15.6, 2.5, 1.0 or + // some other value depending on hardware and software) so that we can + // use Sleep( 1 ) to avoid wasting CPU time without missing our frame + // rate. + timeBeginPeriod( 1 ); + } +#endif + + Sleep( nMilliseconds ); +#elif PS3 + if( nMilliseconds == 0 ) + { + // sys_ppu_thread_yield doesn't seem to function properly, so sleep instead. +// sys_timer_usleep( 60 ); + sys_ppu_thread_yield(); + } + else + { + sys_timer_usleep( nMilliseconds * 1000 ); + } +#elif defined(POSIX) + usleep( nMilliseconds * 1000 ); +#endif +} + +//----------------------------------------------------------------------------- +void ThreadNanoSleep(unsigned ns) +{ +#ifdef _WIN32 + // ceil + Sleep( ( ns + 999 ) / 1000 ); +#elif PS3 + sys_timer_usleep( ns ); +#elif defined(POSIX) + struct timespec tm; + tm.tv_sec = 0; + tm.tv_nsec = ns; + nanosleep( &tm, NULL ); +#endif +} + + +//----------------------------------------------------------------------------- + #ifndef ThreadGetCurrentId ThreadId_t ThreadGetCurrentId() { diff --git a/vstdlib/jobthread.cpp b/vstdlib/jobthread.cpp index 634d5358..922b770f 100644 --- a/vstdlib/jobthread.cpp +++ b/vstdlib/jobthread.cpp @@ -214,11 +214,7 @@ public: //----------------------------------------------------- virtual int YieldWait( CThreadEvent **pEvents, int nEvents, bool bWaitAll = true, unsigned timeout = TT_INFINITE ); virtual int YieldWait( CJob **, int nJobs, bool bWaitAll = true, unsigned timeout = TT_INFINITE ); - inline void Yield( unsigned timeout ) - { - Assert( ThreadInMainThread() ); - ThreadSleep( timeout ); - } + void Yield( unsigned timeout ); //----------------------------------------------------- // Add a native job to the queue (master thread) @@ -660,6 +656,20 @@ int CThreadPool::YieldWait( CJob **ppJobs, int nJobs, bool bWaitAll, unsigned ti return YieldWait( handles.Base(), handles.Count(), bWaitAll, timeout); } +//--------------------------------------------------------- + +void CThreadPool::Yield( unsigned timeout ) +{ + // @MULTICORE (toml 10/24/2006): not implemented + Assert( ThreadInMainThread() ); + if ( !ThreadInMainThread() ) + { + ThreadSleep( timeout ); + return; + } + ThreadSleep( timeout ); +} + //--------------------------------------------------------- // Add a job to the queue //--------------------------------------------------------- From bca8a497ad181d819ba46b5208d898e3a0267c8a Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 11 Feb 2023 15:56:06 +0300 Subject: [PATCH 08/17] engine: set net_usesocketsforloopback 0 by default( 1 breaks singleplayer mode ) --- engine/net_ws.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/net_ws.cpp b/engine/net_ws.cpp index b2680f1a..6f3c656b 100644 --- a/engine/net_ws.cpp +++ b/engine/net_ws.cpp @@ -45,7 +45,7 @@ static ConVar droppackets ( "net_droppackets", "0", FCVAR_CHEAT, "Drops next n p static ConVar fakejitter ( "net_fakejitter", "0", FCVAR_CHEAT, "Jitter fakelag packet time" ); static ConVar net_compressvoice( "net_compressvoice", "0", 0, "Attempt to compress out of band voice payloads (360 only)." ); -ConVar net_usesocketsforloopback( "net_usesocketsforloopback", "1", 0, "Use network sockets layer even for listen server local player's packets (multiplayer only)." ); +ConVar net_usesocketsforloopback( "net_usesocketsforloopback", "0", 0, "Use network sockets layer even for listen server local player's packets (multiplayer only)." ); #ifdef _DEBUG static ConVar fakenoise ( "net_fakenoise", "0", FCVAR_CHEAT, "Simulate corrupt network packets (changes n bits per packet randomly)" ); From 70cc94bd0125c56fff8cf06487ad67b8f45bad10 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 11 Feb 2023 15:57:06 +0300 Subject: [PATCH 09/17] engine(masterserver): fix latency calculation --- engine/masterserver.cpp | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index e7580773..fe3b5389 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -24,7 +24,7 @@ extern ConVar sv_tags; extern ConVar sv_lan; #define S2A_EXTRA_DATA_HAS_GAMETAG_DATA 0x01 // Next bytes are the game tag string -#define RETRY_INFO_REQUEST_TIME 0.4 // seconds +#define RETRY_INFO_REQUEST_TIME 0.3 // seconds #define INFO_REQUEST_TIMEOUT 5.0 // seconds //----------------------------------------------------------------------------- @@ -97,6 +97,7 @@ private: double m_flRetryRequestTime; uint m_iInfoSequence; + char m_szGameDir[256]; // If nomaster is true, the server will not send heartbeats to the master server bool m_bNoMasters; @@ -130,7 +131,7 @@ CMaster::CMaster( void ) SetDefLessFunc( m_serverAddresses ); SetDefLessFunc( m_serversRequestTime ); m_bWaitingForReplys = false; - m_iInfoSequence = 0; + m_iInfoSequence = 1; Init(); } @@ -150,13 +151,19 @@ void CMaster::RunFrame() m_flStartRequestTime < Plat_FloatTime()-INFO_REQUEST_TIMEOUT ) { m_serverListResponse->RefreshComplete( NServerResponse::nServerFailedToRespond ); - m_bWaitingForReplys = false; + StopRefresh(); } if( m_flRetryRequestTime < Plat_FloatTime() - RETRY_INFO_REQUEST_TIME ) { m_flRetryRequestTime = Plat_FloatTime(); + if( m_serverAddresses.Count() == 0 ) // Retry masterserver request + { + g_pServersInfo->RequestInternetServerList(m_szGameDir, NULL); + return; + } + if( m_iServersResponded < m_serverAddresses.Count() ) RequestServersInfo(); } @@ -164,6 +171,9 @@ void CMaster::RunFrame() void CMaster::StopRefresh() { + if( !m_bWaitingForReplys ) + return; + m_bWaitingForReplys = false; m_serverAddresses.RemoveAll(); m_serversRequestTime.RemoveAll(); @@ -264,7 +274,8 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) } case M2C_QUERY: { - m_serverAddresses.RemoveAll(); + if( m_serverAddresses.Count() > 0 ) + break; ip = msg.ReadLong(); port = msg.ReadShort(); @@ -281,7 +292,6 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) m_iServersResponded = 0; RequestServersInfo(); - m_flRetryRequestTime = m_flStartRequestTime = Plat_FloatTime(); break; } case C2S_INFOREQUEST: @@ -303,8 +313,11 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) double requestTime = m_serversRequestTime[rindex]; + if( m_serverAddresses[index] ) // shit happens + return; + m_serverAddresses[index] = true; - s.m_nPing = (packet->received-requestTime)*1000.0; + s.m_nPing = (Plat_FloatTime()-requestTime)*1000.0; s.m_NetAdr = packet->from; m_serverListResponse->ServerResponded( s ); @@ -337,13 +350,11 @@ void CMaster::RequestServersInfo() msg.WriteLong( CONNECTIONLESS_HEADER ); msg.WriteByte( C2S_INFOREQUEST ); msg.WriteLong( m_iInfoSequence ); - m_serversRequestTime.Insert(m_iInfoSequence, net_time); + m_serversRequestTime.Insert(m_iInfoSequence, Plat_FloatTime()); m_iInfoSequence++; NET_SendPacket( NULL, NS_CLIENT, adr, msg.GetData(), msg.GetNumBytesWritten() ); } - - m_bWaitingForReplys = true; } //----------------------------------------------------------------------------- @@ -633,7 +644,15 @@ void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse { if( m_bNoMasters ) return; - m_serverListResponse = response; + strncpy( m_szGameDir, gamedir, sizeof(m_szGameDir) ); + + if( response ) + { + StopRefresh(); + m_bWaitingForReplys = true; + m_serverListResponse = response; + m_flRetryRequestTime = m_flStartRequestTime = Plat_FloatTime(); + } ALIGN4 char buf[256] ALIGN4_POST; bf_write msg(buf, sizeof(buf)); From dda12fcec6017d130e356d2f62e52729f7a1d4fe Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 11 Feb 2023 19:17:57 +0300 Subject: [PATCH 10/17] engine(masterserver): add additional masterserver, implement setmaster command --- engine/master.h | 4 +- engine/masterserver.cpp | 103 +++++++++++++++++++++++++--------------- 2 files changed, 65 insertions(+), 42 deletions(-) diff --git a/engine/master.h b/engine/master.h index eddb39e0..34a86ffe 100644 --- a/engine/master.h +++ b/engine/master.h @@ -23,8 +23,6 @@ #include "engine/iserversinfo.h" -#define DEFAULT_MASTER_ADDRESS "185.192.97.130:27010" - //----------------------------------------------------------------------------- // Purpose: Implements a master server interface. //----------------------------------------------------------------------------- @@ -48,7 +46,7 @@ public: // Master sent back a challenge value, read it and send the actual heartbeat virtual void RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ) = 0; // Console command to set/remove master server - virtual void SetMaster_f( void ) = 0; + virtual void SetMaster_f( const CCommand &args ) = 0; // Force a heartbeat to be issued right away virtual void Heartbeat_f( void ) = 0; diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index fe3b5389..9356425a 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -24,9 +24,15 @@ extern ConVar sv_tags; extern ConVar sv_lan; #define S2A_EXTRA_DATA_HAS_GAMETAG_DATA 0x01 // Next bytes are the game tag string -#define RETRY_INFO_REQUEST_TIME 0.3 // seconds +#define RETRY_INFO_REQUEST_TIME 0.4 // seconds #define INFO_REQUEST_TIMEOUT 5.0 // seconds +static char g_MasterServers[][64] = +{ + "185.192.97.130:27010", + "168.138.92.21:27016" +}; + //----------------------------------------------------------------------------- // Purpose: List of master servers and some state info about them //----------------------------------------------------------------------------- @@ -69,11 +75,11 @@ public: void ProcessConnectionlessPacket( netpacket_t *packet ); - void SetMaster_f( void ); + void SetMaster_f( const CCommand &args ); void Heartbeat_f( void ); void RunFrame(); - void RequestServersInfo(); + void RetryServersInfoRequest(); void ReplyInfo( const netadr_t &adr, uint sequence ); newgameserver_t &ProcessInfo( bf_read &buf ); @@ -83,6 +89,7 @@ public: void RequestLANServerList( const char *gamedir, IServerListResponse *response ); void AddServerAddresses( netadr_t **adr, int count ); void StopRefresh(); + void RequestServerInfo( const netadr_t &adr ); private: // List of known master servers @@ -165,7 +172,7 @@ void CMaster::RunFrame() } if( m_iServersResponded < m_serverAddresses.Count() ) - RequestServersInfo(); + RetryServersInfoRequest(); } } @@ -174,6 +181,7 @@ void CMaster::StopRefresh() if( !m_bWaitingForReplys ) return; + m_iServersResponded = 0; m_bWaitingForReplys = false; m_serverAddresses.RemoveAll(); m_serversRequestTime.RemoveAll(); @@ -274,9 +282,6 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) } case M2C_QUERY: { - if( m_serverAddresses.Count() > 0 ) - break; - ip = msg.ReadLong(); port = msg.ReadShort(); @@ -284,14 +289,20 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) { netadr_t adr(ip, port); + unsigned short index = m_serverAddresses.Find(adr); + if( index != m_serverAddresses.InvalidIndex() ) + { + ip = msg.ReadLong(); + port = msg.ReadShort(); + continue; + } + m_serverAddresses.Insert(adr, false); + RequestServerInfo(adr); ip = msg.ReadLong(); port = msg.ReadShort(); } - - m_iServersResponded = 0; - RequestServersInfo(); break; } case C2S_INFOREQUEST: @@ -333,12 +344,22 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) } } -void CMaster::RequestServersInfo() +void CMaster::RequestServerInfo( const netadr_t &adr ) { static ALIGN4 char string[256] ALIGN4_POST; // Buffer for sending heartbeat - bf_write msg( string, sizeof(string) ); + msg.WriteLong( CONNECTIONLESS_HEADER ); + msg.WriteByte( C2S_INFOREQUEST ); + msg.WriteLong( m_iInfoSequence ); + m_serversRequestTime.Insert(m_iInfoSequence, Plat_FloatTime()); + + m_iInfoSequence++; + NET_SendPacket( NULL, NS_CLIENT, adr, msg.GetData(), msg.GetNumBytesWritten() ); +} + +void CMaster::RetryServersInfoRequest() +{ FOR_EACH_MAP_FAST( m_serverAddresses, i ) { bool bResponded = m_serverAddresses.Element(i); @@ -346,14 +367,7 @@ void CMaster::RequestServersInfo() continue; const netadr_t adr = m_serverAddresses.Key(i); - - msg.WriteLong( CONNECTIONLESS_HEADER ); - msg.WriteByte( C2S_INFOREQUEST ); - msg.WriteLong( m_iInfoSequence ); - m_serversRequestTime.Insert(m_iInfoSequence, Plat_FloatTime()); - - m_iInfoSequence++; - NET_SendPacket( NULL, NS_CLIENT, adr, msg.GetData(), msg.GetNumBytesWritten() ); + RequestServerInfo( adr ); } } @@ -378,8 +392,7 @@ void CMaster::SendHeartbeat ( adrlist_t *p ) return; // Send to master - // TODO(nillerusr): send engine version in this packet - Q_FileBase( com_gamedir, szGD, sizeof( szGD ) ); + Q_FileBase( com_gamedir, szGD, sizeof( szGD ) ); bf_write buf( string, sizeof(string) ); buf.WriteByte( S2M_HEARTBEAT ); @@ -510,11 +523,14 @@ void CMaster::UseDefault ( void ) { netadr_t adr; - // Convert to netadr_t - if ( NET_StringToAdr ( DEFAULT_MASTER_ADDRESS, &adr ) ) + for( int i = 0; i < ARRAYSIZE(g_MasterServers);i++ ) { - // Add to master list - AddServer( &adr ); + // Convert to netadr_t + if ( NET_StringToAdr ( g_MasterServers[i], &adr ) ) + { + // Add to master list + AddServer( &adr ); + } } } @@ -563,9 +579,19 @@ void CMaster::RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ) //----------------------------------------------------------------------------- // Purpose: Add/remove master servers //----------------------------------------------------------------------------- -void CMaster::SetMaster_f (void) +void CMaster::SetMaster_f ( const CCommand &args ) { + CUtlString cmd( ( args.ArgC() > 1 ) ? args[ 1 ] : "" ); + netadr_t adr; + + if( !NET_StringToAdr(cmd.String(), &adr) ) + { + Warning("Invalid address\n"); + return; + } + + this->AddServer(&adr); } @@ -589,9 +615,9 @@ void CMaster::Heartbeat_f (void) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void SetMaster_f( void ) +void SetMaster_f( const CCommand &args ) { - master->SetMaster_f(); + master->SetMaster_f( args ); } //----------------------------------------------------------------------------- @@ -643,7 +669,6 @@ void CMaster::Shutdown(void) void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse *response) { if( m_bNoMasters ) return; - strncpy( m_szGameDir, gamedir, sizeof(m_szGameDir) ); if( response ) @@ -660,8 +685,15 @@ void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse msg.WriteByte( C2M_CLIENTQUERY ); msg.WriteString(gamedir); - // TODO(nillerusr): add switching between masters? - NET_SendPacket(NULL, NS_CLIENT, m_pMasterAddresses->adr, msg.GetData(), msg.GetNumBytesWritten() ); + adrlist_t *p; + + p = m_pMasterAddresses; + while ( p ) + { + Msg("master server %s request\n", p->adr.ToString()); + NET_SendPacket(NULL, NS_CLIENT, p->adr, msg.GetData(), msg.GetNumBytesWritten() ); + p = p->next; + } } void CMaster::RequestLANServerList(const char *gamedir, IServerListResponse *response) @@ -673,10 +705,3 @@ void CMaster::AddServerAddresses( netadr_t **adr, int count ) { } - -void Master_Request_f() -{ - g_pServersInfo->RequestInternetServerList("cstrike", NULL); -} - -ConCommand master_request( "master_request", Master_Request_f ); From efbcaf7820e4864baf339f205de252b1508df142 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 11 Feb 2023 19:36:39 +0300 Subject: [PATCH 11/17] engine(masterserver): add master request timeout --- engine/masterserver.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index 9356425a..300ffb39 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -25,6 +25,7 @@ extern ConVar sv_lan; #define S2A_EXTRA_DATA_HAS_GAMETAG_DATA 0x01 // Next bytes are the game tag string #define RETRY_INFO_REQUEST_TIME 0.4 // seconds +#define MASTER_RESPONSE_TIMEOUT 1.5 // seconds #define INFO_REQUEST_TIMEOUT 5.0 // seconds static char g_MasterServers[][64] = @@ -102,6 +103,7 @@ private: double m_flStartRequestTime; double m_flRetryRequestTime; + double m_flMasterRequestTime; uint m_iInfoSequence; char m_szGameDir[256]; @@ -161,6 +163,15 @@ void CMaster::RunFrame() StopRefresh(); } + if( m_iServersResponded > 0 && + m_iServersResponded >= m_serverAddresses.Count() && + m_flMasterRequestTime < Plat_FloatTime() - MASTER_RESPONSE_TIMEOUT ) + { + StopRefresh(); + m_serverListResponse->RefreshComplete( NServerResponse::nServerResponded ); + return; + } + if( m_flRetryRequestTime < Plat_FloatTime() - RETRY_INFO_REQUEST_TIME ) { m_flRetryRequestTime = Plat_FloatTime(); @@ -250,7 +261,7 @@ newgameserver_t &CMaster::ProcessInfo(bf_read &buf) // Password? s.m_bPassword = buf.ReadByte(); - +m_iServersResponded s.m_iFlags = buf.ReadLong(); if( s.m_iFlags & S2A_EXTRA_DATA_HAS_GAMETAG_DATA ) @@ -333,12 +344,6 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) m_serverListResponse->ServerResponded( s ); m_iServersResponded++; - - if( m_iServersResponded >= m_serverAddresses.Count() ) - { - StopRefresh(); - m_serverListResponse->RefreshComplete( NServerResponse::nServerResponded ); - } break; } } @@ -676,7 +681,7 @@ void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse StopRefresh(); m_bWaitingForReplys = true; m_serverListResponse = response; - m_flRetryRequestTime = m_flStartRequestTime = Plat_FloatTime(); + m_flRetryRequestTime = m_flStartRequestTime = m_flMasterRequestTime = Plat_FloatTime(); } ALIGN4 char buf[256] ALIGN4_POST; @@ -690,7 +695,6 @@ void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse p = m_pMasterAddresses; while ( p ) { - Msg("master server %s request\n", p->adr.ToString()); NET_SendPacket(NULL, NS_CLIENT, p->adr, msg.GetData(), msg.GetNumBytesWritten() ); p = p->next; } From 2b2ca63b4869dc6d2f7e5956abe840910dba9a88 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 11 Feb 2023 19:39:01 +0300 Subject: [PATCH 12/17] serverbrowser: rewrite according my expectations --- serverbrowser/BaseGamesPage.cpp | 326 ++++++-------------------- serverbrowser/BaseGamesPage.h | 14 +- serverbrowser/DialogAddServer.cpp | 34 +-- serverbrowser/DialogAddServer.h | 8 +- serverbrowser/InternetGames.cpp | 4 +- serverbrowser/ServerBrowserDialog.cpp | 53 +++-- serverbrowser/ServerBrowserDialog.h | 9 +- serverbrowser/ServerListCompare.cpp | 75 ++---- serverbrowser/igamelist.h | 4 +- serverbrowser/pch_serverbrowser.h | 2 +- 10 files changed, 155 insertions(+), 374 deletions(-) diff --git a/serverbrowser/BaseGamesPage.cpp b/serverbrowser/BaseGamesPage.cpp index 5f76f78d..d87900c0 100644 --- a/serverbrowser/BaseGamesPage.cpp +++ b/serverbrowser/BaseGamesPage.cpp @@ -46,13 +46,13 @@ bool GameSupportsReplay() #endif //-------------------------------------------------------------------------------------------------------- -bool IsReplayServer( gameserveritem_t &server ) +bool IsReplayServer( newgameserver_t &server ) { bool bReplay = false; if ( GameSupportsReplay() ) { - if ( server.m_szGameTags && server.m_szGameTags[0] ) + if ( server.m_szGameTags[0] ) { CUtlVector TagList; V_SplitString( server.m_szGameTags, ",", TagList ); @@ -156,11 +156,11 @@ CBaseGamesPage::CBaseGamesPage( vgui::Panel *parent, const char *name, EPageType m_pConnect = new Button(this, "ConnectButton", "#ServerBrowser_Connect"); m_pConnect->SetEnabled(false); m_pRefreshAll = new Button(this, "RefreshButton", "#ServerBrowser_Refresh"); - m_pRefreshQuick = new Button(this, "RefreshQuickButton", "#ServerBrowser_RefreshQuick"); m_pAddServer = new Button(this, "AddServerButton", "#ServerBrowser_AddServer"); m_pAddCurrentServer = new Button(this, "AddCurrentServerButton", "#ServerBrowser_AddCurrentServer"); m_pGameList = new CGameListPanel(this, "gamelist"); m_pGameList->SetAllowUserModificationOfColumns(true); + m_pRefreshQuick = new Button(this, "RefreshQuickButton", "#ServerBrowser_RefreshQuick"); m_pQuickList = new PanelListPanel(this, "quicklist"); m_pQuickList->SetFirstColumnWidth( 0 ); @@ -191,14 +191,14 @@ CBaseGamesPage::CBaseGamesPage( vgui::Panel *parent, const char *name, EPageType 300, // maxwidth 0 // flags ); - m_pGameList->AddColumnHeader( k_nColumn_Players, "Players", "#ServerBrowser_Players", 55, ListPanel::COLUMN_FIXEDSIZE); - m_pGameList->AddColumnHeader( k_nColumn_Bots, "Bots", "#ServerBrowser_Bots", 40, ListPanel::COLUMN_FIXEDSIZE); + m_pGameList->AddColumnHeader( k_nColumn_Players, "Players", "#ServerBrowser_Players", 80, ListPanel::COLUMN_FIXEDSIZE); + m_pGameList->AddColumnHeader( k_nColumn_Bots, "Bots", "#ServerBrowser_Bots", 60, ListPanel::COLUMN_FIXEDSIZE); m_pGameList->AddColumnHeader( k_nColumn_Map, "Map", "#ServerBrowser_Map", 90, 90, // minwidth 300, // maxwidth 0 // flags ); - m_pGameList->AddColumnHeader( k_nColumn_Ping, "Ping", "#ServerBrowser_Latency", 55, ListPanel::COLUMN_FIXEDSIZE); + m_pGameList->AddColumnHeader( k_nColumn_Ping, "Ping", "#ServerBrowser_Latency", 55, ListPanel::COLUMN_RESIZEWITHWINDOW); m_pGameList->SetColumnHeaderTooltip( k_nColumn_Password, "#ServerBrowser_PasswordColumn_Tooltip"); m_pGameList->SetColumnHeaderTooltip( k_nColumn_Bots, "#ServerBrowser_BotColumn_Tooltip"); @@ -280,12 +280,10 @@ void CBaseGamesPage::PerformLayout() if (SupportsItem(IGameList::GETNEWLIST)) { - m_pRefreshQuick->SetVisible(true); m_pRefreshAll->SetText("#ServerBrowser_RefreshAll"); } else { - m_pRefreshQuick->SetVisible(false); m_pRefreshAll->SetText("#ServerBrowser_Refresh"); } @@ -313,25 +311,8 @@ void CBaseGamesPage::PerformLayout() m_pRefreshAll->SetText( "#ServerBrowser_StopRefreshingList" ); } - if (m_pGameList->GetItemCount() > 0) - { - m_pRefreshQuick->SetEnabled(true); - } - else - { - m_pRefreshQuick->SetEnabled(false); - } - -/* if ( !steamapicontext->SteamMatchmakingServers() || !steamapicontext->SteamMatchmaking() ) - { - m_pAddCurrentServer->SetVisible( false ); - m_pRefreshQuick->SetEnabled( false ); - m_pAddServer->SetEnabled( false ); - m_pConnect->SetEnabled( false ); - m_pRefreshAll->SetEnabled( false ); - m_pAddToFavoritesButton->SetEnabled( false ); - m_pGameList->SetEmptyListText( "#ServerBrowser_SteamRunning" ); - }*/ + m_pRefreshQuick->SetVisible( false ); + m_pFilter->SetVisible(false); Repaint(); } @@ -378,20 +359,6 @@ struct serverqualitysort_t int ServerQualitySort( const serverqualitysort_t *pSQ1, const serverqualitysort_t *pSQ2 ) { - int iMaxP = sb_mod_suggested_maxplayers.GetInt(); - if ( iMaxP && pSQ1->iMaxPlayerCount != pSQ2->iMaxPlayerCount ) - { - if ( pSQ1->iMaxPlayerCount > iMaxP ) - return 1; - if ( pSQ2->iMaxPlayerCount > iMaxP ) - return -1; - } - - if ( pSQ1->iPing <= 100 && pSQ2->iPing <= 100 && pSQ1->iPlayerCount != pSQ2->iPlayerCount ) - { - return pSQ2->iPlayerCount - pSQ1->iPlayerCount; - } - return pSQ1->iPing - pSQ2->iPing; } @@ -400,156 +367,72 @@ int ServerQualitySort( const serverqualitysort_t *pSQ1, const serverqualitysort_ //----------------------------------------------------------------------------- void CBaseGamesPage::SelectQuickListServers( void ) { - int iIndex = m_pQuickList->FirstItem(); - - while ( iIndex != m_pQuickList->InvalidItemID() ) - { - CQuickListPanel *pQuickListPanel = dynamic_cast< CQuickListPanel *> ( m_pQuickList->GetItemPanel( iIndex ) ); - - if ( pQuickListPanel ) - { - CUtlVector< serverqualitysort_t > vecServerQuality; - - int iElement = m_quicklistserverlist.Find( pQuickListPanel->GetName() ); - - if ( iElement != m_quicklistserverlist.InvalidIndex() ) - { - CQuickListMapServerList *vecMapServers = &m_quicklistserverlist[iElement]; - - if ( vecMapServers ) - { - for ( int i =0; i < vecMapServers->Count(); i++ ) - { - int iListID = vecMapServers->Element( i ); - - serverqualitysort_t serverquality; - - serverquality.iIndex = iListID; - - KeyValues *kv = NULL; - if ( m_pGameList->IsValidItemID( iListID ) ) - { - kv = m_pGameList->GetItem( iListID ); - } - - if ( kv ) - { - serverquality.iPing = kv->GetInt( "ping", 0 ); - serverquality.iPlayerCount = kv->GetInt( "PlayerCount", 0 ); - serverquality.iMaxPlayerCount = kv->GetInt( "MaxPlayerCount", 0 ); - } - - vecServerQuality.AddToTail( serverquality ); - } - - vecServerQuality.Sort( ServerQualitySort ); - - serverqualitysort_t bestserver = vecServerQuality.Head(); - - if ( m_pGameList->IsValidItemID( bestserver.iIndex ) ) - { - pQuickListPanel->SetServerInfo( m_pGameList->GetItem( bestserver.iIndex ), bestserver.iIndex, vecServerQuality.Count() ); - } - } - } - } - - iIndex = m_pQuickList->NextItem( iIndex ); - } - - //Force the connect button to recalculate its state. - OnItemSelected(); } -int ServerMapnameSortFunc( const servermaps_t *p1, const servermaps_t *p2 ) +int ServerPingSortFunc( const serverping_t *p1, const serverping_t *p2 ) { - //If they're both on disc OR both missing then sort them alphabetically - if ( (p1->bOnDisk && p2->bOnDisk) || (!p1->bOnDisk && !p2->bOnDisk ) ) - return Q_strcmp( p1->pFriendlyName, p2->pFriendlyName ); - - //Otherwise maps you have show up first - return p2->bOnDisk - p1->bOnDisk; + return p1->m_nPing - p2->m_nPing; } //----------------------------------------------------------------------------- // Purpose: prepares all the QuickListPanel map panels... //----------------------------------------------------------------------------- -void CBaseGamesPage::PrepareQuickListMap( const char *pMapName, int iListID ) +void CBaseGamesPage::PrepareQuickListMap( newgameserver_t *server, int iListID ) { char szMapName[ 512 ]; - Q_snprintf( szMapName, sizeof( szMapName ), "%s", pMapName ); + Q_snprintf( szMapName, sizeof( szMapName ), "%s", server->m_szMap ); Q_strlower( szMapName ); char path[ 512 ]; Q_snprintf( path, sizeof( path ), "maps/%s.bsp", szMapName ); - - int iIndex = m_quicklistserverlist.Find( szMapName ); - if ( m_quicklistserverlist.IsValidIndex( iIndex ) == false ) + char szFriendlyName[MAX_MAP_NAME]; + const char *pszFriendlyGameTypeName = ServerBrowser().GetMapFriendlyNameAndGameType( szMapName, szFriendlyName, sizeof(szFriendlyName) ); + + //Add the map to our list of panels. + if ( m_pQuickList ) { - CQuickListMapServerList vecMapServers; - iIndex = m_quicklistserverlist.Insert( szMapName, vecMapServers ); + serverping_t serverping; + const char *pFriendlyName = CloneString( szFriendlyName ); + const char *pOriginalName = CloneString( szMapName ); - char szFriendlyName[MAX_MAP_NAME]; - const char *pszFriendlyGameTypeName = ServerBrowser().GetMapFriendlyNameAndGameType( szMapName, szFriendlyName, sizeof(szFriendlyName) ); + char path[ 512 ]; + Q_snprintf( path, sizeof( path ), "maps/%s.bsp", szMapName ); - //Add the map to our list of panels. - if ( m_pQuickList ) + CQuickListPanel *pQuickListPanel = new CQuickListPanel( m_pQuickList, "QuickListPanel"); + + if ( pQuickListPanel ) { - servermaps_t servermap; + pQuickListPanel->InvalidateLayout(); + pQuickListPanel->SetName( pOriginalName ); + pQuickListPanel->SetMapName( pFriendlyName ); + pQuickListPanel->SetImage( pOriginalName ); + pQuickListPanel->SetGameType( pszFriendlyGameTypeName ); + pQuickListPanel->SetVisible( true ); + pQuickListPanel->SetRefreshing(); + pQuickListPanel->SetServerInfo( m_pGameList->GetItem( iListID ), iListID, 1 ); - servermap.pFriendlyName = CloneString( szFriendlyName ); - servermap.pOriginalName = CloneString( szMapName ); + serverping.iPanelIndex = m_pQuickList->AddItem( NULL, pQuickListPanel ); - char path[ 512 ]; - Q_snprintf( path, sizeof( path ), "maps/%s.bsp", szMapName ); + serverping.m_nPing = server->m_nPing; - servermap.bOnDisk = g_pFullFileSystem->FileExists( path, "MOD" ); - - CQuickListPanel *pQuickListPanel = new CQuickListPanel( m_pQuickList, "QuickListPanel"); - - if ( pQuickListPanel ) - { - pQuickListPanel->InvalidateLayout(); - pQuickListPanel->SetName( servermap.pOriginalName ); - pQuickListPanel->SetMapName( servermap.pFriendlyName ); - pQuickListPanel->SetImage( servermap.pOriginalName ); - pQuickListPanel->SetGameType( pszFriendlyGameTypeName ); - pQuickListPanel->SetVisible( true ); - pQuickListPanel->SetRefreshing(); - - servermap.iPanelIndex = m_pQuickList->AddItem( NULL, pQuickListPanel ); - } - - m_vecMapNamesFound.AddToTail( servermap ); - m_vecMapNamesFound.Sort( ServerMapnameSortFunc ); + m_vecServersFound.AddToTail( serverping ); + m_vecServersFound.Sort( ServerPingSortFunc ); } - //Now make sure that list is sorted. - CUtlVector *pPanelSort = m_pQuickList->GetSortedVector(); - - if ( pPanelSort ) - { - pPanelSort->RemoveAll(); - - for ( int i = 0; i < m_vecMapNamesFound.Count(); i++ ) - { - pPanelSort->AddToTail( m_vecMapNamesFound[i].iPanelIndex ); - } - } } - if ( iIndex != m_quicklistserverlist.InvalidIndex() ) - { - CQuickListMapServerList *vecMapServers = &m_quicklistserverlist[iIndex]; + //Now make sure that list is sorted. + CUtlVector *pPanelSort = m_pQuickList->GetSortedVector(); - if ( vecMapServers ) + if ( pPanelSort ) + { + pPanelSort->RemoveAll(); + + for ( int i = 0; i < m_vecServersFound.Count(); i++ ) { - if ( vecMapServers->Find( iListID ) == vecMapServers->InvalidIndex() ) - { - vecMapServers->AddToTail( iListID ); - } + pPanelSort->AddToTail( m_vecServersFound[i].iPanelIndex ); } } } @@ -557,21 +440,10 @@ void CBaseGamesPage::PrepareQuickListMap( const char *pMapName, int iListID ) //----------------------------------------------------------------------------- // Purpose: gets information about specified server //----------------------------------------------------------------------------- -gameserveritem_t *CBaseGamesPage::GetServer( unsigned int serverID ) +newgameserver_t *CBaseGamesPage::GetServer( unsigned int serverID ) { - if ( !steamapicontext->SteamMatchmakingServers() ) - return NULL; - - // No point checking for >= 0 when serverID is unsigned. - //if ( serverID >= 0 ) - { - return steamapicontext->SteamMatchmakingServers()->GetServerDetails( m_hRequest, serverID ); - } - //else - //{ - // Assert( !"Unable to return a useful entry" ); - // return NULL; // bugbug Alfred: temp Favorites/History objects won't return a good value here... - //} + if( serverID >= m_serversInfo.Count() ) return NULL; + return &m_serversInfo[serverID]; } //----------------------------------------------------------------------------- @@ -680,8 +552,8 @@ void CBaseGamesPage::CreateFilters() int iItemID = m_pGameFilter->AddItem(ModList().GetModName(i), pkv); m_mapGamesFilterItem.Insert( ModList().GetAppID(i).ToUint64(), iItemID ); } - pkv->deleteThis(); + pkv->deleteThis(); } @@ -710,7 +582,7 @@ void CBaseGamesPage::LoadFilterSettings() m_bFilterNoEmptyServers = filter->GetInt("NoEmpty"); m_bFilterNoPasswordedServers = filter->GetInt("NoPassword"); m_bFilterReplayServers = filter->GetInt("Replay"); - m_pQuickListCheckButton->SetSelected( filter->GetInt( "QuickList", 0 ) ); + m_pQuickListCheckButton->SetSelected( filter->GetInt( "QuickList", IsAndroid() ) ); int secureFilter = filter->GetInt("Secure"); m_pSecureFilter->ActivateItem(secureFilter); @@ -1005,7 +877,13 @@ void CBaseGamesPage::UpdateFilterAndQuickListVisibility() int wide, tall; GetSize( wide, tall ); - SetSize( 624, 278 ); + + int w = 640; int h = 384; + + w = IsProportional() ? vgui::scheme()->GetProportionalScaledValue(w) : w; + h = IsProportional() ? vgui::scheme()->GetProportionalScaledValue(h) : h; + + SetSize( w, h ); UpdateDerivedLayouts(); UpdateGameFilter(); @@ -1018,12 +896,10 @@ void CBaseGamesPage::UpdateFilterAndQuickListVisibility() SetSize( wide, tall ); - m_pQuickList->SetVisible( showQuickList ); m_pGameList->SetVisible( !showQuickList ); m_pFilter->SetVisible( !showQuickList ); - m_pFilterString->SetVisible ( !showQuickList ); - + m_pFilterString->SetVisible ( !showQuickList ); InvalidateLayout(); @@ -1638,7 +1514,6 @@ void CBaseGamesPage::SetRefreshing(bool state) m_pGameList->SetEmptyListText(""); m_pRefreshAll->SetText("#ServerBrowser_StopRefreshingList"); m_pRefreshAll->SetCommand("stoprefresh"); - m_pRefreshQuick->SetEnabled(false); } else { @@ -1654,14 +1529,6 @@ void CBaseGamesPage::SetRefreshing(bool state) m_pRefreshAll->SetCommand("GetNewList"); // 'refresh quick' button is only enabled if there are servers in the list - if (m_pGameList->GetItemCount() > 0) - { - m_pRefreshQuick->SetEnabled(true); - } - else - { - m_pRefreshQuick->SetEnabled(false); - } } } @@ -1762,7 +1629,7 @@ int CBaseGamesPage::GetSelectedItemsCount() //----------------------------------------------------------------------------- void CBaseGamesPage::OnAddToFavorites() { - if ( !steamapicontext->SteamMatchmakingServers() ) +/* if ( !steamapicontext->SteamMatchmakingServers() ) return; // loop through all the selected favorites @@ -1776,7 +1643,7 @@ void CBaseGamesPage::OnAddToFavorites() // add to favorites list ServerBrowserDialog().AddServerToFavorites(*pServer); } - } + }*/ } //----------------------------------------------------------------------------- @@ -1838,6 +1705,8 @@ void CBaseGamesPage::StartRefresh() MatchMakingKeyValuePair_t *pFilters; int nFilters = GetServerFilters( &pFilters ); + m_serversInfo.SetCount(0); + /* if ( m_hRequest ) { steamapicontext->SteamMatchmakingServers()->ReleaseRequest( m_hRequest ); @@ -1852,7 +1721,6 @@ void CBaseGamesPage::StartRefresh() m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestHistoryServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); break;*/ case eInternetServer: - Msg("RequestInternetServerList\n"); g_pServersInfo->RequestInternetServerList(COM_GetModDirectory(), this); //m_hRequest = steamapicontext->SteamMatchmakingServers()->RequestInternetServerList( GetFilterAppID().AppID(), &pFilters, nFilters, this ); break; @@ -1878,20 +1746,7 @@ void CBaseGamesPage::StartRefresh() void CBaseGamesPage::ClearQuickList( void ) { m_pQuickList->DeleteAllItems(); - m_vecMapNamesFound.RemoveAll(); - - int iIndex = m_quicklistserverlist.First(); - - while ( iIndex != m_quicklistserverlist.InvalidIndex() ) - { - CQuickListMapServerList *vecMapServers = &m_quicklistserverlist[iIndex]; - - vecMapServers->RemoveAll(); - - iIndex = m_quicklistserverlist.Next( iIndex ); - } - - m_quicklistserverlist.RemoveAll(); + m_vecServersFound.RemoveAll(); } //----------------------------------------------------------------------------- @@ -1925,8 +1780,7 @@ void CBaseGamesPage::StopRefresh() m_iServerRefreshCount = 0; // Stop the server list refreshing - if ( steamapicontext->SteamMatchmakingServers() ) - steamapicontext->SteamMatchmakingServers()->CancelQuery( m_hRequest ); + g_pServersInfo->StopRefresh(); // update UI RefreshComplete( nServerResponded ); @@ -1940,7 +1794,8 @@ void CBaseGamesPage::StopRefresh() //----------------------------------------------------------------------------- void CBaseGamesPage::RefreshComplete( NServerResponse response ) { - SelectQuickListServers(); + //Force the connect button to recalculate its state. + OnItemSelected(); } //----------------------------------------------------------------------------- @@ -2235,12 +2090,7 @@ void CBaseGamesPage::ServerResponded( newgameserver_t &server ) kv->SetString("GameDir", pServerItem->m_szGameDir); kv->SetString("GameDesc", pServerItem->m_szGameDescription); kv->SetInt("password", pServerItem->m_bPassword ? m_nImageIndexPassword : 0); - - if ( pServerItem->m_nBotPlayers > 0 ) - kv->SetInt("bots", pServerItem->m_nBotPlayers); - else - kv->SetString("bots", ""); - + kv->SetInt("bots", pServerItem->m_nBotPlayers); kv->SetInt("secure", 0); @@ -2257,51 +2107,21 @@ void CBaseGamesPage::ServerResponded( newgameserver_t &server ) kv->SetInt("Ping", pServerItem->m_nPing); - kv->SetString("Tags", ""); + kv->SetString("Tags", pServerItem->m_szGameTags); kv->SetInt("Replay", 0); -/* if ( pServerItem->m_ulTimeLastPlayed ) - { - // construct a time string for last played time - struct tm *now; - now = localtime( (time_t*)&pServerItem->m_ulTimeLastPlayed ); - - if ( now ) - { - char buf[64]; - strftime(buf, sizeof(buf), "%a %d %b %I:%M%p", now); - Q_strlower(buf + strlen(buf) - 4); - kv->SetString("LastPlayed", buf); - } - }*/ - int iServerIndex = m_serversInfo.AddToTail( server ); - //if ( !m_pGameList->IsValidItemID( pServer->m_iListID ) ) + // new server, add to list + int iListID = m_pGameList->AddItem(kv, iServerIndex, false, false); - // new server, add to list - int iListID = m_pGameList->AddItem(kv, iServerIndex, false, false); - /*if ( m_bAutoSelectFirstItemInGameList && m_pGameList->GetItemCount() == 1 ) - { - m_pGameList->AddSelectedItem( pServer->m_iListID ); - }*/ + m_pGameList->SetItemVisible( iListID, true ); + kv->deleteThis(); - m_pGameList->SetItemVisible( iListID, true ); - - kv->deleteThis(); - -/* else - { - // tell the list that we've changed the data - m_pGameList->ApplyItemChanges( pServer->m_iListID ); - m_pGameList->SetItemVisible( pServer->m_iListID, !removeItem ); - }*/ - - PrepareQuickListMap( pServerItem->m_szMap, iListID ); + PrepareQuickListMap( &server, iListID ); UpdateStatus(); m_iServerRefreshCount++; - } //----------------------------------------------------------------------------- diff --git a/serverbrowser/BaseGamesPage.h b/serverbrowser/BaseGamesPage.h index fca73685..d3e0ce87 100644 --- a/serverbrowser/BaseGamesPage.h +++ b/serverbrowser/BaseGamesPage.h @@ -66,12 +66,10 @@ public: virtual void OnCursorExited(); }; -struct servermaps_t +struct serverping_t { - const char *pOriginalName; - const char *pFriendlyName; - int iPanelIndex; - bool bOnDisk; + int m_nPing; + int iPanelIndex; }; struct gametypes_t @@ -120,7 +118,7 @@ public: virtual void ApplySchemeSettings(vgui::IScheme *pScheme); // gets information about specified server - virtual gameserveritem_t *GetServer(unsigned int serverID); + virtual newgameserver_t *GetServer(unsigned int serverID); virtual const char *GetConnectCode(); uint32 GetServerFilters( MatchMakingKeyValuePair_t **pFilters ); @@ -144,7 +142,7 @@ public: virtual void UpdateDerivedLayouts( void ); - void PrepareQuickListMap( const char *pMapName, int iListID ); + void PrepareQuickListMap( newgameserver_t *server, int iListID ); void SelectQuickListServers( void ); vgui::Panel *GetActiveList( void ); virtual bool IsQuickListButtonChecked() @@ -242,7 +240,7 @@ protected: CUtlVector m_vecServerFilters; CUtlDict< CQuickListMapServerList, int > m_quicklistserverlist; int m_iServerRefreshCount; - CUtlVector< servermaps_t > m_vecMapNamesFound; + CUtlVector m_vecServersFound; EPageType m_eMatchMakingType; diff --git a/serverbrowser/DialogAddServer.cpp b/serverbrowser/DialogAddServer.cpp index 5dbc9ed5..50ce17ca 100644 --- a/serverbrowser/DialogAddServer.cpp +++ b/serverbrowser/DialogAddServer.cpp @@ -177,15 +177,13 @@ void CDialogAddServer::OnOK() if ( AllowInvalidIPs() || netaddr.IsValid() ) { - gameserveritem_t server; + newgameserver_t server; memset(&server, 0, sizeof(server)); - server.SetName( address ); + strncpy( server.m_szServerName, address, sizeof(server.m_szServerName) ); // We assume here that the query and connection ports are the same. This is why it's much // better if they click "Servers" and choose a server in there. - server.m_NetAdr.Init( netaddr.GetIPHostByteOrder(), netaddr.GetPort(), netaddr.GetPort() ); - - server.m_nAppID = 0; + server.m_NetAdr = netaddr; FinishAddServer( server ); } else @@ -257,21 +255,21 @@ void CDialogAddServer::TestServers() m_pTabPanel->AddPage( m_pDiscoveredGames, str ); m_pTabPanel->InvalidateLayout(); - FOR_EACH_VEC( vecAdress, iAddress ) +/* FOR_EACH_VEC( vecAdress, iAddress ) { m_Queries.AddToTail( steamapicontext->SteamMatchmakingServers()->PingServer( vecAdress[ iAddress ].GetIPHostByteOrder(), vecAdress[ iAddress ].GetPort(), this ) ); - } + }*/ } //----------------------------------------------------------------------------- // Purpose: A server answered our ping //----------------------------------------------------------------------------- -void CDialogAddServer::ServerResponded( gameserveritem_t &server ) +void CDialogAddServer::ServerResponded( newgameserver_t &server ) { KeyValues *kv = new KeyValues( "Server" ); - kv->SetString( "name", server.GetName() ); + kv->SetString( "name", server.m_szServerName ); kv->SetString( "map", server.m_szMap ); kv->SetString( "GameDir", server.m_szGameDir ); kv->SetString( "GameDesc", server.m_szGameDescription ); @@ -279,21 +277,9 @@ void CDialogAddServer::ServerResponded( gameserveritem_t &server ) kv->SetInt( "password", server.m_bPassword ? 1 : 0); kv->SetInt( "bots", server.m_nBotPlayers ? 2 : 0); kv->SetInt( "Replay", IsReplayServer( server ) ? 5 : 0 ); + kv->SetInt("secure", 0); - if ( server.m_bSecure ) - { - // show the denied icon if banned from secure servers, the secure icon otherwise - kv->SetInt("secure", ServerBrowser().IsVACBannedFromGame( server.m_nAppID ) ? 4 : 3); - } - else - { - kv->SetInt("secure", 0); - } - - netadr_t reportedIPAddr; - reportedIPAddr.SetIP( server.m_NetAdr.GetIP() ); - reportedIPAddr.SetPort( server.m_NetAdr.GetConnectionPort() ); - kv->SetString("IPAddr", reportedIPAddr.ToString() ); + kv->SetString("IPAddr", server.m_NetAdr.ToString() ); char buf[32]; Q_snprintf(buf, sizeof(buf), "%d / %d", server.m_nPlayers, server.m_nMaxPlayers); @@ -366,7 +352,7 @@ void CDialogAddServer::OnItemSelected() //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CDialogAddServer::FinishAddServer( gameserveritem_t &pServer ) +void CDialogAddServer::FinishAddServer( newgameserver_t &pServer ) { ServerBrowserDialog().AddServerToFavorites( pServer ); } diff --git a/serverbrowser/DialogAddServer.h b/serverbrowser/DialogAddServer.h index c340904b..6128561c 100644 --- a/serverbrowser/DialogAddServer.h +++ b/serverbrowser/DialogAddServer.h @@ -17,7 +17,7 @@ class IGameList; //----------------------------------------------------------------------------- // Purpose: Dialog which lets the user add a server by IP address //----------------------------------------------------------------------------- -class CDialogAddServer : public vgui::Frame, public ISteamMatchmakingPingResponse +class CDialogAddServer : public vgui::Frame //, public ISteamMatchmakingPingResponse { DECLARE_CLASS_SIMPLE( CDialogAddServer, vgui::Frame ); friend class CAddServerGameList; @@ -26,7 +26,7 @@ public: CDialogAddServer(vgui::Panel *parent, IGameList *gameList); ~CDialogAddServer(); - void ServerResponded( gameserveritem_t &server ); + void ServerResponded( newgameserver_t &server ); void ServerFailedToRespond(); void ApplySchemeSettings( vgui::IScheme *pScheme ); @@ -40,7 +40,7 @@ private: void TestServers(); MESSAGE_FUNC( OnTextChanged, "TextChanged" ); - virtual void FinishAddServer( gameserveritem_t &pServer ); + virtual void FinishAddServer( newgameserver_t &pServer ); virtual bool AllowInvalidIPs( void ) { return false; } protected: @@ -54,7 +54,7 @@ protected: vgui::TextEntry *m_pTextEntry; vgui::ListPanel *m_pDiscoveredGames; int m_OriginalHeight; - CUtlVector m_Servers; + CUtlVector m_Servers; CUtlVector m_Queries; }; diff --git a/serverbrowser/InternetGames.cpp b/serverbrowser/InternetGames.cpp index 2e77e0ab..00a46ccf 100644 --- a/serverbrowser/InternetGames.cpp +++ b/serverbrowser/InternetGames.cpp @@ -23,7 +23,7 @@ CInternetGames::CInternetGames(vgui::Panel *parent, const char *panelName, EPage m_fLastSort = 0.0f; m_bDirty = false; m_bRequireUpdate = true; - m_bOfflineMode = false; //ro!IsSteamGameServerBrowsingEnabled(); + m_bOfflineMode = false; m_bAnyServersRetrievedFromMaster = false; m_bNoServersListedOnMaster = false; @@ -311,7 +311,7 @@ int CInternetGames::GetRegionCodeToFilter() bool CInternetGames::CheckTagFilter( gameserveritem_t &server ) { // Servers without tags go in the official games, servers with tags go in custom games - bool bOfficialServer = !( server.m_szGameTags && server.m_szGameTags[0] ); + bool bOfficialServer = !server.m_szGameTags[0]; if ( !bOfficialServer ) return false; diff --git a/serverbrowser/ServerBrowserDialog.cpp b/serverbrowser/ServerBrowserDialog.cpp index b3e9738b..2ba47348 100644 --- a/serverbrowser/ServerBrowserDialog.cpp +++ b/serverbrowser/ServerBrowserDialog.cpp @@ -59,6 +59,7 @@ void GetMostCommonQueryPorts( CUtlVector &ports ) //----------------------------------------------------------------------------- CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, "CServerBrowserDialog") { + SetProportional( NeedProportional() ); s_InternetDlg = this; m_szGameName[0] = 0; @@ -67,19 +68,25 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, m_pFilterData = NULL; m_pFavorites = NULL; m_pHistory = NULL; + m_pLanGames = NULL; LoadUserData(); m_pInternetGames = new CInternetGames(this); +/* m_pFavorites = new CFavoriteGames(this); m_pHistory = new CHistoryGames(this); - - // TODO(nillerusr): implement spectate games without steam - //m_pSpectateGames = new CSpectateGames(this); + m_pSpectateGames = new CSpectateGames(this); m_pLanGames = new CLanGames(this); +*/ - SetMinimumSize( 640, 384 ); - SetSize( 640, 384 ); + int w = 640; int h = 384; + + w = IsProportional() ? vgui::scheme()->GetProportionalScaledValue(w) : w; + h = IsProportional() ? vgui::scheme()->GetProportionalScaledValue(h) : h; + + SetMinimumSize( w, h ); + SetSize( w, h ); m_pGameList = m_pInternetGames; @@ -89,10 +96,10 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, m_pTabPanel = new PropertySheet(this, "GameTabs"); m_pTabPanel->SetTabWidth(72); m_pTabPanel->AddPage(m_pInternetGames, "#ServerBrowser_InternetTab"); - m_pTabPanel->AddPage(m_pFavorites, "#ServerBrowser_FavoritesTab"); - m_pTabPanel->AddPage(m_pHistory, "#ServerBrowser_HistoryTab"); + //m_pTabPanel->AddPage(m_pFavorites, "#ServerBrowser_FavoritesTab"); + //m_pTabPanel->AddPage(m_pHistory, "#ServerBrowser_HistoryTab"); //m_pTabPanel->AddPage(m_pSpectateGames, "#ServerBrowser_SpectateTab"); - m_pTabPanel->AddPage(m_pLanGames, "#ServerBrowser_LanTab"); + //m_pTabPanel->AddPage(m_pLanGames, "#ServerBrowser_LanTab"); m_pTabPanel->AddActionSignalTarget(this); @@ -109,7 +116,7 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, { m_pTabPanel->SetActivePage(m_pSpectateGames); } - else */ + else if (!Q_stricmp(gameList, "favorites")) { m_pTabPanel->SetActivePage(m_pFavorites); @@ -122,7 +129,7 @@ CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, { m_pTabPanel->SetActivePage(m_pLanGames); } - else + else*/ { m_pTabPanel->SetActivePage(m_pInternetGames); } @@ -160,7 +167,7 @@ void CServerBrowserDialog::Initialize() //----------------------------------------------------------------------------- // Purpose: returns a server in the list //----------------------------------------------------------------------------- -gameserveritem_t *CServerBrowserDialog::GetServer( unsigned int serverID ) +newgameserver_t *CServerBrowserDialog::GetServer( unsigned int serverID ) { if (m_pGameList) return m_pGameList->GetServer( serverID ); @@ -257,7 +264,7 @@ void CServerBrowserDialog::SaveUserData() { m_pSavedData->SetString("GameList", "spectate"); } - else */ + else if (m_pGameList == m_pFavorites) { m_pSavedData->SetString("GameList", "favorites"); @@ -270,7 +277,7 @@ void CServerBrowserDialog::SaveUserData() { m_pSavedData->SetString("GameList", "history"); } - else + else*/ { m_pSavedData->SetString("GameList", "internet"); } @@ -363,9 +370,9 @@ CServerBrowserDialog *CServerBrowserDialog::GetInstance() //----------------------------------------------------------------------------- // Purpose: Adds a server to the list of favorites //----------------------------------------------------------------------------- -void CServerBrowserDialog::AddServerToFavorites(gameserveritem_t &server) +void CServerBrowserDialog::AddServerToFavorites(newgameserver_t &server) { - if ( steamapicontext->SteamMatchmaking() ) +/* if ( steamapicontext->SteamMatchmaking() ) { steamapicontext->SteamMatchmaking()->AddFavoriteGame( server.m_nAppID, @@ -374,7 +381,7 @@ void CServerBrowserDialog::AddServerToFavorites(gameserveritem_t &server) server.m_NetAdr.GetQueryPort(), k_unFavoriteFlagFavorite, time( NULL ) ); - } + }*/ } //----------------------------------------------------------------------------- @@ -527,10 +534,10 @@ void CServerBrowserDialog::OnActiveGameName( KeyValues *pKV ) void CServerBrowserDialog::ReloadFilterSettings() { m_pInternetGames->LoadFilterSettings(); - //m_pSpectateGames->LoadFilterSettings(); + /*m_pSpectateGames->LoadFilterSettings(); m_pFavorites->LoadFilterSettings(); m_pLanGames->LoadFilterSettings(); - m_pHistory->LoadFilterSettings(); + m_pHistory->LoadFilterSettings();*/ } //----------------------------------------------------------------------------- @@ -572,7 +579,7 @@ void CServerBrowserDialog::OnConnectToGame( KeyValues *pMessageValues ) } // forward to favorites - m_pFavorites->OnConnectToGame(); + //m_pFavorites->OnConnectToGame(); m_bCurrentlyConnected = true; @@ -582,7 +589,7 @@ void CServerBrowserDialog::OnConnectToGame( KeyValues *pMessageValues ) { iQuickListBitField |= ( 1 << 1 ); } -/* if ( m_pSpectateGames && m_pSpectateGames->IsQuickListButtonChecked() ) + /*if ( m_pSpectateGames && m_pSpectateGames->IsQuickListButtonChecked() ) { iQuickListBitField |= ( 1 << 2 ); }*/ @@ -625,7 +632,7 @@ void CServerBrowserDialog::OnDisconnectFromGame( void ) memset( &m_CurrentConnection, 0, sizeof(gameserveritem_t) ); // forward to favorites - m_pFavorites->OnDisconnectFromGame(); + //m_pFavorites->OnDisconnectFromGame(); } //----------------------------------------------------------------------------- @@ -634,10 +641,10 @@ void CServerBrowserDialog::OnDisconnectFromGame( void ) void CServerBrowserDialog::OnLoadingStarted( void ) { m_pInternetGames->OnLoadingStarted(); -// m_pSpectateGames->OnLoadingStarted(); +/* m_pSpectateGames->OnLoadingStarted(); m_pFavorites->OnLoadingStarted(); m_pLanGames->OnLoadingStarted(); - m_pHistory->OnLoadingStarted(); + m_pHistory->OnLoadingStarted();*/ } //----------------------------------------------------------------------------- diff --git a/serverbrowser/ServerBrowserDialog.h b/serverbrowser/ServerBrowserDialog.h index 8180a9f1..dfd4955f 100644 --- a/serverbrowser/ServerBrowserDialog.h +++ b/serverbrowser/ServerBrowserDialog.h @@ -31,7 +31,7 @@ public: void Open( void ); // gets server info - gameserveritem_t *GetServer(unsigned int serverID); + newgameserver_t *GetServer(unsigned int serverID); // called every frame virtual void OnTick(); @@ -49,7 +49,7 @@ public: static CServerBrowserDialog *GetInstance(); // Adds a server to the list of favorites - void AddServerToFavorites(gameserveritem_t &server); + void AddServerToFavorites(newgameserver_t &server); // begins the process of joining a server from a game list // the game info dialog it opens will also update the game list @@ -118,11 +118,12 @@ private: // property sheet vgui::PropertySheet *m_pTabPanel; - CFavoriteGames *m_pFavorites; - CHistoryGames *m_pHistory; + CInternetGames *m_pInternetGames; //CSpectateGames *m_pSpectateGames; CLanGames *m_pLanGames; + CFavoriteGames *m_pFavorites; + CHistoryGames *m_pHistory; KeyValues *m_pSavedData; KeyValues *m_pFilterData; diff --git a/serverbrowser/ServerListCompare.cpp b/serverbrowser/ServerListCompare.cpp index f17678bd..6e195f59 100644 --- a/serverbrowser/ServerListCompare.cpp +++ b/serverbrowser/ServerListCompare.cpp @@ -7,15 +7,15 @@ #include "pch_serverbrowser.h" -bool IsReplayServer( gameserveritem_t &server ); +bool IsReplayServer( newgameserver_t &server ); //----------------------------------------------------------------------------- // Purpose: List password column sort function //----------------------------------------------------------------------------- int __cdecl PasswordCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -37,8 +37,8 @@ int __cdecl PasswordCompare(ListPanel *pPanel, const ListPanelItem &p1, const Li //----------------------------------------------------------------------------- int __cdecl BotsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -60,21 +60,6 @@ int __cdecl BotsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPa //----------------------------------------------------------------------------- int __cdecl SecureCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); - - if ( !s1 && s2 ) - return -1; - if ( !s2 && s1 ) - return 1; - if ( !s1 && !s2 ) - return 0; - - if ( s1->m_bSecure < s2->m_bSecure ) - return 1; - else if ( s1->m_bSecure > s2->m_bSecure ) - return -1; - return 0; } @@ -83,8 +68,8 @@ int __cdecl SecureCompare(ListPanel *pPanel, const ListPanelItem &p1, const List //----------------------------------------------------------------------------- int __cdecl IPAddressCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -106,8 +91,8 @@ int __cdecl IPAddressCompare(ListPanel *pPanel, const ListPanelItem &p1, const L //----------------------------------------------------------------------------- int __cdecl PingCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -132,8 +117,8 @@ int __cdecl PingCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPa //----------------------------------------------------------------------------- int __cdecl MapCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -150,8 +135,8 @@ int __cdecl MapCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPan //----------------------------------------------------------------------------- int __cdecl GameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -171,8 +156,8 @@ int __cdecl GameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPa //----------------------------------------------------------------------------- int __cdecl ServerNameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -181,7 +166,7 @@ int __cdecl ServerNameCompare(ListPanel *pPanel, const ListPanelItem &p1, const if ( !s1 && !s2 ) return 0; - return Q_stricmp( s1->GetName(), s2->GetName() ); + return Q_stricmp( s1->m_szServerName, s2->m_szServerName ); } //----------------------------------------------------------------------------- @@ -189,8 +174,8 @@ int __cdecl ServerNameCompare(ListPanel *pPanel, const ListPanelItem &p1, const //----------------------------------------------------------------------------- int __cdecl PlayersCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -224,22 +209,6 @@ int __cdecl PlayersCompare(ListPanel *pPanel, const ListPanelItem &p1, const Lis //----------------------------------------------------------------------------- int __cdecl LastPlayedCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer( p1.userData ); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer( p2.userData ); - - if ( !s1 && s2 ) - return -1; - if ( !s2 && s1 ) - return 1; - if ( !s1 && !s2 ) - return 0; - - // compare number of players - if ( s1->m_ulTimeLastPlayed > s2->m_ulTimeLastPlayed ) - return -1; - if ( s1->m_ulTimeLastPlayed < s2->m_ulTimeLastPlayed ) - return 1; - return 0; } @@ -248,8 +217,8 @@ int __cdecl LastPlayedCompare(ListPanel *pPanel, const ListPanelItem &p1, const //----------------------------------------------------------------------------- int __cdecl TagsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; @@ -266,8 +235,8 @@ int __cdecl TagsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPa //----------------------------------------------------------------------------- int __cdecl ReplayCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2) { - gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData); - gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData); + newgameserver_t *s1 = ServerBrowserDialog().GetServer(p1.userData); + newgameserver_t *s2 = ServerBrowserDialog().GetServer(p2.userData); if ( !s1 && s2 ) return -1; diff --git a/serverbrowser/igamelist.h b/serverbrowser/igamelist.h index 3944c9b0..3be6fcda 100644 --- a/serverbrowser/igamelist.h +++ b/serverbrowser/igamelist.h @@ -20,7 +20,7 @@ class gameserveritem_t; #include "FindSteamServers.h" #endif #include "netadr.h" - +#include "engine/iserversinfo.h" typedef enum { @@ -75,7 +75,7 @@ public: virtual bool IsRefreshing() = 0; // gets information about specified server - virtual gameserveritem_t *GetServer(unsigned int serverID) = 0; + virtual newgameserver_t *GetServer(unsigned int serverID) = 0; // called when Connect button is pressed virtual void OnBeginConnect() = 0; diff --git a/serverbrowser/pch_serverbrowser.h b/serverbrowser/pch_serverbrowser.h index 8e44f2ba..6812359c 100644 --- a/serverbrowser/pch_serverbrowser.h +++ b/serverbrowser/pch_serverbrowser.h @@ -69,7 +69,7 @@ #include "replay/ienginereplay.h" extern bool GameSupportsReplay(); -extern bool IsReplayServer( gameserveritem_t &server ); +extern bool IsReplayServer( newgameserver_t &server ); #pragma warning( disable: 4355 ) // warning C4355: 'this' : used in base member initializer list From 67ef35bb783b610c9ab511f8c03ea018e058d33a Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 11 Feb 2023 20:34:22 +0300 Subject: [PATCH 13/17] engine(masterserver): typo fix --- engine/masterserver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index 300ffb39..42eb37ca 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -261,7 +261,6 @@ newgameserver_t &CMaster::ProcessInfo(bf_read &buf) // Password? s.m_bPassword = buf.ReadByte(); -m_iServersResponded s.m_iFlags = buf.ReadLong(); if( s.m_iFlags & S2A_EXTRA_DATA_HAS_GAMETAG_DATA ) From c3417ca08da09a837a4fc5ce65db65ce487291bb Mon Sep 17 00:00:00 2001 From: nillerusr Date: Mon, 13 Feb 2023 00:27:40 +0300 Subject: [PATCH 14/17] engine: fix cmdrate/updaterate values --- engine/baseclient.cpp | 2 +- engine/masterserver.cpp | 1 + engine/sv_client.cpp | 4 ++-- engine/sv_main.cpp | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/engine/baseclient.cpp b/engine/baseclient.cpp index ed81068f..4ec46652 100644 --- a/engine/baseclient.cpp +++ b/engine/baseclient.cpp @@ -1431,7 +1431,7 @@ void CBaseClient::UpdateUserSettings() SetRate( rate, false ); // set server to client update rate - SetUpdateRate( m_ConVars->GetInt( "cl_updaterate", 20), false ); + SetUpdateRate( m_ConVars->GetInt( "cl_updaterate", 60), false ); SetMaxRoutablePayloadSize( m_ConVars->GetInt( "net_maxroutable", MAX_ROUTABLE_PAYLOAD ) ); diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index 42eb37ca..ced9aa81 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -161,6 +161,7 @@ void CMaster::RunFrame() { m_serverListResponse->RefreshComplete( NServerResponse::nServerFailedToRespond ); StopRefresh(); + return; } if( m_iServersResponded > 0 && diff --git a/engine/sv_client.cpp b/engine/sv_client.cpp index 6279a267..566cbeee 100644 --- a/engine/sv_client.cpp +++ b/engine/sv_client.cpp @@ -41,8 +41,8 @@ static ConVar sv_timeout( "sv_timeout", "65", 0, "After this many seconds withou static ConVar sv_maxrate( "sv_maxrate", "0", FCVAR_REPLICATED, "Max bandwidth rate allowed on server, 0 == unlimited" ); static ConVar sv_minrate( "sv_minrate", "3500", FCVAR_REPLICATED, "Min bandwidth rate allowed on server, 0 == unlimited" ); - ConVar sv_maxupdaterate( "sv_maxupdaterate", "66", FCVAR_REPLICATED, "Maximum updates per second that the server will allow" ); - ConVar sv_minupdaterate( "sv_minupdaterate", "10", FCVAR_REPLICATED, "Minimum updates per second that the server will allow" ); + ConVar sv_maxupdaterate( "sv_maxupdaterate", "100", FCVAR_REPLICATED, "Maximum updates per second that the server will allow" ); + ConVar sv_minupdaterate( "sv_minupdaterate", "20", FCVAR_REPLICATED, "Minimum updates per second that the server will allow" ); ConVar sv_stressbots("sv_stressbots", "0", FCVAR_DEVELOPMENTONLY, "If set to 1, the server calculates data and fills packets to bots. Used for perf testing."); static ConVar sv_allowdownload ("sv_allowdownload", "1", 0, "Allow clients to download files"); diff --git a/engine/sv_main.cpp b/engine/sv_main.cpp index 1456e44d..1d104966 100644 --- a/engine/sv_main.cpp +++ b/engine/sv_main.cpp @@ -218,8 +218,8 @@ static ConVar sv_voicecodec( "sv_voicecodec", "vaudio_opus", 0, "steam - Use Steam voice API" ); -ConVar sv_mincmdrate( "sv_mincmdrate", "10", FCVAR_REPLICATED, "This sets the minimum value for cl_cmdrate. 0 == unlimited." ); -ConVar sv_maxcmdrate( "sv_maxcmdrate", "66", FCVAR_REPLICATED, "(If sv_mincmdrate is > 0), this sets the maximum value for cl_cmdrate." ); +ConVar sv_mincmdrate( "sv_mincmdrate", "20", FCVAR_REPLICATED, "This sets the minimum value for cl_cmdrate. 0 == unlimited." ); +ConVar sv_maxcmdrate( "sv_maxcmdrate", "100", FCVAR_REPLICATED, "(If sv_mincmdrate is > 0), this sets the maximum value for cl_cmdrate." ); ConVar sv_client_cmdrate_difference( "sv_client_cmdrate_difference", "20", FCVAR_REPLICATED, "cl_cmdrate is moved to within sv_client_cmdrate_difference units of cl_updaterate before it " "is clamped between sv_mincmdrate and sv_maxcmdrate." ); From e10f29854ee2139901ee45e0c90f42da65f52ae7 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Tue, 14 Feb 2023 20:22:18 +0300 Subject: [PATCH 15/17] engine(masterserver): fix servers duplication --- engine/master.h | 2 +- engine/masterserver.cpp | 36 ++++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/engine/master.h b/engine/master.h index 34a86ffe..1d5c5ad4 100644 --- a/engine/master.h +++ b/engine/master.h @@ -46,7 +46,7 @@ public: // Master sent back a challenge value, read it and send the actual heartbeat virtual void RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ) = 0; // Console command to set/remove master server - virtual void SetMaster_f( const CCommand &args ) = 0; + virtual void AddMaster_f( const CCommand &args ) = 0; // Force a heartbeat to be issued right away virtual void Heartbeat_f( void ) = 0; diff --git a/engine/masterserver.cpp b/engine/masterserver.cpp index ced9aa81..acdcf272 100644 --- a/engine/masterserver.cpp +++ b/engine/masterserver.cpp @@ -76,7 +76,7 @@ public: void ProcessConnectionlessPacket( netpacket_t *packet ); - void SetMaster_f( const CCommand &args ); + void AddMaster_f( const CCommand &args ); void Heartbeat_f( void ); void RunFrame(); @@ -89,15 +89,15 @@ public: void RequestInternetServerList( const char *gamedir, IServerListResponse *response ); void RequestLANServerList( const char *gamedir, IServerListResponse *response ); void AddServerAddresses( netadr_t **adr, int count ); - void StopRefresh(); void RequestServerInfo( const netadr_t &adr ); + void StopRefresh(); private: // List of known master servers adrlist_t *m_pMasterAddresses; bool m_bInitialized; - bool m_bWaitingForReplys; + bool m_bRefreshing; int m_iServersResponded; @@ -139,7 +139,7 @@ CMaster::CMaster( void ) m_serverListResponse = NULL; SetDefLessFunc( m_serverAddresses ); SetDefLessFunc( m_serversRequestTime ); - m_bWaitingForReplys = false; + m_bRefreshing = false; m_iInfoSequence = 1; Init(); @@ -153,14 +153,14 @@ void CMaster::RunFrame() { CheckHeartbeat(); - if( !m_bWaitingForReplys ) + if( !m_bRefreshing ) return; if( m_serverListResponse && - m_flStartRequestTime < Plat_FloatTime()-INFO_REQUEST_TIMEOUT ) + m_flStartRequestTime < Plat_FloatTime()-INFO_REQUEST_TIMEOUT ) { - m_serverListResponse->RefreshComplete( NServerResponse::nServerFailedToRespond ); StopRefresh(); + m_serverListResponse->RefreshComplete( NServerResponse::nServerFailedToRespond ); return; } @@ -190,11 +190,11 @@ void CMaster::RunFrame() void CMaster::StopRefresh() { - if( !m_bWaitingForReplys ) + if( !m_bRefreshing ) return; m_iServersResponded = 0; - m_bWaitingForReplys = false; + m_bRefreshing = false; m_serverAddresses.RemoveAll(); m_serversRequestTime.RemoveAll(); } @@ -235,9 +235,7 @@ void CMaster::ReplyInfo( const netadr_t &adr, uint sequence ) 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() ); } @@ -293,6 +291,9 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) } case M2C_QUERY: { + if( !m_bRefreshing ) + break; + ip = msg.ReadLong(); port = msg.ReadShort(); @@ -323,6 +324,9 @@ void CMaster::ProcessConnectionlessPacket( netpacket_t *packet ) } case S2C_INFOREPLY: { + if( !m_bRefreshing ) + break; + uint sequence = msg.ReadLong(); newgameserver_t &s = ProcessInfo( msg ); @@ -584,7 +588,7 @@ void CMaster::RespondToHeartbeatChallenge( netadr_t &from, bf_read &msg ) //----------------------------------------------------------------------------- // Purpose: Add/remove master servers //----------------------------------------------------------------------------- -void CMaster::SetMaster_f ( const CCommand &args ) +void CMaster::AddMaster_f ( const CCommand &args ) { CUtlString cmd( ( args.ArgC() > 1 ) ? args[ 1 ] : "" ); @@ -620,9 +624,9 @@ void CMaster::Heartbeat_f (void) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void SetMaster_f( const CCommand &args ) +void AddMaster_f( const CCommand &args ) { - master->SetMaster_f( args ); + master->AddMaster_f( args ); } //----------------------------------------------------------------------------- @@ -633,7 +637,7 @@ void Heartbeat1_f( void ) master->Heartbeat_f(); } -static ConCommand setmaster("setmaster", SetMaster_f ); +static ConCommand setmaster("addmaster", AddMaster_f ); static ConCommand heartbeat("heartbeat", Heartbeat1_f, "Force heartbeat of master servers" ); //----------------------------------------------------------------------------- @@ -679,7 +683,7 @@ void CMaster::RequestInternetServerList(const char *gamedir, IServerListResponse if( response ) { StopRefresh(); - m_bWaitingForReplys = true; + m_bRefreshing = true; m_serverListResponse = response; m_flRetryRequestTime = m_flStartRequestTime = m_flMasterRequestTime = Plat_FloatTime(); } From e4f5549cbd4f5c9eaa8b952f3a1db40fdf8942e1 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Thu, 16 Feb 2023 17:16:35 +0300 Subject: [PATCH 16/17] serverbrowser: copy gametype to map name in quicklist --- serverbrowser/QuickListPanel.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/serverbrowser/QuickListPanel.cpp b/serverbrowser/QuickListPanel.cpp index 0b08ca02..19c17bb0 100644 --- a/serverbrowser/QuickListPanel.cpp +++ b/serverbrowser/QuickListPanel.cpp @@ -165,16 +165,16 @@ void CQuickListPanel::SetMapName( const char *pMapName ) //----------------------------------------------------------------------------- void CQuickListPanel::SetGameType( const char *pGameType ) { - if ( strlen ( pGameType ) == 0 ) - { - m_pGameTypeLabel->SetVisible( false ); + m_pGameTypeLabel->SetVisible( false ); + + if ( strlen ( pGameType ) == 0 || !m_pMapNameLabel ) return; - } char gametype[ 512 ]; - Q_snprintf( gametype, sizeof( gametype ), "(%s)", pGameType ); + Q_snprintf( gametype, sizeof( gametype ), "%s (%s)", m_szMapName, pGameType ); - m_pGameTypeLabel->SetText( gametype ); + m_pMapNameLabel->SetText( gametype ); + m_pMapNameLabel->SizeToContents(); } //----------------------------------------------------------------------------- From 2aa14bb24c8f7b4f60bd22ad3667627f837d8974 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Thu, 16 Feb 2023 17:30:53 +0300 Subject: [PATCH 17/17] restore threadtools and vstdlib from 12716fd commit --- public/tier0/threadtools.h | 44 +++++++++++++++++++++++++++---- tier0/threadtools.cpp | 53 -------------------------------------- vstdlib/jobthread.cpp | 20 ++++---------- 3 files changed, 44 insertions(+), 73 deletions(-) diff --git a/public/tier0/threadtools.h b/public/tier0/threadtools.h index 2b18dda7..b7216193 100644 --- a/public/tier0/threadtools.h +++ b/public/tier0/threadtools.h @@ -52,6 +52,12 @@ #pragma once #pragma warning(push) #pragma warning(disable:4251) + +extern "C" +{ + void __declspec(dllimport) __stdcall Sleep( unsigned long ); +} + #endif #ifdef COMPILER_MSVC64 @@ -194,8 +200,6 @@ PLATFORM_INTERFACE bool ReleaseThreadHandle( ThreadHandle_t ); //----------------------------------------------------------------------------- -PLATFORM_INTERFACE void ThreadSleep(unsigned duration = 0); -PLATFORM_INTERFACE void ThreadNanoSleep(unsigned ns); PLATFORM_INTERFACE ThreadId_t ThreadGetCurrentId(); PLATFORM_INTERFACE ThreadHandle_t ThreadGetCurrentHandle(); PLATFORM_INTERFACE int ThreadGetPriority( ThreadHandle_t hThread = NULL ); @@ -229,10 +233,10 @@ inline void ThreadPause() { #if defined( COMPILER_PS3 ) __db16cyc(); -#elif defined(__arm__) || defined(__aarch64__) - sched_yield(); -#elif defined( COMPILER_GCC ) +#elif defined( COMPILER_GCC ) && (defined( __i386__ ) || defined( __x86_64__ )) __asm __volatile( "pause" ); +#elif defined( POSIX ) + sched_yield(); #elif defined ( COMPILER_MSVC64 ) _mm_pause(); #elif defined( COMPILER_MSVC32 ) @@ -247,6 +251,36 @@ inline void ThreadPause() #endif } +inline void ThreadSleep(unsigned nMilliseconds = 0) +{ + if( nMilliseconds == 0 ) + { + ThreadPause(); + return; + } + +#ifdef _WIN32 + +#ifdef _WIN32_PC + static bool bInitialized = false; + if ( !bInitialized ) + { + bInitialized = true; + // Set the timer resolution to 1 ms (default is 10.0, 15.6, 2.5, 1.0 or + // some other value depending on hardware and software) so that we can + // use Sleep( 1 ) to avoid wasting CPU time without missing our frame + // rate. + timeBeginPeriod( 1 ); + } +#endif + Sleep( nMilliseconds ); +#elif PS3 + sys_timer_usleep( nMilliseconds * 1000 ); +#elif defined(POSIX) + usleep( nMilliseconds * 1000 ); +#endif +} + PLATFORM_INTERFACE bool ThreadJoin( ThreadHandle_t, unsigned timeout = TT_INFINITE ); PLATFORM_INTERFACE void ThreadSetDebugName( ThreadHandle_t hThread, const char *pszName ); diff --git a/tier0/threadtools.cpp b/tier0/threadtools.cpp index b0dbb645..06c8296f 100644 --- a/tier0/threadtools.cpp +++ b/tier0/threadtools.cpp @@ -485,59 +485,6 @@ bool ReleaseThreadHandle( ThreadHandle_t hThread ) // //----------------------------------------------------------------------------- -void ThreadSleep(unsigned nMilliseconds) -{ -#ifdef _WIN32 - -#ifdef _WIN32_PC - static bool bInitialized = false; - if ( !bInitialized ) - { - bInitialized = true; - // Set the timer resolution to 1 ms (default is 10.0, 15.6, 2.5, 1.0 or - // some other value depending on hardware and software) so that we can - // use Sleep( 1 ) to avoid wasting CPU time without missing our frame - // rate. - timeBeginPeriod( 1 ); - } -#endif - - Sleep( nMilliseconds ); -#elif PS3 - if( nMilliseconds == 0 ) - { - // sys_ppu_thread_yield doesn't seem to function properly, so sleep instead. -// sys_timer_usleep( 60 ); - sys_ppu_thread_yield(); - } - else - { - sys_timer_usleep( nMilliseconds * 1000 ); - } -#elif defined(POSIX) - usleep( nMilliseconds * 1000 ); -#endif -} - -//----------------------------------------------------------------------------- -void ThreadNanoSleep(unsigned ns) -{ -#ifdef _WIN32 - // ceil - Sleep( ( ns + 999 ) / 1000 ); -#elif PS3 - sys_timer_usleep( ns ); -#elif defined(POSIX) - struct timespec tm; - tm.tv_sec = 0; - tm.tv_nsec = ns; - nanosleep( &tm, NULL ); -#endif -} - - -//----------------------------------------------------------------------------- - #ifndef ThreadGetCurrentId ThreadId_t ThreadGetCurrentId() { diff --git a/vstdlib/jobthread.cpp b/vstdlib/jobthread.cpp index 922b770f..634d5358 100644 --- a/vstdlib/jobthread.cpp +++ b/vstdlib/jobthread.cpp @@ -214,7 +214,11 @@ public: //----------------------------------------------------- virtual int YieldWait( CThreadEvent **pEvents, int nEvents, bool bWaitAll = true, unsigned timeout = TT_INFINITE ); virtual int YieldWait( CJob **, int nJobs, bool bWaitAll = true, unsigned timeout = TT_INFINITE ); - void Yield( unsigned timeout ); + inline void Yield( unsigned timeout ) + { + Assert( ThreadInMainThread() ); + ThreadSleep( timeout ); + } //----------------------------------------------------- // Add a native job to the queue (master thread) @@ -656,20 +660,6 @@ int CThreadPool::YieldWait( CJob **ppJobs, int nJobs, bool bWaitAll, unsigned ti return YieldWait( handles.Base(), handles.Count(), bWaitAll, timeout); } -//--------------------------------------------------------- - -void CThreadPool::Yield( unsigned timeout ) -{ - // @MULTICORE (toml 10/24/2006): not implemented - Assert( ThreadInMainThread() ); - if ( !ThreadInMainThread() ) - { - ThreadSleep( timeout ); - return; - } - ThreadSleep( timeout ); -} - //--------------------------------------------------------- // Add a job to the queue //---------------------------------------------------------