1 //====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
2 //
3 // Purpose: interface to steam managing game server/client match making
4 //
5 //=============================================================================
6 
7 #ifndef ISTEAMMATCHMAKING
8 #define ISTEAMMATCHMAKING
9 #ifdef _WIN32
10 #pragma once
11 #endif
12 
13 #include "steamtypes.h"
14 #include "steamclientpublic.h"
15 #include "matchmakingtypes.h"
16 #include "isteamclient.h"
17 #include "isteamfriends.h"
18 
19 // lobby type description
20 enum ELobbyType
21 {
22 	k_ELobbyTypePrivate = 0,		// only way to join the lobby is to invite to someone else
23 	k_ELobbyTypeFriendsOnly = 1,	// shows for friends or invitees, but not in lobby list
24 	k_ELobbyTypePublic = 2,			// visible for friends and in lobby list
25 	k_ELobbyTypeInvisible = 3,		// returned by search, but not visible to other friends
26 									//    useful if you want a user in two lobbies, for example matching groups together
27 									//	  a user can be in only one regular lobby, and up to two invisible lobbies
28 };
29 
30 // lobby search filter tools
31 enum ELobbyComparison
32 {
33 	k_ELobbyComparisonEqualToOrLessThan = -2,
34 	k_ELobbyComparisonLessThan = -1,
35 	k_ELobbyComparisonEqual = 0,
36 	k_ELobbyComparisonGreaterThan = 1,
37 	k_ELobbyComparisonEqualToOrGreaterThan = 2,
38 	k_ELobbyComparisonNotEqual = 3,
39 };
40 
41 // lobby search distance. Lobby results are sorted from closest to farthest.
42 enum ELobbyDistanceFilter
43 {
44 	k_ELobbyDistanceFilterClose,		// only lobbies in the same immediate region will be returned
45 	k_ELobbyDistanceFilterDefault,		// only lobbies in the same region or near by regions
46 	k_ELobbyDistanceFilterFar,			// for games that don't have many latency requirements, will return lobbies about half-way around the globe
47 	k_ELobbyDistanceFilterWorldwide,	// no filtering, will match lobbies as far as India to NY (not recommended, expect multiple seconds of latency between the clients)
48 };
49 
50 // maximum number of characters a lobby metadata key can be
51 #define k_nMaxLobbyKeyLength 255
52 
53 //-----------------------------------------------------------------------------
54 // Purpose: Functions for match making services for clients to get to favorites
55 //			and to operate on game lobbies.
56 //-----------------------------------------------------------------------------
57 class ISteamMatchmaking
58 {
59 public:
60 	// game server favorites storage
61 	// saves basic details about a multiplayer game server locally
62 
63 	// returns the number of favorites servers the user has stored
64 	virtual int GetFavoriteGameCount() = 0;
65 
66 	// returns the details of the game server
67 	// iGame is of range [0,GetFavoriteGameCount())
68 	// *pnIP, *pnConnPort are filled in the with IP:port of the game server
69 	// *punFlags specify whether the game server was stored as an explicit favorite or in the history of connections
70 	// *pRTime32LastPlayedOnServer is filled in the with the Unix time the favorite was added
71 	virtual bool GetFavoriteGame( int iGame, AppId_t *pnAppID, uint32 *pnIP, uint16 *pnConnPort, uint16 *pnQueryPort, uint32 *punFlags, uint32 *pRTime32LastPlayedOnServer ) = 0;
72 
73 	// adds the game server to the local list; updates the time played of the server if it already exists in the list
74 	virtual int AddFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags, uint32 rTime32LastPlayedOnServer ) = 0;
75 
76 	// removes the game server from the local storage; returns true if one was removed
77 	virtual bool RemoveFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags ) = 0;
78 
79 	///////
80 	// Game lobby functions
81 
82 	// Get a list of relevant lobbies
83 	// this is an asynchronous request
84 	// results will be returned by LobbyMatchList_t callback & call result, with the number of lobbies found
85 	// this will never return lobbies that are full
86 	// to add more filter, the filter calls below need to be call before each and every RequestLobbyList() call
87 	// use the CCallResult<> object in steam_api.h to match the SteamAPICall_t call result to a function in an object, e.g.
88 	/*
89 		class CMyLobbyListManager
90 		{
91 			CCallResult<CMyLobbyListManager, LobbyMatchList_t> m_CallResultLobbyMatchList;
92 			void FindLobbies()
93 			{
94 				// SteamMatchmaking()->AddRequestLobbyListFilter*() functions would be called here, before RequestLobbyList()
95 				SteamAPICall_t hSteamAPICall = SteamMatchmaking()->RequestLobbyList();
96 				m_CallResultLobbyMatchList.Set( hSteamAPICall, this, &CMyLobbyListManager::OnLobbyMatchList );
97 			}
98 
99 			void OnLobbyMatchList( LobbyMatchList_t *pLobbyMatchList, bool bIOFailure )
100 			{
101 				// lobby list has be retrieved from Steam back-end, use results
102 			}
103 		}
104 	*/
105 	//
106 	CALL_RESULT( LobbyMatchList_t )
107 	virtual SteamAPICall_t RequestLobbyList() = 0;
108 	// filters for lobbies
109 	// this needs to be called before RequestLobbyList() to take effect
110 	// these are cleared on each call to RequestLobbyList()
111 	virtual void AddRequestLobbyListStringFilter( const char *pchKeyToMatch, const char *pchValueToMatch, ELobbyComparison eComparisonType ) = 0;
112 	// numerical comparison
113 	virtual void AddRequestLobbyListNumericalFilter( const char *pchKeyToMatch, int nValueToMatch, ELobbyComparison eComparisonType ) = 0;
114 	// returns results closest to the specified value. Multiple near filters can be added, with early filters taking precedence
115 	virtual void AddRequestLobbyListNearValueFilter( const char *pchKeyToMatch, int nValueToBeCloseTo ) = 0;
116 	// returns only lobbies with the specified number of slots available
117 	virtual void AddRequestLobbyListFilterSlotsAvailable( int nSlotsAvailable ) = 0;
118 	// sets the distance for which we should search for lobbies (based on users IP address to location map on the Steam backed)
119 	virtual void AddRequestLobbyListDistanceFilter( ELobbyDistanceFilter eLobbyDistanceFilter ) = 0;
120 	// sets how many results to return, the lower the count the faster it is to download the lobby results & details to the client
121 	virtual void AddRequestLobbyListResultCountFilter( int cMaxResults ) = 0;
122 
123 	virtual void AddRequestLobbyListCompatibleMembersFilter( CSteamID steamIDLobby ) = 0;
124 
125 	// returns the CSteamID of a lobby, as retrieved by a RequestLobbyList call
126 	// should only be called after a LobbyMatchList_t callback is received
127 	// iLobby is of the range [0, LobbyMatchList_t::m_nLobbiesMatching)
128 	// the returned CSteamID::IsValid() will be false if iLobby is out of range
129 	virtual CSteamID GetLobbyByIndex( int iLobby ) = 0;
130 
131 	// Create a lobby on the Steam servers.
132 	// If private, then the lobby will not be returned by any RequestLobbyList() call; the CSteamID
133 	// of the lobby will need to be communicated via game channels or via InviteUserToLobby()
134 	// this is an asynchronous request
135 	// results will be returned by LobbyCreated_t callback and call result; lobby is joined & ready to use at this point
136 	// a LobbyEnter_t callback will also be received (since the local user is joining their own lobby)
137 	CALL_RESULT( LobbyCreated_t )
138 	virtual SteamAPICall_t CreateLobby( ELobbyType eLobbyType, int cMaxMembers ) = 0;
139 
140 	// Joins an existing lobby
141 	// this is an asynchronous request
142 	// results will be returned by LobbyEnter_t callback & call result, check m_EChatRoomEnterResponse to see if was successful
143 	// lobby metadata is available to use immediately on this call completing
144 	CALL_RESULT( LobbyEnter_t )
145 	virtual SteamAPICall_t JoinLobby( CSteamID steamIDLobby ) = 0;
146 
147 	// Leave a lobby; this will take effect immediately on the client side
148 	// other users in the lobby will be notified by a LobbyChatUpdate_t callback
149 	virtual void LeaveLobby( CSteamID steamIDLobby ) = 0;
150 
151 	// Invite another user to the lobby
152 	// the target user will receive a LobbyInvite_t callback
153 	// will return true if the invite is successfully sent, whether or not the target responds
154 	// returns false if the local user is not connected to the Steam servers
155 	// if the other user clicks the join link, a GameLobbyJoinRequested_t will be posted if the user is in-game,
156 	// or if the game isn't running yet the game will be launched with the parameter +connect_lobby <64-bit lobby id>
157 	virtual bool InviteUserToLobby( CSteamID steamIDLobby, CSteamID steamIDInvitee ) = 0;
158 
159 	// Lobby iteration, for viewing details of users in a lobby
160 	// only accessible if the lobby user is a member of the specified lobby
161 	// persona information for other lobby members (name, avatar, etc.) will be asynchronously received
162 	// and accessible via ISteamFriends interface
163 
164 	// returns the number of users in the specified lobby
165 	virtual int GetNumLobbyMembers( CSteamID steamIDLobby ) = 0;
166 	// returns the CSteamID of a user in the lobby
167 	// iMember is of range [0,GetNumLobbyMembers())
168 	// note that the current user must be in a lobby to retrieve CSteamIDs of other users in that lobby
169 	virtual CSteamID GetLobbyMemberByIndex( CSteamID steamIDLobby, int iMember ) = 0;
170 
171 	// Get data associated with this lobby
172 	// takes a simple key, and returns the string associated with it
173 	// "" will be returned if no value is set, or if steamIDLobby is invalid
174 	virtual const char *GetLobbyData( CSteamID steamIDLobby, const char *pchKey ) = 0;
175 	// Sets a key/value pair in the lobby metadata
176 	// each user in the lobby will be broadcast this new value, and any new users joining will receive any existing data
177 	// this can be used to set lobby names, map, etc.
178 	// to reset a key, just set it to ""
179 	// other users in the lobby will receive notification of the lobby data change via a LobbyDataUpdate_t callback
180 	virtual bool SetLobbyData( CSteamID steamIDLobby, const char *pchKey, const char *pchValue ) = 0;
181 
182 	// returns the number of metadata keys set on the specified lobby
183 	virtual int GetLobbyDataCount( CSteamID steamIDLobby ) = 0;
184 
185 	// returns a lobby metadata key/values pair by index, of range [0, GetLobbyDataCount())
186 	virtual bool GetLobbyDataByIndex( CSteamID steamIDLobby, int iLobbyData, char *pchKey, int cchKeyBufferSize, char *pchValue, int cchValueBufferSize ) = 0;
187 
188 	// removes a metadata key from the lobby
189 	virtual bool DeleteLobbyData( CSteamID steamIDLobby, const char *pchKey ) = 0;
190 
191 	// Gets per-user metadata for someone in this lobby
192 	virtual const char *GetLobbyMemberData( CSteamID steamIDLobby, CSteamID steamIDUser, const char *pchKey ) = 0;
193 	// Sets per-user metadata (for the local user implicitly)
194 	virtual void SetLobbyMemberData( CSteamID steamIDLobby, const char *pchKey, const char *pchValue ) = 0;
195 
196 	// Broadcasts a chat message to the all the users in the lobby
197 	// users in the lobby (including the local user) will receive a LobbyChatMsg_t callback
198 	// returns true if the message is successfully sent
199 	// pvMsgBody can be binary or text data, up to 4k
200 	// if pvMsgBody is text, cubMsgBody should be strlen( text ) + 1, to include the null terminator
201 	virtual bool SendLobbyChatMsg( CSteamID steamIDLobby, const void *pvMsgBody, int cubMsgBody ) = 0;
202 	// Get a chat message as specified in a LobbyChatMsg_t callback
203 	// iChatID is the LobbyChatMsg_t::m_iChatID value in the callback
204 	// *pSteamIDUser is filled in with the CSteamID of the member
205 	// *pvData is filled in with the message itself
206 	// return value is the number of bytes written into the buffer
207 	virtual int GetLobbyChatEntry( CSteamID steamIDLobby, int iChatID, OUT_STRUCT() CSteamID *pSteamIDUser, void *pvData, int cubData, EChatEntryType *peChatEntryType ) = 0;
208 
209 	// Refreshes metadata for a lobby you're not necessarily in right now
210 	// you never do this for lobbies you're a member of, only if your
211 	// this will send down all the metadata associated with a lobby
212 	// this is an asynchronous call
213 	// returns false if the local user is not connected to the Steam servers
214 	// results will be returned by a LobbyDataUpdate_t callback
215 	// if the specified lobby doesn't exist, LobbyDataUpdate_t::m_bSuccess will be set to false
216 	virtual bool RequestLobbyData( CSteamID steamIDLobby ) = 0;
217 
218 	// sets the game server associated with the lobby
219 	// usually at this point, the users will join the specified game server
220 	// either the IP/Port or the steamID of the game server has to be valid, depending on how you want the clients to be able to connect
221 	virtual void SetLobbyGameServer( CSteamID steamIDLobby, uint32 unGameServerIP, uint16 unGameServerPort, CSteamID steamIDGameServer ) = 0;
222 	// returns the details of a game server set in a lobby - returns false if there is no game server set, or that lobby doesn't exist
223 	virtual bool GetLobbyGameServer( CSteamID steamIDLobby, uint32 *punGameServerIP, uint16 *punGameServerPort, OUT_STRUCT() CSteamID *psteamIDGameServer ) = 0;
224 
225 	// set the limit on the # of users who can join the lobby
226 	virtual bool SetLobbyMemberLimit( CSteamID steamIDLobby, int cMaxMembers ) = 0;
227 	// returns the current limit on the # of users who can join the lobby; returns 0 if no limit is defined
228 	virtual int GetLobbyMemberLimit( CSteamID steamIDLobby ) = 0;
229 
230 	// updates which type of lobby it is
231 	// only lobbies that are k_ELobbyTypePublic or k_ELobbyTypeInvisible, and are set to joinable, will be returned by RequestLobbyList() calls
232 	virtual bool SetLobbyType( CSteamID steamIDLobby, ELobbyType eLobbyType ) = 0;
233 
234 	// sets whether or not a lobby is joinable - defaults to true for a new lobby
235 	// if set to false, no user can join, even if they are a friend or have been invited
236 	virtual bool SetLobbyJoinable( CSteamID steamIDLobby, bool bLobbyJoinable ) = 0;
237 
238 	// returns the current lobby owner
239 	// you must be a member of the lobby to access this
240 	// there always one lobby owner - if the current owner leaves, another user will become the owner
241 	// it is possible (bur rare) to join a lobby just as the owner is leaving, thus entering a lobby with self as the owner
242 	virtual CSteamID GetLobbyOwner( CSteamID steamIDLobby ) = 0;
243 
244 	// changes who the lobby owner is
245 	// you must be the lobby owner for this to succeed, and steamIDNewOwner must be in the lobby
246 	// after completion, the local user will no longer be the owner
247 	virtual bool SetLobbyOwner( CSteamID steamIDLobby, CSteamID steamIDNewOwner ) = 0;
248 
249 	// link two lobbies for the purposes of checking player compatibility
250 	// you must be the lobby owner of both lobbies
251 	virtual bool SetLinkedLobby( CSteamID steamIDLobby, CSteamID steamIDLobbyDependent ) = 0;
252 
253 #ifdef _PS3
254 	// changes who the lobby owner is
255 	// you must be the lobby owner for this to succeed, and steamIDNewOwner must be in the lobby
256 	// after completion, the local user will no longer be the owner
257 	virtual void CheckForPSNGameBootInvite( unsigned int iGameBootAttributes  ) = 0;
258 #endif
259 	CALL_BACK( LobbyChatUpdate_t )
260 };
261 #define STEAMMATCHMAKING_INTERFACE_VERSION "SteamMatchMaking009"
262 
263 
264 //-----------------------------------------------------------------------------
265 // Callback interfaces for server list functions (see ISteamMatchmakingServers below)
266 //
267 // The idea here is that your game code implements objects that implement these
268 // interfaces to receive callback notifications after calling asynchronous functions
269 // inside the ISteamMatchmakingServers() interface below.
270 //
271 // This is different than normal Steam callback handling due to the potentially
272 // large size of server lists.
273 //-----------------------------------------------------------------------------
274 
275 //-----------------------------------------------------------------------------
276 // Typedef for handle type you will receive when requesting server list.
277 //-----------------------------------------------------------------------------
278 typedef void* HServerListRequest;
279 
280 //-----------------------------------------------------------------------------
281 // Purpose: Callback interface for receiving responses after a server list refresh
282 // or an individual server update.
283 //
284 // Since you get these callbacks after requesting full list refreshes you will
285 // usually implement this interface inside an object like CServerBrowser.  If that
286 // object is getting destructed you should use ISteamMatchMakingServers()->CancelQuery()
287 // to cancel any in-progress queries so you don't get a callback into the destructed
288 // object and crash.
289 //-----------------------------------------------------------------------------
290 class ISteamMatchmakingServerListResponse
291 {
292 public:
293 	// Server has responded ok with updated data
294 	virtual void ServerResponded( HServerListRequest hRequest, int iServer ) = 0;
295 
296 	// Server has failed to respond
297 	virtual void ServerFailedToRespond( HServerListRequest hRequest, int iServer ) = 0;
298 
299 	// A list refresh you had initiated is now 100% completed
300 	virtual void RefreshComplete( HServerListRequest hRequest, EMatchMakingServerResponse response ) = 0;
301 };
302 
303 
304 //-----------------------------------------------------------------------------
305 // Purpose: Callback interface for receiving responses after pinging an individual server
306 //
307 // These callbacks all occur in response to querying an individual server
308 // via the ISteamMatchmakingServers()->PingServer() call below.  If you are
309 // destructing an object that implements this interface then you should call
310 // ISteamMatchmakingServers()->CancelServerQuery() passing in the handle to the query
311 // which is in progress.  Failure to cancel in progress queries when destructing
312 // a callback handler may result in a crash when a callback later occurs.
313 //-----------------------------------------------------------------------------
314 class ISteamMatchmakingPingResponse
315 {
316 public:
317 	// Server has responded successfully and has updated data
318 	virtual void ServerResponded( gameserveritem_t &server ) = 0;
319 
320 	// Server failed to respond to the ping request
321 	virtual void ServerFailedToRespond() = 0;
322 };
323 
324 
325 //-----------------------------------------------------------------------------
326 // Purpose: Callback interface for receiving responses after requesting details on
327 // who is playing on a particular server.
328 //
329 // These callbacks all occur in response to querying an individual server
330 // via the ISteamMatchmakingServers()->PlayerDetails() call below.  If you are
331 // destructing an object that implements this interface then you should call
332 // ISteamMatchmakingServers()->CancelServerQuery() passing in the handle to the query
333 // which is in progress.  Failure to cancel in progress queries when destructing
334 // a callback handler may result in a crash when a callback later occurs.
335 //-----------------------------------------------------------------------------
336 class ISteamMatchmakingPlayersResponse
337 {
338 public:
339 	// Got data on a new player on the server -- you'll get this callback once per player
340 	// on the server which you have requested player data on.
341 	virtual void AddPlayerToList( const char *pchName, int nScore, float flTimePlayed ) = 0;
342 
343 	// The server failed to respond to the request for player details
344 	virtual void PlayersFailedToRespond() = 0;
345 
346 	// The server has finished responding to the player details request
347 	// (ie, you won't get anymore AddPlayerToList callbacks)
348 	virtual void PlayersRefreshComplete() = 0;
349 };
350 
351 
352 //-----------------------------------------------------------------------------
353 // Purpose: Callback interface for receiving responses after requesting rules
354 // details on a particular server.
355 //
356 // These callbacks all occur in response to querying an individual server
357 // via the ISteamMatchmakingServers()->ServerRules() call below.  If you are
358 // destructing an object that implements this interface then you should call
359 // ISteamMatchmakingServers()->CancelServerQuery() passing in the handle to the query
360 // which is in progress.  Failure to cancel in progress queries when destructing
361 // a callback handler may result in a crash when a callback later occurs.
362 //-----------------------------------------------------------------------------
363 class ISteamMatchmakingRulesResponse
364 {
365 public:
366 	// Got data on a rule on the server -- you'll get one of these per rule defined on
367 	// the server you are querying
368 	virtual void RulesResponded( const char *pchRule, const char *pchValue ) = 0;
369 
370 	// The server failed to respond to the request for rule details
371 	virtual void RulesFailedToRespond() = 0;
372 
373 	// The server has finished responding to the rule details request
374 	// (ie, you won't get anymore RulesResponded callbacks)
375 	virtual void RulesRefreshComplete() = 0;
376 };
377 
378 
379 //-----------------------------------------------------------------------------
380 // Typedef for handle type you will receive when querying details on an individual server.
381 //-----------------------------------------------------------------------------
382 typedef int HServerQuery;
383 const int HSERVERQUERY_INVALID = 0xffffffff;
384 
385 //-----------------------------------------------------------------------------
386 // Purpose: Functions for match making services for clients to get to game lists and details
387 //-----------------------------------------------------------------------------
388 class ISteamMatchmakingServers
389 {
390 public:
391 	// Request a new list of servers of a particular type.  These calls each correspond to one of the EMatchMakingType values.
392 	// Each call allocates a new asynchronous request object.
393 	// Request object must be released by calling ReleaseRequest( hServerListRequest )
394 	virtual HServerListRequest RequestInternetServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
395 	virtual HServerListRequest RequestLANServerList( AppId_t iApp, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
396 	virtual HServerListRequest RequestFriendsServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
397 	virtual HServerListRequest RequestFavoritesServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
398 	virtual HServerListRequest RequestHistoryServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
399 	virtual HServerListRequest RequestSpectatorServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
400 
401 	// Releases the asynchronous request object and cancels any pending query on it if there's a pending query in progress.
402 	// RefreshComplete callback is not posted when request is released.
403 	virtual void ReleaseRequest( HServerListRequest hServerListRequest ) = 0;
404 
405 	/* the filter operation codes that go in the key part of MatchMakingKeyValuePair_t should be one of these:
406 
407 		"map"
408 			- Server passes the filter if the server is playing the specified map.
409 		"gamedataand"
410 			- Server passes the filter if the server's game data (ISteamGameServer::SetGameData) contains all of the
411 			specified strings.  The value field is a comma-delimited list of strings to match.
412 		"gamedataor"
413 			- Server passes the filter if the server's game data (ISteamGameServer::SetGameData) contains at least one of the
414 			specified strings.  The value field is a comma-delimited list of strings to match.
415 		"gamedatanor"
416 			- Server passes the filter if the server's game data (ISteamGameServer::SetGameData) does not contain any
417 			of the specified strings.  The value field is a comma-delimited list of strings to check.
418 		"gametagsand"
419 			- Server passes the filter if the server's game tags (ISteamGameServer::SetGameTags) contains all
420 			of the specified strings.  The value field is a comma-delimited list of strings to check.
421 		"gametagsnor"
422 			- Server passes the filter if the server's game tags (ISteamGameServer::SetGameTags) does not contain any
423 			of the specified strings.  The value field is a comma-delimited list of strings to check.
424 		"and" (x1 && x2 && ... && xn)
425 		"or" (x1 || x2 || ... || xn)
426 		"nand" !(x1 && x2 && ... && xn)
427 		"nor" !(x1 || x2 || ... || xn)
428 			- Performs Boolean operation on the following filters.  The operand to this filter specifies
429 			the "size" of the Boolean inputs to the operation, in Key/value pairs.  (The keyvalue
430 			pairs must immediately follow, i.e. this is a prefix logical operator notation.)
431 			In the simplest case where Boolean expressions are not nested, this is simply
432 			the number of operands.
433 
434 			For example, to match servers on a particular map or with a particular tag, would would
435 			use these filters.
436 
437 				( server.map == "cp_dustbowl" || server.gametags.contains("payload") )
438 				"or", "2"
439 				"map", "cp_dustbowl"
440 				"gametagsand", "payload"
441 
442 			If logical inputs are nested, then the operand specifies the size of the entire
443 			"length" of its operands, not the number of immediate children.
444 
445 				( server.map == "cp_dustbowl" || ( server.gametags.contains("payload") && !server.gametags.contains("payloadrace") ) )
446 				"or", "4"
447 				"map", "cp_dustbowl"
448 				"and", "2"
449 				"gametagsand", "payload"
450 				"gametagsnor", "payloadrace"
451 
452 			Unary NOT can be achieved using either "nand" or "nor" with a single operand.
453 
454 		"addr"
455 			- Server passes the filter if the server's query address matches the specified IP or IP:port.
456 		"gameaddr"
457 			- Server passes the filter if the server's game address matches the specified IP or IP:port.
458 
459 		The following filter operations ignore the "value" part of MatchMakingKeyValuePair_t
460 
461 		"dedicated"
462 			- Server passes the filter if it passed true to SetDedicatedServer.
463 		"secure"
464 			- Server passes the filter if the server is VAC-enabled.
465 		"notfull"
466 			- Server passes the filter if the player count is less than the reported max player count.
467 		"hasplayers"
468 			- Server passes the filter if the player count is greater than zero.
469 		"noplayers"
470 			- Server passes the filter if it doesn't have any players.
471 		"linux"
472 			- Server passes the filter if it's a linux server
473 	*/
474 
475 	// Get details on a given server in the list, you can get the valid range of index
476 	// values by calling GetServerCount().  You will also receive index values in
477 	// ISteamMatchmakingServerListResponse::ServerResponded() callbacks
478 	virtual gameserveritem_t *GetServerDetails( HServerListRequest hRequest, int iServer ) = 0;
479 
480 	// Cancel an request which is operation on the given list type.  You should call this to cancel
481 	// any in-progress requests before destructing a callback object that may have been passed
482 	// to one of the above list request calls.  Not doing so may result in a crash when a callback
483 	// occurs on the destructed object.
484 	// Canceling a query does not release the allocated request handle.
485 	// The request handle must be released using ReleaseRequest( hRequest )
486 	virtual void CancelQuery( HServerListRequest hRequest ) = 0;
487 
488 	// Ping every server in your list again but don't update the list of servers
489 	// Query callback installed when the server list was requested will be used
490 	// again to post notifications and RefreshComplete, so the callback must remain
491 	// valid until another RefreshComplete is called on it or the request
492 	// is released with ReleaseRequest( hRequest )
493 	virtual void RefreshQuery( HServerListRequest hRequest ) = 0;
494 
495 	// Returns true if the list is currently refreshing its server list
496 	virtual bool IsRefreshing( HServerListRequest hRequest ) = 0;
497 
498 	// How many servers in the given list, GetServerDetails above takes 0... GetServerCount() - 1
499 	virtual int GetServerCount( HServerListRequest hRequest ) = 0;
500 
501 	// Refresh a single server inside of a query (rather than all the servers )
502 	virtual void RefreshServer( HServerListRequest hRequest, int iServer ) = 0;
503 
504 
505 	//-----------------------------------------------------------------------------
506 	// Queries to individual servers directly via IP/Port
507 	//-----------------------------------------------------------------------------
508 
509 	// Request updated ping time and other details from a single server
510 	virtual HServerQuery PingServer( uint32 unIP, uint16 usPort, ISteamMatchmakingPingResponse *pRequestServersResponse ) = 0;
511 
512 	// Request the list of players currently playing on a server
513 	virtual HServerQuery PlayerDetails( uint32 unIP, uint16 usPort, ISteamMatchmakingPlayersResponse *pRequestServersResponse ) = 0;
514 
515 	// Request the list of rules that the server is running (See ISteamGameServer::SetKeyValue() to set the rules server side)
516 	virtual HServerQuery ServerRules( uint32 unIP, uint16 usPort, ISteamMatchmakingRulesResponse *pRequestServersResponse ) = 0;
517 
518 	// Cancel an outstanding Ping/Players/Rules query from above.  You should call this to cancel
519 	// any in-progress requests before destructing a callback object that may have been passed
520 	// to one of the above calls to avoid crashing when callbacks occur.
521 	virtual void CancelServerQuery( HServerQuery hServerQuery ) = 0;
522 };
523 #define STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION "SteamMatchMakingServers002"
524 
525 // game server flags
526 const uint32 k_unFavoriteFlagNone			= 0x00;
527 const uint32 k_unFavoriteFlagFavorite		= 0x01; // this game favorite entry is for the favorites list
528 const uint32 k_unFavoriteFlagHistory		= 0x02; // this game favorite entry is for the history list
529 
530 
531 //-----------------------------------------------------------------------------
532 // Purpose: Used in ChatInfo messages - fields specific to a chat member - must fit in a uint32
533 //-----------------------------------------------------------------------------
534 enum EChatMemberStateChange
535 {
536 	// Specific to joining / leaving the chatroom
537 	k_EChatMemberStateChangeEntered			= 0x0001,		// This user has joined or is joining the chat room
538 	k_EChatMemberStateChangeLeft			= 0x0002,		// This user has left or is leaving the chat room
539 	k_EChatMemberStateChangeDisconnected	= 0x0004,		// User disconnected without leaving the chat first
540 	k_EChatMemberStateChangeKicked			= 0x0008,		// User kicked
541 	k_EChatMemberStateChangeBanned			= 0x0010,		// User kicked and banned
542 };
543 
544 // returns true of the flags indicate that a user has been removed from the chat
545 #define BChatMemberStateChangeRemoved( rgfChatMemberStateChangeFlags ) ( rgfChatMemberStateChangeFlags & ( k_EChatMemberStateChangeDisconnected | k_EChatMemberStateChangeLeft | k_EChatMemberStateChangeKicked | k_EChatMemberStateChangeBanned ) )
546 
547 
548 //-----------------------------------------------------------------------------
549 // Callbacks for ISteamMatchmaking (which go through the regular Steam callback registration system)
550 #if defined( VALVE_CALLBACK_PACK_SMALL )
551 #pragma pack( push, 4 )
552 #elif defined( VALVE_CALLBACK_PACK_LARGE )
553 #pragma pack( push, 8 )
554 #else
555 #error isteamclient.h must be included
556 #endif
557 
558 //-----------------------------------------------------------------------------
559 // Purpose: a server was added/removed from the favorites list, you should refresh now
560 //-----------------------------------------------------------------------------
561 struct FavoritesListChanged_t
562 {
563 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 2 };
564 	uint32 m_nIP; // an IP of 0 means reload the whole list, any other value means just one server
565 	uint32 m_nQueryPort;
566 	uint32 m_nConnPort;
567 	uint32 m_nAppID;
568 	uint32 m_nFlags;
569 	bool m_bAdd; // true if this is adding the entry, otherwise it is a remove
570 	AccountID_t m_unAccountId;
571 };
572 
573 
574 //-----------------------------------------------------------------------------
575 // Purpose: Someone has invited you to join a Lobby
576 //			normally you don't need to do anything with this, since
577 //			the Steam UI will also display a '<user> has invited you to the lobby, join?' dialog
578 //
579 //			if the user outside a game chooses to join, your game will be launched with the parameter "+connect_lobby <64-bit lobby id>",
580 //			or with the callback GameLobbyJoinRequested_t if they're already in-game
581 //-----------------------------------------------------------------------------
582 struct LobbyInvite_t
583 {
584 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 3 };
585 
586 	uint64 m_ulSteamIDUser;		// Steam ID of the person making the invite
587 	uint64 m_ulSteamIDLobby;	// Steam ID of the Lobby
588 	uint64 m_ulGameID;			// GameID of the Lobby
589 };
590 
591 
592 //-----------------------------------------------------------------------------
593 // Purpose: Sent on entering a lobby, or on failing to enter
594 //			m_EChatRoomEnterResponse will be set to k_EChatRoomEnterResponseSuccess on success,
595 //			or a higher value on failure (see enum EChatRoomEnterResponse)
596 //-----------------------------------------------------------------------------
597 struct LobbyEnter_t
598 {
599 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 4 };
600 
601 	uint64 m_ulSteamIDLobby;							// SteamID of the Lobby you have entered
602 	uint32 m_rgfChatPermissions;						// Permissions of the current user
603 	bool m_bLocked;										// If true, then only invited users may join
604 	uint32 m_EChatRoomEnterResponse;	// EChatRoomEnterResponse
605 };
606 
607 
608 //-----------------------------------------------------------------------------
609 // Purpose: The lobby metadata has changed
610 //			if m_ulSteamIDMember is the steamID of a lobby member, use GetLobbyMemberData() to access per-user details
611 //			if m_ulSteamIDMember == m_ulSteamIDLobby, use GetLobbyData() to access lobby metadata
612 //-----------------------------------------------------------------------------
613 struct LobbyDataUpdate_t
614 {
615 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 5 };
616 
617 	uint64 m_ulSteamIDLobby;		// steamID of the Lobby
618 	uint64 m_ulSteamIDMember;		// steamID of the member whose data changed, or the room itself
619 	uint8 m_bSuccess;				// true if we lobby data was successfully changed;
620 									// will only be false if RequestLobbyData() was called on a lobby that no longer exists
621 };
622 
623 
624 //-----------------------------------------------------------------------------
625 // Purpose: The lobby chat room state has changed
626 //			this is usually sent when a user has joined or left the lobby
627 //-----------------------------------------------------------------------------
628 struct LobbyChatUpdate_t
629 {
630 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 6 };
631 
632 	uint64 m_ulSteamIDLobby;			// Lobby ID
633 	uint64 m_ulSteamIDUserChanged;		// user who's status in the lobby just changed - can be recipient
634 	uint64 m_ulSteamIDMakingChange;		// Chat member who made the change (different from SteamIDUserChange if kicking, muting, etc.)
635 										// for example, if one user kicks another from the lobby, this will be set to the id of the user who initiated the kick
636 	uint32 m_rgfChatMemberStateChange;	// bitfield of EChatMemberStateChange values
637 };
638 
639 
640 //-----------------------------------------------------------------------------
641 // Purpose: A chat message for this lobby has been sent
642 //			use GetLobbyChatEntry( m_iChatID ) to retrieve the contents of this message
643 //-----------------------------------------------------------------------------
644 struct LobbyChatMsg_t
645 {
646 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 7 };
647 
648 	uint64 m_ulSteamIDLobby;			// the lobby id this is in
649 	uint64 m_ulSteamIDUser;			// steamID of the user who has sent this message
650 	uint8 m_eChatEntryType;			// type of message
651 	uint32 m_iChatID;				// index of the chat entry to lookup
652 };
653 
654 
655 //-----------------------------------------------------------------------------
656 // Purpose: A game created a game for all the members of the lobby to join,
657 //			as triggered by a SetLobbyGameServer()
658 //			it's up to the individual clients to take action on this; the usual
659 //			game behavior is to leave the lobby and connect to the specified game server
660 //-----------------------------------------------------------------------------
661 struct LobbyGameCreated_t
662 {
663 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 9 };
664 
665 	uint64 m_ulSteamIDLobby;		// the lobby we were in
666 	uint64 m_ulSteamIDGameServer;	// the new game server that has been created or found for the lobby members
667 	uint32 m_unIP;					// IP & Port of the game server (if any)
668 	uint16 m_usPort;
669 };
670 
671 
672 //-----------------------------------------------------------------------------
673 // Purpose: Number of matching lobbies found
674 //			iterate the returned lobbies with GetLobbyByIndex(), from values 0 to m_nLobbiesMatching-1
675 //-----------------------------------------------------------------------------
676 struct LobbyMatchList_t
677 {
678 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 10 };
679 	uint32 m_nLobbiesMatching;		// Number of lobbies that matched search criteria and we have SteamIDs for
680 };
681 
682 
683 //-----------------------------------------------------------------------------
684 // Purpose: posted if a user is forcefully removed from a lobby
685 //			can occur if a user loses connection to Steam
686 //-----------------------------------------------------------------------------
687 struct LobbyKicked_t
688 {
689 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 12 };
690 	uint64 m_ulSteamIDLobby;			// Lobby
691 	uint64 m_ulSteamIDAdmin;			// User who kicked you - possibly the ID of the lobby itself
692 	uint8 m_bKickedDueToDisconnect;		// true if you were kicked from the lobby due to the user losing connection to Steam (currently always true)
693 };
694 
695 
696 //-----------------------------------------------------------------------------
697 // Purpose: Result of our request to create a Lobby
698 //			m_eResult == k_EResultOK on success
699 //			at this point, the lobby has been joined and is ready for use
700 //			a LobbyEnter_t callback will also be received (since the local user is joining their own lobby)
701 //-----------------------------------------------------------------------------
702 struct LobbyCreated_t
703 {
704 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 13 };
705 
706 	EResult m_eResult;		// k_EResultOK - the lobby was successfully created
707 							// k_EResultNoConnection - your Steam client doesn't have a connection to the back-end
708 							// k_EResultTimeout - you the message to the Steam servers, but it didn't respond
709 							// k_EResultFail - the server responded, but with an unknown internal error
710 							// k_EResultAccessDenied - your game isn't set to allow lobbies, or your client does haven't rights to play the game
711 							// k_EResultLimitExceeded - your game client has created too many lobbies
712 
713 	uint64 m_ulSteamIDLobby;		// chat room, zero if failed
714 };
715 
716 // used by now obsolete RequestFriendsLobbiesResponse_t
717 // enum { k_iCallback = k_iSteamMatchmakingCallbacks + 14 };
718 
719 
720 //-----------------------------------------------------------------------------
721 // Purpose: Result of CheckForPSNGameBootInvite
722 //			m_eResult == k_EResultOK on success
723 //			at this point, the local user may not have finishing joining this lobby;
724 //			game code should wait until the subsequent LobbyEnter_t callback is received
725 //-----------------------------------------------------------------------------
726 struct PSNGameBootInviteResult_t
727 {
728 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 15 };
729 
730 	bool m_bGameBootInviteExists;
731 	CSteamID m_steamIDLobby;		// Should be valid if m_bGameBootInviteExists == true
732 };
733 
734 
735 //-----------------------------------------------------------------------------
736 // Purpose: Result of our request to create a Lobby
737 //			m_eResult == k_EResultOK on success
738 //			at this point, the lobby has been joined and is ready for use
739 //			a LobbyEnter_t callback will also be received (since the local user is joining their own lobby)
740 //-----------------------------------------------------------------------------
741 struct FavoritesListAccountsUpdated_t
742 {
743 	enum { k_iCallback = k_iSteamMatchmakingCallbacks + 16 };
744 
745 	EResult m_eResult;
746 };
747 
748 #pragma pack( pop )
749 
750 
751 #endif // ISTEAMMATCHMAKING
752