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

模拟服务器

开发平台:

C/C++

  1. #include "stdlib.h"
  2. #include "stdio.h"
  3. #include "KStdAfx.h"
  4. #include "S3PDBSocketPool.h"
  5. #include "S3PDBConnectionPool.h"
  6. #include "GlobalFun.h"
  7. #include <process.h>
  8. #include "../../../Headers/ServerPort.h"
  9. #include "resource.h"
  10. #include <initguid.h>  // Include only once in your application
  11. #define _WIN32_DCOM
  12. #include "../../Multiserver/Heaven/Interface/IServer.h"
  13. #include "adoid.h"     // ADO GUID's
  14. #include "adoint.h"
  15. #include "time.h"
  16. #include "LogFile.h"
  17. const char log_directory[] = "relayserver_log";
  18. const size_t log_threshold = 1024 * 1024;
  19. static CLogFile gs_LogFile;
  20. typedef HRESULT ( __stdcall * pfnCreateServerInterface )(
  21. REFIID riid,
  22. void **ppv
  23. );
  24. void __stdcall ServerEventNotify(
  25. LPVOID lpParam,
  26. const unsigned long &ulnID,
  27. const unsigned long &ulnEventType )
  28. {
  29. S3PDBSocketPool *pSocketPool = (S3PDBSocketPool *)lpParam;
  30. switch( ulnEventType )
  31. {
  32. case enumClientConnectCreate:
  33. pSocketPool->AddUserClientID(ulnID);
  34. break;
  35. case enumClientConnectClose:
  36. pSocketPool->RemoveUserClientID(ulnID);
  37. break;
  38. }
  39. }
  40. static inline sLogProgram(BOOL bEnter)
  41. {
  42. SYSTEMTIME systm;
  43. ::GetLocalTime(&systm);
  44. TCHAR buff[256];
  45. int len = 0;
  46. if (bEnter)
  47. len = _stprintf(buff, "rn*rn***** S3RelayServer Start (@ %04d/%02d/%02d %02d:%02d:%02d.%03d) >>>>>rn*rnrn",
  48. systm.wYear, systm.wMonth, systm.wDay, systm.wHour, systm.wMinute, systm.wSecond, systm.wMilliseconds);
  49. else
  50. len = _stprintf(buff, "rn*rn***** S3RelayServer Stop (@ %04d/%02d/%02d %02d:%02d:%02d.%03d) <<<<<rn*rnrn",
  51. systm.wYear, systm.wMonth, systm.wDay, systm.wHour, systm.wMinute, systm.wSecond, systm.wMilliseconds);
  52. gs_LogFile.TraceLog(buff, len * sizeof(TCHAR));
  53. }
  54. ATOM RegisterSysClass(HINSTANCE hInstance);
  55. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, int nLogTime);
  56. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  57. char g_szWindowClass[MAX_PATH];
  58. int APIENTRY WinMain(HINSTANCE hInstance,
  59.                      HINSTANCE hPrevInstance,
  60.                      LPSTR     lpCmdLine,
  61.                      int       nCmdShow)
  62. {
  63. TCHAR szExePath[MAX_PATH + 1];
  64. KPIGetExePath( szExePath, MAX_PATH );
  65. TCHAR szLogDir[MAX_PATH + 1];
  66. _tcscpy(szLogDir, szExePath);
  67. _tcscat(szLogDir, log_directory);
  68. ::CreateDirectory(szLogDir, NULL);
  69. if (!gs_LogFile.Initialize(szLogDir, log_threshold))
  70. {
  71. ::MessageBox(NULL, "Initializing LogFile fail", "error", MB_OK|MB_ICONERROR);
  72. return FALSE;
  73. }
  74. sLogProgram(TRUE);
  75. TCHAR szINIPath[MAX_PATH + 1];
  76. _tcscpy(szINIPath, szExePath);
  77. _tcscat(szINIPath, "relay_setup.ini");
  78. TCHAR szPort[32];
  79. sprintf(szPort, "%d", RELAY_ROUTE_PORT);
  80. DWORD dwResult = KPIGetPrivateProfileString("Local",
  81. "port",
  82. szPort,
  83. szPort,
  84. 31,
  85. szINIPath);
  86. short siPort = atoi(szPort);
  87. dwResult = KPIGetPrivateProfileString("Local",
  88. "maxconnect",
  89. "10",
  90. szPort,
  91. 31,
  92. szINIPath);
  93. int snMaxPlayerCount = atoi(szPort);
  94. dwResult = KPIGetPrivateProfileString("Local",
  95. "precision",
  96. "1",
  97. szPort,
  98. 31,
  99. szINIPath);
  100. int snPrecision = atoi(szPort);
  101. dwResult = KPIGetPrivateProfileString("Local",
  102. "maxbuffer",
  103. "15",
  104. szPort,
  105. 31,
  106. szINIPath);
  107. int snMaxBuffer = atoi(szPort);
  108. dwResult = KPIGetPrivateProfileString("Local",
  109. "sizebuffer",
  110. "1048576",
  111. szPort,
  112. 31,
  113. szINIPath);
  114. int snBufferSize = atoi(szPort);
  115. dwResult = KPIGetPrivateProfileString("Local",
  116. "timelog",
  117. "3000",
  118. szPort,
  119. 31,
  120. szINIPath);
  121. int nTimelog = atoi(szPort);
  122. IServer *pServer = NULL;
  123. HMODULE hModule = ::LoadLibrary("heaven.dll");
  124. if (hModule)
  125. {
  126. pfnCreateServerInterface pFactroyFun = (pfnCreateServerInterface)GetProcAddress(hModule, "CreateInterface");
  127. IServerFactory *pServerFactory = NULL;
  128. if (SUCCEEDED( pFactroyFun( IID_IServerFactory, reinterpret_cast< void ** >(&pServerFactory ))))
  129. {
  130. pServerFactory->SetEnvironment(snMaxPlayerCount, snPrecision, snMaxBuffer, snBufferSize);
  131. pServerFactory->CreateServerInterface(IID_IIOCPServer, reinterpret_cast< void ** >(&pServer));
  132. pServerFactory->Release();
  133. }
  134. }
  135. _tcscpy(szINIPath, szExePath);
  136. _tcscat(szINIPath, "DataBase.ini");
  137. dwResult = KPIGetPrivateProfileString("Local",
  138. "DBConnects",
  139. "5",
  140. szPort,
  141. 31,
  142. szINIPath);
  143. int nDBConns = atoi(szPort);
  144. S3PDBConnectionPool * pConnectPool = S3PDBConnectionPool::Instance();
  145. S3PDBSocketPool *pSocketPool = S3PDBSocketPool::Instance();
  146. if (pServer == NULL)
  147. {
  148. ::MessageBox(NULL, "heaven Error!", "error", MB_OK | MB_ICONERROR);
  149. goto Exit0;
  150. }
  151. if (!pConnectPool->Init(szINIPath, "account", nDBConns))
  152. {
  153. ::MessageBox(NULL, "Connect DB Error!", "error", MB_OK | MB_ICONERROR);
  154. goto Exit0;
  155. }
  156. pSocketPool->Start(pServer);
  157. pServer->Startup();
  158. pServer->RegisterMsgFilter((LPVOID)pSocketPool, ServerEventNotify);
  159. pServer->OpenService(INADDR_ANY, siPort);
  160. MSG msg;
  161. LoadString(hInstance, IDC_S3RELAYSYS, g_szWindowClass, MAX_PATH);
  162. RegisterSysClass(hInstance);
  163. // Perform application initialization:
  164. if (InitInstance(hInstance, nCmdShow, nTimelog)) 
  165. {
  166. //hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_S3RELAY);
  167. // Main message loop:
  168. while (GetMessage(&msg, NULL, 0, 0)) 
  169. {
  170. //if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
  171. {
  172. TranslateMessage(&msg);
  173. DispatchMessage(&msg);
  174. }
  175. }
  176. }
  177. pSocketPool->Stop();
  178. Exit0:
  179. S3PDBSocketPool::ReleaseInstance();
  180. S3PDBConnectionPool::ReleaseInstance();
  181. if (pServer)
  182. {
  183. pServer->CloseService();
  184. pServer->Cleanup();
  185. pServer->Release();
  186. }
  187. if (hModule)
  188. ::FreeLibrary(hModule);
  189. sLogProgram(FALSE);
  190. gs_LogFile.Uninitialize();
  191. return 0;
  192. }
  193. //  FUNCTION: RegisterSysClass()
  194. //
  195. //  PURPOSE: Registers the window class.
  196. //
  197. //  COMMENTS:
  198. //
  199. //    This function and its usage is only necessary if you want this code
  200. //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
  201. //    function that was added to Windows 95. It is important to call this function
  202. //    so that the application will get 'well formed' small icons associated
  203. //    with it.
  204. //
  205. ATOM RegisterSysClass(HINSTANCE hInstance)
  206. {
  207. WNDCLASSEX wcex;
  208. wcex.cbSize = sizeof(WNDCLASSEX); 
  209. wcex.style = CS_HREDRAW | CS_VREDRAW;
  210. wcex.lpfnWndProc = (WNDPROC)WndProc;
  211. wcex.cbClsExtra = 0;
  212. wcex.cbWndExtra = 0;
  213. wcex.hInstance = hInstance;
  214. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MAIN);
  215. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  216. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  217. wcex.lpszMenuName = (LPCSTR)IDC_S3RELAYSYS;
  218. wcex.lpszClassName = g_szWindowClass;
  219. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  220. return RegisterClassEx(&wcex);
  221. }
  222. class TwoFixBuffer
  223. {
  224. protected:
  225. #define MAX_BUFFER_LEN 1024 * 1024
  226. struct CSBuffer
  227. {
  228. BYTE buff[MAX_BUFFER_LEN + sizeof(DWORD)];
  229. DWORD nInfoStart;
  230. };
  231. CSBuffer m_RW_Buffer[2];
  232. int m_nRead;
  233. int m_nWrite;
  234. CRITICAL_SECTION m_switchsect;
  235. BOOL HasWriteInfo()
  236. {
  237. return m_RW_Buffer[m_nWrite].nInfoStart > 0;
  238. }
  239. BOOL HasReadInfo()
  240. {
  241. DWORD* pLen = (DWORD*)(m_RW_Buffer[m_nRead].buff + m_RW_Buffer[m_nRead].nInfoStart);
  242. return  *pLen != 0;
  243. }
  244. public:
  245. TwoFixBuffer()
  246. {
  247. ::InitializeCriticalSection(&m_switchsect);
  248. for (int n = 0; n < 2; n++)
  249. {
  250. memset(m_RW_Buffer[n].buff, 0, MAX_BUFFER_LEN + sizeof(DWORD));
  251. m_RW_Buffer[n].nInfoStart = 0;
  252. }
  253. m_nRead = 0;
  254. m_nWrite = 1;
  255. }
  256. ~TwoFixBuffer()
  257. {
  258. ::LeaveCriticalSection(&m_switchsect);
  259. ::DeleteCriticalSection(&m_switchsect);
  260. }
  261. //WriteInfo可以多个线程使用
  262. //其中nLen指内存长度
  263. BOOL WriteInfo(BYTE* szInfo, DWORD nLen)
  264. {
  265. if (nLen <= 0 || szInfo == NULL)
  266. return FALSE;
  267. ::EnterCriticalSection(&m_switchsect);
  268. BOOL bCanAdd = FALSE;
  269. DWORD nMemLen = nLen + sizeof(DWORD);
  270. DWORD nInfoStart = m_RW_Buffer[m_nWrite].nInfoStart;
  271. if (nInfoStart < MAX_BUFFER_LEN - nMemLen)
  272. {
  273. memcpy(m_RW_Buffer[m_nWrite].buff + nInfoStart, &nLen, sizeof(DWORD));
  274. memcpy(m_RW_Buffer[m_nWrite].buff + nInfoStart + sizeof(DWORD), szInfo, nLen);
  275. m_RW_Buffer[m_nWrite].nInfoStart += nMemLen;
  276. bCanAdd = TRUE;
  277. DWORD* pLen = (DWORD*)(m_RW_Buffer[m_nWrite].buff + nInfoStart + nMemLen);
  278. *pLen = 0;
  279. }
  280. ::LeaveCriticalSection(&m_switchsect);
  281. return bCanAdd;
  282. }
  283. //ReadInfo只能一个线程访问
  284. BYTE* ReadInfo()
  285. {
  286. BYTE* pInfo = NULL;
  287. if (HasReadInfo())
  288. {
  289. pInfo = m_RW_Buffer[m_nRead].buff + m_RW_Buffer[m_nRead].nInfoStart;
  290. DWORD nLen = *((DWORD*)pInfo);
  291. m_RW_Buffer[m_nRead].nInfoStart += nLen + sizeof(DWORD);
  292. }
  293. return pInfo;
  294. }
  295. void SwitchReadWrite()
  296. {
  297. if (!HasReadInfo() && HasWriteInfo())
  298. {
  299. ::EnterCriticalSection(&m_switchsect);
  300. //first clear read buffer
  301. m_RW_Buffer[m_nRead].nInfoStart = 0;
  302. DWORD* pLen = (DWORD*)m_RW_Buffer[m_nRead].buff;
  303. *pLen = 0;
  304. //switch read buffer and write buffer
  305. DWORD nTemp = m_nRead;
  306. m_nRead = m_nWrite;
  307. m_nWrite = nTemp;
  308. //read from head
  309. m_RW_Buffer[m_nRead].nInfoStart = 0;
  310. ::LeaveCriticalSection(&m_switchsect);
  311. }
  312. }
  313. };
  314. TwoFixBuffer g_TraceBuffer;
  315. HWND g_listwnd = NULL;
  316. long g_cnt = 0;
  317. int gTrace(LPCSTR fmt, ...)
  318. {
  319. if (g_listwnd == NULL)
  320. return -1;
  321. TCHAR tempbuff[256];
  322. g_cnt++;
  323. sprintf(tempbuff, "%d -- ", g_cnt);
  324. int n = strlen(tempbuff);
  325. va_list marker;
  326. va_start( marker, fmt );
  327. _vstprintf(tempbuff + n, fmt, marker);
  328. va_end( marker );
  329. n = strlen(tempbuff);
  330. g_TraceBuffer.WriteInfo((BYTE*)tempbuff, n + 1); //带0写入
  331. return 0;
  332. }
  333. int gTimeStamp(char* sDest, char* pTail)
  334. {
  335. assert(sDest);
  336. time_t curtm = ::time(NULL);
  337. struct tm* ptm = localtime(&curtm);
  338. return sprintf(sDest, "[%04d/%02d/%02d %02d:%02d:%02d]%s",
  339. ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, pTail);
  340. }
  341. void gTraceLogFile(LPCTSTR pBuffer, long nLen)
  342. {
  343. if (!gs_LogFile.BeginBatch())
  344. return;
  345. char szTime[128];
  346. int nTime = gTimeStamp(szTime, " ");
  347. gs_LogFile.TraceLog(szTime, nTime);
  348. gs_LogFile.TraceLog(pBuffer, nLen);
  349. gs_LogFile.TraceLog(_T("rn"), 2 * sizeof(TCHAR));
  350. gs_LogFile.EndBatch();
  351. }
  352. void gClearTrace()
  353. {
  354. if (g_listwnd)
  355. ::SendMessage(g_listwnd, LB_RESETCONTENT, 0, 0);
  356. }
  357. void gShowTrace()
  358. {
  359. if (!g_listwnd)
  360. return;
  361. static BOOL bLastRead = FALSE;
  362. char* pBuff = NULL;
  363. DWORD* pMem = NULL;
  364. int nPercent = 0;
  365. int n1 = ::SendMessage(g_listwnd, LB_GETCOUNT, 0, 0);
  366. int n = n1;
  367. while (1)
  368. {
  369. pMem = (DWORD*)g_TraceBuffer.ReadInfo();
  370. if (pMem)
  371. {
  372. pBuff = (char*)(pMem + 1);
  373. if (n > 0 && n % 8100 == 0)
  374. {
  375. ::SendMessage(g_listwnd, LB_DELETESTRING, 0, NULL);
  376. n = 0;
  377. }
  378. if (::SendMessage(g_listwnd, LB_ADDSTRING, 0, (LPARAM)pBuff) >= 0)
  379. n++;
  380. gTraceLogFile(pBuff, (*pMem) - 1); //去0写文件
  381. }
  382. else
  383. break;
  384. }
  385. if (n != n1)
  386. {
  387. ::SendMessage(g_listwnd, LB_SETCURSEL, (WPARAM)n - 1, 0);
  388. }
  389. g_TraceBuffer.SwitchReadWrite();
  390. }
  391. HINSTANCE g_hInst = 0;
  392. int g_nShowTime = 0;
  393. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, int nLogTime)
  394. {
  395. HWND hWnd;
  396.  
  397. hWnd = CreateWindow(g_szWindowClass, g_szWindowClass, WS_OVERLAPPEDWINDOW,
  398.   CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  399. if (!hWnd)
  400. {
  401.   return FALSE;
  402. }
  403. RECT rc = {0};
  404. GetClientRect(hWnd, &rc);
  405. g_listwnd = ::CreateWindow("ListBox", "Out", WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|LBS_NOINTEGRALHEIGHT, 0, 0, rc.right, rc.bottom, hWnd, NULL, hInstance, NULL);
  406. if (!g_listwnd)
  407.    return FALSE;
  408. ShowWindow(hWnd, nCmdShow);
  409. UpdateWindow(hWnd);
  410. g_nShowTime = SetTimer(hWnd, 1, nLogTime, NULL);
  411. g_hInst = hInstance;
  412. return TRUE;
  413. }
  414. // Mesage handler for about box.
  415. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  416. {
  417. switch (message)
  418. {
  419. case WM_INITDIALOG:
  420. return TRUE;
  421. case WM_COMMAND:
  422. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  423. {
  424. EndDialog(hDlg, LOWORD(wParam));
  425. return TRUE;
  426. }
  427. break;
  428. }
  429.     return FALSE;
  430. }
  431. //
  432. //  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
  433. //
  434. //  PURPOSE:  Processes messages for the main window.
  435. //
  436. //  WM_COMMAND - process the application menu
  437. //  WM_PAINT - Paint the main window
  438. //  WM_DESTROY - post a quit message and return
  439. //
  440. //
  441. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  442. {
  443. int wmId, wmEvent;
  444. PAINTSTRUCT ps;
  445. HDC hdc;
  446. switch (message) 
  447. {
  448. case WM_COMMAND:
  449. wmId    = LOWORD(wParam); 
  450. wmEvent = HIWORD(wParam); 
  451. // Parse the menu selections:
  452. switch (wmId)
  453. {
  454. case IDM_ABOUT:
  455.    DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  456.    break;
  457. case IDM_EXIT:
  458.    SendMessage(hWnd, WM_CLOSE, 0, 0);
  459.    break;
  460. case IDM_CLEARLOG:
  461.    gClearTrace();
  462.    break;
  463. case IDM_SHOWINFO:
  464. {
  465. S3PDBSocketPool* p = S3PDBSocketPool::Instance();
  466. if (p)
  467. p->ShowAllClientInfo();
  468. }
  469. break;
  470. default:
  471.    return DefWindowProc(hWnd, message, wParam, lParam);
  472. }
  473. break;
  474. case WM_PAINT:
  475. hdc = BeginPaint(hWnd, &ps);
  476. EndPaint(hWnd, &ps);
  477. break;
  478. case WM_DESTROY:
  479. if (g_nShowTime)
  480. KillTimer(hWnd, g_nShowTime);
  481. PostQuitMessage(0);
  482. break;
  483. case WM_CLOSE:
  484. if (::MessageBox(hWnd, "Are you sure ?", "warning", MB_YESNO) == IDYES)
  485. {
  486. DestroyWindow(hWnd);
  487. }
  488. break;
  489. case WM_SIZE:
  490. {
  491. RECT rc;
  492. GetClientRect(hWnd, &rc);
  493. MoveWindow(g_listwnd, 0, 0, rc.right, rc.bottom, TRUE);
  494. }
  495. break;
  496. case WM_TIMER:
  497. if (wParam == 1)
  498. gShowTrace();
  499. break;
  500. default:
  501. return DefWindowProc(hWnd, message, wParam, lParam);
  502.    }
  503.    return 0;
  504. }