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

模拟服务器

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include <objbase.h>
  3. #include <initguid.h>
  4. #include "KRoleInfomation.h"
  5. #include "KRoleDBServer.h"
  6. #include "KException.h"
  7. #include "S3DBINTERFACE.H"
  8. #include "KDBProcessThread.h"
  9. #include "KROleDBHeader.h"
  10. #include "resource.h"
  11. #include "MainFrm.h"
  12. #include "RoleDBServerDoc.h"
  13. #include "RoleDBServerView.h"
  14. #pragma warning(disable:4786)
  15. #include <crtdbg.h>
  16. #include <list>
  17. #include "stdio.h"
  18. using namespace std;
  19. static const int g_snMaxPlayerCount = 5;
  20. static const int g_snPrecision = 1;
  21. static const int g_snMaxBuffer = 15;
  22. static const int g_snBufferSize = 1024;
  23. IServer *g_pNetServer = NULL;
  24. static HMODULE hDllModule;
  25. DWORD g_dwPerSaveTime;//每次存档的时间
  26. DWORD g_dwMaxUnModifyTime;
  27. list<TCmd*> g_MainThreadCmdList;
  28. list<TGetRoleInfoFromDB*> g_DBLoadThreadCmdList;
  29. list<TCmd*> g_NetServiceThreadCmdList;
  30. extern BOOL InitNetEngine();
  31. extern RoleDBServer::KNetServer g_NetServer;
  32. CRITICAL_SECTION g_RoleInfoMutex;
  33. CRITICAL_SECTION g_RoleInfoListMutex;
  34. CRITICAL_SECTION g_RoleInfoMapMutex;
  35. CRITICAL_SECTION g_MainMsgListMutex;
  36. CRITICAL_SECTION g_NetMsgListMutex;
  37. CRITICAL_SECTION g_GetRoleInfoMutex;
  38. HANDLE  g_NetEventMutex = 0;
  39. TThreadData g_ThreadData[4];
  40. char * GetRoleNameFromRoleBuffer(char * pRoleBuffer)
  41. {
  42. if (pRoleBuffer == NULL)
  43. return NULL;
  44. try
  45. {
  46. TRoleData *pRoleData = (TRoleData*) pRoleBuffer;
  47. return pRoleData->BaseInfo.szName;
  48. }
  49. catch(...)
  50. {
  51. throw KException("GetRoleNameFromRoleBuffer", "内存有问题");
  52. }
  53. }
  54. int InitServer()
  55. {
  56. int nReturn;
  57. S3DBI_InitDBInterface();
  58. nReturn = InitNetEngine();
  59. InitializeCriticalSection(&g_RoleInfoMutex);
  60. InitializeCriticalSection(&g_MainMsgListMutex);
  61. InitializeCriticalSection(&g_NetMsgListMutex);
  62. InitializeCriticalSection(&g_GetRoleInfoMutex);
  63. InitializeCriticalSection(&g_RoleInfoListMutex);
  64. InitializeCriticalSection(&g_RoleInfoMapMutex);
  65. g_NetEventMutex = CreateMutex(NULL, FALSE, NULL);
  66. if (!g_NetEventMutex) return 0;
  67. return nReturn;
  68. }
  69. DWORD ReleaseServer()
  70. {
  71. for(int i = 0; i < 4; i ++)
  72. TerminateThread(g_ThreadData[i].hThread,0);
  73. DeleteCriticalSection(&g_RoleInfoMutex);
  74. DeleteCriticalSection(&g_MainMsgListMutex);
  75. DeleteCriticalSection(&g_NetMsgListMutex);
  76. DeleteCriticalSection(&g_GetRoleInfoMutex);
  77. DeleteCriticalSection(&g_RoleInfoListMutex);
  78. DeleteCriticalSection(&g_RoleInfoMapMutex);
  79. CloseHandle(g_NetEventMutex);
  80. g_pNetServer->CloseService();
  81. g_pNetServer->Cleanup();
  82. g_pNetServer->Release();
  83. ::FreeLibrary( hDllModule );
  84. S3DBI_ReleaseDBInterface();
  85. return 1;
  86. }
  87. //
  88. DWORD WINAPI DatabaseSaveThreadFun(void * pParam)
  89. {
  90. /*
  91. while(1)
  92. {
  93. list<KRoleInfomation*>::iterator I = g_RoleInfoList.begin();
  94. while(!I->end())
  95. {
  96. if (I->m_bModify)
  97. {
  98. if (I->CheckRoleInfoValid())
  99. {
  100. S3DBI_SaveRoleInfo()
  101. (*I)->m_nSaveDBCount ++;
  102. (*I)->m_nUnModifyTime = 0;
  103. }
  104. else
  105. {
  106. ASSERT(0);
  107. }
  108.   }
  109.   else
  110.   {
  111.   //长时间未存则从存档列表中删除
  112.   if (I->m_nUnModifyTime >= g_dwMaxUnModifyTime)
  113.   {
  114.   //Question
  115.   I->erase();
  116.   }
  117.   else
  118.   I->m_nLastSaveTime ++;
  119.   
  120. }
  121. I ++;
  122. }
  123.   Sleep(g_dwPerSaveTime);
  124.   }
  125. */
  126. return 1;
  127. }
  128. //循环处理向数据库请求获得玩家信息的操作 
  129. DWORD WINAPI DatabaseLoadThreadFun(void * pParam)
  130. {
  131. CMainFrame * pFrame = (CMainFrame *) AfxGetMainWnd(); CRoleDBServerView *pView = (CRoleDBServerView*)pFrame->GetActiveView();
  132. while(1)
  133. {
  134. list<TGetRoleInfoFromDB *>::iterator I = g_DBLoadThreadCmdList.begin();
  135. pView->UpdateDBServiceList();
  136. while(I != g_DBLoadThreadCmdList.end())
  137. {
  138. static unsigned char szRoleInfo[MAX_ROLEINFORMATION_SIZE];
  139. int nBufferSize = 0;
  140. char * szName1 =  (*I)->szRoleName;
  141. if (!S3DBI_GetRoleInfo(szRoleInfo, (*I)->szRoleName, nBufferSize)) continue;
  142. static ii = 0;
  143. char FileName[100] ;
  144. sprintf(FileName, "d:\LoadRoleout_%d.txt", ii++);
  145. TextOutRoleInfo(szRoleInfo ,FileName );
  146. //增加角色数据和向两个列表增加数据
  147. EnterCriticalSection(&g_RoleInfoMutex);//同时只能有一个线程修改角色数据
  148. char * szName = (char *)((*I)->szRoleName);
  149. if (szName)
  150. {
  151. KRoleInfomation * pRoleInfomation =   g_RoleInfoMap[szName] ;
  152. if (!pRoleInfomation)//新加角色!需要立即存档
  153. {
  154. KRoleInfomation * pNewRoleInfomation = new KRoleInfomation;
  155. pNewRoleInfomation->SetRoleInfoBuffer(szRoleInfo, nBufferSize);
  156. LeaveCriticalSection(&g_RoleInfoMutex);
  157. EnterCriticalSection(&g_RoleInfoMapMutex);
  158. g_RoleInfoMap[szName] = pNewRoleInfomation;
  159. EnterCriticalSection(&g_RoleInfoListMutex);
  160. g_RoleInfoList.push_back(pNewRoleInfomation);
  161. LeaveCriticalSection(&g_RoleInfoMapMutex);
  162. LeaveCriticalSection(&g_RoleInfoListMutex);
  163. }
  164. TCmd * pNewCmd = (TCmd *)new char [sizeof(TCmd)  + strlen(szName)];
  165. pNewCmd->ulNetId = (*I)->nNetId;
  166. pNewCmd->nProtoId = PROTOL_LOADROLE;
  167. pNewCmd->nDataLen = strlen(szName) + 1;
  168. strcpy((char *)&pNewCmd->pDataBuffer[0], szName);
  169. EnterCriticalSection(&g_MainMsgListMutex);
  170. g_MainThreadCmdList.push_back(pNewCmd);
  171. LeaveCriticalSection(&g_MainMsgListMutex);
  172. /*
  173. //要求服务列表增加一个读档服务
  174. if (I->nNetId != 0)
  175. {
  176. unsigned char * pBuffer = new unsigned char [nBufferSize + sizeof(TCmd) - 1];
  177. TCmd * pCmd = (TCmd *)pBuffer;
  178. pCmd->nNetId = I->nNetId ;
  179. pCmd->Size = nBufferSize;
  180. pCmd->Cmd = PROTOL_LOADROLE;
  181. memcpy(&pCmd->pDataBuffer[0], szRoleInfo, )
  182. }
  183. WaitForSingleObject();//同时只能有一个线程修改网络服务列表的数据
  184. */
  185. }
  186. else
  187. LeaveCriticalSection(&g_RoleInfoMutex);
  188. // delete *I;
  189. g_DBLoadThreadCmdList.erase(I);
  190. I = g_DBLoadThreadCmdList.begin();
  191. pView->UpdateDBServiceList();
  192. }
  193. Sleep(10);
  194. }
  195. return 1;
  196. }
  197. //主循环,负责处理网络端发来的完整的请求数据
  198. DWORD  WINAPI RoleServerMainThreadFun(void * pParam)
  199. {
  200. CMainFrame * pFrame = (CMainFrame *) AfxGetMainWnd(); CRoleDBServerView *pView = (CRoleDBServerView*)pFrame->GetActiveView();
  201. while(1)
  202. {
  203. pView->UpdateMainLoopList();
  204. list<TCmd *>::iterator I = g_MainThreadCmdList.begin();
  205. while (I != g_MainThreadCmdList.end())
  206. {
  207. switch((*I)->nProtoId)
  208. {
  209. //Save
  210. case PROTOL_ONLYSAVEROLE://游戏服务器向数据库服务器要求保存数据
  211. case PROTOL_SAVEORCREATEROLE:
  212. {
  213. EnterCriticalSection(&g_RoleInfoMutex);
  214. const char * szName = GetRoleNameFromRoleBuffer((char *)&(*I)->pDataBuffer[0]);
  215. static ii = 0;
  216. char FileName[100] ;
  217. sprintf(FileName, "d:\SaveRoleout_%d.txt", ii++);
  218. TextOutRoleInfo((unsigned char *)&(*I)->pDataBuffer[0],FileName );
  219. if (szName)
  220. {
  221. map<std::string , KRoleInfomation * >::iterator II;
  222. II =  g_RoleInfoMap.find((const char *)szName) ;
  223. KRoleInfomation * pRoleInfomation = II->second;
  224. if (!pRoleInfomation)//新加角色!需要立即存档
  225. {
  226. KRoleInfomation * pNewRoleInfomation = new KRoleInfomation;
  227. pRoleInfomation->SetRoleInfoBuffer((unsigned char *)&((*I)->pDataBuffer[0]), (*I)->nDataLen);
  228. EnterCriticalSection(&g_RoleInfoMapMutex);
  229. g_RoleInfoMap[szName] = pNewRoleInfomation;
  230. EnterCriticalSection(&g_RoleInfoListMutex);
  231. g_RoleInfoList.push_back(pNewRoleInfomation);
  232. LeaveCriticalSection(&g_RoleInfoMapMutex);
  233. LeaveCriticalSection(&g_RoleInfoListMutex);
  234. }
  235. else
  236. {
  237. pRoleInfomation->SetRoleInfoBuffer((unsigned char *)&((*I)->pDataBuffer), (*I)->nDataLen);
  238. }
  239. }
  240. LeaveCriticalSection(&g_RoleInfoMutex);
  241. }
  242. break;
  243. //Load
  244. case PROTOL_LOADROLE://获得角色数据
  245. {
  246. char szName[100] ;
  247. memcpy(szName, (*I)->pDataBuffer, (*I)->nDataLen);// GetRoleNameFromRoleBuffer((char *)&(*I)->pDataBuffer);
  248. szName[(*I)->nDataLen] = 0;
  249. if (szName)
  250. {
  251. KRoleInfomation * pRoleInfomation = g_RoleInfoMap[szName];
  252. /*map<const char * , KRoleInfomation * >::iterator II;
  253. II =  g_RoleInfoMap.find((const char *)szName) ;
  254. KRoleInfomation * pRoleInfomation = II->second;
  255. */
  256. if (pRoleInfomation )
  257. {
  258. size_t BufferSize = 0;
  259. BYTE * pBuffer = pRoleInfomation->GetRoleInfoBuffer(BufferSize);
  260. _ASSERT(BufferSize && pBuffer);
  261. BYTE * pNewBuffer = new BYTE[sizeof(TCmd) + BufferSize - 1];
  262. TCmd * pNewCmd = (TCmd*)pNewBuffer;
  263. pNewCmd->nProtoId = PROTOL_ROLEINFO;
  264. pNewCmd->nDataLen = BufferSize;
  265. pNewCmd->ulNetId = (*I)->ulNetId;
  266. memcpy(pNewCmd->pDataBuffer, pBuffer, BufferSize);
  267. EnterCriticalSection(&g_NetMsgListMutex);
  268. g_NetServiceThreadCmdList.push_back(pNewCmd);
  269. LeaveCriticalSection(&g_NetMsgListMutex);
  270. }
  271. else//没有则需要实际的取数据,需要向LoadThread发送消息
  272. {
  273. TGetRoleInfoFromDB * pNewCmd = new TGetRoleInfoFromDB;
  274. pNewCmd->nNetId = (*I)->ulNetId;
  275. strcpy(pNewCmd->szRoleName, szName);
  276. EnterCriticalSection(&g_GetRoleInfoMutex);
  277. g_DBLoadThreadCmdList.push_back(pNewCmd);
  278. LeaveCriticalSection(&g_GetRoleInfoMutex);
  279. }
  280. }
  281. }break;
  282. //LoadRoleList
  283. case PROTOL_GETROLELIST://获得某个帐号的角色列表
  284. {
  285. unsigned char  MaxRoleCount = (int)(*I)->pDataBuffer[0];
  286. unsigned char * pNewBuffer = new  unsigned char [sizeof(S3DBI_RoleBaseInfo) * MaxRoleCount + 1];//列表和1个
  287. TCmd * pCmd = (TCmd*)pNewBuffer;
  288. pCmd->ulNetId = (*I)->ulNetId;
  289. pCmd->nProtoId =  (*I)->nProtoId;
  290. pCmd->nDataLen  =  sizeof(S3DBI_RoleBaseInfo) * MaxRoleCount + 1;
  291. S3DBI_RoleBaseInfo *pRoleBaseInfoList  =(S3DBI_RoleBaseInfo*) ((char*)&pCmd->pDataBuffer[0] + 1);
  292. char  szAccountName[32];
  293. memcpy(szAccountName, &(*I)->pDataBuffer[0] + 1, (*I)->nDataLen - 1 );
  294. szAccountName[(*I)->nDataLen - 1] = 0;
  295. pCmd->pDataBuffer[0]  = (unsigned char )S3DBI_GetRoleListOfAccount(szAccountName, pRoleBaseInfoList, MaxRoleCount);
  296. for (int i  = 0; i < pCmd->pDataBuffer[0]; i ++)
  297. {
  298. KRoleInfomation * pRoleInfo = g_RoleInfoMap[pRoleBaseInfoList->szRoleName];
  299. if (pRoleInfo)
  300. {
  301. size_t nSize = 0;
  302. TRoleData * pRoleData = (TRoleData*)pRoleInfo->GetRoleInfoBuffer(nSize);
  303. if (pRoleData && nSize)
  304. {
  305. pRoleBaseInfoList->nArmorType = pRoleData->BaseInfo.iarmorres;
  306. pRoleBaseInfoList->nHelmType  = pRoleData->BaseInfo.ihelmres;
  307. pRoleBaseInfoList->nLevel     = pRoleData->BaseInfo.ifightlevel;
  308. pRoleBaseInfoList->nSex   = pRoleData->BaseInfo.bSex;
  309. pRoleBaseInfoList->nWeaponType = pRoleData->BaseInfo.iweaponres;
  310. }
  311. }
  312. }
  313. EnterCriticalSection(&g_NetMsgListMutex);
  314. g_NetServiceThreadCmdList.push_back(pCmd);
  315. LeaveCriticalSection(&g_NetMsgListMutex);
  316. }
  317. break;
  318. case PROTOL_DELETEROLE:
  319. {
  320. }break;
  321. //Exit
  322. }
  323. g_MainThreadCmdList.erase(I);
  324. I = g_MainThreadCmdList.begin();
  325. pView->UpdateMainLoopList();
  326. }
  327. Sleep(20);
  328. }
  329. return 1;
  330. }
  331. //
  332. DWORD WINAPI  RoleNetWorkServiceThreadFun(void * pParam)
  333. {
  334. g_NetServer.Init();
  335. //g_NetServer.RegisterClient(1);
  336. while(1)
  337. {
  338. g_NetServer.Receive();
  339. g_NetServer.Send();
  340. Sleep(10);
  341. }
  342. }
  343. TRoleNetMsg  * pTestCmd = NULL;
  344. void * EnumSendMsg(unsigned long nId, size_t& nDataLen)
  345. {
  346. if (pTestCmd)
  347. {
  348. nDataLen = pTestCmd->nDataLen;
  349. return  pTestCmd;
  350. }
  351. else 
  352. {
  353. nDataLen = 0;
  354. return NULL;
  355. }
  356. }
  357. FILE *streamout;
  358. FILE *streamin;
  359. void SendToClient(unsigned long nId, TRoleNetMsg * pMsg, size_t nMsgLen)
  360. {
  361. static i = 0;
  362. char FileName[100] ;
  363. sprintf(FileName, "d:\testout_%d.txt", i++);
  364. if( (streamout = fopen( FileName, "wb" )) != NULL )
  365. {
  366. fwrite(pMsg, 1, nMsgLen, streamout);
  367. }
  368. fclose(streamout);
  369. }
  370. void TextOutRoleInfo(BYTE * pDataBuffer, char * FileName)
  371. {
  372. if (!pDataBuffer) return ;
  373. char showString[50000];
  374. S3DBI_ShowDebugInfo(pDataBuffer, showString);
  375. FILE * streamout;
  376. if( (streamout = fopen( FileName, "wb" )) != NULL )
  377. {
  378. fwrite(showString, 1, strlen(showString), streamout);
  379. }
  380. fclose(streamout);
  381. }
  382. typedef HRESULT ( __stdcall * pfnCreateServerInterface )(
  383. REFIID riid,
  384. void **ppv
  385. );
  386. void __stdcall ServerEventNotify(
  387. LPVOID lpParam,
  388. const unsigned long &ulnID,
  389. const unsigned long &ulnEventType )
  390. {
  391. CMainFrame * pFrame = (CMainFrame *) AfxGetMainWnd(); CRoleDBServerView *pView = (CRoleDBServerView*)pFrame->GetActiveView();
  392. switch( ulnEventType )
  393. {
  394. case enumClientConnectCreate:
  395. WaitForSingleObject(g_NetEventMutex, INFINITE);
  396. g_NetServer.RegisterClient(ulnID);
  397. ReleaseMutex(g_NetEventMutex);
  398. break;
  399. case enumClientConnectClose:
  400. WaitForSingleObject(g_NetEventMutex, INFINITE);
  401. g_NetServer.DestoryClient(ulnID);
  402. ReleaseMutex(g_NetEventMutex);
  403. break;
  404. }
  405. pView->UpdateRoleServerList();
  406. }
  407. unsigned _stdcall ThreadFunction( void *pParam )
  408. {
  409. IServer *pServer = reinterpret_cast< IServer * >( pParam );
  410. while ( pServer )
  411. {
  412. Sleep( 1 );
  413. size_t datalength = 0;
  414. const void *pData = pServer->GetPackFromClient( 4, datalength );
  415. if ( !pData || 0 == datalength )
  416. {
  417. continue;
  418. }
  419. }
  420. if ( pServer )
  421. {
  422. pServer->Release();
  423. pServer = NULL;
  424. }
  425. return 0L;
  426. }
  427. BOOL InitNetEngine()
  428. {
  429. hDllModule = ::LoadLibrary( "heaven.dll" );
  430. if ( hDllModule )
  431. {
  432. pfnCreateServerInterface pFactroyFun = ( pfnCreateServerInterface )GetProcAddress( hDllModule, "CreateInterface" );
  433. IServerFactory *pServerFactory = NULL;
  434. if ( SUCCEEDED( pFactroyFun( IID_IServerFactory, reinterpret_cast< void ** >( &pServerFactory ) ) ) )
  435. {
  436. pServerFactory->SetEnvironment( g_snMaxPlayerCount, g_snPrecision, g_snMaxBuffer, g_snBufferSize  );
  437. pServerFactory->CreateServerInterface( IID_IIOCPServer, reinterpret_cast< void ** >( &g_pNetServer ) );
  438. pServerFactory->Release();
  439. }
  440. }
  441. else
  442. return FALSE;
  443. g_pNetServer->Startup();
  444. g_pNetServer->RegisterMsgFilter( reinterpret_cast< void * >( g_pNetServer ), ServerEventNotify );
  445. g_pNetServer->OpenService( 0, 5001 );
  446. //unsigned int threadid = 0;
  447. //HANDLE handle = (HANDLE)::_beginthreadex( 0, 0, ThreadFunction, reinterpret_cast< void * >( pClonServer ), 0, &threadid );
  448. //CloseHandle( handle );
  449. /* const size_t len = strlen( "to client" );
  450. while ( pServer )
  451. {
  452. pServer->PreparePackSink();
  453. pServer->PackDataToClient( 4, "to client", len );
  454. pServer->SendPackToClient();
  455. Sleep( 100 );
  456. }
  457. */
  458. return 1;
  459. }