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

模拟服务器

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "ClientNode.h"
  3. #include <process.h>
  4. #include <iostream>
  5. #include "IDBRoleServer.h"
  6. #include "Macro.h"
  7. using OnlineGameLib::Win32::CCriticalSection;
  8. using OnlineGameLib::Win32::CPackager;
  9. using OnlineGameLib::Win32::CEvent;
  10. using OnlineGameLib::Win32::CBuffer;
  11. HANDLE CClientNode::m_hThread = NULL;
  12. CEvent CClientNode::m_hQuitEvent( NULL, true, false );
  13. CCriticalSection CClientNode::m_csCL;
  14. CClientNode::stdMap CClientNode::m_theClientMap;
  15. CClientNode::CDataQueue::CDataQueue( size_t bufferSize /*= 1024 * 64*/, size_t maxFreeBuffers /*= 160*/ )
  16. : m_theDQAllocator( bufferSize, maxFreeBuffers )
  17. {
  18. }
  19. CClientNode::CDataQueue::~CDataQueue()
  20. {
  21. }
  22. bool CClientNode::CDataQueue::AddData( const BYTE *pData, size_t datalength )
  23. {
  24. CBuffer *pBuffer = m_theDQAllocator.Allocate();
  25. pBuffer->AddData( pData, datalength );
  26. {
  27. CCriticalSection::Owner lock( m_csQueue );
  28. m_theData.push_back( pBuffer );
  29. }
  30. return true;
  31. }
  32. CBuffer *CClientNode::CDataQueue::Get()
  33. {
  34. {
  35. CCriticalSection::Owner lock( m_csQueue );
  36. if ( !m_theData.empty() )
  37. {
  38. CBuffer *pBuffer = m_theData.front();
  39. pBuffer->AddRef();
  40. m_theData.pop_front();
  41. pBuffer->Release();
  42. return pBuffer;
  43. }
  44. }
  45. return NULL;
  46. }
  47. CClientNode::CClientNode( IServer *pServer, size_t id )
  48. : m_nIndentity( id ) 
  49. , m_theAllocator( 1024 * 64, 3 )
  50. , m_pServer( pServer )
  51. {
  52. ZeroMemory( m_theProcessArray, sizeof( m_theProcessArray ) );
  53. m_theProcessArray[c2s_roleserver_getrolelist] = _QueryRoleList;
  54. m_theProcessArray[c2s_roleserver_createroleinfo] = _CreateRole;
  55. m_theProcessArray[c2s_roleserver_saveroleinfo] = _SaveRoleInfo;
  56. m_theProcessArray[c2s_roleserver_deleteplayer] = _DelRole;
  57. m_theProcessArray[c2s_roleserver_getroleinfo] = _GetRoleInfo;
  58. }
  59. CClientNode::~CClientNode()
  60. {
  61. SAFE_RELEASE( m_pServer );
  62. }
  63. CClientNode *CClientNode::AddNode( IServer *pServer, size_t id )
  64. {
  65. CCriticalSection::Owner lock( CClientNode::m_csCL );
  66. IServer *pCloneServer = NULL;
  67. pServer->QueryInterface( IID_IIOCPServer, ( void ** )&pCloneServer );
  68. CClientNode *pNode = new CClientNode( pCloneServer, id );
  69. CClientNode::m_theClientMap.insert( stdMap::value_type( id, pNode ) );
  70. return pNode;
  71. }
  72. void CClientNode::DelNode( size_t id )
  73. {
  74. stdMap::iterator it;
  75. if ( CClientNode::m_theClientMap.end() != ( it = CClientNode::m_theClientMap.find( id ) ) )
  76. {
  77. CCriticalSection::Owner lock( CClientNode::m_csCL );
  78. CClientNode *pNode = ( *it ).second;
  79. CClientNode::m_theClientMap.erase( id );
  80. SAFE_DELETE( pNode );
  81. }
  82. }
  83. bool CClientNode::Start( IServer *pServer )
  84. {
  85. unsigned int threadID = 0;
  86. CClientNode::m_hThread = (HANDLE)::_beginthreadex(0,
  87. 0,
  88. ThreadFunction,
  89. ( void * )pServer,
  90. 0,
  91. &threadID );
  92. if ( CClientNode::m_hThread == INVALID_HANDLE_VALUE )
  93. {
  94. return false;
  95. }
  96. return true;
  97. }
  98. void CClientNode::End()
  99. {
  100. CClientNode::m_hQuitEvent.Set();
  101. DWORD result = ::WaitForSingleObject( CClientNode::m_hThread, 50000 );
  102. if ( result == WAIT_TIMEOUT )
  103. {
  104. ::TerminateThread( CClientNode::m_hThread, ( DWORD )( -2 ) );
  105. }
  106. if ( CClientNode::m_hThread != INVALID_HANDLE_VALUE )
  107. {
  108. ::CloseHandle( CClientNode::m_hThread );
  109. CClientNode::m_hThread = INVALID_HANDLE_VALUE;
  110. }
  111. /*
  112.  * Save all
  113.  */
  114. }
  115. unsigned int __stdcall CClientNode::ThreadFunction( void *pV )
  116. {
  117. IServer *pServer = reinterpret_cast< IServer * >( pV );
  118. ASSERT( pServer );
  119. try
  120. {
  121. while ( !CClientNode::m_hQuitEvent.Wait( 0 ) )
  122. {
  123. {
  124. CCriticalSection::Owner lock( CClientNode::m_csCL );
  125. CClientNode::stdMap::iterator it;
  126. for ( it = CClientNode::m_theClientMap.begin();
  127. it != CClientNode::m_theClientMap.end();
  128. it ++ )
  129. {
  130. CClientNode *pNode = ( CClientNode * )( ( *it ).second );
  131. ASSERT( pNode );
  132. pNode->Process();
  133. }
  134. }
  135. ::Sleep( 1 );
  136. }
  137. }
  138. catch(...)
  139. {
  140. ::MessageBox( NULL, "CClientNode::ThreadFunction was error!", "Warning", MB_OK );
  141. }
  142. return 0L;
  143. }
  144. void CClientNode::AppendData( const void *pData, size_t datalength )
  145. {
  146. if ( pData && datalength )
  147. {
  148. BYTE cProtocol = CPackager::Peek( pData );
  149. if ( cProtocol < s2c_micropackbegin )
  150. {
  151. LargePackProcess( pData, datalength );
  152. }
  153. else if ( cProtocol > s2c_micropackbegin )
  154. {
  155. SmallPackProcess( pData, datalength );
  156. }
  157. else
  158. {
  159. ASSERT( FALSE && "Error!" );
  160. }
  161. }
  162. }
  163. void CClientNode::SmallPackProcess( const void *pData, size_t dataLength )
  164. {
  165. BYTE cProtocol = CPackager::Peek( pData );
  166. ASSERT( cProtocol >= 0 && cProtocol < s2c_end );
  167. m_theDataQueue.AddData( ( const BYTE * )pData, dataLength );
  168. }
  169. void CClientNode::LargePackProcess( const void *pData, size_t dataLength )
  170. {
  171. ASSERT( pData && dataLength );
  172. CBuffer *pBuffer = m_theRecv.PackUp( pData, dataLength );
  173. if ( pBuffer )
  174. {
  175. m_theDataQueue.AddData( pBuffer->GetBuffer(), pBuffer->GetUsed() );
  176. SAFE_RELEASE( pBuffer );
  177. }
  178. }
  179. void CClientNode::Process()
  180. {
  181. CBuffer *pBuffer = m_theDataQueue.Get();
  182. if ( pBuffer )
  183. {
  184. const BYTE *pData = pBuffer->GetBuffer();
  185. const size_t dataLength = pBuffer->GetUsed();
  186. BYTE cProtocol = CPackager::Peek( pData );
  187. if ( cProtocol < c2s_end && m_theProcessArray[cProtocol] )
  188. {
  189. ( this->*m_theProcessArray[cProtocol] )( ( const void * )pData, dataLength );
  190. }
  191. }
  192. SAFE_RELEASE( pBuffer );
  193. }
  194. void CClientNode::_QueryRoleList( const void *pData, size_t dataLength )
  195. {
  196. static char szAccountName[_NAME_LENGTH];
  197. ASSERT( m_pServer && pData && dataLength );
  198. #ifdef CONSOLE_DEBUG
  199. cout << "_QueryRoleList::Begin" << endl;
  200. #endif
  201. TProcessData *pPlayerList = ( TProcessData * )pData;
  202. int nRoleListCount = pPlayerList->pDataBuffer[0];
  203. int nLen = pPlayerList->nDataLen;
  204. unsigned long ulIdentity = pPlayerList->ulIdentity;
  205. if ( nLen <= 1 || nLen >= _NAME_LENGTH )
  206. {
  207. #ifdef CONSOLE_DEBUG
  208. cout << "_QueryRoleList::Name is invalid" << endl;
  209. #endif
  210. return;
  211. }
  212. memcpy( szAccountName, ( const char * )( &pPlayerList->pDataBuffer[1] ), nLen - 1 );
  213. szAccountName[nLen - 1] = '';
  214. /*
  215.  * Database
  216.  */
  217. S3DBI_RoleBaseInfo DBI[4];
  218. static const size_t s_nStructSize = sizeof( S3DBI_RoleBaseInfo );
  219. #ifdef CONSOLE_DEBUG
  220. cout << "_QueryRoleList::GetRoleListOfAccount " << szAccountName << endl;
  221. #endif
  222. int nCount = GetRoleListOfAccount( szAccountName, &DBI[0], nRoleListCount );
  223. CBuffer *pBuffer = m_theAllocator.Allocate();
  224. TProcessData *pListData = reinterpret_cast< TProcessData * >( const_cast< BYTE * >( pBuffer->GetBuffer() ) );
  225. pListData->nProtoId = s2c_roleserver_getrolelist_result;
  226. pListData->ulIdentity = ulIdentity;
  227. int nDataLen = nCount * s_nStructSize + 1;
  228. pListData->nDataLen = nDataLen;
  229. pListData->pDataBuffer[0] = nCount;
  230. memcpy( &pListData->pDataBuffer[1], &DBI[0], nDataLen );
  231. int nUsedLen = sizeof( TProcessData ) - 1 + nDataLen;
  232. pBuffer->Use( nUsedLen );
  233. m_pServer->SendData( m_nIndentity, ( const void * )pListData, nUsedLen );
  234. SAFE_RELEASE( pBuffer );
  235. #ifdef CONSOLE_DEBUG
  236. cout << "_QueryRoleList::end" << endl;
  237. #endif
  238. }
  239. void CClientNode::_CreateRole( const void *pData, size_t dataLength )
  240. {
  241. ASSERT( m_pServer && pData && dataLength );
  242. #ifdef CONSOLE_DEBUG
  243. cout << "_CreateRole::Begin" << endl;
  244. #endif
  245. TProcessData *pPD = ( TProcessData * )pData;
  246. int nResult = SaveRoleInfo( &pPD->pDataBuffer[1], NULL, TRUE );
  247. TProcessData Info;
  248. Info.nProtoId = s2c_roleserver_createrole_result;
  249. Info.ulIdentity = pPD->ulIdentity;
  250. Info.nDataLen = 1;
  251. Info.pDataBuffer[0] = ( nResult == 1 ) ? 1 : -1;
  252. m_pServer->SendData( m_nIndentity, ( const void * )&Info, sizeof( Info ) );
  253. #ifdef CONSOLE_DEBUG
  254. cout << "_CreateRole::End" << endl;
  255. #endif
  256. }
  257. void CClientNode::_SaveRoleInfo( const void *pData, size_t dataLength )
  258. {
  259. ASSERT( m_pServer && pData && dataLength );
  260. #ifdef CONSOLE_DEBUG
  261. cout << "_SaveRoleInfo::Begin" << endl;
  262. #endif
  263. TProcessData *pPD = ( TProcessData * )pData;
  264. int nResult = SaveRoleInfo( &pPD->pDataBuffer[0], NULL, FALSE );
  265. if ( pPD->ulIdentity >= 0 )
  266. {
  267. TProcessData Info;
  268. Info.nProtoId = s2c_roleserver_saverole_result;
  269. Info.ulIdentity = pPD->ulIdentity;
  270. Info.nDataLen = 1;
  271. Info.pDataBuffer[0] = ( nResult == 1 ) ? 1 : -1;
  272. m_pServer->SendData( m_nIndentity, ( const void * )&Info, sizeof( Info ) );
  273. }
  274. #ifdef CONSOLE_DEBUG
  275. cout << "_SaveRoleInfo::End" << endl;
  276. #endif
  277. }
  278. void CClientNode::_DelRole( const void *pData, size_t dataLength )
  279. {
  280. ASSERT( m_pServer && pData && dataLength );
  281. #ifdef CONSOLE_DEBUG
  282. cout << "_DelRole::Begin" << endl;
  283. #endif
  284. TProcessData *pRoleInfo = ( TProcessData * )pData;
  285. static char szRoleName[_NAME_LENGTH];
  286. int nDataLen = pRoleInfo->nDataLen;
  287. nDataLen = ( nDataLen > _NAME_LENGTH ) ? _NAME_LENGTH : nDataLen;
  288. int result = -1;
  289. if ( nDataLen > 0 )
  290. {
  291. memcpy( szRoleName, &pRoleInfo->pDataBuffer[0], nDataLen );
  292. szRoleName[nDataLen] = '';
  293. #ifdef CONSOLE_DEBUG
  294. cout << "_DelRole::DeleteRole " << szRoleName << endl;
  295. #endif
  296. if ( DeleteRole( szRoleName ) )
  297. {
  298. result = 1;
  299. }
  300. else
  301. {
  302. result = -1;
  303. }
  304. }
  305. if ( pRoleInfo->ulIdentity >= 0 )
  306. {
  307. TProcessData Info;
  308. Info.nProtoId = s2c_roleserver_deleterole_result;
  309. Info.ulIdentity = pRoleInfo->ulIdentity;
  310. Info.nDataLen = 1;
  311. Info.pDataBuffer[0] = result;
  312. m_pServer->SendData( m_nIndentity, ( const void * )&Info, sizeof( Info ) );
  313. }
  314. #ifdef CONSOLE_DEBUG
  315. cout << "_DelRole::End" << endl;
  316. #endif
  317. }
  318. void CClientNode::_GetRoleInfo( const void *pData, size_t dataLength )
  319. {
  320. ASSERT( m_pServer && pData && dataLength );
  321. #ifdef CONSOLE_DEBUG
  322. cout << "_GetRoleInfo::Begin" << endl;
  323. #endif
  324. TProcessData *pRoleInfo = ( TProcessData * )pData;
  325. static char szRoleName[_NAME_LENGTH];
  326. int nDataLen = pRoleInfo->nDataLen;
  327. nDataLen = ( nDataLen > _NAME_LENGTH ) ? _NAME_LENGTH : nDataLen;
  328. CBuffer *pBuffer = m_theAllocator.Allocate();
  329. TProcessData *pRoleData = reinterpret_cast< TProcessData * >( const_cast< BYTE * >( pBuffer->GetBuffer() ) );
  330. int nUsedLength = sizeof( TProcessData );
  331. size_t nIdentity = pRoleInfo->ulIdentity;
  332. pRoleData->nProtoId = s2c_roleserver_getroleinfo_result;
  333. pRoleData->pDataBuffer[0] = -1;
  334. pRoleData->nDataLen = 1;
  335. pRoleData->ulIdentity = nIdentity;
  336. if ( nDataLen > 0 )
  337. {
  338. memcpy( szRoleName, &pRoleInfo->pDataBuffer[0], nDataLen );
  339. szRoleName[nDataLen] = '';
  340. int result = -1;
  341. #ifdef CONSOLE_DEBUG
  342. cout << "_GetRoleInfo::GetRoleInfo " << szRoleName << endl;
  343. #endif
  344. int nRoleInfoLen = 0;
  345. GetRoleInfo( &pRoleData->pDataBuffer[1], szRoleName, nRoleInfoLen );
  346. if ( nRoleInfoLen > 0 )
  347. {
  348. pRoleData->pDataBuffer[0] = 1;
  349. pRoleData->nDataLen = nRoleInfoLen + 1;
  350. nUsedLength = sizeof( TProcessData ) + nRoleInfoLen;
  351. }
  352. }
  353. pBuffer->Use( nUsedLength );
  354. m_theSend.AddData( s2c_roleserver_getroleinfo_result, pBuffer->GetBuffer(), nUsedLength, nIdentity );
  355. CBuffer *pPack = m_theSend.GetHeadPack( s2c_roleserver_getroleinfo_result );
  356. while ( pPack )
  357. {
  358. m_pServer->SendData( m_nIndentity, ( const void * )pPack->GetBuffer(), pPack->GetUsed() );
  359. SAFE_RELEASE( pPack );
  360. pPack = m_theSend.GetNextPack( s2c_roleserver_getroleinfo_result );
  361. }
  362. m_theSend.DelData( s2c_roleserver_getroleinfo_result );
  363. SAFE_RELEASE( pPack );
  364. SAFE_RELEASE( pBuffer );
  365. #ifdef CONSOLE_DEBUG
  366. cout << "_GetRoleInfo::End" << endl;
  367. #endif
  368. }