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

模拟服务器

开发平台:

C/C++

  1. //******************************************************************************
  2. /*! file       Robot.cpp
  3. *   brief      简要描述
  4. *
  5. * 详细描述
  6. *   author 作者
  7. *   version 版本号
  8. *   date 2003-6-3 16:17:20
  9. *   sa 参考内容
  10. *   todo 需要完成退出时的帐号回收
  11. 退出时角色的删除
  12. g_csPlayerList没有用
  13. *******************************************************************************/
  14. #include "stdafx.h"
  15. #include "resource.h"
  16. #include "Player.h"
  17. #include "Robot.h"
  18. #include <objbase.h>
  19. #include <initguid.h>
  20. #include <process.h>
  21. #include <Shellapi.h>
  22. #include "..RobotManagerprotocol.h"
  23. #include "..RobotManagerstruct.h"
  24. #include "RainbowInterface.h"
  25. #include "library.h"
  26. #include "Macro.h"
  27. #include "Utils.h"
  28. #include "tstring.h"
  29. #include "Inifile.h"
  30. #include "buffer.h"
  31. #include "CriticalSection.h"
  32. #include "Event.h"
  33. using OnlineGameLib::Win32::CIniFile;
  34. using OnlineGameLib::Win32::GetAppFullPath;
  35. using OnlineGameLib::Win32::_tstring;
  36. using OnlineGameLib::Win32::CPackager;
  37. using OnlineGameLib::Win32::CCriticalSection;
  38. using OnlineGameLib::Win32::CEvent;
  39. PLAYER_LIST g_thePlayers;
  40. #define MAX_LOADSTRING 100
  41. // Global Variables:
  42. HINSTANCE g_hInst; // current instance
  43. TCHAR g_szBuffer[MAX_LOADSTRING]; // The title bar text
  44. TCHAR g_szWindowClass[MAX_LOADSTRING]; // The title bar text
  45. // 要跟随的角色的名字
  46. char g_szRoleName[32];
  47. char *g_pRoleName = g_szRoleName;
  48. NOTIFYICONDATA g_nidIconData = { 0 };
  49. const UINT g_unTrayIconID = 500;
  50. #define WM_TRAY_NOTIFY_MSG WM_USER + 0x100
  51. _tstring g_sAppPath;
  52. CIniFile g_theIniFile;
  53. HANDLE g_hWorkThread = INVALID_HANDLE_VALUE;
  54. CEvent g_hQuitEvent( NULL, true, false, "QuitEvent" );
  55. // 相对于RobotManager的客户
  56. IClient *g_pClientToManager = NULL;
  57. OnlineGameLib::Win32::CLibrary g_theRainbowLib( "rainbow.dll" );
  58. typedef HRESULT ( __stdcall * pfnCreateClientInterface )( REFIID riid, void **ppv );
  59. _tstring g_pAddressToManager;
  60. unsigned short g_usPortToManager = 0;
  61. bool StartupNetwork();
  62. void DestroyNetwork();
  63. void FreePlayerList();
  64. unsigned int __stdcall HelperThread( void *pParam );
  65. void OnDispatchTask(const void* pData);
  66. // Foward declarations of functions included in this code module:
  67. ATOM RegisterClass(HINSTANCE hInstance);
  68. BOOL InitInstance(HINSTANCE, int);
  69. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  70. LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  71. int APIENTRY WinMain(HINSTANCE hInstance,
  72.                      HINSTANCE hPrevInstance,
  73.                      LPSTR     lpCmdLine,
  74.                      int       nCmdShow)
  75. {
  76.   // TODO: Place code here.
  77. MSG msg;
  78. HACCEL hAccelTable;
  79. // Initialize global strings
  80. LoadString(hInstance, IDS_APP_TITLE, g_szBuffer, MAX_LOADSTRING);
  81. LoadString(hInstance, IDC_ROBOT, g_szWindowClass, MAX_LOADSTRING);
  82. RegisterClass(hInstance);
  83. g_sAppPath = GetAppFullPath( hInstance );
  84. char szIniFile[MAX_PATH];
  85. sprintf( szIniFile, "%srtcfg.ini", g_sAppPath.c_str() );
  86. g_theIniFile.SetFile( szIniFile );
  87. g_usPortToManager = g_theIniFile.ReadInteger( "Robot", "PORT", 5096 );
  88. g_pAddressToManager.resize( MAX_LOADSTRING );
  89. g_theIniFile.ReadString( "Robot", 
  90. "IPAddr", 
  91. const_cast< char * >( g_pAddressToManager.c_str() ), 
  92. MAX_LOADSTRING, 
  93. "..." );
  94. g_theIniFile.ReadString( "Role", "Main", g_szRoleName, 32, "" );
  95. if( !StartupNetwork())
  96. return FALSE;
  97. if (!InitInstance (hInstance, nCmdShow)) 
  98. return FALSE;
  99. ::Shell_NotifyIcon( NIM_ADD, &g_nidIconData );
  100. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_ROBOT);
  101. // Main message loop:
  102. while (GetMessage(&msg, NULL, 0, 0)) 
  103. {
  104. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
  105. {
  106. TranslateMessage(&msg);
  107. DispatchMessage(&msg);
  108. }
  109. }
  110. FreePlayerList();
  111. ::Shell_NotifyIcon( NIM_DELETE, &g_nidIconData );
  112. DestroyNetwork();
  113. return msg.wParam;
  114. }
  115. ATOM RegisterClass(HINSTANCE hInstance)
  116. {
  117. WNDCLASSEX wcex = { 0 };
  118. wcex.cbSize = sizeof(WNDCLASSEX); 
  119. wcex.lpfnWndProc = (WNDPROC)WndProc;
  120. wcex.hInstance = hInstance;
  121. wcex.lpszClassName = g_szWindowClass;
  122. return RegisterClassEx(&wcex);
  123. }
  124. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  125. {
  126.    HWND hWnd = NULL;
  127.    g_hInst = hInstance; // Store instance handle in our global variable
  128.    if ( NULL == ( hWnd = CreateWindow(g_szWindowClass, g_szBuffer, 0,
  129. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL) ) )
  130.    {
  131.       return FALSE;
  132.    }
  133. g_nidIconData.cbSize = sizeof( NOTIFYICONDATA );
  134. g_nidIconData.hWnd = hWnd;
  135. g_nidIconData.uID = g_unTrayIconID;
  136. g_nidIconData.uCallbackMessage = WM_TRAY_NOTIFY_MSG;
  137. g_nidIconData.uFlags = NIF_MESSAGE;
  138. strcpy( g_nidIconData.szTip, "Robot" );
  139. g_nidIconData.uFlags |= NIF_TIP;
  140. HICON hIcon = NULL;
  141. if ( NULL != ( hIcon = ::LoadIcon( hInstance, MAKEINTRESOURCE( IDI_TRAYICON ) ) ) )
  142. {
  143. g_nidIconData.hIcon = hIcon;
  144. g_nidIconData.uFlags |= NIF_ICON;
  145.    return TRUE;
  146. }
  147. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  148. {
  149. int wmId, wmEvent;
  150. switch (message) 
  151. {
  152. case WM_COMMAND:
  153. wmId    = LOWORD(wParam); 
  154. wmEvent = HIWORD(wParam); 
  155. // Parse the menu selections:
  156. switch (wmId)
  157. {
  158. case IDM_ABOUT:
  159.    DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  160.    break;
  161. case IDM_EXIT:
  162.    DestroyWindow(hWnd);
  163.    break;
  164. default:
  165.    return DefWindowProc(hWnd, message, wParam, lParam);
  166. }
  167. break;
  168. case WM_DESTROY:
  169. PostQuitMessage(0);
  170. break;
  171. case WM_TRAY_NOTIFY_MSG:
  172. {
  173. UINT uID = (UINT)wParam;
  174. UINT uMsg = (UINT)lParam;
  175. POINT pt = { 0 };
  176. if ( g_unTrayIconID == uID )
  177. {
  178. switch ( uMsg )
  179. {
  180. case WM_LBUTTONDOWN:
  181. case WM_RBUTTONDOWN:
  182. case WM_CONTEXTMENU:
  183. {
  184. ::GetCursorPos( &pt );
  185. HMENU hMenu = ::GetSubMenu( ::LoadMenu( g_hInst,
  186. MAKEINTRESOURCE( IDC_ROBOT ) ), 
  187. 0 );
  188. ::SetForegroundWindow( hWnd );
  189. ::TrackPopupMenu( hMenu, 
  190. TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  191. pt.x,
  192. pt.y,
  193. 0,
  194. hWnd,
  195. NULL );
  196. ::PostMessage( hWnd, WM_NULL, 0, 0 );
  197. }
  198. break;
  199. }
  200. }
  201. }
  202. break;
  203. default:
  204. return DefWindowProc(hWnd, message, wParam, lParam);
  205.    }
  206.    return 0;
  207. }
  208. // Mesage handler for about box.
  209. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  210. {
  211. switch (message)
  212. {
  213. case WM_INITDIALOG:
  214. return TRUE;
  215. case WM_COMMAND:
  216. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  217. {
  218. EndDialog(hDlg, LOWORD(wParam));
  219. return TRUE;
  220. }
  221. break;
  222. }
  223.     return FALSE;
  224. }
  225. //******************************************************************************
  226. /*! fn     bool StartupNetwork()
  227. *   brief   启动与RobotManager的连接,robot是RobotManager的客户,RobotManager向每个Robot
  228. 分配帐号,密码和角色的名字
  229. *******************************************************************************/
  230. bool StartupNetwork()
  231. {
  232. // 启动与RobotManager的连接
  233. pfnCreateClientInterface pClientFactroyFun = ( pfnCreateClientInterface )( g_theRainbowLib.GetProcAddress( _T( "CreateInterface" ) ) );
  234. IClientFactory *pClientFactory = NULL;
  235. if ( pClientFactroyFun && SUCCEEDED( pClientFactroyFun( IID_IClientFactory, reinterpret_cast< void ** >( &pClientFactory ) ) ) )
  236. {
  237. pClientFactory->SetEnvironment( 50, 1024 );
  238. pClientFactory->CreateClientInterface( IID_IESClient, reinterpret_cast< void ** >( &g_pClientToManager ) );
  239. SAFE_RELEASE( pClientFactory );
  240. }
  241. if ( g_pClientToManager )
  242. {
  243. g_pClientToManager->Startup();
  244. g_pClientToManager->RegisterMsgFilter( 0, NULL );
  245. if ( FAILED( g_pClientToManager->ConnectTo( g_pAddressToManager.c_str(), g_usPortToManager ) ) )
  246. {
  247. g_pClientToManager->Cleanup();
  248. SAFE_RELEASE( g_pClientToManager );
  249. return false;
  250. }
  251. }
  252. // 启动工作线程
  253. IClient *pCloneClient = NULL;
  254. g_pClientToManager->QueryInterface( IID_IESClient, reinterpret_cast< void ** >( &pCloneClient ) );
  255. unsigned int threadID = 0;
  256. g_hWorkThread = (HANDLE)::_beginthreadex(0, 
  257. 0, 
  258. HelperThread,
  259. ( void * )pCloneClient, 
  260. 0, 
  261. &threadID );
  262. if ( g_hWorkThread == INVALID_HANDLE_VALUE )
  263. {
  264. return false;
  265. }
  266. // 向RobotManager发送消息,请求登陆帐号,和服务器地址
  267. tagReqT_CMD rt;
  268. rt.cProtocol = enumRequireTask;
  269. g_pClientToManager->SendPackToServer( &rt, sizeof( rt ) );
  270. return true;
  271. }
  272. void DestroyNetwork()
  273. {
  274. // 关闭网络连接
  275. if ( g_pClientToManager )
  276. {
  277. g_pClientToManager->Cleanup();
  278. SAFE_RELEASE( g_pClientToManager );
  279. }
  280. // 中止工作线程
  281. g_hQuitEvent.Set();
  282. if ( WAIT_TIMEOUT == ::WaitForSingleObject( g_hWorkThread, 2000 ) )
  283. {
  284. ::TerminateThread( g_hWorkThread, 0 );
  285. }
  286. if ( INVALID_HANDLE_VALUE != g_hWorkThread )
  287. {
  288. SAFE_CLOSEHANDLE( g_hWorkThread );
  289. }
  290. }
  291. // Robot 与 RobotManager 通讯的线程
  292. unsigned int __stdcall HelperThread( void *pParam )
  293. {
  294. IClient *pCloneClient = ( IClient * )pParam;
  295. ASSERT( pCloneClient );
  296. while ( !g_hQuitEvent.Wait( 0 ) )
  297. {
  298. size_t datalength = 0;
  299. const void *pData = pCloneClient->GetPackFromServer( datalength );
  300. if ( pData && datalength )
  301. {
  302. BYTE cProtocol = CPackager::Peek( pData );
  303. switch ( cProtocol )
  304. {
  305. case enumDispatchTask:
  306. OnDispatchTask(pData);
  307. break;
  308. default:
  309. break;
  310. }
  311. }
  312. ::Sleep( 40 );
  313. }
  314. SAFE_RELEASE( pCloneClient );
  315. return 0L;
  316. }
  317. //******************************************************************************
  318. /*! fn     void OnDispatchTask(const void* pData)
  319. *   brief  从RobotManager接受任务
  320. *******************************************************************************/
  321. void OnDispatchTask(const void* pData)
  322. {
  323. tagDspT_INFO *pDTI = ( tagDspT_INFO * )pData;
  324. if ( pDTI->dwVersion != 1 )
  325. {
  326. ::MessageBox( NULL, "Version is old, Please update this application", "Info", MB_ICONEXCLAMATION );
  327. return;
  328. }
  329. size_t nAccCount = pDTI->nAccCount;
  330. size_t nNameLen = pDTI->nNameLen;
  331. char* pAccName = pDTI->szAccName; 
  332. for ( int i = 0; i < nAccCount; i ++ )
  333. {
  334. memcpy( g_szBuffer, pAccName + i*nNameLen, nNameLen );
  335. IPlayer *pPlayer = new CPlayer( pDTI->theGameSvrInfo.szIP, 
  336. pDTI->theGameSvrInfo.nPort,
  337. g_szBuffer );
  338. pPlayer->ConnectToGateway();
  339. g_thePlayers.push_back( pPlayer );
  340. }
  341. }
  342. //******************************************************************************
  343. /*! fn     void FreePlayerList()
  344. *   brief  释放所有的Player
  345. *******************************************************************************/
  346. void FreePlayerList()
  347. {
  348. CCriticalSection::Owner locker( g_csPlayerList);
  349. PLAYER_LIST::iterator it;
  350. for ( it = g_thePlayers.begin(); it != g_thePlayers.end(); it ++ )
  351. {
  352. IPlayer *pPlayer = ( *it );
  353. if ( pPlayer )
  354. {
  355. delete pPlayer;
  356. }
  357. }
  358. }