Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

398 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef MATCHMAKING_H
  7. #define MATCHMAKING_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #ifdef _WIN32
  12. #include "winerror.h"
  13. #endif
  14. #include "utlmap.h"
  15. #include "inetmsghandler.h"
  16. #include "netmessages.h"
  17. #include "Session.h"
  18. #include "engine/imatchmaking.h"
  19. enum MMPACKETS
  20. {
  21. PTH_CONNECT,
  22. PTH_SYSTEMLINK_SEARCH,
  23. HTP_SYSTEMLINK_REPLY
  24. };
  25. enum MMSTATE
  26. {
  27. MMSTATE_INITIAL,
  28. MMSTATE_IDLE,
  29. MMSTATE_CREATING,
  30. MMSTATE_MODIFYING,
  31. MMSTATE_ACCEPTING_CONNECTIONS,
  32. MMSTATE_SEARCHING,
  33. MMSTATE_WAITING_QOS,
  34. MMSTATE_BROWSING,
  35. MMSTATE_SESSION_CONNECTING,
  36. MMSTATE_SESSION_CONNECTED,
  37. MMSTATE_SESSION_DISCONNECTING,
  38. MMSTATE_HOSTMIGRATE_STARTINGMIGRATION,
  39. MMSTATE_HOSTMIGRATE_MIGRATING,
  40. MMSTATE_HOSTMIGRATE_WAITINGFORCLIENTS,
  41. MMSTATE_HOSTMIGRATE_WAITINGFORHOST,
  42. MMSTATE_GAME_LOCKED, // in ranked games, clients can't join after this point
  43. MMSTATE_PREGAME,
  44. MMSTATE_REPORTING_STATS,
  45. MMSTATE_POSTGAME,
  46. MMSTATE_GAME_ACTIVE, // clients are no longer in the lobby
  47. MMSTATE_LOADING,
  48. MMSTATE_CONNECTED_TO_SERVER,
  49. MMSTATE_INGAME,
  50. };
  51. // For sending host data back in search results
  52. enum eGameState
  53. {
  54. GAMESTATE_INLOBBY,
  55. GAMESTATE_INPROGRESS
  56. };
  57. #define HEARTBEAT_INTERVAL_LONG 1.0 // send a heartbeat every second during gameplay
  58. #define HEARTBEAT_INTERVAL_SHORT 0.1 // send a heartbeat ten times a second in the lobby
  59. #define HEARTBEAT_TIMEOUT 10.0 // time out if a heartbeat isn't recieved for ten seconds
  60. #if defined( _DEBUG )
  61. #define HEARTBEAT_TIMEOUT_LOADING 300 // in debug loads take much longer
  62. #else
  63. #define HEARTBEAT_TIMEOUT_LOADING 100 // allow for longer communication gaps during map load
  64. #endif
  65. #define STARTGAME_COUNTDOWN 15.0 // start game countdown timer
  66. #define DISCONNECT_WAITTIME 1.0 // wait for the server to reply to our disconnect notification
  67. #define QOSLOOKUP_WAITTIME 20.0 // wait to get quality of service data about session hosts
  68. #define JOINREPLY_WAITTIME 15.0 // time to wait for the host to reply to our join request
  69. #define REPORTSTATS_WAITTIME 20.0 // time to wait for clients to report their stats to live
  70. // 360 TCR's require system link searches complete in less than 3 seconds
  71. #define SYSTEMLINK_RETRYINTERVAL 1.f // in seconds
  72. #define SYSTEMLINK_MAXRETRIES 3 // number of tries before giving up
  73. #define SESSIONMODIRY_MAXWAITTIME 10 // max time for clients to update their session properties
  74. #define REGISTRATION_MAXWAITTIME 10 // max time for clients to register
  75. #define HOSTMIGRATION_RETRYINTERVAL 1.0 // in seconds
  76. #define HOSTMIGRATION_MAXRETRIES 10 // max migrate sends to clients
  77. #define HOSTMIGRATION_MAXWAITTIME 10 // time to wait for a new host to contact us
  78. #define MAX_SEARCHRESULTS 20 // Maximum number of results when searching for a session.
  79. #define PING_MAX_GREEN 70
  80. #define PING_MAX_YELLOW 140
  81. #define PING_MAX_RED 250
  82. #define VOICE_STATUS_OFF 0
  83. #define VOICE_STATUS_IDLE 1
  84. #define VOICE_STATUS_TALKING 2
  85. // HACK: For simplicity, we know TF has two teams plus spectator.
  86. #define MAX_TEAMS 3
  87. #define MAX_PLAYERS 16
  88. #define VOICE_ICON_BLINK_TIME 0.5
  89. class CMatchmaking : public IMatchmaking, public IMatchmakingMessageHandler, public IClientMessageHandler, public INetChannelHandler, public IConnectionlessPacketHandler
  90. {
  91. public:
  92. CMatchmaking();
  93. ~CMatchmaking();
  94. // IMatchmaking implementation
  95. virtual void SessionNotification( const SESSION_NOTIFY notification, const int param = 0 );
  96. virtual void AddSessionProperty( const uint nType, const char *pID, const char *pValue, const char *pValueType );
  97. virtual void SetSessionProperties( KeyValues *pPropertyKeys );
  98. virtual void SelectSession( uint sessionIdx );
  99. virtual void ModifySession();
  100. virtual void UpdateMuteList();
  101. virtual void StartHost( bool bSystemLink = false );
  102. virtual void StartClient( bool bSystemLink = false );
  103. virtual bool StartGame();
  104. virtual bool CancelStartGame();
  105. virtual void ChangeTeam( const char *pTeamName );
  106. virtual void TellClientsToConnect();
  107. virtual void CancelCurrentOperation();
  108. virtual void EndStatsReporting();
  109. virtual void JoinInviteSessionByID( XNKID nSessionID );
  110. virtual void JoinInviteSession( XSESSION_INFO *pHostInfo );
  111. virtual void KickPlayerFromSession( uint64 id );
  112. // For GameUI
  113. virtual KeyValues *GetSessionProperties();
  114. // For voice chat
  115. virtual uint64 PlayerIdToXuid( int playerId );
  116. virtual bool IsPlayerMuted( int iUserId, XUID id );
  117. // To determine host Quality-of-Service
  118. virtual MM_QOS_t GetQosWithLIVE();
  119. virtual bool PreventFullServerStartup();
  120. // IConnectionlessPacketHandler implementation (Host/Client shared)
  121. virtual bool ProcessConnectionlessPacket( netpacket_t * packet );
  122. // INetChannelHandler implementation
  123. virtual void ConnectionStart(INetChannel *chan); // called first time network channel is established
  124. virtual void PacketEnd(); // all messages have been parsed
  125. // NetChannel message handlers
  126. PROCESS_NET_MESSAGE( Tick ) { return true; }
  127. PROCESS_NET_MESSAGE( SetConVar ) { return true; }
  128. PROCESS_NET_MESSAGE( StringCmd ) { return true; }
  129. PROCESS_NET_MESSAGE( SignonState ) { return true; }
  130. PROCESS_CLC_MESSAGE( VoiceData );
  131. PROCESS_CLC_MESSAGE( ClientInfo ) { return true; }
  132. PROCESS_CLC_MESSAGE( Move ) { return true; }
  133. PROCESS_CLC_MESSAGE( BaselineAck ) { return true; }
  134. PROCESS_CLC_MESSAGE( ListenEvents ) { return true; }
  135. PROCESS_CLC_MESSAGE( RespondCvarValue ) { return true; }
  136. PROCESS_CLC_MESSAGE( FileCRCCheck ) { return true; }
  137. PROCESS_CLC_MESSAGE( FileMD5Check ) { return true; }
  138. PROCESS_CLC_MESSAGE( SaveReplay ) { return true; }
  139. PROCESS_CLC_MESSAGE( CmdKeyValues ) { return true; }
  140. PROCESS_MM_MESSAGE( JoinResponse );
  141. PROCESS_MM_MESSAGE( ClientInfo );
  142. PROCESS_MM_MESSAGE( RegisterResponse );
  143. PROCESS_MM_MESSAGE( Migrate );
  144. PROCESS_MM_MESSAGE( Mutelist );
  145. PROCESS_MM_MESSAGE( Checkpoint );
  146. PROCESS_MM_MESSAGE( Heartbeat ) { return true; }
  147. // (Not used)
  148. virtual void ConnectionClosing(const char *reason) {}; // network channel is being closed by remote site
  149. virtual void ConnectionCrashed(const char *reason) {}; // network error occurred
  150. virtual void PacketStart(int incoming_sequence, int outgoing_acknowledged) {}; // called each time a new packet arrived
  151. virtual void FileRequested(const char *fileName, unsigned int transferID ) {}; // other side request a file for download
  152. virtual void FileReceived(const char *fileName, unsigned int transferID ) {}; // we received a file
  153. virtual void FileDenied(const char *fileName, unsigned int transferID ) {}; // a file request was denied by other side
  154. virtual void FileSent(const char *fileName, unsigned int transferID ) {}; // a file was sent
  155. // Debugging helpers
  156. void ShowSessionInfo();
  157. void SendDevMessage( const char *message );
  158. void SetSessionSlots( const uint nSlotsTotal, const uint nSlotsPrivate );
  159. void RunFrame();
  160. void EndGame();
  161. void AddLocalPlayersToTeams();
  162. void OnLevelLoadingFinished();
  163. void TestSendMessage();
  164. void TestStats();
  165. bool GameIsActive();
  166. void PrintVoiceStatus( void );
  167. private:
  168. // NetChannel send
  169. void SendMessage( INetMessage *msg, netadr_t *adr, bool bVoice = false );
  170. void SendMessage( INetMessage *msg, CClientInfo *pClient, bool bVoice = false );
  171. void SendToRemoteClients( INetMessage *msg, bool bVoice = false, XUID excludeXUID = -1 );
  172. // Session Host
  173. void OnHostSessionCreated();
  174. void UpdateAcceptingConnections();
  175. void SendModifySessionMessage();
  176. void EndSessionModify();
  177. bool IsAcceptingConnections();
  178. void HandleSystemLinkSearch( netpacket_t *pPacket );
  179. void HandleJoinRequest( netpacket_t *pPacket );
  180. void StartCountdown();
  181. void CancelCountdown();
  182. void UpdatePregame();
  183. void UpdateRegistration();
  184. void UpdateSessionModify();
  185. void ProcessRegistrationResults();
  186. void UpdateServerNegotiation();
  187. void UpdateSessionReplyData( uint flags );
  188. void SwitchToNextOpenTeam( CClientInfo *pClient );
  189. void SetupTeams();
  190. int ChooseTeam();
  191. int GetPlayersNeeded();
  192. // Session Client
  193. bool StartSystemLinkSearch();
  194. void HandleSystemLinkReply( netpacket_t *pPacket );
  195. bool SearchForSession();
  196. void UpdateSearch();
  197. void UpdateQosLookup();
  198. void CancelSearch();
  199. void CancelQosLookup();
  200. void ClearSearchResults();
  201. void SendJoinRequest( netadr_t *adr );
  202. bool ConnectToHost();
  203. void UpdateConnecting();
  204. void ApplySessionProperties( int numContexts, int numProperties, XUSER_CONTEXT *pContexts, XUSER_PROPERTY *pProperties );
  205. // Host/Client shared
  206. bool InitializeLocalClient( bool bIsHost );
  207. void AddPlayersToSession( CClientInfo *pClient );
  208. void SendPlayerInfoToLobby( CClientInfo *pClient, int iHostIdx = -1 );
  209. void RemovePlayersFromSession( CClientInfo *pClient );
  210. void ClientDropped( CClientInfo *pClient );
  211. void PerformDisconnect();
  212. void GenerateMutelist( MM_Mutelist *pMsg );
  213. int FindOrCreateContext( const uint id );
  214. int FindOrCreateProperty( const uint id );
  215. void AddSessionPropertyInternal( KeyValues *pProperty );
  216. // Host Migration
  217. CClientInfo *SelectNewHost();
  218. void StartHostMigration();
  219. void BeginHosting();
  220. void TellClientsToMigrate();
  221. void SwitchToNewHost();
  222. void EndMigration();
  223. // General utility functions
  224. void Cleanup();
  225. void SwitchToState( int newState );
  226. double GetTime();
  227. void SendHeartbeat();
  228. bool SendHeartbeat( CClientInfo *pClient );
  229. void ClientInfoToNetMessage( MM_ClientInfo *pInfo, const CClientInfo *pClient );
  230. void NetMessageToClientInfo( CClientInfo *pClient, const MM_ClientInfo *pInfo );
  231. bool GameIsLocked();
  232. bool IsInMigration();
  233. bool IsServer();
  234. bool ConnectedToServer();
  235. // Netchannel handling
  236. INetChannel *CreateNetChannel( netadr_t *adr );
  237. INetChannel *AddRemoteChannel( netadr_t *adr );
  238. INetChannel *FindChannel( const unsigned int ip );
  239. CClientInfo *FindClient( netadr_t *adr );
  240. CClientInfo *FindClientByXUID( XUID xuid );
  241. void SetChannelTimeout( netadr_t *adr, int timeout );
  242. void RemoveRemoteChannel( netadr_t *adr, const char *pReason );
  243. void MarkChannelForRemoval( netadr_t *adr );
  244. void CleanupMarkedChannels();
  245. void UpdateVoiceStatus( void );
  246. void SetPreventFullServerStartup( bool bState, PRINTF_FORMAT_STRING char const *fmt, ... );
  247. private:
  248. // Used by a systemlink host to reply to broadcast searches
  249. struct systemLinkInfo_s
  250. {
  251. char szHostName[MAX_PLAYER_NAME_LENGTH];
  252. char szScenario[MAX_MAP_NAME];
  253. int gameState;
  254. int gameTime;
  255. int iScenarioIndex;
  256. XUID xuid;
  257. XSESSION_SEARCHRESULT Result;
  258. };
  259. hostData_s m_HostData; // pass host info back to searching clients
  260. CClientInfo m_Host; // the session host
  261. CClientInfo m_Local; // the local client
  262. CClientInfo *m_pNewHost; // new host when migrating the session
  263. CClientInfo *m_pGameServer; // the client that will act as the game server
  264. CUtlVector< CClientInfo* > m_Remote; // remote clients
  265. CUtlVector< char* > m_pSystemLinkResults; // results from a system link search
  266. XSESSION_SEARCHRESULT_HEADER *m_pSearchResults; // dynamic buffer to hold session search results
  267. // Arbitration registration
  268. XSESSION_REGISTRATION_RESULTS *m_pRegistrationResults;
  269. // QoS Data
  270. BOOL m_bQoSTesting;
  271. XNQOS m_QoSResult;
  272. XNQOS* m_pQoSResult;
  273. const XNADDR* m_QoSxnaddr[MAX_SEARCHRESULTS];
  274. const XNKID* m_QoSxnkid[MAX_SEARCHRESULTS];
  275. const XNKEY* m_QoSxnkey[MAX_SEARCHRESULTS];
  276. CUtlMap< unsigned int, INetChannel* >m_Channels;
  277. CUtlVector< unsigned int > m_ChannelsToRemove;
  278. AsyncHandle_t m_hSearchHandle;
  279. CSession m_Session;
  280. int m_CurrentState;
  281. int m_PreMigrateState;
  282. double m_fNextHeartbeatTime;
  283. double m_fCountdownStartTime;
  284. double m_fRegistrationTimer;
  285. bool m_bCreatedLocalTalker;
  286. bool m_bInitialized;
  287. bool m_bCleanup;
  288. bool m_bPreventFullServerStartup;
  289. bool m_bEnteredLobby;
  290. int m_nHostOwnerId;
  291. int m_nGameSize;
  292. int m_nTotalTeams;
  293. int m_nPrivateSlots;
  294. int m_nQOSProbeCount;
  295. double m_fQOSProbeTimer;
  296. int m_nSendCount;
  297. double m_fSendTimer;
  298. double m_fWaitTimer;
  299. double m_fHeartbeatInterval;
  300. uint64 m_Nonce; // used in system link queries
  301. int CountPlayersOnTeam( int idxTeam ); // players on each team
  302. XUID m_Mutelist[MAX_PLAYERS_PER_CLIENT][MAX_PLAYERS];
  303. CUtlVector< XUID > m_MutedBy[MAX_PLAYERS_PER_CLIENT];
  304. // Contexts and properties
  305. CUtlVector< XUSER_CONTEXT > m_SessionContexts; // for session creation
  306. CUtlVector< XUSER_PROPERTY > m_SessionProperties; // for session creation
  307. CUtlVector< XUSER_PROPERTY > m_PlayerStats;
  308. KeyValues *m_pSessionKeys; // for GameUI lobby setup
  309. double m_flVoiceBlinkTime;
  310. XSESSION_INFO m_InviteSessionInfo;
  311. enum InviteState_t
  312. {
  313. INVITE_NONE,
  314. INVITE_PENDING,
  315. INVITE_VALIDATING,
  316. INVITE_AWAITING_STORAGE,
  317. INVITE_ACCEPTING
  318. } m_InviteState;
  319. struct InviteWaitingInfo_t
  320. {
  321. DWORD m_UserIdx;
  322. #if defined( _X360 )
  323. XUSER_SIGNIN_INFO m_SignInInfo;
  324. #endif
  325. DWORD m_SignInState;
  326. BOOL m_PrivilegeMultiplayer;
  327. int m_InviteStorageDeviceSelected;
  328. int m_bAcceptingInvite;
  329. } m_InviteWaitingInfo;
  330. void RunFrameInvite();
  331. void InviteCancel();
  332. };
  333. extern CMatchmaking *g_pMatchmaking;
  334. #endif // MATCHMAKING_H