PlayerManager.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:13k
源码类别:

模拟服务器

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "PlayerManager.h"
  3. #include "....Sword3PaySysS3AccServerAccountLoginDef.h"
  4. #include "....s3clientloginLoginDef.h"
  5. #include "....RoleDBManagerkroledbheader.h"
  6. #include "KProtocolDef.h"
  7. #include "....coreSrcKProtocol.h"
  8. #include "Macro.h"
  9. #include "Buffer.h"
  10. using OnlineGameLib::Win32::CEvent;
  11. using OnlineGameLib::Win32::CCriticalSection;
  12. using OnlineGameLib::Win32::CPackager;
  13. OnlineGameLib::Win32::CLibrary CPlayerManager::m_theHeavenLib( "heaven.dll" );
  14. OnlineGameLib::Win32::CLibrary CPlayerManager::m_theRainbowLib( "rainbow.dll" );
  15. CPlayerManager::CPlayerManager( unsigned long lnMaxPlayerCount, CNetwork &theNetworkConfig )
  16. : m_pAccSvrClient( NULL )
  17. , m_pDBRoleClient( NULL )
  18. , m_pGameSvrServer( NULL )
  19. , m_pPlayerServer( NULL )
  20. , m_hWorkingThread( INVALID_HANDLE_VALUE )
  21. , m_hHelperThread( INVALID_HANDLE_VALUE )
  22. , m_hQuitEvent( NULL, true, false, "PM_Quit_Event" )
  23. , m_hStartupWoringThreadEvent( NULL, false, false, "PM_WORKING_EVENT" )
  24. , m_hStartupHelperThreadEvent( NULL, false, false, "PM_HELPER_EVENT" )
  25. , m_theNetworkConfig( theNetworkConfig )
  26. , m_lnMaxPlayerCount( lnMaxPlayerCount )
  27. {
  28. }
  29. CPlayerManager::~CPlayerManager()
  30. {
  31. }
  32. bool CPlayerManager::Create()
  33. {
  34. /*
  35.  * Start a working thread
  36.  */
  37. DWORD dwThreadID = 0;
  38. m_hWorkingThread = ::CreateThread( NULL, 
  39. 0, 
  40. WorkingThreadFunction, 
  41. ( void * )this, 
  42. 0, 
  43. &dwThreadID );
  44. if ( m_hWorkingThread == INVALID_HANDLE_VALUE )
  45. {
  46. return false;
  47. }
  48. /*
  49.  * Startup a helper thread
  50.  */
  51. dwThreadID = 0;
  52. m_hHelperThread = ::CreateThread( NULL, 
  53. 0, 
  54. HelperThreadFunction, 
  55. ( void * )this,
  56. 0, 
  57. &dwThreadID );
  58. if ( m_hHelperThread == INVALID_HANDLE_VALUE )
  59. {
  60. return false;
  61. }
  62. m_pAccSvrClient = m_theNetworkConfig.CreateAccSvrClient( m_theNetworkConfig.GetAccSvrIP(), m_theNetworkConfig.GetAccSvrPort() );
  63. ASSERT( m_pAccSvrClient );
  64. m_pAccSvrClient->RegisterMsgFilter( ( void * )this, AccountEventNotify );
  65. return StartupNetwork();
  66. }
  67. void CPlayerManager::Destroy()
  68. {
  69. m_hStartupWoringThreadEvent.Set();
  70. m_hStartupHelperThreadEvent.Set();
  71. m_hQuitEvent.Set();
  72. SAFE_CLOSEHANDLE( m_hWorkingThread );
  73. SAFE_CLOSEHANDLE( m_hHelperThread );
  74. SAFE_RELEASE( m_pAccSvrClient );
  75. CleanNetwork();
  76. }
  77. void __stdcall CPlayerManager::AccountEventNotify( LPVOID lpParam, 
  78. const unsigned long &ulnEventType )
  79. {
  80. }
  81. void __stdcall CPlayerManager::DBRoleEventNotify( LPVOID lpParam, 
  82. const unsigned long &ulnEventType )
  83. {
  84. }
  85. void __stdcall CPlayerManager::PlayerEventNotify( LPVOID lpParam,
  86. const unsigned long &ulnID,
  87. const unsigned long &ulnEventType )
  88. {
  89. CPlayerManager *pPlayerManager = reinterpret_cast< CPlayerManager * >( lpParam );
  90. ASSERT( pPlayerManager );
  91. try
  92. {
  93. pPlayerManager->_PlayerEventNotify( ulnID, ulnEventType );
  94. }
  95. catch(...)
  96. {}
  97. }
  98. void CPlayerManager::_PlayerEventNotify( const unsigned long &ulnID,
  99. const unsigned long &ulnEventType )
  100. {
  101. CCriticalSection::Owner locker( m_csUsedClientList );
  102. switch ( ulnEventType )
  103. {
  104. case enumClientConnectCreate:
  105. m_usedClientNode.push_back( ulnID );
  106. break;
  107. case enumClientConnectClose:
  108. PLAYER_MAP::iterator it;
  109. if ( m_thePlayers.end() != ( it = m_thePlayers.find( ulnID ) ) )
  110. {
  111. IPlayer *pPlayer = m_thePlayers[ulnID];
  112. ASSERT( pPlayer );
  113. pPlayer->Destroy( NULL );
  114. }
  115. m_usedClientNode.remove( ulnID );
  116. break;
  117. }
  118. }
  119. void __stdcall CPlayerManager::GameSvrEventNotify( LPVOID lpParam,
  120. const unsigned long &ulnID,
  121. const unsigned long &ulnEventType )
  122. {
  123. CPlayerManager *pPlayerManager = reinterpret_cast< CPlayerManager * >( lpParam );
  124. ASSERT( pPlayerManager );
  125. try
  126. {
  127. pPlayerManager->_GameServerEventNotify( ulnID, ulnEventType );
  128. }
  129. catch(...)
  130. {}
  131. }
  132. void CPlayerManager::_GameServerEventNotify( const unsigned long &ulnID,
  133. const unsigned long &ulnEventType )
  134. {
  135. CCriticalSection::Owner locker( m_csGameSvrAction );
  136. switch ( ulnEventType )
  137. {
  138. case enumClientConnectCreate:
  139. break;
  140. case enumClientConnectClose:
  141. break;
  142. }
  143. }
  144. bool CPlayerManager::StartupNetwork()
  145. {
  146. bool bPlayerServerSucceed = false;
  147. bool bDBRoleServerSucceed = false;
  148. bool bGameSvrServerSucceed = false;
  149. /*
  150.  * There is connectted the heaven by the rainbow
  151.  */
  152. /*
  153.  * For the db-role server
  154.  */
  155. pfnCreateClientInterface pClientFactroyFun = ( pfnCreateClientInterface )( m_theRainbowLib.GetProcAddress( _T( "CreateInterface" ) ) );
  156. IClientFactory *pClientFactory = NULL;
  157. if ( pClientFactroyFun && SUCCEEDED( pClientFactroyFun( IID_IClientFactory, reinterpret_cast< void ** >( &pClientFactory ) ) ) )
  158. {
  159. pClientFactory->SetEnvironment( 10, 1024 * 64 );
  160. pClientFactory->CreateClientInterface( IID_IESClient, reinterpret_cast< void ** >( &m_pDBRoleClient ) );
  161. SAFE_RELEASE( pClientFactory );
  162. }
  163. if ( m_pDBRoleClient )
  164. {
  165. m_pDBRoleClient->Startup();
  166. m_pDBRoleClient->RegisterMsgFilter( reinterpret_cast< void * >( this ), DBRoleEventNotify );
  167. if ( SUCCEEDED( m_pDBRoleClient->ConnectTo( m_theNetworkConfig.GetRoleSvrIP(), m_theNetworkConfig.GetRoleSvrPort() ) ) )
  168. {
  169. bDBRoleServerSucceed = true;
  170. }
  171. }
  172. /*
  173.  * We open the heaven to wait for the rainbow
  174.  */
  175. pfnCreateServerInterface pServerFactroyFun = 
  176. ( pfnCreateServerInterface )( m_theHeavenLib.GetProcAddress( _T( "CreateInterface" ) ) );
  177. IServerFactory *pServerFactory = NULL;
  178. if ( pServerFactroyFun && 
  179. SUCCEEDED( pServerFactroyFun( IID_IServerFactory, reinterpret_cast< void ** >( &pServerFactory ) ) ) )
  180. {
  181. pServerFactory->SetEnvironment( m_lnMaxPlayerCount, 10, 1000, 1024 * 8 );
  182. /*
  183.  * For player
  184.  */
  185. pServerFactory->CreateServerInterface( IID_IIOCPServer, reinterpret_cast< void ** >( &m_pPlayerServer ) );
  186. /*
  187.  * For gameserver
  188.  */
  189. pServerFactory->CreateServerInterface( IID_IIOCPServer, reinterpret_cast< void ** >( &m_pGameSvrServer ) );
  190. pServerFactory->Release();
  191. }
  192. if ( m_pGameSvrServer )
  193. {
  194. m_pGameSvrServer->Startup();
  195. m_pGameSvrServer->RegisterMsgFilter( reinterpret_cast< void * >( this ), GameSvrEventNotify );
  196. if ( SUCCEEDED( m_pGameSvrServer->OpenService( INADDR_ANY, m_theNetworkConfig.GetGameSvrOpenPort() ) ) )
  197. {
  198. bGameSvrServerSucceed = true;
  199. }
  200. }
  201. if ( m_pPlayerServer )
  202. {
  203. m_pPlayerServer->Startup();
  204. m_pPlayerServer->RegisterMsgFilter( reinterpret_cast< void * >( this ), PlayerEventNotify );
  205. if ( SUCCEEDED( m_pPlayerServer->OpenService( INADDR_ANY, m_theNetworkConfig.GetClientOpenPort() ) ) )
  206. {
  207. bPlayerServerSucceed = true;
  208. }
  209. }
  210. if ( bPlayerServerSucceed && 
  211. bDBRoleServerSucceed && 
  212. bGameSvrServerSucceed )
  213. {
  214. CCriticalSection::Owner lock( m_csPlayerAction );
  215. /*
  216.  * Initialize all of player
  217.  */
  218. for ( size_t index = 0; index < m_lnMaxPlayerCount; index ++ )
  219. {
  220. IClient *pCloneAcc = NULL;
  221. m_pAccSvrClient->QueryInterface( IID_IESClient, reinterpret_cast< void ** >( &pCloneAcc ) );
  222. IServer *pClonePlayer = NULL;
  223. m_pPlayerServer->QueryInterface( IID_IIOCPServer, reinterpret_cast< void ** >( &pClonePlayer ) );
  224. IClient *pCloneDBRole = NULL;
  225. m_pDBRoleClient->QueryInterface( IID_IESClient, reinterpret_cast< void ** >( &pCloneDBRole ) );
  226. ASSERT( pCloneAcc && pClonePlayer );
  227. /*
  228.  * Create a player node and add it into list
  229.  */
  230. IPlayer *pPlayer = new CGamePlayer( pCloneAcc, pClonePlayer, pCloneDBRole, index );
  231. ASSERT( pPlayer );
  232. m_thePlayers[index] = pPlayer;
  233. }
  234. m_hStartupWoringThreadEvent.Set();
  235. m_hStartupHelperThreadEvent.Set();
  236. }
  237. return ( bPlayerServerSucceed && bDBRoleServerSucceed && bGameSvrServerSucceed );
  238. }
  239. void CPlayerManager::CleanNetwork()
  240. {
  241. /*
  242.  * Disconnect network and relase this resource
  243.  */
  244. if ( m_pPlayerServer )
  245. {
  246. m_pPlayerServer->CloseService();
  247. m_pPlayerServer->Cleanup();
  248. SAFE_RELEASE( m_pPlayerServer );
  249. }
  250. if ( m_pDBRoleClient )
  251. {
  252. m_pDBRoleClient->Cleanup();
  253. SAFE_RELEASE( m_pDBRoleClient );
  254. }
  255. if ( m_pGameSvrServer )
  256. {
  257. m_pGameSvrServer->CloseService();
  258. m_pGameSvrServer->Cleanup();
  259. SAFE_RELEASE( m_pGameSvrServer );
  260. }
  261. /*
  262.  * Clear client node
  263.  */
  264. {
  265. CCriticalSection::Owner locker( m_csUsedClientList );
  266. m_usedClientNode.erase( m_usedClientNode.begin(), m_usedClientNode.end() );
  267. }
  268. /*
  269.  * Clear player info
  270.  */
  271. {
  272. CCriticalSection::Owner locker( m_csPlayerAction );
  273. PLAYER_MAP::iterator it;
  274. for ( it = m_thePlayers.begin(); it != m_thePlayers.end(); it ++ )
  275. {
  276. IPlayer *pPlayer = ( IPlayer * )( ( *it ).second );
  277. ASSERT( pPlayer );
  278. pPlayer->Destroy( NULL );
  279. SAFE_DELETE( pPlayer );
  280. }
  281. m_thePlayers.erase( m_thePlayers.begin(), m_thePlayers.end() );
  282. }
  283. /*
  284.  * MAPID_MAPTO_GAMESVR
  285.  */
  286. {
  287. CCriticalSection::Owner locker( m_csMI2GSAction );
  288. m_theMapIDMapToGameSvr.erase( m_theMapIDMapToGameSvr.begin(), 
  289. m_theMapIDMapToGameSvr.end() );
  290. }
  291. /*
  292.  * PLAYERID_MAPTO_GAMESVR
  293.  */
  294. {
  295. CCriticalSection::Owner locker( m_csPI2GSAction );
  296. m_thePlayerIDMapToGameSvr.erase( m_thePlayerIDMapToGameSvr.begin(), 
  297. m_thePlayerIDMapToGameSvr.end() );
  298. }
  299. }
  300. DWORD WINAPI CPlayerManager::WorkingThreadFunction( void *pV )
  301. {
  302. CPlayerManager *pThis = reinterpret_cast< CPlayerManager * >( pV );
  303. ASSERT( pThis );
  304. try
  305. {
  306. pThis->Working();
  307. }
  308. catch(...)
  309. {
  310. ::MessageBox( NULL, "Startup a working thread is failed!", "CPlayerManager class", MB_OK );
  311. }
  312. return 0;
  313. }
  314. int CPlayerManager::Working()
  315. {
  316. m_hStartupWoringThreadEvent.Wait();
  317. while ( !m_hQuitEvent.Wait( 0 ) )
  318. {
  319. CCriticalSection::Owner locker( m_csUsedClientList );
  320. LIST::iterator it;
  321. for ( it = m_usedClientNode.begin(); it != m_usedClientNode.end(); it ++ )
  322. {
  323. size_t index = *it;
  324. /*
  325.  * Get data from player
  326.  */
  327. size_t datalength = 0;
  328. const void *pData = m_pPlayerServer->GetPackFromClient( index, datalength );
  329. while ( pData && datalength )
  330. {
  331. AnalyzePlayerRequire( index, pData, datalength );
  332. pData = m_pPlayerServer->GetPackFromClient( index, datalength );
  333. }
  334. /*
  335.  * Execute work
  336.  */
  337. IPlayer *pPlayer = m_thePlayers[index];
  338. ASSERT( pPlayer );
  339. pPlayer->Run();
  340. }
  341. ::Sleep( 1 );
  342. }
  343. return 0;
  344. }
  345. DWORD WINAPI CPlayerManager::HelperThreadFunction( void *pV )
  346. {
  347. CPlayerManager *pThis = reinterpret_cast< CPlayerManager * >( pV );
  348. ASSERT( pThis );
  349. try
  350. {
  351. pThis->Helper();
  352. }
  353. catch(...)
  354. {
  355. ::MessageBox( NULL, "Startup a helper thread is failed!", "CPlayerManager class", MB_OK );
  356. }
  357. return 0;
  358. }
  359. int CPlayerManager::Helper()
  360. {
  361. m_hStartupHelperThreadEvent.Wait();
  362. while ( !m_hQuitEvent.Wait( 0 ) )
  363. {
  364. /*
  365.  * Get data from role-database
  366.  */
  367. size_t dataLength = 0;
  368. const void *pData = m_pAccSvrClient->GetPackFromServer( dataLength );
  369. while( pData && dataLength )
  370. {
  371. ASSERT( CPackager::Peek( pData ) > s2c_micropackbegin );
  372. KAccountHead *pAUR = ( KAccountHead * )( ( ( char * )pData ) + 1 );
  373. UINT uID = pAUR->Operate;
  374. if ( uID < m_lnMaxPlayerCount )
  375. {
  376. IPlayer *pPlayer = m_thePlayers[uID];
  377. ASSERT( pPlayer );
  378. pPlayer->AppendData( CGamePlayer::enumOwnerAccSvr, pData, dataLength );
  379. }
  380. pData = m_pAccSvrClient->GetPackFromServer( dataLength );
  381. }
  382. /*
  383.  * Get data from role-database
  384.  */
  385. dataLength = 0;
  386. pData = m_pDBRoleClient->GetPackFromServer( dataLength );
  387. while( pData && dataLength )
  388. {
  389. BYTE cProtocol = CPackager::Peek( pData );
  390. UINT uID = ( UINT )( -1 );
  391. if ( cProtocol < s2c_micropackbegin )
  392. {
  393. uID = *( const unsigned long * )( ( const char * )pData + 2 );
  394. }
  395. else // cProtocol > s2c_micropackbegin
  396. {
  397. TProcessData *pPD = ( TProcessData * )( pData );
  398. uID = pPD->ulIdentity;
  399. }
  400. if ( uID < m_lnMaxPlayerCount )
  401. {
  402. IPlayer *pPlayer = m_thePlayers[uID];
  403. ASSERT( pPlayer );
  404. pPlayer->AppendData( CGamePlayer::enumOwnerRoleSvr, pData, dataLength );
  405. }
  406. pData = m_pDBRoleClient->GetPackFromServer( dataLength );
  407. }
  408. ::Sleep( 1 );
  409. }
  410. return 0;
  411. }
  412. bool CPlayerManager::AnalyzePlayerRequire( size_t index, const void *pData, size_t datalength )
  413. {
  414. ASSERT( pData && datalength );
  415. BYTE cProtocol = *( const BYTE * )pData;
  416. switch ( cProtocol )
  417. {
  418. case c2s_login:
  419. {
  420. const BYTE *pBuffer = ( const BYTE * )pData + 1;
  421. KLoginAccountInfo *pLAI = ( KLoginAccountInfo * )pBuffer;
  422. ASSERT( pLAI );
  423. if ( m_thePlayers[index]->Create( pLAI->Account, pLAI->Password ) )
  424. {
  425. m_thePlayers[index]->DispatchTask( CGamePlayer::enumLogin );
  426. }
  427. }
  428. break;
  429. case c2s_dbplayerselect:
  430. {
  431. if ( index < m_lnMaxPlayerCount )
  432. {
  433. IPlayer *pPlayer = m_thePlayers[index];
  434. ASSERT( pPlayer );
  435. pPlayer->AppendData( CGamePlayer::enumOwnerPlayer, pData, datalength );
  436. }
  437. }
  438. break;
  439. default:
  440. break;
  441. }
  442. return true;
  443. }