1. #include "stdafx.h"
  2. #include <sstream>
  3. #include "desc.h"
  4. #include "desc_manager.h"
  5. #include "char.h"
  6. #include "buffer_manager.h"
  7. #include "config.h"
  8. #include "profiler.h"
  9. #include "p2p.h"
  10. #include "log.h"
  11. #include "db.h"
  12. #include "questmanager.h"
  13. #include "login_sim.h"
  14. #include "fishing.h"
  15. #include "TrafficProfiler.h"
  16. #include "priv_manager.h"
  17. #include "castle.h"
  18. #include "dev_log.h"
  19. extern time_t get_global_time();
  20. bool IsEmptyAdminPage()
  21. {
  22. return g_stAdminPageIP.empty();
  23. }
  24. bool IsAdminPage(const char * ip)
  25. {
  26. for (size_t n = 0; n < g_stAdminPageIP.size(); ++n)
  27. {
  28. if (g_stAdminPageIP[n] == ip)
  29. return 1;
  30. }
  31. return 0;
  32. }
  33. void ClearAdminPages()
  34. {
  35. for (size_t n = 0; n < g_stAdminPageIP.size(); ++n)
  36. g_stAdminPageIP[n].clear();
  37. g_stAdminPageIP.clear();
  38. }
  39. CInputProcessor::CInputProcessor() : m_pPacketInfo(NULL), m_iBufferLeft(0)
  40. {
  41. if (!m_pPacketInfo)
  42. BindPacketInfo(&m_packetInfoCG);
  43. }
  44. void CInputProcessor::BindPacketInfo(CPacketInfo * pPacketInfo)
  45. {
  46. m_pPacketInfo = pPacketInfo;
  47. }
  48. bool CInputProcessor::Process(LPDESC lpDesc, const void * c_pvOrig, int iBytes, int & r_iBytesProceed)
  49. {
  50. const char * c_pData = (const char *) c_pvOrig;
  51. BYTE bLastHeader = 0;
  52. int iLastPacketLen = 0;
  53. int iPacketLen;
  54. if (!m_pPacketInfo)
  55. {
  56. sys_err("No packet info has been binded to");
  57. return true;
  58. }
  59. for (m_iBufferLeft = iBytes; m_iBufferLeft > 0;)
  60. {
  61. BYTE bHeader = (BYTE) *(c_pData);
  62. const char * c_pszName;
  63. if (bHeader == 0) // ¾Ïȣȭ 󸮰¡ ÀÖÀ¸¹Ç·Î 0¹ø Çì´õ´Â ½ºÅµÇÑ´Ù.
  64. iPacketLen = 1;
  65. else if (!m_pPacketInfo->Get(bHeader, &iPacketLen, &c_pszName))
  66. {
  67. sys_err("UNKNOWN HEADER: %d, LAST HEADER: %d(%d), REMAIN BYTES: %d, fd: %d",
  68. bHeader, bLastHeader, iLastPacketLen, m_iBufferLeft, lpDesc->GetSocket());
  69. //printdata((BYTE *) c_pvOrig, m_iBufferLeft);
  70. lpDesc->SetPhase(PHASE_CLOSE);
  71. return true;
  72. }
  73. if (m_iBufferLeft < iPacketLen)
  74. return true;
  75. if (bHeader)
  76. {
  77. if (test_server && bHeader != HEADER_CG_MOVE)
  78. sys_log(0, "Packet Analyze [Header %d][bufferLeft %d] ", bHeader, m_iBufferLeft);
  79. m_pPacketInfo->Start();
  80. int iExtraPacketSize = Analyze(lpDesc, bHeader, c_pData);
  81. if (iExtraPacketSize < 0)
  82. return true;
  83. iPacketLen += iExtraPacketSize;
  84. lpDesc->Log("%s %d", c_pszName, iPacketLen);
  85. m_pPacketInfo->End();
  86. }
  87. // TRAFFIC_PROFILER
  88. if (g_bTrafficProfileOn)
  89. TrafficProfiler::instance().Report(TrafficProfiler::IODIR_INPUT, bHeader, iPacketLen);
  90. // END_OF_TRAFFIC_PROFILER
  91. if (bHeader == HEADER_CG_PONG)
  92. sys_log(0, "PONG! %u %u", m_pPacketInfo->IsSequence(bHeader), *(BYTE *) (c_pData + iPacketLen - sizeof(BYTE)));
  93. c_pData += iPacketLen;
  94. m_iBufferLeft -= iPacketLen;
  95. r_iBytesProceed += iPacketLen;
  96. iLastPacketLen = iPacketLen;
  97. bLastHeader = bHeader;
  98. if (GetType() != lpDesc->GetInputProcessor()->GetType())
  99. return false;
  100. }
  101. return true;
  102. }
  103. void CInputProcessor::Pong(LPDESC d)
  104. {
  105. d->SetPong(true);
  106. }
  107. void CInputProcessor::Handshake(LPDESC d, const char * c_pData)
  108. {
  109. TPacketCGHandshake * p = (TPacketCGHandshake *) c_pData;
  110. if (d->GetHandshake() != p->dwHandshake)
  111. {
  112. sys_err("Invalid Handshake on %d", d->GetSocket());
  113. d->SetPhase(PHASE_CLOSE);
  114. }
  115. else
  116. {
  117. if (d->IsPhase(PHASE_HANDSHAKE))
  118. {
  119. if (d->HandshakeProcess(p->dwTime, p->lDelta, false))
  120. {
  121. #ifdef _IMPROVED_PACKET_ENCRYPTION_
  122. d->SendKeyAgreement();
  123. #else
  124. if (g_bAuthServer)
  125. d->SetPhase(PHASE_AUTH);
  126. else
  127. d->SetPhase(PHASE_LOGIN);
  128. #endif // #ifdef _IMPROVED_PACKET_ENCRYPTION_
  129. }
  130. }
  131. else
  132. d->HandshakeProcess(p->dwTime, p->lDelta, true);
  133. }
  134. }
  135. void CInputProcessor::Version(LPCHARACTER ch, const char* c_pData)
  136. {
  137. if (!ch)
  138. return;
  139. TPacketCGClientVersion * p = (TPacketCGClientVersion *) c_pData;
  140. sys_log(0, "VERSION: %s %s %s", ch->GetName(), p->timestamp, p->filename);
  141. ch->GetDesc()->SetClientVersion(p->timestamp);
  142. }
  143. void LoginFailure(LPDESC d, const char * c_pszStatus)
  144. {
  145. if (!d)
  146. return;
  147. TPacketGCLoginFailure failurePacket;
  148. failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  149. strlcpy(failurePacket.szStatus, c_pszStatus, sizeof(failurePacket.szStatus));
  150. d->Packet(&failurePacket, sizeof(failurePacket));
  151. }
  152. CInputHandshake::CInputHandshake()
  153. {
  154. CPacketInfoCG * pkPacketInfo = M2_NEW CPacketInfoCG;
  155. pkPacketInfo->SetSequence(HEADER_CG_PONG, false);
  156. m_pMainPacketInfo = m_pPacketInfo;
  157. BindPacketInfo(pkPacketInfo);
  158. }
  159. CInputHandshake::~CInputHandshake()
  160. {
  161. if( NULL != m_pPacketInfo )
  162. {
  163. M2_DELETE(m_pPacketInfo);
  164. m_pPacketInfo = NULL;
  165. }
  166. }
  167. std::map<DWORD, CLoginSim *> g_sim;
  168. std::map<DWORD, CLoginSim *> g_simByPID;
  169. std::vector<TPlayerTable> g_vec_save;
  170. // BLOCK_CHAT
  171. ACMD(do_block_chat);
  172. // END_OF_BLOCK_CHAT
  173. int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
  174. {
  175. if (bHeader == 10) // ¿£ÅÍ´Â ¹«½Ã
  176. return 0;
  177. if (bHeader == HEADER_CG_TEXT)
  178. {
  179. if (IsEmptyAdminPage() || !IsAdminPage(inet_ntoa(d->GetAddr().sin_addr)))
  180. {
  181. sys_log(0, "SOCKET_CMD: BLOCK FROM(%s)", d->GetHostName());
  182. return -1;
  183. }
  184. ++c_pData;
  185. const char * c_pSep;
  186. if (!(c_pSep = strchr(c_pData, '\n'))) // \nÀ» ã´Â´Ù.
  187. return -1;
  188. if (*(c_pSep - 1) == '\r')
  189. --c_pSep;
  190. std::string stResult;
  191. std::string stBuf;
  192. stBuf.assign(c_pData, 0, c_pSep - c_pData);
  193. sys_log(0, "SOCKET_CMD: FROM(%s) CMD(%s)", d->GetHostName(), stBuf.c_str());
  194. if (!stBuf.compare("IS_SERVER_UP"))
  195. {
  196. if (g_bNoMoreClient)
  197. stResult = "NO";
  198. else
  199. stResult = "YES";
  200. }
  201. //else if (!stBuf.compare("SHOWMETHEMONEY"))
  202. else if (stBuf == g_stAdminPagePassword)
  203. {
  204. if (!IsEmptyAdminPage())
  205. {
  206. if (!IsAdminPage(inet_ntoa(d->GetAddr().sin_addr)))
  207. {
  208. char szTmp[64];
  209. snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", inet_ntoa(d->GetAddr().sin_addr));
  210. stResult += szTmp;
  211. }
  212. else
  213. {
  214. d->SetAdminMode();
  215. stResult = "UNKNOWN";
  216. }
  217. }
  218. else
  219. {
  220. d->SetAdminMode();
  221. stResult = "UNKNOWN";
  222. }
  223. }
  224. else if (!stBuf.compare("USER_COUNT"))
  225. {
  226. char szTmp[64];
  227. if (!IsEmptyAdminPage())
  228. {
  229. if (!IsAdminPage(inet_ntoa(d->GetAddr().sin_addr)))
  230. {
  231. snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", inet_ntoa(d->GetAddr().sin_addr));
  232. }
  233. else
  234. {
  235. int iTotal;
  236. int * paiEmpireUserCount;
  237. int iLocal;
  238. DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal);
  239. snprintf(szTmp, sizeof(szTmp), "%d %d %d %d %d", iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3], iLocal);
  240. }
  241. }
  242. else
  243. {
  244. int iTotal;
  245. int * paiEmpireUserCount;
  246. int iLocal;
  247. DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal);
  248. snprintf(szTmp, sizeof(szTmp), "%d %d %d %d %d", iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3], iLocal);
  249. }
  250. stResult += szTmp;
  251. }
  252. else if (!stBuf.compare("CHECK_P2P_CONNECTIONS"))
  253. {
  254. std::ostringstream oss(std::ostringstream::out);
  255. oss << "P2P CONNECTION NUMBER : " << P2P_MANAGER::instance().GetDescCount() << "\n";
  256. std::string hostNames;
  257. P2P_MANAGER::Instance().GetP2PHostNames(hostNames);
  258. oss << hostNames;
  259. stResult = oss.str();
  260. TPacketGGCheckAwakeness packet;
  261. packet.bHeader = HEADER_GG_CHECK_AWAKENESS;
  262. P2P_MANAGER::instance().Send(&packet, sizeof(packet));
  263. }
  264. else if (!stBuf.compare("PACKET_INFO"))
  265. {
  266. m_pMainPacketInfo->Log("packet_info.txt");
  267. stResult = "OK";
  268. }
  269. else if (!stBuf.compare("PROFILE"))
  270. {
  271. CProfiler::instance().Log("profile.txt");
  272. stResult = "OK";
  273. }
  274. //gift notify delete command
  275. else if (!stBuf.compare(0,15,"DELETE_AWARDID "))
  276. {
  277. char szTmp[64];
  278. std::string msg = stBuf.substr(15,26); // item_awardÀÇ id¹üÀ§?
  279. TPacketDeleteAwardID p;
  280. p.dwID = (DWORD)(atoi(msg.c_str()));
  281. snprintf(szTmp,sizeof(szTmp),"Sent to DB cache to delete ItemAward, id: %d",p.dwID);
  282. //sys_log(0,"%d",p.dwID);
  283. // strlcpy(p.login, msg.c_str(), sizeof(p.login));
  284. db_clientdesc->DBPacket(HEADER_GD_DELETE_AWARDID, 0, &p, sizeof(p));
  285. stResult += szTmp;
  286. }
  287. else
  288. {
  289. stResult = "UNKNOWN";
  290. if (d->IsAdminMode())
  291. {
  292. // ¾îµå¹Î ¸í·Éµé
  293. if (!stBuf.compare(0, 7, "NOTICE "))
  294. {
  295. std::string msg = stBuf.substr(7, 50);
  296. LogManager::instance().CharLog(0, 0, 0, 1, "NOTICE", msg.c_str(), d->GetHostName());
  297. BroadcastNotice(msg.c_str());
  298. }
  299. else if (!stBuf.compare("SHUTDOWN"))
  300. {
  301. LogManager::instance().CharLog(0, 0, 0, 2, "SHUTDOWN", "", d->GetHostName());
  302. TPacketGGShutdown p;
  303. p.bHeader = HEADER_GG_SHUTDOWN;
  304. P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShutdown));
  305. sys_err("Accept shutdown command from %s.", d->GetHostName());
  306. Shutdown(10);
  307. }
  308. else if (!stBuf.compare("SHUTDOWN_ONLY"))
  309. {
  310. LogManager::instance().CharLog(0, 0, 0, 2, "SHUTDOWN", "", d->GetHostName());
  311. sys_err("Accept shutdown only command from %s.", d->GetHostName());
  312. Shutdown(10);
  313. }
  314. else if (!stBuf.compare(0, 3, "DC "))
  315. {
  316. std::string msg = stBuf.substr(3, LOGIN_MAX_LEN);
  317. dev_log(LOG_DEB0, "DC : '%s'", msg.c_str());
  318. TPacketGGDisconnect pgg;
  319. pgg.bHeader = HEADER_GG_DISCONNECT;
  320. strlcpy(pgg.szLogin, msg.c_str(), sizeof(pgg.szLogin));
  321. P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGDisconnect));
  322. // delete login key
  323. {
  324. TPacketDC p;
  325. strlcpy(p.login, msg.c_str(), sizeof(p.login));
  326. db_clientdesc->DBPacket(HEADER_GD_DC, 0, &p, sizeof(p));
  327. }
  328. }
  329. else if (!stBuf.compare(0, 10, "RELOAD_CRC"))
  330. {
  331. LoadValidCRCList();
  332. BYTE bHeader = HEADER_GG_RELOAD_CRC_LIST;
  333. P2P_MANAGER::instance().Send(&bHeader, sizeof(BYTE));
  334. stResult = "OK";
  335. }
  336. else if (!stBuf.compare(0, 20, "CHECK_CLIENT_VERSION"))
  337. {
  338. CheckClientVersion();
  339. BYTE bHeader = HEADER_GG_CHECK_CLIENT_VERSION;
  340. P2P_MANAGER::instance().Send(&bHeader, sizeof(BYTE));
  341. stResult = "OK";
  342. }
  343. else if (!stBuf.compare(0, 6, "RELOAD"))
  344. {
  345. if (stBuf.size() == 6)
  346. {
  347. LoadStateUserCount();
  348. db_clientdesc->DBPacket(HEADER_GD_RELOAD_PROTO, 0, NULL, 0);
  349. DBManager::instance().LoadDBString();
  350. }
  351. else
  352. {
  353. char c = stBuf[7];
  354. switch (LOWER(c))
  355. {
  356. case 'u':
  357. LoadStateUserCount();
  358. break;
  359. case 'p':
  360. db_clientdesc->DBPacket(HEADER_GD_RELOAD_PROTO, 0, NULL, 0);
  361. break;
  362. case 's':
  363. DBManager::instance().LoadDBString();
  364. break;
  365. case 'q':
  366. quest::CQuestManager::instance().Reload();
  367. break;
  368. case 'f':
  369. fishing::Initialize();
  370. break;
  371. case 'a':
  372. db_clientdesc->DBPacket(HEADER_GD_RELOAD_ADMIN, 0, NULL, 0);
  373. sys_log(0, "Reloading admin infomation.");
  374. break;
  375. }
  376. }
  377. }
  378. else if (!stBuf.compare(0, 6, "EVENT "))
  379. {
  380. std::istringstream is(stBuf);
  381. std::string strEvent, strFlagName;
  382. long lValue;
  383. is >> strEvent >> strFlagName >> lValue;
  384. if (!is.fail())
  385. {
  386. sys_log(0, "EXTERNAL EVENT FLAG name %s value %d", strFlagName.c_str(), lValue);
  387. quest::CQuestManager::instance().RequestSetEventFlag(strFlagName, lValue);
  388. stResult = "EVENT FLAG CHANGE ";
  389. stResult += strFlagName;
  390. }
  391. else
  392. {
  393. stResult = "EVENT FLAG FAIL";
  394. }
  395. }
  396. // BLOCK_CHAT
  397. else if (!stBuf.compare(0, 11, "BLOCK_CHAT "))
  398. {
  399. std::istringstream is(stBuf);
  400. std::string strBlockChat, strCharName;
  401. long lDuration;
  402. is >> strBlockChat >> strCharName >> lDuration;
  403. if (!is.fail())
  404. {
  405. sys_log(0, "EXTERNAL BLOCK_CHAT name %s duration %d", strCharName.c_str(), lDuration);
  406. do_block_chat(NULL, const_cast<char*>(stBuf.c_str() + 11), 0, 0);
  407. stResult = "BLOCK_CHAT ";
  408. stResult += strCharName;
  409. }
  410. else
  411. {
  412. stResult = "BLOCK_CHAT FAIL";
  413. }
  414. }
  415. // END_OF_BLOCK_CHAT
  416. else if (!stBuf.compare(0, 12, "PRIV_EMPIRE "))
  417. {
  418. int empire, type, value, duration;
  419. std::istringstream is(stBuf);
  420. std::string strPrivEmpire;
  421. is >> strPrivEmpire >> empire >> type >> value >> duration;
  422. // ÃÖ´ëÄ¡ 10¹è
  423. value = MINMAX(0, value, 1000);
  424. stResult = "PRIV_EMPIRE FAIL";
  425. if (!is.fail())
  426. {
  427. // check parameter
  428. if (empire < 0 || 3 < empire);
  429. else if (type < 1 || 4 < type);
  430. else if (value < 0);
  431. else if (duration < 0);
  432. else
  433. {
  434. stResult = "PRIV_EMPIRE SUCCEED";
  435. // ½Ã°£ ´ÜÀ§·Î º¯°æ
  436. duration = duration * (60 * 60);
  437. sys_log(0, "_give_empire_privileage(empire=%d, type=%d, value=%d, duration=%d) by web",
  438. empire, type, value, duration);
  439. CPrivManager::instance().RequestGiveEmpirePriv(empire, type, value, duration);
  440. }
  441. }
  442. }
  443. }
  444. }
  445. sys_log(1, "TEXT %s RESULT %s", stBuf.c_str(), stResult.c_str());
  446. stResult += "\n";
  447. d->Packet(stResult.c_str(), stResult.length());
  448. return (c_pSep - c_pData) + 1;
  449. }
  450. else if (bHeader == HEADER_CG_MARK_LOGIN)
  451. {
  452. if (!guild_mark_server)
  453. {
  454. // ²÷¾î¹ö·Á! - ¸¶Å© ¼­¹ö°¡ ¾Æ´Ñµ¥ ¸¶Å©¸¦ ¿äûÇÏ·Á°í?
  455. sys_err("Guild Mark login requested but i'm not a mark server!");
  456. d->SetPhase(PHASE_CLOSE);
  457. return 0;
  458. }
  459. // ¹«Á¶°Ç ÀÎÁõ --;
  460. sys_log(0, "MARK_SERVER: Login");
  461. d->SetPhase(PHASE_LOGIN);
  462. return 0;
  463. }
  464. else if (bHeader == HEADER_CG_STATE_CHECKER)
  465. {
  466. if (d->isChannelStatusRequested()) {
  467. return 0;
  468. }
  469. d->SetChannelStatusRequested(true);
  470. db_clientdesc->DBPacket(HEADER_GD_REQUEST_CHANNELSTATUS, d->GetHandle(), NULL, 0);
  471. }
  472. else if (bHeader == HEADER_CG_PONG)
  473. Pong(d);
  474. else if (bHeader == HEADER_CG_HANDSHAKE)
  475. Handshake(d, c_pData);
  476. #ifdef _IMPROVED_PACKET_ENCRYPTION_
  477. else if (bHeader == HEADER_CG_KEY_AGREEMENT)
  478. {
  479. // Send out the key agreement completion packet first
  480. // to help client to enter encryption mode
  481. d->SendKeyAgreementCompleted();
  482. // Flush socket output before going encrypted
  483. d->ProcessOutput();
  484. TPacketKeyAgreement* p = (TPacketKeyAgreement*)c_pData;
  485. if (!d->IsCipherPrepared())
  486. {
  487. sys_err ("Cipher isn't prepared. %s maybe a Hacker.", inet_ntoa(d->GetAddr().sin_addr));
  488. d->DelayedDisconnect(5);
  489. return 0;
  490. }
  491. if (d->FinishHandshake(p->wAgreedLength, p->data, p->wDataLength)) {
  492. // Handshaking succeeded
  493. if (g_bAuthServer) {
  494. d->SetPhase(PHASE_AUTH);
  495. } else {
  496. d->SetPhase(PHASE_LOGIN);
  497. }
  498. } else {
  499. sys_log(0, "[CInputHandshake] Key agreement failed: al=%u dl=%u",
  500. p->wAgreedLength, p->wDataLength);
  501. d->SetPhase(PHASE_CLOSE);
  502. }
  503. }
  504. #endif // _IMPROVED_PACKET_ENCRYPTION_
  505. else
  506. sys_err("Handshake phase does not handle packet %d (fd %d)", bHeader, d->GetSocket());
  507. return 0;
  508. }

INPUT.CPP