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

模拟服务器

开发平台:

C/C++

  1. #include "Stdafx.h"
  2. #include "GameServer.h"
  3. #include "IPlayer.h"
  4. #include "GamePlayer.h"
  5. #include "msg_define.h"
  6. #include <process.h>
  7. #include "AccountLoginDef.h"
  8. #include "Macro.h"
  9. #include "SmartClient.h"
  10. using OnlineGameLib::Win32::CCriticalSection;
  11. using OnlineGameLib::Win32::CEvent;
  12. using OnlineGameLib::Win32::CBuffer;
  13. using OnlineGameLib::Win32::CPackager;
  14. using OnlineGameLib::Win32::ToString;
  15. using OnlineGameLib::Win32::_tstring;
  16. CBuffer::Allocator CGameServer::m_theGlobalAllocator( 1024 * 96, 200 );
  17. CCriticalSection CGameServer::m_csMapIDAction;
  18. CGameServer::stdMapIDConvert CGameServer::m_theMapIDConvert;
  19. CEvent CGameServer::m_shQuitEvent( NULL, true, false, NULL/*"GS_QUIT_EVENT"*/ );
  20. CEvent CGameServer::m_shStartupManagerThreadEvent( NULL, false, false, NULL/*"GS_MANAGER_EVENT"*/ );
  21. HANDLE CGameServer::m_shManagerThread = NULL;
  22. CGameServer::stdGameSvr CGameServer::m_theGameServers;
  23. CCriticalSection CGameServer::m_csGameSvrAction;
  24. /*
  25.  * CGamePlayer Global Function
  26.  */
  27. bool CGameServer::SetupGlobalAllocator( size_t bufferSize, size_t maxFreeBuffers )
  28. {
  29. return CGameServer::m_theGlobalAllocator.ReSet( bufferSize, maxFreeBuffers );
  30. }
  31. LONG CGameServer::m_slnIdentityCounts = 0L;
  32. /*
  33.  * A generator of guid
  34.  */
  35. static void GenGuid( GUID *guid )
  36. {
  37. ASSERT( guid );
  38. static char szData[9] = { 0 };
  39. static DWORD dwBase = 0;
  40. if ( FAILED( ::CoCreateGuid( guid ) ) )
  41. {
  42. if ( ( dwBase >> 31 ) & 0x1 )
  43. {
  44. dwBase = 0;
  45. }
  46. /*
  47.  * Make a 128 bits cipher
  48.  */
  49. guid->Data1 = dwBase++;
  50. guid->Data2 = ( DWORD )rand() & 0xFFFF;
  51. guid->Data3 = ( ( DWORD )rand() >> 16 ) & 0xFFFF ;
  52. sprintf( ( char * )szData, "%d%d", ( ( DWORD )rand() + dwBase++ ), ( DWORD )rand() );
  53. memcpy( guid->Data4, szData, 8 );
  54. }
  55. }
  56. /*
  57.  * class CGameServer
  58.  */
  59. CGameServer::CGameServer( IServer *pGameSvrServer,
  60.  IClient *pAccountClient,
  61.  UINT nIdentityID /* = -1 */ )
  62. : m_lnIdentityID( nIdentityID )
  63. , m_pGameSvrServer( pGameSvrServer )
  64. // , m_pAccountClient( pAccountClient )
  65. , m_nServerIP_Internet( 0 )
  66. , m_nServerIP_Intraner( 0 )
  67. , m_nServerPort( 0 )
  68. , m_dwCapability( -1 )
  69. {
  70. LONG lnID = ::InterlockedExchangeAdd( &m_slnIdentityCounts, 1 );
  71. m_lnIdentityID = ( ( UINT )( -1 ) == m_lnIdentityID ) ? lnID : m_lnIdentityID;
  72. }
  73. CGameServer::~CGameServer()
  74. {
  75. // SAFE_RELEASE( m_pGameSvrServer );
  76. // SAFE_RELEASE( m_pAccountClient );
  77. m_thePackager.Empty();
  78. ::InterlockedExchangeAdd( &m_slnIdentityCounts, -1 );
  79. }
  80. bool CGameServer::Create()
  81. {
  82. ZeroMemory( m_theProcessProtocolFun, sizeof( m_theProcessProtocolFun ) );
  83. m_theProcessProtocolFun[c2s_registeraccount]  = _RegisterAccount;
  84. m_theProcessProtocolFun[c2s_entergame] = _NotifyEnterGame;
  85. m_theProcessProtocolFun[c2s_leavegame] = _NotifyLeaveGame;
  86. m_theProcessProtocolFun[c2s_permitplayerlogin] = _NotifyPlayerLogin;
  87. m_theProcessProtocolFun[c2s_updatemapinfo] = _UpdateMapID;
  88. m_theProcessProtocolFun[c2s_updategameserverinfo] = _UpdateGameSvrInfo;
  89. m_theProcessProtocolFun[c2s_requestsvrip] = _RequestSvrIP;
  90. /*
  91.  * Query gameserver information
  92.  */
  93. _QueryGameSvrInfo();
  94. return _QueryMapID();
  95. }
  96. bool CGameServer::Destroy()
  97. {
  98. {
  99. CCriticalSection::Owner lock( m_csAITS );
  100. stdAccountAttachIn::iterator it;
  101. for ( it = m_theAccountInThisServer.begin(); it != m_theAccountInThisServer.end(); it ++ )
  102. {
  103. string sAccountName = ( *it ).first;
  104. FreezeMoney( sAccountName.c_str(), 0);
  105. }
  106. }
  107. m_dwCapability = 0;
  108. m_nServerPort = 0;
  109. m_nServerIP_Intraner = 0;
  110. m_nServerIP_Internet = 0;
  111. m_sServerIPAddr_Internet = "";
  112. m_sServerIPAddr_Intraner = "";
  113. {
  114. CCriticalSection::Owner locker( m_csMapIDAction );
  115. stdMapIDConvert::iterator itM2C;
  116. for ( itM2C = m_theMapIDConvert.begin(); itM2C != m_theMapIDConvert.end(); itM2C ++ )
  117. {
  118. stdServerList &sl = ( *itM2C ).second;
  119. if ( !sl.empty() )
  120. {
  121. sl.remove( this );
  122. }
  123. }
  124. }
  125. return true;
  126. }
  127. void __stdcall CGameServer::GameSvrEventNotify( LPVOID lpParam,
  128. const unsigned long &ulnID,
  129. const unsigned long &ulnEventType )
  130. {
  131. CGameServer::LPNI pNI = reinterpret_cast< CGameServer::NI * >( lpParam );
  132. ASSERT( pNI );
  133. CCriticalSection::Owner locker( CGameServer::m_csGameSvrAction );
  134. switch ( ulnEventType )
  135. {
  136. case enumClientConnectCreate:
  137. {
  138. IGServer *pGServer = new CGameServer( pNI->pServer, pNI->pClient, ulnID );
  139. ASSERT( pGServer );
  140. pGServer->Create();
  141. std::pair< CGameServer::stdGameSvr::iterator, bool > result = 
  142. CGameServer::m_theGameServers.insert( CGameServer::stdGameSvr::value_type( ulnID, pGServer ) );
  143. if ( result.second && pNI->hwndContainer && ::IsWindow( pNI->hwndContainer ) )
  144. {
  145. ::PostMessage( pNI->hwndContainer, WM_GAMESERVER_EXCHANGE, ADD_GAMESERVER_ACTION, ulnID );
  146. }
  147. }
  148. break;
  149. case enumClientConnectClose:
  150. {
  151. stdGameSvr::iterator it;
  152. if ( CGameServer::m_theGameServers.end() != 
  153. ( it = CGameServer::m_theGameServers.find( ulnID ) ) )
  154. {
  155. if ( pNI->hwndContainer && ::IsWindow( pNI->hwndContainer ) )
  156. {
  157. ::PostMessage( pNI->hwndContainer, WM_GAMESERVER_EXCHANGE, DEL_GAMESERVER_ACTION, ulnID );
  158. }
  159. IGServer *pGServer = ( *it ).second;
  160. ASSERT( pGServer );
  161. CGameServer::m_theGameServers.erase( it );
  162. pGServer->Destroy();
  163. SAFE_DELETE( pGServer );
  164. }
  165. }
  166. break;
  167. }
  168. }
  169. bool CGameServer::Begin( IServer *pGameSvrServer )
  170. {
  171. /*
  172.  * Startup a manager thread
  173.  */
  174. DWORD dwThreadID = 0;
  175. m_shManagerThread = ::CreateThread( NULL, 
  176. 0, 
  177. ManagerThreadFunction, 
  178. ( void * )pGameSvrServer,
  179. 0, 
  180. &dwThreadID );
  181. if ( m_shManagerThread == INVALID_HANDLE_VALUE )
  182. {
  183. return false;
  184. }
  185. m_shStartupManagerThreadEvent.Set();
  186. return true;
  187. }
  188. void CGameServer::End()
  189. {
  190. m_shQuitEvent.Set();
  191. m_shStartupManagerThreadEvent.Set();
  192. if ( WAIT_TIMEOUT == ::WaitForSingleObject( m_shManagerThread, 5000 ) )
  193. {
  194. ::TerminateThread( m_shManagerThread, 0 );
  195. }
  196. SAFE_CLOSEHANDLE( m_shManagerThread );
  197. /*
  198.  * MapID & GameServer
  199.  */
  200. {
  201. CCriticalSection::Owner locker( m_csMapIDAction );
  202. stdMapIDConvert::iterator itM2C;
  203. for ( itM2C = m_theMapIDConvert.begin(); itM2C != m_theMapIDConvert.end(); itM2C ++ )
  204. {
  205. stdServerList &SL = ( *itM2C ).second;
  206. SL.clear();
  207. }
  208. m_theMapIDConvert.erase( m_theMapIDConvert.begin(), m_theMapIDConvert.end() );
  209. }
  210. /*
  211.  * Clear gameserver information
  212.  */
  213. {
  214. CCriticalSection::Owner locker( m_csGameSvrAction );
  215. m_theGameServers.erase( m_theGameServers.begin(), m_theGameServers.end() );
  216. }
  217. }
  218. DWORD WINAPI CGameServer::ManagerThreadFunction( void *pParam )
  219. {
  220. IServer *pGameSvrServer = ( IServer * )pParam;
  221. ASSERT( pGameSvrServer );
  222. m_shStartupManagerThreadEvent.Wait();
  223. stdGameSvr::iterator it;
  224. while ( !m_shQuitEvent.Wait( 0 ) )
  225. {
  226. CCriticalSection::Owner locker( CGameServer::m_csGameSvrAction );
  227. for ( it = CGameServer::m_theGameServers.begin(); 
  228. it != CGameServer::m_theGameServers.end(); 
  229. it ++ )
  230. {
  231. UINT nlnID = ( *it ).first;
  232. size_t datalength = 0;
  233. const void *pData = pGameSvrServer->GetPackFromClient( nlnID, datalength );
  234. if ( 0 == datalength || NULL == pData )
  235. {
  236. continue;
  237. }
  238. IGServer *pGServer = ( *it ).second;
  239. if ( pGServer )
  240. {
  241. pGServer->AnalyzeRequire( pData, datalength );
  242. }
  243. }
  244. ::Sleep( 1 );
  245. }
  246. SAFE_RELEASE( pGameSvrServer );
  247. return 0;
  248. }
  249. bool CGameServer::AnalyzeRequire( const void *pData, size_t datalength )
  250. {
  251. bool ok = true;
  252. BYTE cProtocol = CPackager::Peek( pData );
  253. if ( cProtocol < g_nGlobalProtocolType )
  254. {
  255. return LargePackProcess( cProtocol, pData, datalength );
  256. }
  257. else if ( cProtocol > g_nGlobalProtocolType )
  258. {
  259. return SmallPackProcess( cProtocol, pData, datalength );
  260. }
  261. return false;
  262. }
  263. bool CGameServer::LargePackProcess( BYTE cProtocol, const void *pData, size_t datalength )
  264. {
  265. return true;
  266. }
  267. bool CGameServer::SmallPackProcess( BYTE cProtocol, const void *pData, size_t datalength )
  268. {
  269. if ( cProtocol < c2s_end && m_theProcessProtocolFun[cProtocol] )
  270. {
  271. return ( this->*m_theProcessProtocolFun[cProtocol] )( ( const void * )pData, datalength );
  272. }
  273. return false;
  274. }
  275. bool CGameServer::DispatchTask( UINT nTask, const void *pData, size_t datalength, WORD nData )
  276. {
  277. bool ok = true;
  278. switch ( nTask )
  279. {
  280. case enumSyncRoleInfo:
  281. ok = _SyncRoleInfo( pData, datalength, nData);
  282. break;
  283. case enumPlayerLogicLogout:
  284. ok = _PlayerLogicLogout( pData, datalength );
  285. break;
  286. case enumTaskProtocol:
  287. default:
  288. break;
  289. }
  290. return true;
  291. }
  292. bool CGameServer::_QueryMapID()
  293. {
  294. tagQueryMapInfo qmi;
  295. qmi.cProtocol = s2c_querymapinfo;
  296. m_pGameSvrServer->SendData( m_lnIdentityID, ( const void * )&qmi, sizeof( tagQueryMapInfo ) );
  297. return true;
  298. }
  299. bool CGameServer::_QueryGameSvrInfo()
  300. {
  301. tagQueryGameSvrInfo qgsi;
  302. qgsi.cProtocol = s2c_querygameserverinfo;
  303. m_pGameSvrServer->SendData( m_lnIdentityID, ( const void * )&qgsi, sizeof( tagQueryGameSvrInfo ) );
  304. return true;
  305. }
  306. bool CGameServer::_UpdateMapID( const void *pData, size_t datalength )
  307. {
  308. tagUpdateMapID *pUMI = ( tagUpdateMapID * )pData;
  309. int  nMapCount = pUMI->cMapCount;
  310. BYTE *pMapID = pUMI->szMapID;
  311. while ( --nMapCount >= 0 )
  312. {
  313. RegisterServer( pMapID[nMapCount], ( IGServer * )this );
  314. }
  315. return true;
  316. }
  317. bool CGameServer::_UpdateGameSvrInfo( const void *pData, size_t datalength )
  318. {
  319. ASSERT( sizeof( tagGameSvrInfo ) == datalength );
  320. tagGameSvrInfo *pGSI = ( tagGameSvrInfo * )pData;
  321. m_dwCapability = pGSI->wCapability;
  322. m_nServerPort = pGSI->nPort;
  323. m_nServerIP_Internet = pGSI->nIPAddr_Internet;
  324. m_nServerIP_Intraner = pGSI->nIPAddr_Intraner;
  325. m_sServerIPAddr_Intraner = OnlineGameLib::Win32::net_ntoa( m_nServerIP_Intraner );
  326. m_sServerIPAddr_Internet = OnlineGameLib::Win32::net_ntoa( m_nServerIP_Internet );
  327. return true;
  328. }
  329. bool CGameServer::_RequestSvrIP( const void *pData, size_t datalength )
  330. {
  331. tagRequestSvrIp *pRSI = ( tagRequestSvrIp * )pData;
  332. ASSERT( sizeof( tagRequestSvrIp ) == datalength );
  333. DWORD dwIP = 0;
  334. IGServer *pGServer = CGameServer::QueryServer( pRSI->dwMapID );
  335. if ( pGServer )
  336. {
  337. dwIP = pGServer->GetIP( pRSI->cIPType );
  338. }
  339. tagNotifySvrIp nsi;
  340. nsi.cProtocol = s2c_notifysvrip;
  341. nsi.pckgID = pRSI->pckgID;
  342. nsi.dwMapID = pRSI->dwMapID;
  343. nsi.cIPType = pRSI->cIPType;
  344. nsi.dwSvrIP = dwIP;
  345. m_pGameSvrServer->SendData( m_lnIdentityID, ( const void * )&nsi, sizeof( tagNotifySvrIp ) );
  346. return true;
  347. }
  348. bool CGameServer::_NotifyPlayerLogin( const void *pData, size_t datalength )
  349. {
  350. tagPermitPlayerLogin *pPPL = ( tagPermitPlayerLogin * )pData;
  351. ASSERT( sizeof( tagPermitPlayerLogin ) == datalength );
  352. bool ok = false;
  353. IPlayer *pPlayer = CGamePlayer::Get( ( const char * )( pPPL->szRoleName ) );
  354. if ( pPlayer )
  355. {
  356. tagNotifyPlayerLogin npl;
  357. npl.cProtocol = s2c_notifyplayerlogin;
  358. int nMinLen = strlen( ( const char * )pPPL->szRoleName );
  359. nMinLen = nMinLen > sizeof( npl.szRoleName ) ? sizeof( npl.szRoleName ) : nMinLen;
  360. memcpy( ( char * )npl.szRoleName, ( const char * )pPPL->szRoleName, nMinLen );
  361. npl.szRoleName[nMinLen] = '';
  362. memcpy( &( npl.guid ), &( pPPL->guid ), sizeof( GUID ) );
  363. npl.bPermit = pPPL->bPermit; 
  364. npl.nIPAddr = m_nServerIP_Internet;
  365. npl.nPort = m_nServerPort;
  366. ok = pPlayer->AppendData( CGamePlayer::enumOwnerPlayer, ( const void * )&npl, sizeof( tagNotifyPlayerLogin ) );
  367. }
  368. return ok;
  369. }
  370. bool CGameServer::_RegisterAccount( const void *pData, size_t datalength )
  371. {
  372. ASSERT( pData && datalength );
  373. tagRegisterAccount *pRA = ( tagRegisterAccount * )pData;
  374. if ( sizeof( tagRegisterAccount ) != datalength )
  375. {
  376. return false;
  377. }
  378. AttatchAccountToGameServer( ( const char * )pRA->szAccountName );
  379. return true;
  380. }
  381. bool CGameServer::_NotifyEnterGame( const void *pData, size_t datalength )
  382. {
  383. ASSERT( pData && datalength );
  384. tagEnterGame *pEG = ( tagEnterGame * )pData;
  385. if ( sizeof( tagEnterGame ) != datalength )
  386. {
  387. return false;
  388. }
  389. BYTE *pAccountName = ( BYTE * )( pEG->szAccountName );
  390. PushAccount( ( const char * )pAccountName );
  391. return true;
  392. }
  393. bool CGameServer::_NotifyLeaveGame( const void *pData, size_t datalength )
  394. {
  395. ASSERT( pData && datalength );
  396. tagLeaveGame *pLG = ( tagLeaveGame * )pData;
  397. ASSERT( sizeof( tagLeaveGame ) == datalength );
  398. BYTE *pAccountName = ( BYTE * )( pLG->szAccountName );
  399. return PopAccount( ( const char * )pAccountName, ( pLG->cCmdType != HOLDACC_LEAVEGAME ), pLG->nExtPoint);
  400. }
  401. bool CGameServer::PushAccount( const char *pAccountName )
  402. {
  403. ASSERT( pAccountName );
  404. return ConsumeMoney( pAccountName );
  405. }
  406. bool CGameServer::PopAccount( const char *pAccountName, bool bUnlockAccount, WORD nExtPoint )
  407. {
  408. ASSERT( pAccountName );
  409. if ( HaveAccountInGameServer( pAccountName ) )
  410. {
  411. if ( bUnlockAccount )
  412. {
  413. FreezeMoney( pAccountName, nExtPoint);
  414. }
  415. DetachAccountFromGameServer( pAccountName );
  416. return true;
  417. }
  418. return false;
  419. }
  420. bool CGameServer::Attach( const char *pAccountName )
  421. {
  422. return AttatchAccountToGameServer( pAccountName );
  423. }
  424. bool CGameServer::AttatchAccountToGameServer( const char *pAccountName )
  425. {
  426. if ( !pAccountName || !pAccountName[0] )
  427. {
  428. return false;
  429. }
  430. if ( _NAME_LEN > strlen( pAccountName ) )
  431. {
  432. CCriticalSection::Owner lock( m_csAITS );
  433. std::pair< stdAccountAttachIn::iterator, bool > result = 
  434. m_theAccountInThisServer.insert( stdAccountAttachIn::value_type( pAccountName, 
  435. reinterpret_cast< void * >( this ) ) );
  436. return result.second;
  437. }
  438. return false;
  439. }
  440. bool CGameServer::HaveAccountInGameServer( const char *pAccountName )
  441. {
  442. if ( !pAccountName || !pAccountName[0] )
  443. {
  444. return false;
  445. }
  446. if ( _NAME_LEN > strlen( pAccountName ) )
  447. {
  448. CCriticalSection::Owner lock( m_csAITS );
  449. stdAccountAttachIn::iterator it;
  450. if ( m_theAccountInThisServer.end() != 
  451. ( it = m_theAccountInThisServer.find( pAccountName ) ) )
  452. {
  453. return true;
  454. }
  455. }
  456. return false;
  457. }
  458. bool CGameServer::DetachAccountFromGameServer( const char *pAccountName )
  459. {
  460. if ( !pAccountName || !pAccountName[0] )
  461. {
  462. return false;
  463. }
  464. if ( _NAME_LEN > strlen( pAccountName ) )
  465. {
  466. CCriticalSection::Owner lock( m_csAITS );
  467. stdAccountAttachIn::iterator it;
  468. if ( m_theAccountInThisServer.end() != 
  469. ( it = m_theAccountInThisServer.find( pAccountName ) ) )
  470. {
  471. CGameServer *pThis = reinterpret_cast< CGameServer * >( ( *it ).second );
  472. ASSERT( pThis && pThis == this );
  473. m_theAccountInThisServer.erase( it );
  474. return true;
  475. }
  476. }
  477. return false;
  478. }
  479. bool CGameServer::ConsumeMoney( const char *pAccountName )
  480. {
  481. if ( !pAccountName || !pAccountName[0] )
  482. {
  483. return false;
  484. }
  485. if ( _NAME_LEN <= strlen( pAccountName ) )
  486. {
  487. return false;
  488. }
  489. CBuffer *pBuffer = m_theGlobalAllocator.Allocate();
  490. BYTE *pContext = const_cast< BYTE * >( pBuffer->GetBuffer() );
  491. const size_t len = sizeof( KAccountUser ) + 1;
  492. KAccountUser user;
  493. user.Size = sizeof( KAccountUser );
  494. user.Type = AccountUser;
  495. user.Version = ACCOUNT_CURRENT_VERSION;
  496. size_t length = strlen( pAccountName );
  497. length = ( length > LOGIN_USER_ACCOUNT_MAX_LEN ) ? LOGIN_USER_ACCOUNT_MAX_LEN : length;
  498. memcpy( user.Account, pAccountName, length );
  499. user.Account[length] = '';
  500. *pContext = c2s_gamelogin;
  501. memcpy( pContext + 1, &user, sizeof( KAccountUser ) );
  502. g_theSmartClient.Send( pContext, len );
  503. //m_pAccountClient->SendPackToServer( pContext, len );
  504. SAFE_RELEASE( pBuffer );
  505. return true;
  506. }
  507. bool CGameServer::FreezeMoney( const char *pAccountName, WORD nExtPoint )
  508. {
  509. if ( !pAccountName || !pAccountName[0] )
  510. {
  511. return false;
  512. }
  513. if ( _NAME_LEN <= strlen( pAccountName ) )
  514. {
  515. return false;
  516. }
  517. CBuffer *pBuffer = m_theGlobalAllocator.Allocate();
  518. BYTE *pData = const_cast< BYTE * >( pBuffer->GetBuffer() );
  519. const size_t datalength = sizeof( KAccountUserLogout ) + 1;
  520. KAccountUserLogout user;
  521. user.Size = sizeof( KAccountUserLogout );
  522. user.Type = AccountUserLogout;
  523. user.Version = ACCOUNT_CURRENT_VERSION;
  524. user.nExtPoint = nExtPoint;
  525. size_t length = strlen( pAccountName );
  526. length = ( length > LOGIN_USER_ACCOUNT_MAX_LEN ) ? LOGIN_USER_ACCOUNT_MAX_LEN : length;
  527. memcpy( user.Account, pAccountName, length );
  528. user.Account[length] = '';
  529. *pData = c2s_accountlogout;
  530. memcpy( pData + 1, &user, sizeof( KAccountUserLogout ) );
  531. g_theSmartClient.Send( ( const void * )pData, datalength );
  532. //m_pAccountClient->SendPackToServer( ( const void * )pData, datalength );
  533. SAFE_RELEASE( pBuffer );
  534. return true;
  535. }
  536. bool CGameServer::_PlayerLogicLogout( const void *pData, size_t datalength )
  537. {
  538. tagLogicLogout ll;
  539. if ( sizeof( ll.szRoleName ) < datalength )
  540. {
  541. return false;
  542. }
  543. ll.cProtocol = s2c_logiclogout;
  544. memcpy( ll.szRoleName, pData, datalength );
  545. m_pGameSvrServer->SendData( m_lnIdentityID, ( const void * )&ll, sizeof( tagLogicLogout ) );
  546. return true;
  547. }
  548. bool CGameServer::_SyncRoleInfo( const void *pData, size_t datalength, WORD nData )
  549. {
  550. /*
  551.  * Send role data to the game server
  552.  */
  553. tagGuidableInfo ginfo;
  554. ginfo.cProtocol = s2c_syncgamesvr_roleinfo_cipher;
  555. GenGuid( &( ginfo.guid ) );
  556. ginfo.nExtPoint = nData;
  557. ginfo.nChangePoint = 0;
  558. ginfo.datalength = datalength;
  559. m_thePackager.AddData( s2c_syncgamesvr_roleinfo_cipher, ( const char * )&ginfo, sizeof( tagGuidableInfo ) );
  560. m_thePackager.AddData( s2c_syncgamesvr_roleinfo_cipher, ( const char * )pData, datalength );
  561. /*
  562.  * Begin to split this buffer
  563.  */
  564. CBuffer *pBuffer = m_thePackager.GetHeadPack( s2c_syncgamesvr_roleinfo_cipher );
  565. while ( pBuffer )
  566. {
  567. m_pGameSvrServer->SendData( m_lnIdentityID, pBuffer->GetBuffer(), pBuffer->GetUsed() );
  568. /*
  569.  * Your must relase this buffer
  570.  */
  571. SAFE_RELEASE( pBuffer );
  572. /*
  573.  * Get next package
  574.  */
  575. pBuffer = m_thePackager.GetNextPack( s2c_syncgamesvr_roleinfo_cipher );
  576. }
  577. SAFE_RELEASE( pBuffer );
  578. m_thePackager.DelData( s2c_syncgamesvr_roleinfo_cipher );
  579. return true;
  580. }
  581. bool CGameServer::RegisterServer( UINT nID, IGServer *pGServer )
  582. {
  583. ASSERT( pGServer );
  584. CCriticalSection::Owner locker( m_csMapIDAction );
  585. stdMapIDConvert::iterator it;
  586. /*
  587.  * Append this sever information into table
  588.  */
  589. if ( m_theMapIDConvert.end() != ( it = m_theMapIDConvert.find( nID ) ) )
  590. {
  591. stdServerList& sl = ( *it ).second;
  592. sl.push_back( pGServer );
  593. }
  594. else
  595. {
  596. /*
  597.  * Insert this server information into table
  598.  */
  599. stdServerList sl;
  600. sl.push_back( pGServer );
  601. std::pair< stdMapIDConvert::iterator, bool > result =
  602. m_theMapIDConvert.insert( stdMapIDConvert::value_type( nID, sl ) );
  603. return result.second;
  604. }
  605. return true;
  606. }
  607. IGServer *CGameServer::QueryServer( UINT nMapID )
  608. {
  609. CCriticalSection::Owner locker( m_csMapIDAction );
  610. stdMapIDConvert::iterator it;
  611. if ( m_theMapIDConvert.end() != ( it = m_theMapIDConvert.find( nMapID ) ) )
  612. {
  613. stdServerList& sl = ( *it ).second;
  614. /*
  615.  * TODO : Don't get the server when it can't carry anyone
  616.  */
  617. if ( !sl.empty() )
  618. {
  619. IGServer *pGServer = NULL;
  620. stdServerList::iterator it;
  621. for ( it = sl.begin(); it != sl.end(); it ++ )
  622. {
  623. pGServer = ( IGServer * )( *it );
  624. ASSERT( pGServer );
  625. if ( NULL == pGServer )
  626. {
  627. continue;
  628. }
  629. if ( pGServer->GetContent() < pGServer->GetCapability() )
  630. {
  631. return pGServer;
  632. }
  633. }
  634. }
  635. }
  636. return NULL;
  637. }
  638. IGServer *CGameServer::GetServer( size_t nID )
  639. {
  640. CCriticalSection::Owner locker( CGameServer::m_csGameSvrAction );
  641. stdGameSvr::iterator it;
  642. if ( CGameServer::m_theGameServers.end() != 
  643. ( it = CGameServer::m_theGameServers.find( nID ) ) )
  644. {
  645. IGServer *pGServer = ( *it ).second;
  646. ASSERT( pGServer );
  647. return pGServer;
  648. }
  649. return NULL;
  650. }
  651. size_t CGameServer::GetContent()
  652. {
  653. CCriticalSection::Owner lock( m_csAITS );
  654. return m_theAccountInThisServer.size();
  655. }
  656. void CGameServer::SendToAll( const char *pText, int nLength, UINT uOption )
  657. {
  658. stdGameSvr::iterator it;
  659. CCriticalSection::Owner locker( CGameServer::m_csGameSvrAction );
  660. for ( it = CGameServer::m_theGameServers.begin(); 
  661. it != CGameServer::m_theGameServers.end(); 
  662. it ++ )
  663. {
  664. IGServer *pGServer = ( *it ).second;
  665. if ( pGServer )
  666. {
  667. pGServer->SendText( pText, nLength, uOption );
  668. }
  669. }
  670. }
  671. void CGameServer::SendText( const char *pText, int nLength, UINT uOption )
  672. {
  673. if ( !pText || 0 == nLength || !m_pGameSvrServer )
  674. {
  675. return;
  676. }
  677. tagGatewayBroadCast gbc;
  678. gbc.cProtocol = s2c_gateway_broadcast;
  679. gbc.uCmdType = uOption;
  680. int nLen = 0;
  681. if ( sizeof( gbc.szData ) > nLength )
  682. {
  683. strcpy( gbc.szData, pText );
  684. nLen = nLength;
  685. }
  686. gbc.szData[nLen] = '';
  687. m_pGameSvrServer->SendData( m_lnIdentityID, ( const void * )&gbc, sizeof( tagGatewayBroadCast ) );
  688. }