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.

393 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: The main manager of the networking code in the game
  4. //
  5. // $Revision: $
  6. // $NoKeywords: $
  7. //===========================================================================//
  8. #include "networkmanager.h"
  9. #include "legion.h"
  10. #include "networksystem/inetworkmessage.h"
  11. #include "tier1/bitbuf.h"
  12. #include "inetworkmessagelistener.h"
  13. #include "tier0/icommandline.h"
  14. #include "tier2/tier2.h"
  15. //-----------------------------------------------------------------------------
  16. // Singleton accessor
  17. //-----------------------------------------------------------------------------
  18. static CNetworkManager s_NetworkManager;
  19. extern CNetworkManager *g_pNetworkManager = &s_NetworkManager;
  20. //-----------------------------------------------------------------------------
  21. // Static members.
  22. // NOTE: Do *not* set this to 0; it could cause us to lose some registered
  23. // menus since that list is set up during construction
  24. //-----------------------------------------------------------------------------
  25. INetworkMessageFactory *CNetworkManager::m_pFirstFactory;
  26. //-----------------------------------------------------------------------------
  27. // Call to register methods to register network messages
  28. //-----------------------------------------------------------------------------
  29. INetworkMessageFactory *CNetworkManager::RegisterNetworkMessage( INetworkMessageFactory *pNetworkMessageFactory )
  30. {
  31. // NOTE: This method is expected to be called during global constructor
  32. // time, so it must not require any global constructors to be called to work
  33. INetworkMessageFactory *pPrevFactory = m_pFirstFactory;
  34. m_pFirstFactory = pNetworkMessageFactory;
  35. return pPrevFactory;
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Init, shutdown
  39. //-----------------------------------------------------------------------------
  40. bool CNetworkManager::Init()
  41. {
  42. m_bIsClient = m_bIsServer = false;
  43. m_pClientToServerConnection = NULL;
  44. // Make a listener array for each message type
  45. // Register all network messages
  46. INetworkMessageFactory *pFactory;
  47. for ( pFactory = m_pFirstFactory; pFactory; pFactory = pFactory->GetNextFactory() )
  48. {
  49. INetworkMessage *pNetworkMessage = pFactory->CreateNetworkMessage();
  50. g_pNetworkSystem->RegisterMessage( pNetworkMessage );
  51. }
  52. return true;
  53. }
  54. void CNetworkManager::Shutdown()
  55. {
  56. ShutdownClient();
  57. ShutdownServer();
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Start a server up
  61. //-----------------------------------------------------------------------------
  62. bool CNetworkManager::StartServer( unsigned short nServerListenPort )
  63. {
  64. ShutdownServer( );
  65. if ( nServerListenPort == LEGION_DEFAULT_SERVER_PORT )
  66. {
  67. nServerListenPort = CommandLine()->ParmValue( "-serverport", NETWORKSYSTEM_DEFAULT_SERVER_PORT );
  68. }
  69. m_bIsServer = g_pNetworkSystem->StartServer( nServerListenPort );
  70. return m_bIsServer;
  71. }
  72. void CNetworkManager::ShutdownServer( )
  73. {
  74. if ( m_bIsServer )
  75. {
  76. g_pNetworkSystem->ShutdownServer( );
  77. m_bIsServer = false;
  78. }
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Start a client up
  82. //-----------------------------------------------------------------------------
  83. bool CNetworkManager::StartClient( unsigned short nClientListenPort )
  84. {
  85. ShutdownClient( );
  86. if ( nClientListenPort == LEGION_DEFAULT_CLIENT_PORT )
  87. {
  88. nClientListenPort = CommandLine()->ParmValue( "-clientport", NETWORKSYSTEM_DEFAULT_CLIENT_PORT );
  89. }
  90. m_bIsClient = g_pNetworkSystem->StartClient( nClientListenPort );
  91. return m_bIsClient;
  92. }
  93. void CNetworkManager::ShutdownClient( )
  94. {
  95. if ( m_bIsClient )
  96. {
  97. DisconnectClientFromServer();
  98. g_pNetworkSystem->ShutdownClient( );
  99. m_bIsClient = false;
  100. }
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Connects/disconnects the client to a server
  104. //-----------------------------------------------------------------------------
  105. bool CNetworkManager::ConnectClientToServer( const char *pServerName, unsigned short nServerListenPort )
  106. {
  107. DisconnectClientFromServer();
  108. if ( !IsClient() )
  109. return false;
  110. if ( nServerListenPort == LEGION_DEFAULT_SERVER_PORT )
  111. {
  112. nServerListenPort = CommandLine()->ParmValue( "-serverport", NETWORKSYSTEM_DEFAULT_SERVER_PORT );
  113. }
  114. m_pClientToServerConnection = g_pNetworkSystem->ConnectClientToServer( pServerName, nServerListenPort );
  115. return ( m_pClientToServerConnection != NULL );
  116. }
  117. void CNetworkManager::DisconnectClientFromServer( )
  118. {
  119. if ( m_pClientToServerConnection )
  120. {
  121. g_pNetworkSystem->DisconnectClientFromServer( m_pClientToServerConnection );
  122. m_pClientToServerConnection = NULL;
  123. }
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Start up a game where the local player is playing
  127. //-----------------------------------------------------------------------------
  128. bool CNetworkManager::HostGame()
  129. {
  130. if ( !StartServer() )
  131. return false;
  132. if ( !StartClient() )
  133. {
  134. ShutdownServer();
  135. return false;
  136. }
  137. if ( !ConnectClientToServer( "localhost" ) )
  138. {
  139. ShutdownClient();
  140. ShutdownServer();
  141. return false;
  142. }
  143. return true;
  144. }
  145. void CNetworkManager::StopHostingGame()
  146. {
  147. ShutdownClient();
  148. ShutdownServer();
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Are we a client?/Are we a server? (we can be both)
  152. //-----------------------------------------------------------------------------
  153. bool CNetworkManager::IsClient()
  154. {
  155. return m_bIsClient;
  156. }
  157. bool CNetworkManager::IsServer()
  158. {
  159. return m_bIsServer;
  160. }
  161. //-----------------------------------------------------------------------------
  162. // If we are a client, are we connected to the server?
  163. //-----------------------------------------------------------------------------
  164. bool CNetworkManager::IsClientConnected()
  165. {
  166. return m_bIsClient && ( m_pClientToServerConnection != NULL ) && ( m_pClientToServerConnection->GetConnectionState() == CONNECTION_STATE_CONNECTED );
  167. }
  168. //-----------------------------------------------------------------------------
  169. // Post a network message to the server
  170. //-----------------------------------------------------------------------------
  171. void CNetworkManager::PostClientToServerMessage( INetworkMessage *pMessage )
  172. {
  173. if ( IsClientConnected() )
  174. {
  175. m_pClientToServerConnection->AddNetMsg( pMessage );
  176. }
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Broadcast a network message to all clients
  180. //-----------------------------------------------------------------------------
  181. void CNetworkManager::BroadcastServerToClientMessage( INetworkMessage *pMessage )
  182. {
  183. if ( IsServer() )
  184. {
  185. int nCount = m_ServerToClientConnection.Count();
  186. for ( int i = 0; i < nCount; ++i )
  187. {
  188. m_ServerToClientConnection[i]->AddNetMsg( pMessage );
  189. }
  190. }
  191. }
  192. //-----------------------------------------------------------------------------
  193. // Add, remove network message listeners
  194. //-----------------------------------------------------------------------------
  195. void CNetworkManager::AddListener( NetworkMessageRoute_t route, int nGroup, int nType, INetworkMessageListener *pListener )
  196. {
  197. CUtlVector< CUtlVector< CUtlVector < INetworkMessageListener* > > > &listeners = m_Listeners[ route ];
  198. if ( listeners.Count() <= nGroup )
  199. {
  200. listeners.AddMultipleToTail( nGroup - listeners.Count() + 1 );
  201. }
  202. if ( listeners[nGroup].Count() <= nType )
  203. {
  204. listeners[nGroup].AddMultipleToTail( nType - listeners[nGroup].Count() + 1 );
  205. }
  206. Assert( listeners[nGroup][nType].Find( pListener ) < 0 );
  207. listeners[nGroup][nType].AddToTail( pListener );
  208. }
  209. void CNetworkManager::RemoveListener( NetworkMessageRoute_t route, int nGroup, int nType, INetworkMessageListener *pListener )
  210. {
  211. CUtlVector< CUtlVector< CUtlVector < INetworkMessageListener* > > > &listeners = m_Listeners[ route ];
  212. if ( listeners.Count() > nGroup )
  213. {
  214. if( listeners[nGroup].Count() > nType )
  215. {
  216. // Maintain order of listeners (not sure if it matters)
  217. listeners[nGroup][nType].FindAndRemove( pListener );
  218. }
  219. }
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Notifies listeners about a network message
  223. //-----------------------------------------------------------------------------
  224. void CNetworkManager::NotifyListeners( NetworkMessageRoute_t route, INetworkMessage *pMessage )
  225. {
  226. CUtlVector< CUtlVector< CUtlVector < INetworkMessageListener* > > > &listeners = m_Listeners[ route ];
  227. // based on id, search for installed listeners
  228. int nGroup = pMessage->GetGroup();
  229. if ( listeners.Count() > nGroup )
  230. {
  231. int nType = pMessage->GetType();
  232. if ( listeners[nGroup].Count() > nType )
  233. {
  234. CUtlVector< INetworkMessageListener* > &list = listeners[nGroup][nType];
  235. int nCount = list.Count();
  236. for ( int i = 0; i < nCount; ++i )
  237. {
  238. list[i]->OnNetworkMessage( route, pMessage );
  239. }
  240. }
  241. }
  242. }
  243. //-----------------------------------------------------------------------------
  244. // Process messages received by the client
  245. //-----------------------------------------------------------------------------
  246. void CNetworkManager::ProcessClientMessages()
  247. {
  248. NetworkEvent_t *pEvent = g_pNetworkSystem->FirstNetworkEvent();
  249. for ( ; pEvent; pEvent = g_pNetworkSystem->NextNetworkEvent( ) )
  250. {
  251. switch ( pEvent->m_nType )
  252. {
  253. /*
  254. case NETWORK_EVENT_CONNECTED:
  255. {
  256. NetworkConnectionEvent_t* pConnectEvent = static_cast<NetworkConnectionEvent_t*>( pEvent );
  257. m_pClientToServerConnection = pConnectEvent->m_pChannel;
  258. }
  259. break;
  260. case NETWORK_EVENT_DISCONNECTED:
  261. {
  262. NetworkDisconnectionEvent_t* pDisconnectEvent = static_cast<NetworkDisconnectionEvent_t*>( pEvent );
  263. Assert( m_pClientToServerConnection == pDisconnectEvent->m_pChannel );
  264. if ( m_pClientToServerConnection == pDisconnectEvent->m_pChannel )
  265. {
  266. m_pClientToServerConnection = NULL;
  267. }
  268. }
  269. break;
  270. */
  271. case NETWORK_EVENT_MESSAGE_RECEIVED:
  272. {
  273. NetworkMessageReceivedEvent_t* pPacketEvent = static_cast<NetworkMessageReceivedEvent_t*>( pEvent );
  274. NotifyListeners( NETWORK_MESSAGE_SERVER_TO_CLIENT, pPacketEvent->m_pNetworkMessage );
  275. }
  276. break;
  277. }
  278. }
  279. }
  280. //-----------------------------------------------------------------------------
  281. // Process messages received by the server
  282. //-----------------------------------------------------------------------------
  283. void CNetworkManager::ProcessServerMessages()
  284. {
  285. NetworkEvent_t *pEvent = g_pNetworkSystem->FirstNetworkEvent();
  286. for ( ; pEvent; pEvent = g_pNetworkSystem->NextNetworkEvent( ) )
  287. {
  288. switch ( pEvent->m_nType )
  289. {
  290. case NETWORK_EVENT_CONNECTED:
  291. {
  292. NetworkConnectionEvent_t* pConnectEvent = static_cast<NetworkConnectionEvent_t*>( pEvent );
  293. m_ServerToClientConnection.AddToTail( pConnectEvent->m_pChannel );
  294. }
  295. break;
  296. case NETWORK_EVENT_DISCONNECTED:
  297. {
  298. NetworkDisconnectionEvent_t* pDisconnectEvent = static_cast<NetworkDisconnectionEvent_t*>( pEvent );
  299. m_ServerToClientConnection.FindAndRemove( pDisconnectEvent->m_pChannel );
  300. }
  301. break;
  302. case NETWORK_EVENT_MESSAGE_RECEIVED:
  303. {
  304. NetworkMessageReceivedEvent_t* pPacketEvent = static_cast<NetworkMessageReceivedEvent_t*>( pEvent );
  305. NotifyListeners( NETWORK_MESSAGE_CLIENT_TO_SERVER, pPacketEvent->m_pNetworkMessage );
  306. }
  307. break;
  308. }
  309. }
  310. }
  311. //-----------------------------------------------------------------------------
  312. // Per-frame update
  313. //-----------------------------------------------------------------------------
  314. void CNetworkManager::Update( )
  315. {
  316. if ( IsClient() )
  317. {
  318. g_pNetworkSystem->ClientSendMessages();
  319. }
  320. if ( IsServer() )
  321. {
  322. g_pNetworkSystem->ServerReceiveMessages();
  323. ProcessServerMessages();
  324. g_pNetworkSystem->ServerSendMessages();
  325. }
  326. if ( IsClient() )
  327. {
  328. g_pNetworkSystem->ClientReceiveMessages();
  329. ProcessClientMessages();
  330. }
  331. }