1 //========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
2 //
3 // Purpose:
4 //
5 // $NoKeywords: $
6 //=============================================================================
7 
8 #ifndef MATCHMAKINGTYPES_H
9 #define MATCHMAKINGTYPES_H
10 
11 #ifdef _WIN32
12 #pragma once
13 #endif
14 
15 #ifdef POSIX
16 #ifndef _snprintf
17 #define _snprintf snprintf
18 #endif
19 #endif
20 
21 #include <stdio.h>
22 #include <string.h>
23 
24 //
25 // Max size (in bytes of UTF-8 data, not in characters) of server fields, including null terminator.
26 // WARNING: These cannot be changed easily, without breaking clients using old interfaces.
27 //
28 const int k_cbMaxGameServerGameDir = 32;
29 const int k_cbMaxGameServerMapName = 32;
30 const int k_cbMaxGameServerGameDescription = 64;
31 const int k_cbMaxGameServerName = 64;
32 const int k_cbMaxGameServerTags = 128;
33 const int k_cbMaxGameServerGameData = 2048;
34 
35 /// Store key/value pair used in matchmaking queries.
36 ///
37 /// Actually, the name Key/Value is a bit misleading.  The "key" is better
38 /// understood as "filter operation code" and the "value" is the operand to this
39 /// filter operation.  The meaning of the operand depends upon the filter.
40 struct MatchMakingKeyValuePair_t
41 {
MatchMakingKeyValuePair_tMatchMakingKeyValuePair_t42 	MatchMakingKeyValuePair_t() { m_szKey[0] = m_szValue[0] = 0; }
MatchMakingKeyValuePair_tMatchMakingKeyValuePair_t43 	MatchMakingKeyValuePair_t( const char *pchKey, const char *pchValue )
44 	{
45 		strncpy( m_szKey, pchKey, sizeof(m_szKey) ); // this is a public header, use basic c library string funcs only!
46 		m_szKey[ sizeof( m_szKey ) - 1 ] = '\0';
47 		strncpy( m_szValue, pchValue, sizeof(m_szValue) );
48 		m_szValue[ sizeof( m_szValue ) - 1 ] = '\0';
49 	}
50 	char m_szKey[ 256 ];
51 	char m_szValue[ 256 ];
52 };
53 
54 
55 enum EMatchMakingServerResponse
56 {
57 	eServerResponded = 0,
58 	eServerFailedToRespond,
59 	eNoServersListedOnMasterServer // for the Internet query type, returned in response callback if no servers of this type match
60 };
61 
62 // servernetadr_t is all the addressing info the serverbrowser needs to know about a game server,
63 // namely: its IP, its connection port, and its query port.
64 class servernetadr_t
65 {
66 public:
67 
servernetadr_t()68 	servernetadr_t() : m_usConnectionPort( 0 ), m_usQueryPort( 0 ), m_unIP( 0 ) {}
69 
70 	void	Init( unsigned int ip, uint16 usQueryPort, uint16 usConnectionPort );
71 #ifdef NETADR_H
72 	netadr_t	GetIPAndQueryPort();
73 #endif
74 
75 	// Access the query port.
76 	uint16	GetQueryPort() const;
77 	void	SetQueryPort( uint16 usPort );
78 
79 	// Access the connection port.
80 	uint16	GetConnectionPort() const;
81 	void	SetConnectionPort( uint16 usPort );
82 
83 	// Access the IP
84 	uint32 GetIP() const;
85 	void SetIP( uint32 );
86 
87 	// This gets the 'a.b.c.d:port' string with the connection port (instead of the query port).
88 	const char *GetConnectionAddressString() const;
89 	const char *GetQueryAddressString() const;
90 
91 	// Comparison operators and functions.
92 	bool	operator<(const servernetadr_t &netadr) const;
93 	void operator=( const servernetadr_t &that )
94 	{
95 		m_usConnectionPort = that.m_usConnectionPort;
96 		m_usQueryPort = that.m_usQueryPort;
97 		m_unIP = that.m_unIP;
98 	}
99 
100 
101 private:
102 	const char *ToString( uint32 unIP, uint16 usPort ) const;
103 	uint16	m_usConnectionPort;	// (in HOST byte order)
104 	uint16	m_usQueryPort;
105 	uint32  m_unIP;
106 };
107 
108 
Init(unsigned int ip,uint16 usQueryPort,uint16 usConnectionPort)109 inline void	servernetadr_t::Init( unsigned int ip, uint16 usQueryPort, uint16 usConnectionPort )
110 {
111 	m_unIP = ip;
112 	m_usQueryPort = usQueryPort;
113 	m_usConnectionPort = usConnectionPort;
114 }
115 
116 #ifdef NETADR_H
GetIPAndQueryPort()117 inline netadr_t servernetadr_t::GetIPAndQueryPort()
118 {
119 	return netadr_t( m_unIP, m_usQueryPort );
120 }
121 #endif
122 
GetQueryPort()123 inline uint16 servernetadr_t::GetQueryPort() const
124 {
125 	return m_usQueryPort;
126 }
127 
SetQueryPort(uint16 usPort)128 inline void	servernetadr_t::SetQueryPort( uint16 usPort )
129 {
130 	m_usQueryPort = usPort;
131 }
132 
GetConnectionPort()133 inline uint16 servernetadr_t::GetConnectionPort() const
134 {
135 	return m_usConnectionPort;
136 }
137 
SetConnectionPort(uint16 usPort)138 inline void	servernetadr_t::SetConnectionPort( uint16 usPort )
139 {
140 	m_usConnectionPort = usPort;
141 }
142 
GetIP()143 inline uint32 servernetadr_t::GetIP() const
144 {
145 	return m_unIP;
146 }
147 
SetIP(uint32 unIP)148 inline void	servernetadr_t::SetIP( uint32 unIP )
149 {
150 	m_unIP = unIP;
151 }
152 
ToString(uint32 unIP,uint16 usPort)153 inline const char *servernetadr_t::ToString( uint32 unIP, uint16 usPort ) const
154 {
155 	static char s[4][64];
156 	static int nBuf = 0;
157 	unsigned char *ipByte = (unsigned char *)&unIP;
158 #ifdef VALVE_BIG_ENDIAN
159 	_snprintf (s[nBuf], sizeof( s[nBuf] ), "%u.%u.%u.%u:%i", (int)(ipByte[0]), (int)(ipByte[1]), (int)(ipByte[2]), (int)(ipByte[3]), usPort );
160 #else
161 	_snprintf (s[nBuf], sizeof( s[nBuf] ), "%u.%u.%u.%u:%i", (int)(ipByte[3]), (int)(ipByte[2]), (int)(ipByte[1]), (int)(ipByte[0]), usPort );
162 #endif
163 	const char *pchRet = s[nBuf];
164 	++nBuf;
165 	nBuf %= ( (sizeof(s)/sizeof(s[0])) );
166 	return pchRet;
167 }
168 
GetConnectionAddressString()169 inline const char* servernetadr_t::GetConnectionAddressString() const
170 {
171 	return ToString( m_unIP, m_usConnectionPort );
172 }
173 
GetQueryAddressString()174 inline const char* servernetadr_t::GetQueryAddressString() const
175 {
176 	return ToString( m_unIP, m_usQueryPort );
177 }
178 
179 inline bool servernetadr_t::operator<(const servernetadr_t &netadr) const
180 {
181 	return ( m_unIP < netadr.m_unIP ) || ( m_unIP == netadr.m_unIP && m_usQueryPort < netadr.m_usQueryPort );
182 }
183 
184 //-----------------------------------------------------------------------------
185 // Purpose: Data describing a single server
186 //-----------------------------------------------------------------------------
187 class gameserveritem_t
188 {
189 public:
190 	gameserveritem_t();
191 
192 	const char* GetName() const;
193 	void SetName( const char *pName );
194 
195 public:
196 	servernetadr_t m_NetAdr;									///< IP/Query Port/Connection Port for this server
197 	int m_nPing;												///< current ping time in milliseconds
198 	bool m_bHadSuccessfulResponse;								///< server has responded successfully in the past
199 	bool m_bDoNotRefresh;										///< server is marked as not responding and should no longer be refreshed
200 	char m_szGameDir[k_cbMaxGameServerGameDir];					///< current game directory
201 	char m_szMap[k_cbMaxGameServerMapName];						///< current map
202 	char m_szGameDescription[k_cbMaxGameServerGameDescription];	///< game description
203 	uint32 m_nAppID;											///< Steam App ID of this server
204 	int m_nPlayers;												///< total number of players currently on the server.  INCLUDES BOTS!!
205 	int m_nMaxPlayers;											///< Maximum players that can join this server
206 	int m_nBotPlayers;											///< Number of bots (i.e simulated players) on this server
207 	bool m_bPassword;											///< true if this server needs a password to join
208 	bool m_bSecure;												///< Is this server protected by VAC
209 	uint32 m_ulTimeLastPlayed;									///< time (in unix time) when this server was last played on (for favorite/history servers)
210 	int	m_nServerVersion;										///< server version as reported to Steam
211 
212 private:
213 
214 	/// Game server name
215 	char m_szServerName[k_cbMaxGameServerName];
216 
217 	// For data added after SteamMatchMaking001 add it here
218 public:
219 	/// the tags this server exposes
220 	char m_szGameTags[k_cbMaxGameServerTags];
221 
222 	/// steamID of the game server - invalid if it's doesn't have one (old server, or not connected to Steam)
223 	CSteamID m_steamID;
224 };
225 
226 
gameserveritem_t()227 inline gameserveritem_t::gameserveritem_t()
228 {
229 	m_szGameDir[0] = m_szMap[0] = m_szGameDescription[0] = m_szServerName[0] = 0;
230 	m_bHadSuccessfulResponse = m_bDoNotRefresh = m_bPassword = m_bSecure = false;
231 	m_nPing = m_nAppID = m_nPlayers = m_nMaxPlayers = m_nBotPlayers = m_ulTimeLastPlayed = m_nServerVersion = 0;
232 	m_szGameTags[0] = 0;
233 }
234 
GetName()235 inline const char* gameserveritem_t::GetName() const
236 {
237 	// Use the IP address as the name if nothing is set yet.
238 	if ( m_szServerName[0] == 0 )
239 		return m_NetAdr.GetConnectionAddressString();
240 	else
241 		return m_szServerName;
242 }
243 
SetName(const char * pName)244 inline void gameserveritem_t::SetName( const char *pName )
245 {
246 	strncpy( m_szServerName, pName, sizeof( m_szServerName ) );
247 	m_szServerName[ sizeof( m_szServerName ) - 1 ] = '\0';
248 }
249 
250 
251 #endif // MATCHMAKINGTYPES_H
252