ROA.cpp
上传用户:tianheyiqi
上传日期:2010-04-16
资源大小:282k
文件大小:30k
源码类别:

外挂编程

开发平台:

Visual C++

  1. // ROA.cpp : Defines the class behaviors for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "ROA.h"
  5. #include "MainFrm.h"
  6. #include "ROADoc.h"
  7. #include "ROAView.h"
  8. #include "DlgOption.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. CROAApp theApp;
  15. int processModeMvp()
  16. {
  17. int nTargetIndex = monsters.FindId(dwMvpId);
  18. if(settingmvp.bAttack && nTargetIndex != -1)
  19. {
  20. CString strSkillName = _T("");
  21. int nSkillId = -1;
  22. do
  23. {
  24. // Check for REGION ATTACK
  25. if(settingmvp.bRegionAtk)
  26. {
  27. if(CheckForRegionAttack(strSkillName, nTargetIndex))
  28. break;
  29. }
  30. // Check for ATTACK2
  31. if(settingmvp.bAttack2)
  32. {
  33. for(int j=0; j<spells.GetSize(); j++)
  34. {
  35. if((spells[j].pntPos.x == monsters[nTargetIndex].pntPos.x && spells[j].pntPos.y == monsters[nTargetIndex].pntPos.y) ||
  36. (spells[j].pntPos.x == monsters[nTargetIndex].pntTo.x && spells[j].pntPos.y == monsters[nTargetIndex].pntTo.y))
  37. {
  38. if(mapStatus011f.FindValue(spells[j].wSkill).CompareNoCase(settingmvp.strAttack2Cond) == 0)
  39. {
  40. strSkillName = settingmvp.strAttack2Skill;
  41. break;
  42. }
  43. }
  44. }
  45. }
  46. /* if(0 != monsters[nTargetIndex].nProtecting)
  47. if(utlFindSkillIdByAlias(settingmvp.strAttack2Cond) == monsters[nTargetIndex].nProtecting)
  48. break;}*/
  49. if(strSkillName.IsEmpty())
  50. strSkillName = settingmvp.strAttackSkill;
  51. break;
  52. }while(0);
  53. if(0 != strSkillName.CompareNoCase(_T("停止攻击")))
  54. {
  55. do
  56. {
  57. POINT pnt;
  58. if(settingmvp.bFollow &&
  59. utlDistanceFrom(you.pntTo, monsters[nTargetIndex].pntPos) > 3 &&
  60. field.FindNearestPoint(you.pntTo, monsters[nTargetIndex].pntPos, &pnt))
  61. {
  62. sendMove(pnt);
  63. break;
  64. }
  65. if(0 == strSkillName.CompareNoCase(_T("普通物理攻击")))
  66. {
  67. for(int attack=0; attack < utlGetAttackPerSecond(); attack++)
  68. sendAttack(monsters[nTargetIndex].dwId, 0);
  69. break;
  70. }
  71. nSkillId = utlFindSkillByAlias(strSkillName);
  72. if(nSkillId != -1 && you.wSp > 20)
  73. {
  74. for(int attack=0; attack < utlGetAttackPerSecond(); attack++)
  75. {
  76. sendUseSkill(skills[nSkillId].wLevel, (WORD)skills[nSkillId].dwId, monsters[nTargetIndex].dwId);
  77. }
  78. break;
  79. }
  80. }while(0);
  81. }
  82. }
  83. return(0);
  84. }
  85. int processModeNormal()
  86. {
  87. if(bAutoSearch && dwAutoSearchTick != 0 && GetTickCount() > dwAutoSearchTick)
  88. {
  89. if(strAutoSearchMap.CompareNoCase(field.m_strFieldname) == 0)
  90. {
  91. utlUseTeleport(1);
  92. dwAutoSearchTick = 0;
  93. }
  94. else
  95. {
  96. // Lock map
  97. utlSetAutoSearchMvp(false);
  98. }
  99. }
  100. if(bAutoSa && GetTickCount() > dwAutoSaTick)
  101. {
  102. int nIndex = utlFindSkillByAlias(_T("随机技能"));
  103. if(nIndex != -1 && you.wSp >= 50)
  104. {
  105. sendUseSkill(skills[nIndex].wLevel, (unsigned short)skills[nIndex].dwId, dwAccountId);
  106. dwAutoSaTick = GetTickCount() + 500;
  107. }
  108. else
  109. {
  110. ufAutoSaClassChange(0);
  111. }
  112. }
  113. return(0);
  114. }
  115. int processShortkey()
  116. {
  117. EnterCriticalSection(&csShortcutFuncs);
  118. if(curFunc != NULL)
  119. {
  120. curFunc(curFuncPara);
  121. curFunc = NULL;
  122. curFuncPara = 0;
  123. }
  124. LeaveCriticalSection(&csShortcutFuncs);
  125. return(0);
  126. }
  127. int LaunchRoProgram()
  128. {
  129. int nRet = -1;
  130. CString strTemp, strRoFile, strRoPath, strError, strRoaFile, strRoaInject, strDInput, strDInputFake;
  131. CString strRoExec, strRoaExec;
  132. int nIndex;
  133. int nClientType = eUnknown;
  134. strTemp = option.strLauncher;
  135. do
  136. {
  137. // Get EXE Name
  138. nIndex = strTemp.ReverseFind(_T('\'));
  139. if(-1 == nIndex)
  140. {
  141. strError = "客户端启动程序定义错误,请检查并重新定义!";
  142. nRet = -2;
  143. break;
  144. }
  145. strRoFile = strTemp.Right(strTemp.GetLength() - nIndex -1);
  146. strRoPath = strTemp.Left(nIndex + 1);
  147. if(strRoFile.CompareNoCase("roclient.exe") == 0)
  148. {
  149. nClientType = eRagexe;
  150. }
  151. else if(strRoFile.CompareNoCase("sakclient.exe") == 0)
  152. {
  153. nClientType = eSakexe;
  154. }
  155. else if(strRoFile.CompareNoCase("sakexe.exe") == 0 || strRoFile.CompareNoCase("ragexe.exe") == 0)
  156. {
  157. nClientType = eSfExe;
  158. }
  159. if(nClientType == eUnknown)
  160. {
  161. strError = "未知RO客户端版本,请去论坛发布所使用的SF及客户端类型!";
  162. nRet = -3;
  163. break;
  164. }
  165. // COPY INJECT
  166. strRoaInject = strRoPath + "ROAInject.dll";
  167. if(0 == ::CopyFile("ROAInject.dll", strRoaInject, false))
  168. {
  169. strError = "无法复制ROAInject.dll,请检查客户端目录后重新启动ROA!";
  170. nRet = -4;
  171. break;
  172. }
  173. // Check for dinput.dll
  174. strDInput = strRoPath + "dinput.dll";
  175. strDInputFake = strRoPath + "dinput.dl_";
  176. if(utlGetFileSize(strDInput) > 0)
  177. {
  178. strTemp = _T("发现十全大补丸,十全大补丸中的键盘和鼠标功能有可能会使使用ROA的客户端无法正常运行,是否要禁止?");
  179. utlLogout(strTemp, eLogError, false);
  180. if(IDYES == AfxMessageBox(strTemp, MB_ICONQUESTION | MB_YESNO))
  181. {
  182. ::CopyFile(strDInput, strDInputFake, false);
  183. DeleteFile(strDInput);
  184. }
  185. }
  186. // COPY RAGEXE
  187. switch(nClientType)
  188. {
  189. case eRagexe:
  190. strRoExec = strRoPath + "ragexe.exe";
  191. strRoaFile = "ROARagexe.exe";
  192. break;
  193. case eSakexe:
  194. strRoExec = strRoPath + "sakexe.exe";
  195. strRoaFile = "ROASakexe.exe";
  196. break;
  197. case eSfExe:
  198. strRoExec = strRoPath + strRoFile;
  199. strRoaFile = "ROA" + strRoFile;
  200. break;
  201. default:
  202. ASSERT(false);
  203. }
  204. strRoaExec = strRoPath + strRoaFile;
  205. if(utlGetFileSize(strRoExec) > 200000)
  206. {
  207. if(0 == ::CopyFile(strRoExec, strRoaExec, false))
  208. {
  209. strError.Format(_T("无法复制%s,请检查客户端目录后重新启动ROA!"), strRoaExec);
  210. nRet = -6;
  211. break;
  212. }
  213. }
  214. // COPY LOADER
  215. if(0 == ::CopyFile("ROALoader.exe", strRoExec, false))
  216. {
  217. strError.Format(_T("无法复制%s,请检查客户端目录后重新启动ROA!"), strRoExec);
  218. nRet = -8;
  219. break;
  220. }
  221. // WRITE REGISTRY
  222. {
  223. HKEY hKey;
  224. long lRet = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\Gravity Soft", &hKey);
  225. if(lRet == ERROR_SUCCESS && hKey != 0)
  226. {
  227. lRet = RegSetValue(hKey, "LaunchTarget", REG_SZ, (LPCTSTR)strRoaFile, strRoaFile.GetLength());
  228. strTemp.Format("%d", nClientType);
  229. lRet |= RegSetValue(hKey, "LaunchType", REG_SZ, (LPCTSTR)strTemp, strTemp.GetLength());
  230. lRet |= RegSetValue(hKey, "LaunchParam", REG_SZ, (LPCTSTR)option.strLaunchParam, option.strLaunchParam.GetLength());
  231. RegCloseKey(hKey);
  232. strcpy(cSendKey, strRoaFile);
  233. if(lRet != ERROR_SUCCESS)
  234. {
  235. strError = "无法写入注册表,请重新启动ROA!";
  236. nRet = -9;
  237. break;
  238. }
  239. }
  240. else
  241. {
  242. strError = "无法打开注册表,请检查后重新启动ROA!";
  243. nRet = -10;
  244. break;
  245. }
  246. }
  247. // Launch process
  248. {
  249. STARTUPINFO si = {sizeof(STARTUPINFO)};
  250. PROCESS_INFORMATION pi;
  251. CreateProcess(NULL, (LPTSTR)(LPCTSTR)option.strLauncher, NULL, NULL, true, CREATE_DEFAULT_ERROR_MODE,
  252. NULL, strRoPath, &si, &pi);
  253. nRet = 0;
  254. }
  255. }while(0);
  256. if(nRet != 0)
  257. {
  258. strTemp = strError;
  259. strError.Format(_T("%s(ERROR=%d)"), strTemp, nRet);
  260. AfxMessageBox(strError, MB_ICONSTOP | MB_OK);
  261. utlLogout(strError, eLogError, false);
  262. }
  263. return(nRet);
  264. }
  265. int parseRecvPacket(char *buf, int len)
  266. {
  267. static char recvbuf[MAX_BUFFER_LEN*3];
  268. static int recvbuflen = 0;
  269. memcpy(recvbuf+recvbuflen, buf, len);
  270. recvbuflen += len;
  271. while(recvbuflen > 0)
  272. {
  273. int ret = parseRecvData(recvbuf, recvbuflen);
  274. if(ret == -1)
  275. {
  276. recvbuflen = 0;
  277. break;
  278. }else
  279. if(ret > recvbuflen)
  280. {
  281. break;
  282. }else
  283. {
  284. memcpy(recvbuf, recvbuf+ret, recvbuflen-ret);
  285. recvbuflen -= ret;
  286. }
  287. }
  288. return(0);
  289. }
  290. int parseInfoPacket(char *buf, int len)
  291. {
  292. WORD port;
  293. port = buf[0]*256 + buf[0];
  294. if(port != 2350)
  295. {
  296. switch(nConnState)
  297. {
  298. case 1:
  299. memcpy(serverip[0], buf, 6);
  300. serverip[1][0] = 0;
  301. serverip[2][0] = 0;
  302. break;
  303. case 2:
  304. memcpy(serverip[1], buf, 6);
  305. serverip[2][0] = 0;
  306. break;
  307. case 4:
  308. memcpy(serverip[2], buf, 6);
  309. break;
  310. }
  311. }
  312. return(0);
  313. }
  314. int parseSendPacket(char *buf, int len)
  315. {
  316. parseSendData(buf, len, false);
  317. return(0);
  318. }
  319. int connectToInject()
  320. {
  321. int nFuncRet = -1, nRet;
  322. CString strError;
  323. fd_set readfds;
  324. timeval tv;
  325. tv.tv_sec = 0;
  326. tv.tv_usec = 10;
  327. #ifdef _DEBUG
  328. DWORD timereconnect = GetTickCount();
  329. #endif
  330. do
  331. {
  332. sockServer.Close();
  333. if(!sockServer.Create(ROA_PORT, SOCK_STREAM, "127.0.0.1"))
  334. {
  335. strError.Format("Failed to create socket on port %d!", ROA_PORT);
  336. utlLogout(strError, eLogError, false);
  337. ::MessageBox(AfxGetMainWnd()->m_hWnd, strError, "ROA ERROR", MB_OK | MB_ICONSTOP);
  338. break;
  339. }
  340. if(!sockServer.Listen(5))
  341. {
  342. strError.Format("Failed to listen!");
  343. utlLogout(strError, eLogError, false);
  344. ::MessageBox(AfxGetMainWnd()->m_hWnd, strError, "ROA ERROR", MB_OK | MB_ICONSTOP);
  345. sockServer.Close();
  346. break;
  347. }
  348. sockInject.Close();
  349. do
  350. {
  351. if(1 == nThreadTerm)
  352. {
  353. nRet = SOCKET_ERROR; // Force to quit
  354. break;
  355. }
  356. readfds.fd_count = 1;
  357. readfds.fd_array[0] = sockServer.m_hSocket;
  358. Sleep(200);
  359. nRet = select(0, &readfds, 0, 0, &tv);
  360. }while(nRet == 0);
  361. if(nRet == SOCKET_ERROR)
  362. break;
  363. if(sockServer.Accept(sockInject))
  364. nFuncRet = 0;
  365. }while(0);
  366. #ifdef _DEBUG
  367. TRACE("PROC_RECONNECT: %dn", GetTickCount() - timereconnect);
  368. #endif
  369. return(nFuncRet);
  370. }
  371. void loadKeyboardHook()
  372. {
  373. HOOKPROC keybdproc;
  374. hInstDll = LoadLibrary((LPCTSTR) "ROATools.dll"); 
  375. keybdproc = (HOOKPROC)GetProcAddress(hInstDll, "KeyboardProc"); 
  376. if(keybdproc != NULL && hInstDll != NULL)
  377. hHook = SetWindowsHookEx(WH_KEYBOARD, keybdproc, hInstDll,0); 
  378. else
  379. hHook = NULL;
  380. return;
  381. }
  382. UINT _workingThread(LPVOID lpPara)
  383. {
  384. CString strError;
  385. CString strTemp;
  386. DWORD dwSync = GetTickCount();
  387. DWORD dwKeepAlive = 0; //force to connect first time
  388. DWORD dwCheckTime = 0;
  389. char sockbuffer[MAX_BUFFER_LEN];
  390. static char buffer[MAX_BUFFER_LEN*3];
  391. static int buflen = 0;
  392. int nBytesRecv;
  393. DWORD dwSendWelcome = 0;
  394. CString strFile, strPath;
  395. // Receive
  396. fd_set readfds;
  397. timeval tv;
  398. // Load Keyboard Hook
  399. loadKeyboardHook();
  400. // Init Server Ip
  401. memset(serverip, 0, 6*3);
  402. while(true)
  403. {
  404. // Check for terminate
  405. if(1 == nThreadTerm)
  406. {
  407. break;
  408. }
  409. // Keep alive
  410. if(GetTickCount() - dwKeepAlive > 12000)
  411. {
  412. if(0 == connectToInject())
  413. {
  414. bConnected = true;
  415. MessageBeep(MB_OK);
  416. dwKeepAlive = GetTickCount();
  417. }
  418. else
  419. {
  420. bConnected = false;
  421. strError.Format("Failed to connect to RO Client!");
  422. utlLogout(strError, eLogError, false);
  423. ::MessageBox(AfxGetMainWnd()->m_hWnd, strError, "ROA ERROR", MB_OK | MB_ICONSTOP);
  424. break;
  425. }
  426. }
  427. // Sync
  428. if(GetTickCount() - dwSync > 5000)
  429. {
  430. sendSyncInject();
  431. dwSync = GetTickCount();
  432. }
  433. // Select
  434. while(true)
  435. {
  436. tv.tv_sec = 0;
  437. tv.tv_usec = 1000;
  438. readfds.fd_count = 1;
  439. readfds.fd_array[0] = sockInject.m_hSocket;
  440. if(0 != select(0, &readfds, 0, 0, &tv))
  441. break;
  442. // ShortKey
  443. processShortkey();
  444. Sleep(200);
  445. }
  446. // Process packets
  447. TRACE("PROC_PRE-RECVn");
  448. nBytesRecv = sockInject.Receive(sockbuffer, MAX_BUFFER_LEN);
  449. TRACE("PROC_RECV: %dn", nBytesRecv);
  450. if(nBytesRecv <= 0)
  451. {
  452. int err = sockInject.GetLastError();
  453. if(err != 10053)
  454. {
  455. strTemp.Format("Receive error: code:%d", err);
  456. utlLogout(strTemp, eLogError, false);
  457. break;
  458. }
  459. dwKeepAlive = 0;  // force to reconnect
  460. continue;
  461. }
  462. memcpy(buffer + buflen, sockbuffer, nBytesRecv);
  463. buflen += nBytesRecv;
  464. while(buflen >= 3)
  465. {
  466. char cPackType = *buffer;
  467. int nPackLen = *((WORD*)(buffer+1));
  468. int nParsed = 0;
  469. if(cPackType == 'K')
  470. {
  471. // KEEP ALIVE
  472. nParsed = 3;
  473. }
  474. else
  475. {
  476. if((cPackType != 'R' && cPackType != 'S' && cPackType != 'I') || nPackLen > MAX_BUFFER_LEN)
  477. {
  478. // Found Illegle Package, RESET
  479. buflen = 0;
  480. break;
  481. }
  482. if(buflen < nPackLen + 3)
  483. {
  484. // Incompleted packet
  485. strTemp.Format("(%d/%d)", nPackLen + 3, buflen);
  486. strTemp += utlPrintHex(buffer, buflen);
  487. utlLogout(strTemp, eLogDebug, false);
  488. utlLogout("Found incompleted packet, receive next package!", eLogError, false);
  489. break;
  490. }
  491. if(cPackType == 'S')
  492. {
  493. // SEND
  494. strTemp.Format(_T(">>>(%d) %s"), nPackLen, utlPrintHex(buffer+3, nPackLen));
  495. utlLogout(strTemp, eLogDebug, false);
  496. parseSendPacket(buffer+3, nPackLen);
  497. nParsed = nPackLen + 3;
  498. }
  499. else
  500. {
  501. if(cPackType == 'R')
  502. {
  503. // RECEIVE
  504. strTemp.Format(_T("<<<(%d) %s"), nPackLen, utlPrintHex(buffer+3, nPackLen));
  505. utlLogout(strTemp, eLogDebug, false);
  506. parseRecvPacket(buffer+3, nPackLen);
  507. nParsed = nPackLen + 3;
  508. }
  509. else
  510. {
  511. // INFO
  512. parseInfoPacket(buffer+3, nPackLen);
  513. nParsed = nPackLen + 3;
  514. }
  515. }
  516. }
  517. // Shift buffer
  518. memcpy(buffer, buffer+nParsed, buflen-nParsed);
  519. buflen -= nParsed;
  520. }
  521. processShortkey();
  522. dwKeepAlive = GetTickCount();
  523. if(nConnState < 5)
  524. {
  525. Sleep(200);
  526. continue;
  527. }
  528. // Do Ai
  529. if(!bWelcomeSent)
  530. {
  531. if(dwSendWelcome == 0)
  532. {
  533. dwSendWelcome = GetTickCount() + option.nWelcomeDelay;
  534. }
  535. else
  536. {
  537. if(GetTickCount() >= dwSendWelcome)
  538. {
  539. utlLoadBossInfo();
  540. sendWelcomeMessage();
  541. }
  542. }
  543. }
  544. // Process Mode Normal
  545. if(mode == eModeNormal)
  546. {
  547. processModeNormal();
  548. }
  549. if(mode == eModeMvp)
  550. {
  551. processModeMvp();
  552. }
  553. // Process for important items
  554. if(option.bAutoPickup/* && option.bMovePickup*/)
  555. {
  556. for(int i=0; i<items.GetSize(); i++)
  557. {
  558. if(items[i].nPickupFailed < 500)
  559. {
  560. if(utlDistanceFrom(items[i].pntPos, you.pntTo) <= option.nPickupDistance || utlDistanceFrom(items[i].pntPos, you.pntPos) <= option.nPickupDistance)
  561. {
  562. sendTake(items[i].dwId);
  563. }
  564. }
  565. }
  566. }
  567. // Process for miscs
  568. if(GetTickCount() - dwCheckTime > 1000)
  569. {
  570. for(int i=0; i<players.GetSize(); i++)
  571. {
  572. if(strcmp(players[i].cName, _T("Unknown")) == 0)
  573. {
  574. strcpy(players[i].cName, _T("Unknown*"));
  575. sendGetPlayerInfo(players[i].dwId);
  576. }
  577. }
  578. if(option.bBossInfo)
  579. utlPopupBossWarning();
  580. dwCheckTime = GetTickCount();
  581. }
  582. Sleep(100);
  583. }
  584. bConnected = false;
  585. sockInject.Close();
  586. sockServer.Close();
  587. if(hHook != NULL)
  588. UnhookWindowsHookEx(hHook);
  589. AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0);
  590. return(0);
  591. }
  592. /////////////////////////////////////////////////////////////////////////////
  593. // CROAApp
  594. BEGIN_MESSAGE_MAP(CROAApp, CWinApp)
  595. //{{AFX_MSG_MAP(CROAApp)
  596. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  597. //}}AFX_MSG_MAP
  598. // Standard file based document commands
  599. ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
  600. ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
  601. END_MESSAGE_MAP()
  602. /////////////////////////////////////////////////////////////////////////////
  603. // CROAApp construction
  604. CROAApp::CROAApp()
  605. {
  606. // TODO: add construction code here,
  607. // Place all significant initialization in InitInstance
  608. }
  609. /////////////////////////////////////////////////////////////////////////////
  610. // The one and only CROAApp object
  611. /////////////////////////////////////////////////////////////////////////////
  612. // CROAApp initialization
  613. BOOL CROAApp::InitInstance()
  614. {
  615. AfxEnableControlContainer();
  616. // Standard initialization
  617. // If you are not using these features and wish to reduce the size
  618. //  of your final executable, you should remove from the following
  619. //  the specific initialization routines you do not need.
  620. #ifdef _AFXDLL
  621. Enable3dControls(); // Call this when using MFC in a shared DLL
  622. #else
  623. Enable3dControlsStatic(); // Call this when linking to MFC statically
  624. #endif
  625. // Check for WinSock dll and version
  626. WORD wVersionRequested;
  627. WSADATA wsaData;
  628. int err;
  629. srand( (unsigned)time( NULL ) );
  630.  
  631. wVersionRequested = MAKEWORD( 2, 2 );
  632.   err = WSAStartup( wVersionRequested, &wsaData );
  633. if ( err != 0 )
  634. {
  635. ::MessageBox(0, "WinSock DLL could not be found!", "ROA ERROR", MB_OK | MB_ICONSTOP);
  636. return(-1);
  637. }
  638.  
  639. if ( LOBYTE( wsaData.wVersion ) != 2 ||
  640.  HIBYTE( wsaData.wVersion ) != 2 )
  641. {
  642. WSACleanup( );
  643. ::MessageBox(0, "WinSock DLL version error!", "ROA ERROR", MB_OK | MB_ICONSTOP);
  644. return(-1); 
  645. }
  646. if(!fLog.Open("Packets.log", CFile::modeWrite | CFile::modeCreate | CFile::shareDenyNone))
  647. {
  648. WSACleanup( );
  649. ::MessageBox(0, "Failed to create log file!", "ROA ERROR", MB_OK | MB_ICONSTOP);
  650. return(-1); 
  651. }
  652. pWorkingThread = NULL;
  653. bConnected = false;
  654. memset(cSendKey, 0, sizeof(cSendKey));
  655. srand( (unsigned) time(NULL) );
  656. // The one and only window has been initialized, so show and update it.
  657. InitializeCriticalSection(&csShortcutFuncs);
  658. // Change the registry key under which our settings are stored.
  659. // TODO: You should modify this string to be something appropriate
  660. // such as the name of your company or organization.
  661. SetRegistryKey(_T("Local AppWizard-Generated Applications"));
  662. LoadStdProfileSettings();  // Load standard INI file options (including MRU)
  663. utlLoadOption(option);
  664. CDlgOption dlgOption(false);
  665. dlgOption.m_option = option;
  666. bIsModal = true;
  667. if(dlgOption.DoModal() != IDOK)
  668. {
  669. return(0);
  670. }
  671. bIsModal = false;
  672. option = dlgOption.m_option;
  673. utlSaveOption(option);
  674. utlParseHpSpItems();
  675. if(LaunchRoProgram() < 0)
  676. return(0);
  677. // Register the application's document templates.  Document templates
  678. //  serve as the connection between documents, frame windows and views.
  679. CSingleDocTemplate* pDocTemplate;
  680. pDocTemplate = new CSingleDocTemplate(
  681. IDR_MAINFRAME,
  682. RUNTIME_CLASS(CROADoc),
  683. RUNTIME_CLASS(CMainFrame),       // main SDI frame window
  684. RUNTIME_CLASS(CROAView));
  685. AddDocTemplate(pDocTemplate);
  686. // Parse command line for standard shell commands, DDE, file open
  687. CCommandLineInfo cmdInfo;
  688. ParseCommandLine(cmdInfo);
  689. // Dispatch commands specified on the command line
  690. if (!ProcessShellCommand(cmdInfo))
  691. return FALSE;
  692. m_pMainWnd->ShowWindow(SW_SHOWMINIMIZED);
  693. m_pMainWnd->UpdateWindow();
  694. return TRUE;
  695. }
  696. /////////////////////////////////////////////////////////////////////////////
  697. // CAboutDlg dialog used for App About
  698. class CAboutDlg : public CDialog
  699. {
  700. public:
  701. CAboutDlg();
  702. // Dialog Data
  703. //{{AFX_DATA(CAboutDlg)
  704. enum { IDD = IDD_ABOUTBOX };
  705. //}}AFX_DATA
  706. // ClassWizard generated virtual function overrides
  707. //{{AFX_VIRTUAL(CAboutDlg)
  708. protected:
  709. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  710. //}}AFX_VIRTUAL
  711. // Implementation
  712. protected:
  713. //{{AFX_MSG(CAboutDlg)
  714. // No message handlers
  715. //}}AFX_MSG
  716. DECLARE_MESSAGE_MAP()
  717. };
  718. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  719. {
  720. //{{AFX_DATA_INIT(CAboutDlg)
  721. //}}AFX_DATA_INIT
  722. }
  723. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  724. {
  725. CDialog::DoDataExchange(pDX);
  726. //{{AFX_DATA_MAP(CAboutDlg)
  727. //}}AFX_DATA_MAP
  728. }
  729. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  730. //{{AFX_MSG_MAP(CAboutDlg)
  731. // No message handlers
  732. //}}AFX_MSG_MAP
  733. END_MESSAGE_MAP()
  734. // App command to run the dialog
  735. void CROAApp::OnAppAbout()
  736. {
  737. CAboutDlg aboutDlg;
  738. bIsModal = true;
  739. aboutDlg.DoModal();
  740. bIsModal = false;
  741. }
  742. /////////////////////////////////////////////////////////////////////////////
  743. // CROAApp message handlers
  744. int CROAApp::Start()
  745. {
  746. nConnState = 1;
  747. dwAccountId = 0;
  748. nCharSelected = -1;
  749. dwCharId = 0;
  750. dwSessionId = 0;
  751. mode = eModeNormal;
  752. bWelcomeSent = false;
  753. bProfileLoaded = false;
  754. curFunc = NULL;
  755. curFuncPara = 0;
  756. bFlyUsed = false;
  757. bAutoSearch = false;
  758. strAutoSearchMap.Empty();
  759. bAutoSa = false;
  760. dwAutoSearchTick = 0;
  761. dwAttackTick = 0;
  762. dwUseItemTick = 0;
  763. bAiEnabled = false;
  764. pWorkingThread = NULL;
  765. nThreadTerm = 0;
  766. pWorkingThread = AfxBeginThread(_workingThread, NULL, THREAD_PRIORITY_ABOVE_NORMAL);
  767. if( pWorkingThread == NULL )
  768. return( false );
  769. return(true);
  770. }
  771. int CROAApp::ExitInstance() 
  772. {
  773. // TODO: Add your specialized code here and/or call the base class
  774. if(hInstDll != NULL)
  775. ::FreeLibrary(hInstDll);
  776. return CWinApp::ExitInstance();
  777. }
  778. void ufDummy(DWORD dwPara)
  779. {
  780. return;
  781. }
  782. void ufShowStatus(DWORD dwPara)
  783. {
  784. CString strOutput;
  785. strOutput.Format(_T("------------------------------设置列表---------------------------------"));
  786. injectMessage(strOutput);
  787. strOutput.Format(_T("所有AI[%s]"), ((bAiEnabled)?_T("打开"):_T("关闭")));
  788. injectMessage(strOutput);
  789. strOutput.Format(_T("自动攻击[%s]"), (settingmvp.bAttack?_T("打开"):_T("关闭")));
  790. injectMessage(strOutput);
  791. strOutput.Format(_T("被围攻时自动使用技能[%s]"), (settingmvp.bAttack2?_T("打开"):_T("关闭")));
  792. injectMessage(strOutput);
  793. strOutput.Format(_T("使用队聊共享信息[%s]"), (option.bUsePartyChat?_T("打开"):_T("关闭")));
  794. injectMessage(strOutput);
  795. strOutput.Format(_T("自动捡物[%s]"), (option.bAutoPickup?_T("打开"):_T("关闭")));
  796. injectMessage(strOutput);
  797. if(option.bAutoPickup)
  798. {
  799. strOutput.Format(_T("移动捡物[%s]"), (option.bMovePickup?_T("打开"):_T("关闭")));
  800. injectMessage(strOutput);
  801. }
  802. // strOutput.Format(_T("攻击延迟设置为%2.2f秒"), (float)dwDelay[nDelay] / 1000);
  803. // injectMessage(strOutput);
  804. }
  805. void ufAutoAttackMvp(DWORD dwPara)
  806. {
  807. settingmvp.bAttack = !settingmvp.bAttack;
  808. CString strOutput;
  809. strOutput.Format(_T("自动攻击[%s]"), (settingmvp.bAttack?_T("打开"):_T("关闭")));
  810. injectAdminMessage(strOutput);
  811. /* if(monsters.GetSize() > 0)
  812. {
  813. injectAdminMessage(_T("抓宠"));
  814. sendUseSkill(1, 297, monsters[0].dwId);
  815. for(int i=0; i<5; i++)
  816. {
  817. char buffer[6];
  818. *(WORD*)(buffer) = 0x019F;
  819. *(DWORD*)(buffer+2) = monsters[0].dwId;
  820. parseSendData(buffer, 6, true);
  821. }
  822. }*/
  823. }
  824. void ufAutoSearchMvp(DWORD dwPara)
  825. {
  826. utlSetAutoSearchMvp(!bAutoSearch);
  827. }
  828. void ufUseSkillWhen(DWORD dwPara)
  829. {
  830. settingmvp.bRegionAtk = !settingmvp.bRegionAtk;
  831. CString strOutput;
  832. strOutput.Format(_T("被围攻时自动使用技能[%s]"), (settingmvp.bRegionAtk?_T("打开"):_T("关闭")));
  833. injectAdminMessage(strOutput);
  834. }
  835. void ufUseSkillOnMvp(DWORD dwPara)
  836. {
  837. int nMvp = -1;
  838. int nIndex;
  839. if(mode == eModeMvp)
  840. {
  841. nMvp = monsters.FindId(dwMvpId);
  842. if(nMvp != -1)
  843. {
  844. nIndex = utlFindSkillByAlias(_T("光之障壁"));
  845. if(nIndex != -1)
  846. {
  847. sendUseSkillOnLoc(skills[nIndex].wLevel, (WORD)skills[nIndex].dwId, monsters[nMvp].pntTo);
  848. }
  849. }
  850. }
  851. }
  852. void ufTeleport(DWORD dwPara)
  853. {
  854. utlUseTeleport(1);
  855. }
  856. void ufHome(DWORD dwPara)
  857. {
  858. int nIndex;
  859. CString strSavePoint;
  860. nIndex = settingcmn.strSavePoint.Find(_T(" - "));
  861. if(nIndex != -1)
  862. {
  863. strSavePoint = settingcmn.strSavePoint.Left(nIndex);
  864. strSavePoint += _T(".gat");
  865. sendTeleport(strSavePoint);
  866. }
  867. else
  868. {
  869. injectAdminMessage(_T("无法使用技能[回保存地点]"));
  870. }
  871. }
  872. void ufBossList(DWORD dwPara)
  873. {
  874. utlSortBossInfo();
  875. CTime tm=CTime::GetCurrentTime();
  876. CString strTemp;
  877. strTemp.Format(_T("------------------------------BOSS列表---------------------------------"));
  878. injectMessage(strTemp);
  879. for(int i=0; i<bossinfo.GetSize(); i++)
  880. {
  881. CTime tmNow = tm - CTimeSpan( 0, 1, 0, 0 ); // 1 hour exactly
  882. CString strTemp;
  883. CTimeSpan timespan = bossinfo[i].tmBossTime - tmNow;
  884. strTemp.Format(_T("%30s %02d/%02d %02d:%02d:%02d %02d分%02d秒"), bossinfo[i].strBossName,
  885. bossinfo[i].tmBossTime.GetMonth(),
  886. bossinfo[i].tmBossTime.GetDay(),
  887. bossinfo[i].tmBossTime.GetHour(),
  888. bossinfo[i].tmBossTime.GetMinute(),
  889. bossinfo[i].tmBossTime.GetSecond(),
  890. timespan.GetTotalSeconds() > 0?timespan.GetTotalSeconds() / 60:0,
  891. timespan.GetTotalSeconds() > 0?timespan.GetTotalSeconds() % 60:0);
  892. sendChatParty(strTemp);
  893. Sleep(50);
  894. }
  895. strTemp.Format(_T("-----------------------------------------------------------------------"));
  896. sendChatParty(strTemp);
  897. strTemp.Format(_T("%30s %02d/%02d %02d:%02d:%02d"), _T("  现在时间"),
  898. tm.GetMonth(),
  899. tm.GetDay(),
  900. tm.GetHour(),
  901. tm.GetMinute(),
  902. tm.GetSecond());
  903. sendChatParty(strTemp);
  904. }
  905. void ufPartyChat(DWORD dwPara)
  906. {
  907. option.bUsePartyChat = !option.bUsePartyChat;
  908. CString strOutput;
  909. strOutput.Format(_T("使用队聊共享信息%s"), (option.bUsePartyChat?_T("打开"):_T("关闭")));
  910. injectAdminMessage(strOutput);
  911. }
  912. void ufTakeItem(DWORD dwPara)
  913. {
  914. option.bAutoPickup = !option.bAutoPickup;
  915. CString strOutput;
  916. strOutput.Format(_T("自动捡物%s"), (option.bAutoPickup?_T("打开"):_T("关闭")));
  917. injectAdminMessage(strOutput);
  918. }
  919. void ufSpeedUp(DWORD dwPara)
  920. {
  921. CString strOutput;
  922. if(option.nAttackPerSecond < 10)
  923. {
  924. option.nAttackPerSecond++;
  925. }
  926. strOutput.Format(_T("攻击速度倍率设为 %d 倍"), option.nAttackPerSecond);
  927. injectAdminMessage(strOutput);
  928. }
  929. void ufSpeedDown(DWORD dwPara)
  930. {
  931. CString strOutput;
  932. if(option.nAttackPerSecond > 1)
  933. {
  934. option.nAttackPerSecond--;
  935. }
  936. strOutput.Format(_T("攻击速度倍率设为 %d 倍"), option.nAttackPerSecond);
  937. injectAdminMessage(strOutput);
  938. }
  939. #define DEFINE_FUNC(funcname, skillname)  
  940. void funcname(DWORD dwPara){
  941. int nIndex = utlFindSkillByAlias(_T(skillname));
  942. if(nIndex != -1 || skills[nIndex].wLevel > 0)
  943. sendUseSkill(skills[nIndex].wLevel, (unsigned short)skills[nIndex].dwId, dwAccountId);
  944. else
  945. injectAdminMessage(_T("无法使用技能[#skillname]"));}
  946. DEFINE_FUNC(ufRuwach, "光猎");
  947. DEFINE_FUNC(ufAngelus, "天使之障壁");
  948. DEFINE_FUNC(ufMagnificat, "圣母之颂歌");
  949. DEFINE_FUNC(ufGloria, "幸运之颂歌");
  950. DEFINE_FUNC(ufEndure, "霸体");
  951. DEFINE_FUNC(ufLoud, "大声呐喊");
  952. DEFINE_FUNC(ufMaximize, "武器值最大化");
  953. DEFINE_FUNC(ufOverthrust, "凶砍");
  954. DEFINE_FUNC(ufAdrenaline, "速度激发");
  955. DEFINE_FUNC(ufWeaponperfect, "无视体型攻击");
  956. DEFINE_FUNC(ufSight, "火狩");
  957. DEFINE_FUNC(ufConcentration, "心神凝聚");
  958. DEFINE_FUNC(ufEnergyCoat, "能量外套");
  959. DEFINE_FUNC(ufAppleIdun, "伊登的苹果");
  960. DEFINE_FUNC(ufAssassinCross, "刺客的黄昏");
  961. DEFINE_FUNC(ufFrostJoke, "冷笑话");
  962. DEFINE_FUNC(ufDissonance, "不谐和音");
  963. DEFINE_FUNC(ufUglyDance, "丑陋之舞");
  964. DEFINE_FUNC(ufScream, "惊声尖叫");
  965. void ufShowMonsters(DWORD dwPara)
  966. {
  967. CString strTemp;
  968. strTemp.Format(_T("------------------------------怪物列表---------------------------------"));
  969. injectMessage(strTemp);
  970. for(int i=0; i<monsters.GetSize(); i++)
  971. {
  972. strTemp.Format(_T(" [%02d] %08X %s"),
  973. i,
  974. monsters[i].dwId,
  975. monsters[i].cName);
  976. injectMessage(strTemp);
  977. Sleep(10);
  978. }
  979. return;
  980. }
  981. void ufShowPlayers(DWORD dwPara)
  982. {
  983. CString strTemp;
  984. strTemp.Format(_T("------------------------------人物列表---------------------------------"));
  985. injectMessage(strTemp);
  986. for(int i=0; i<players.GetSize(); i++)
  987. {
  988. strTemp.Format(_T(" [%02d] %08X %8s %24s %24s"),
  989. i,
  990. players[i].dwId,
  991. mapJob.FindValue(players[i].wType),
  992. players[i].cName,
  993. players[i].cGuild);
  994. injectMessage(strTemp);
  995. Sleep(50);
  996. }
  997. return;
  998. }
  999. void ufShowCarts(DWORD dwPara)
  1000. {
  1001. CString strTemp;
  1002. INVENTORY inv;
  1003. strTemp.Format(_T("------------------------------手推车内物品列表---------------------------------"));
  1004. injectMessage(strTemp);
  1005. for(int i=0; i<cart.GetSize(); i++)
  1006. {
  1007. inv = cart[i];
  1008. if(inv.wEquipType > 0)
  1009. {
  1010. strTemp.Format(_T(" [%2d] %-20s | 鉴定: %s | 装备: %s"),
  1011. inv.dwIndex, utlGetInventoryName(&inv),
  1012. (inv.bIdentified?_T("是"):_T("否")),
  1013. (inv.wEquipped?mapEquipType.FindValue(inv.wEquipType):_T("否")));
  1014. }
  1015. else
  1016. {
  1017. strTemp.Format(_T(" [%2d] %-20s | 数量: %d"),
  1018. inv.dwIndex, utlGetInventoryName(&inv),
  1019. inv.wAmount);
  1020. }
  1021. injectMessage(strTemp);
  1022. Sleep(50);
  1023. }
  1024. }
  1025. void ufShowInventory(DWORD dwPara)
  1026. {
  1027. CString strTemp;
  1028. INVENTORY inv;
  1029. strTemp.Format(_T("------------------------------物品列表---------------------------------"));
  1030. injectMessage(strTemp);
  1031. for(int i=0; i<inventory.GetSize(); i++)
  1032. {
  1033. inv = inventory[i];
  1034. if(inv.wEquipType > 0)
  1035. {
  1036. strTemp.Format(_T(" [%2d] %-20s | 鉴定: %s | 装备: %s"),
  1037. inv.dwIndex, utlGetInventoryName(&inv),
  1038. (inv.bIdentified?_T("是"):_T("否")),
  1039. (inv.wEquipped?mapEquipType.FindValue(inv.wEquipType):_T("否")));
  1040. }
  1041. else
  1042. {
  1043. strTemp.Format(_T(" [%2d] %-20s | 数量: %d"),
  1044. inv.dwIndex, utlGetInventoryName(&inv),
  1045. inv.wAmount);
  1046. }
  1047. injectMessage(strTemp);
  1048. Sleep(50);
  1049. }
  1050. }
  1051. void ufShowSkills(DWORD dwPara)
  1052. {
  1053. }
  1054. void ufShowEmotion(DWORD dwPara)
  1055. {
  1056. int nIndex = -1;
  1057. for(int i=0; i<EMNUM; i++)
  1058. {
  1059. if(EMOTIONDEF[i].CompareNoCase(emotions[dwPara]) == 0)
  1060. {
  1061. nIndex = i;
  1062. break;
  1063. }
  1064. }
  1065. if(nIndex != -1)
  1066. {
  1067. sendEmotion(nIndex);
  1068. }
  1069. }
  1070. void ufAutoSaClassChange(DWORD dwPara)
  1071. {
  1072. CString strOutput;
  1073. BOOL bStatusOld;
  1074. switch(dwPara)
  1075. {
  1076. case 0:
  1077. // OFF
  1078. bAutoSa = false;
  1079. break;
  1080. case 1:
  1081. // ON
  1082. bAutoSa = true;
  1083. break;
  1084. case 2:
  1085. bAutoSa = !bAutoSa;
  1086. break;
  1087. default:
  1088. ASSERT(false);
  1089. }
  1090. if(bStatusOld == bAutoSa)
  1091. return;
  1092. if(bAutoSa)
  1093. {
  1094. dwAutoSaTick = GetTickCount();
  1095. }
  1096. else
  1097. {
  1098. dwAutoSaTick = 0;
  1099. }
  1100. strOutput.Format(_T("自动贤者 [%s]"), (bAutoSa?_T("打开"):_T("关闭")));
  1101. injectAdminMessage(strOutput);
  1102. return;
  1103. }
  1104. void ufPopupRoaWindow(DWORD dwPara)
  1105. {
  1106. CWnd *pWnd = AfxGetMainWnd();
  1107. HWND hWnd = FindWindow(NULL, "仙境传说");
  1108. if(bIsModal)
  1109. {
  1110. return;
  1111. }
  1112. if(::IsWindow(pWnd->m_hWnd) && ::IsWindow(hWnd))
  1113. {
  1114. ::ShowWindow(hWnd, SW_SHOWMINIMIZED);
  1115. pWnd->ShowWindow(SW_MINIMIZE);
  1116. pWnd->ShowWindow(SW_RESTORE);
  1117. }
  1118. return;
  1119. }
  1120. void ufShowServerIp(DWORD dwPara)
  1121. {
  1122. CString strServerIp;
  1123. strServerIp.Format(_T("------------------------------服务器列表---------------------------------"));
  1124. injectMessage(strServerIp);
  1125. if(0 != serverip[0][0])
  1126. {
  1127. strServerIp.Format(_T("游戏服务器: %d.%d.%d.%d(%d)"),
  1128. serverip[0][2],
  1129. serverip[0][3],
  1130. serverip[0][4],
  1131. serverip[0][5],
  1132. serverip[0][0]*256 + serverip[0][1]);
  1133. injectMessage(strServerIp);
  1134. }
  1135. if(0 != serverip[1][0])
  1136. {
  1137. strServerIp.Format(_T("人物服务器: %d.%d.%d.%d(%d)"),
  1138. serverip[1][2],
  1139. serverip[1][3],
  1140. serverip[1][4],
  1141. serverip[1][5],
  1142. serverip[1][0]*256 + serverip[1][1]);
  1143. injectMessage(strServerIp);
  1144. }
  1145. if(0 != serverip[2][0])
  1146. {
  1147. strServerIp.Format(_T("地图服务器: %d.%d.%d.%d(%d) [%s(%s)]"),
  1148. serverip[2][2],
  1149. serverip[2][3],
  1150. serverip[2][4],
  1151. serverip[2][5],
  1152. serverip[2][0]*256 + serverip[2][1],
  1153. field.m_strAlias,
  1154. field.m_strFieldname);
  1155. injectMessage(strServerIp);
  1156. }
  1157. return;
  1158. }