Advertisement
Guest User

Untitled

a guest
Nov 15th, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 102.84 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "constants.h"
  3. #include "config.h"
  4. #include "utils.h"
  5. #include "desc_client.h"
  6. #include "desc_manager.h"
  7. #include "buffer_manager.h"
  8. #include "packet.h"
  9. #include "protocol.h"
  10. #include "char.h"
  11. #include "char_manager.h"
  12. #include "item.h"
  13. #include "item_manager.h"
  14. #include "cmd.h"
  15. #include "shop.h"
  16. #include "shop_manager.h"
  17. #include "safebox.h"
  18. #include "regen.h"
  19. #include "battle.h"
  20. #include "exchange.h"
  21. #include "questmanager.h"
  22. #include "profiler.h"
  23. #include "messenger_manager.h"
  24. #include "party.h"
  25. #include "p2p.h"
  26. #include "affect.h"
  27. #include "guild.h"
  28. #include "guild_manager.h"
  29. #include "log.h"
  30. #include "banword.h"
  31. #include "empire_text_convert.h"
  32. #include "unique_item.h"
  33. #include "building.h"
  34. #include "locale_service.h"
  35. #include "gm.h"
  36. #include "spam.h"
  37. #include "ani.h"
  38. #include "motion.h"
  39. #include "OXEvent.h"
  40. #include "locale_service.h"
  41. #include "HackShield.h"
  42. #include "XTrapManager.h"
  43. #include "DragonSoul.h"
  44. #include "belt_inventory_helper.h" // @fixme119
  45. #include "../../common/CommonDefines.h"
  46.  
  47. #include "input.h"
  48.  
  49. #define ENABLE_CHAT_COLOR_SYSTEM
  50. #define ENABLE_CHAT_LOGGING
  51. #define ENABLE_CHAT_SPAMLIMIT
  52. #define ENABLE_WHISPER_CHAT_SPAMLIMIT
  53. #define ENABLE_CHECK_GHOSTMODE
  54.  
  55. #ifdef ENABLE_CHAT_LOGGING
  56. static char __escape_string[1024];
  57. static char __escape_string2[1024];
  58. #endif
  59.  
  60. static int __deposit_limit()
  61. {
  62. return (1000*10000); // 1õ¸¸
  63. }
  64.  
  65. #ifdef __SEND_TARGET_INFO__
  66. void CInputMain::TargetInfoLoad(LPCHARACTER ch, const char* c_pData)
  67. {
  68. TPacketCGTargetInfoLoad* p = (TPacketCGTargetInfoLoad*)c_pData;
  69. TPacketGCTargetInfo pInfo;
  70. pInfo.header = HEADER_GC_TARGET_INFO;
  71. static std::vector<LPITEM> s_vec_item;
  72. s_vec_item.clear();
  73. LPITEM pkInfoItem;
  74. LPCHARACTER m_pkChrTarget = CHARACTER_MANAGER::instance().Find(p->dwVID);
  75. if (!ch || !m_pkChrTarget)
  76. return;
  77.  
  78. // if (m_pkChrTarget && (m_pkChrTarget->IsMonster() || m_pkChrTarget->IsStone()))
  79. // {
  80. // if (thecore_heart->pulse - (int) ch->GetLastTargetInfoPulse() < passes_per_sec * 3)
  81. // return;
  82.  
  83. // ch->SetLastTargetInfoPulse(thecore_heart->pulse);
  84.  
  85. if (ITEM_MANAGER::instance().CreateDropItemVector(m_pkChrTarget, ch, s_vec_item) && (m_pkChrTarget->IsMonster() || m_pkChrTarget->IsStone()))
  86. {
  87. if (s_vec_item.size() == 0);
  88. else if (s_vec_item.size() == 1)
  89. {
  90. pkInfoItem = s_vec_item[0];
  91. pInfo.dwVID = m_pkChrTarget->GetVID();
  92. pInfo.race = m_pkChrTarget->GetRaceNum();
  93. pInfo.dwVnum = pkInfoItem->GetVnum();
  94. pInfo.count = pkInfoItem->GetCount();
  95. ch->GetDesc()->Packet(&pInfo, sizeof(TPacketGCTargetInfo));
  96. }
  97. else
  98. {
  99. int iItemIdx = s_vec_item.size() - 1;
  100. while (iItemIdx >= 0)
  101. {
  102. pkInfoItem = s_vec_item[iItemIdx--];
  103.  
  104. if (!pkInfoItem)
  105. {
  106. sys_err("pkInfoItem null in vector idx %d", iItemIdx + 1);
  107. continue;
  108. }
  109.  
  110. pInfo.dwVID = m_pkChrTarget->GetVID();
  111. pInfo.race = m_pkChrTarget->GetRaceNum();
  112. pInfo.dwVnum = pkInfoItem->GetVnum();
  113. pInfo.count = pkInfoItem->GetCount();
  114. ch->GetDesc()->Packet(&pInfo, sizeof(TPacketGCTargetInfo));
  115. }
  116. }
  117. }
  118. // }
  119. }
  120. #endif
  121.  
  122. void SendBlockChatInfo(LPCHARACTER ch, int sec)
  123. {
  124. if (sec <= 0)
  125. {
  126. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("äÆà ±ÝÁö »óÅÂÀÔ´Ï´Ù."));
  127. return;
  128. }
  129.  
  130. long hour = sec / 3600;
  131. sec -= hour * 3600;
  132.  
  133. long min = (sec / 60);
  134. sec -= min * 60;
  135.  
  136. char buf[128+1];
  137.  
  138. if (hour > 0 && min > 0)
  139. snprintf(buf, sizeof(buf), LC_TEXT("%d ½Ã°£ %d ºÐ %d ÃÊ µ¿¾È äÆñÝÁö »óÅÂÀÔ´Ï´Ù"), hour, min, sec);
  140. else if (hour > 0 && min == 0)
  141. snprintf(buf, sizeof(buf), LC_TEXT("%d ½Ã°£ %d ÃÊ µ¿¾È äÆñÝÁö »óÅÂÀÔ´Ï´Ù"), hour, sec);
  142. else if (hour == 0 && min > 0)
  143. snprintf(buf, sizeof(buf), LC_TEXT("%d ºÐ %d ÃÊ µ¿¾È äÆñÝÁö »óÅÂÀÔ´Ï´Ù"), min, sec);
  144. else
  145. snprintf(buf, sizeof(buf), LC_TEXT("%d ÃÊ µ¿¾È äÆñÝÁö »óÅÂÀÔ´Ï´Ù"), sec);
  146.  
  147. ch->ChatPacket(CHAT_TYPE_INFO, buf);
  148. }
  149.  
  150. EVENTINFO(spam_event_info)
  151. {
  152. char host[MAX_HOST_LENGTH+1];
  153.  
  154. spam_event_info()
  155. {
  156. ::memset( host, 0, MAX_HOST_LENGTH+1 );
  157. }
  158. };
  159.  
  160. typedef boost::unordered_map<std::string, std::pair<unsigned int, LPEVENT> > spam_score_of_ip_t;
  161. spam_score_of_ip_t spam_score_of_ip;
  162.  
  163. EVENTFUNC(block_chat_by_ip_event)
  164. {
  165. spam_event_info* info = dynamic_cast<spam_event_info*>( event->info );
  166.  
  167. if ( info == NULL )
  168. {
  169. sys_err( "block_chat_by_ip_event> <Factor> Null pointer" );
  170. return 0;
  171. }
  172.  
  173. const char * host = info->host;
  174.  
  175. spam_score_of_ip_t::iterator it = spam_score_of_ip.find(host);
  176.  
  177. if (it != spam_score_of_ip.end())
  178. {
  179. it->second.first = 0;
  180. it->second.second = NULL;
  181. }
  182.  
  183. return 0;
  184. }
  185.  
  186. bool SpamBlockCheck(LPCHARACTER ch, const char* const buf, const size_t buflen)
  187. {
  188. if (ch->GetLevel() < g_iSpamBlockMaxLevel)
  189. {
  190. spam_score_of_ip_t::iterator it = spam_score_of_ip.find(ch->GetDesc()->GetHostName());
  191.  
  192. if (it == spam_score_of_ip.end())
  193. {
  194. spam_score_of_ip.insert(std::make_pair(ch->GetDesc()->GetHostName(), std::make_pair(0, (LPEVENT) NULL)));
  195. it = spam_score_of_ip.find(ch->GetDesc()->GetHostName());
  196. }
  197.  
  198. if (it->second.second)
  199. {
  200. SendBlockChatInfo(ch, event_time(it->second.second) / passes_per_sec);
  201. return true;
  202. }
  203.  
  204. unsigned int score;
  205. const char * word = SpamManager::instance().GetSpamScore(buf, buflen, score);
  206.  
  207. it->second.first += score;
  208.  
  209. if (word)
  210. sys_log(0, "SPAM_SCORE: %s text: %s score: %u total: %u word: %s", ch->GetName(), buf, score, it->second.first, word);
  211.  
  212. if (it->second.first >= g_uiSpamBlockScore)
  213. {
  214. spam_event_info* info = AllocEventInfo<spam_event_info>();
  215. strlcpy(info->host, ch->GetDesc()->GetHostName(), sizeof(info->host));
  216.  
  217. it->second.second = event_create(block_chat_by_ip_event, info, PASSES_PER_SEC(g_uiSpamBlockDuration));
  218. sys_log(0, "SPAM_IP: %s for %u seconds", info->host, g_uiSpamBlockDuration);
  219.  
  220. LogManager::instance().CharLog(ch, 0, "SPAM", word);
  221.  
  222. SendBlockChatInfo(ch, event_time(it->second.second) / passes_per_sec);
  223.  
  224. return true;
  225. }
  226. }
  227.  
  228. return false;
  229. }
  230.  
  231. enum
  232. {
  233. TEXT_TAG_PLAIN,
  234. TEXT_TAG_TAG, // ||
  235. TEXT_TAG_COLOR, // |cffffffff
  236. TEXT_TAG_HYPERLINK_START, // |H
  237. TEXT_TAG_HYPERLINK_END, // |h ex) |Hitem:1234:1:1:1|h
  238. TEXT_TAG_RESTORE_COLOR,
  239. };
  240.  
  241. int GetTextTag(const char * src, int maxLen, int & tagLen, std::string & extraInfo)
  242. {
  243. tagLen = 1;
  244.  
  245. if (maxLen < 2 || *src != '|')
  246. return TEXT_TAG_PLAIN;
  247.  
  248. const char * cur = ++src;
  249.  
  250. if (*cur == '|') // ||´Â |·Î Ç¥½ÃÇÑ´Ù.
  251. {
  252. tagLen = 2;
  253. return TEXT_TAG_TAG;
  254. }
  255. else if (*cur == 'c') // color |cffffffffblahblah|r
  256. {
  257. tagLen = 2;
  258. return TEXT_TAG_COLOR;
  259. }
  260. else if (*cur == 'H') // hyperlink |Hitem:10000:0:0:0:0|h[À̸§]|h
  261. {
  262. tagLen = 2;
  263. return TEXT_TAG_HYPERLINK_START;
  264. }
  265. else if (*cur == 'h') // end of hyperlink
  266. {
  267. tagLen = 2;
  268. return TEXT_TAG_HYPERLINK_END;
  269. }
  270.  
  271. return TEXT_TAG_PLAIN;
  272. }
  273.  
  274. void GetTextTagInfo(const char * src, int src_len, int & hyperlinks, bool & colored)
  275. {
  276. colored = false;
  277. hyperlinks = 0;
  278.  
  279. int len;
  280. std::string extraInfo;
  281.  
  282. for (int i = 0; i < src_len;)
  283. {
  284. int tag = GetTextTag(&src[i], src_len - i, len, extraInfo);
  285.  
  286. if (tag == TEXT_TAG_HYPERLINK_START)
  287. ++hyperlinks;
  288.  
  289. if (tag == TEXT_TAG_COLOR)
  290. colored = true;
  291.  
  292. i += len;
  293. }
  294. }
  295.  
  296. int ProcessTextTag(LPCHARACTER ch, const char * c_pszText, size_t len)
  297. {
  298. return 0;//2012.05.17 ¡¾e¢¯e¢¯i
  299. //0 : A¢´¡íoAuA¢¬¡¤I ¡íc¢¯e
  300. //1 : ¡¾Y¡Æ¡©¡Æ©¡ ¨¬IA¡¤
  301. //2 : ¡¾Y¡Æ¡©¡Æ©¡AI AOA¢¬©ø¨£, ¡Æ©øAI¡íoA¢®¢¯¢®¨ù¡© ¡íc¢¯eA©¬
  302. //3 : ¡¾©øE?A©¬
  303. //4 : ¢¯¢®¡¤?
  304. int hyperlinks;
  305. bool colored;
  306.  
  307. GetTextTagInfo(c_pszText, len, hyperlinks, colored);
  308.  
  309. if (colored == true && hyperlinks == 0)
  310. return 4;
  311.  
  312. #ifdef ENABLE_NEWSTUFF
  313. if (g_bDisablePrismNeed)
  314. return 0;
  315. #endif
  316. int nPrismCount = ch->CountSpecifyItem(ITEM_PRISM);
  317.  
  318. if (nPrismCount < hyperlinks)
  319. return 1;
  320.  
  321.  
  322. if (!ch->GetMyShop())
  323. {
  324. ch->RemoveSpecifyItem(ITEM_PRISM, hyperlinks);
  325. return 0;
  326. } else
  327. {
  328. int sellingNumber = ch->GetMyShop()->GetNumberByVnum(ITEM_PRISM);
  329. if(nPrismCount - sellingNumber < hyperlinks)
  330. {
  331. return 2;
  332. } else
  333. {
  334. ch->RemoveSpecifyItem(ITEM_PRISM, hyperlinks);
  335. return 0;
  336. }
  337. }
  338.  
  339. return 4;
  340. }
  341.  
  342. int CInputMain::Whisper(LPCHARACTER ch, const char * data, size_t uiBytes)
  343. {
  344. const TPacketCGWhisper* pinfo = reinterpret_cast<const TPacketCGWhisper*>(data);
  345.  
  346. if (uiBytes < pinfo->wSize)
  347. return -1;
  348.  
  349. int iExtraLen = pinfo->wSize - sizeof(TPacketCGWhisper);
  350.  
  351. if (iExtraLen < 0)
  352. {
  353. sys_err("invalid packet length (len %d size %u buffer %u)", iExtraLen, pinfo->wSize, uiBytes);
  354. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  355. return -1;
  356. }
  357.  
  358. #ifdef ENABLE_WHISPER_CHAT_SPAMLIMIT
  359. if (ch->IncreaseChatCounter() >= 10)
  360. {
  361. ch->GetDesc()->DelayedDisconnect(0);
  362. return (iExtraLen);
  363. }
  364. #endif
  365.  
  366. if (ch->FindAffect(AFFECT_BLOCK_CHAT))
  367. {
  368. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("äÆà ±ÝÁö »óÅÂÀÔ´Ï´Ù."));
  369. return (iExtraLen);
  370. }
  371.  
  372. LPCHARACTER pkChr = CHARACTER_MANAGER::instance().FindPC(pinfo->szNameTo);
  373.  
  374. if (pkChr == ch)
  375. return (iExtraLen);
  376.  
  377. LPDESC pkDesc = NULL;
  378.  
  379. BYTE bOpponentEmpire = 0;
  380.  
  381. if (test_server)
  382. {
  383. if (!pkChr)
  384. sys_log(0, "Whisper to %s(%s) from %s", "Null", pinfo->szNameTo, ch->GetName());
  385. else
  386. sys_log(0, "Whisper to %s(%s) from %s", pkChr->GetName(), pinfo->szNameTo, ch->GetName());
  387. }
  388.  
  389. if (ch->IsBlockMode(BLOCK_WHISPER))
  390. {
  391. if (ch->GetDesc())
  392. {
  393. TPacketGCWhisper pack;
  394. pack.bHeader = HEADER_GC_WHISPER;
  395. pack.bType = WHISPER_TYPE_SENDER_BLOCKED;
  396. pack.wSize = sizeof(TPacketGCWhisper);
  397. strlcpy(pack.szNameFrom, pinfo->szNameTo, sizeof(pack.szNameFrom));
  398. ch->GetDesc()->Packet(&pack, sizeof(pack));
  399. }
  400. return iExtraLen;
  401. }
  402.  
  403. if (!pkChr)
  404. {
  405. CCI * pkCCI = P2P_MANAGER::instance().Find(pinfo->szNameTo);
  406.  
  407. if (pkCCI)
  408. {
  409. pkDesc = pkCCI->pkDesc;
  410. pkDesc->SetRelay(pinfo->szNameTo);
  411. bOpponentEmpire = pkCCI->bEmpire;
  412.  
  413. if (test_server)
  414. sys_log(0, "Whisper to %s from %s (Channel %d Mapindex %d)", "Null", ch->GetName(), pkCCI->bChannel, pkCCI->lMapIndex);
  415. }
  416. }
  417. else
  418. {
  419. pkDesc = pkChr->GetDesc();
  420. bOpponentEmpire = pkChr->GetEmpire();
  421. }
  422.  
  423. if (!pkDesc)
  424. {
  425. if (ch->GetDesc())
  426. {
  427. TPacketGCWhisper pack;
  428.  
  429. pack.bHeader = HEADER_GC_WHISPER;
  430. pack.bType = WHISPER_TYPE_NOT_EXIST;
  431. pack.wSize = sizeof(TPacketGCWhisper);
  432. strlcpy(pack.szNameFrom, pinfo->szNameTo, sizeof(pack.szNameFrom));
  433. ch->GetDesc()->Packet(&pack, sizeof(TPacketGCWhisper));
  434. sys_log(0, "WHISPER: no player");
  435. }
  436. }
  437. else
  438. {
  439. if (ch->IsBlockMode(BLOCK_WHISPER))
  440. {
  441. if (ch->GetDesc())
  442. {
  443. TPacketGCWhisper pack;
  444. pack.bHeader = HEADER_GC_WHISPER;
  445. pack.bType = WHISPER_TYPE_SENDER_BLOCKED;
  446. pack.wSize = sizeof(TPacketGCWhisper);
  447. strlcpy(pack.szNameFrom, pinfo->szNameTo, sizeof(pack.szNameFrom));
  448. ch->GetDesc()->Packet(&pack, sizeof(pack));
  449. }
  450. }
  451. else if (pkChr && pkChr->IsBlockMode(BLOCK_WHISPER))
  452. {
  453. if (ch->GetDesc())
  454. {
  455. TPacketGCWhisper pack;
  456. pack.bHeader = HEADER_GC_WHISPER;
  457. pack.bType = WHISPER_TYPE_TARGET_BLOCKED;
  458. pack.wSize = sizeof(TPacketGCWhisper);
  459. strlcpy(pack.szNameFrom, pinfo->szNameTo, sizeof(pack.szNameFrom));
  460. ch->GetDesc()->Packet(&pack, sizeof(pack));
  461. }
  462. }
  463. else
  464. {
  465. BYTE bType = WHISPER_TYPE_NORMAL;
  466.  
  467. char buf[CHAT_MAX_LEN + 1];
  468. strlcpy(buf, data + sizeof(TPacketCGWhisper), MIN(iExtraLen + 1, sizeof(buf)));
  469. const size_t buflen = strlen(buf);
  470.  
  471. if (true == SpamBlockCheck(ch, buf, buflen))
  472. {
  473. if (!pkChr)
  474. {
  475. CCI * pkCCI = P2P_MANAGER::instance().Find(pinfo->szNameTo);
  476.  
  477. if (pkCCI)
  478. {
  479. pkDesc->SetRelay("");
  480. }
  481. }
  482. return iExtraLen;
  483. }
  484.  
  485. CBanwordManager::instance().ConvertString(buf, buflen);
  486.  
  487. if (g_bEmpireWhisper)
  488. if (!ch->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE))
  489. if (!(pkChr && pkChr->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE)))
  490. if (bOpponentEmpire != ch->GetEmpire() && ch->GetEmpire() && bOpponentEmpire // ¼­·Î Á¦±¹ÀÌ ´Ù¸£¸é¼­
  491. && ch->GetGMLevel() == GM_PLAYER && gm_get_level(pinfo->szNameTo) == GM_PLAYER) // µÑ´Ù ÀÏ¹Ý Ç÷¹À̾îÀ̸é
  492. // À̸§ ¹Û¿¡ ¸ð¸£´Ï gm_get_level ÇÔ¼ö¸¦ »ç¿ë
  493. {
  494. if (!pkChr)
  495. {
  496. // ´Ù¸¥ ¼­¹ö¿¡ ÀÖÀ¸´Ï Á¦±¹ Ç¥½Ã¸¸ ÇÑ´Ù. bTypeÀÇ »óÀ§ 4ºñÆ®¸¦ Empire¹øÈ£·Î »ç¿ëÇÑ´Ù.
  497. bType = ch->GetEmpire() << 4;
  498. }
  499. else
  500. {
  501. ConvertEmpireText(ch->GetEmpire(), buf, buflen, 10 + 2 * pkChr->GetSkillPower(SKILL_LANGUAGE1 + ch->GetEmpire() - 1)/*º¯È¯È®·ü*/);
  502. }
  503. }
  504.  
  505. int processReturn = ProcessTextTag(ch, buf, buflen);
  506. if (0!=processReturn)
  507. {
  508. if (ch->GetDesc())
  509. {
  510. TItemTable * pTable = ITEM_MANAGER::instance().GetTable(ITEM_PRISM);
  511.  
  512. if (pTable)
  513. {
  514. char buf[128];
  515. int len;
  516. if (3==processReturn) //±³È¯Áß
  517. len = snprintf(buf, sizeof(buf), LC_TEXT("»ç¿ëÇÒ¼ö ¾ø½À´Ï´Ù."), pTable->szLocaleName);
  518. else
  519. len = snprintf(buf, sizeof(buf), LC_TEXT("%sÀÌ ÇÊ¿äÇÕ´Ï´Ù."), pTable->szLocaleName);
  520.  
  521. if (len < 0 || len >= (int) sizeof(buf))
  522. len = sizeof(buf) - 1;
  523.  
  524. ++len; // \0 ¹®ÀÚ Æ÷ÇÔ
  525.  
  526. TPacketGCWhisper pack;
  527.  
  528. pack.bHeader = HEADER_GC_WHISPER;
  529. pack.bType = WHISPER_TYPE_ERROR;
  530. pack.wSize = sizeof(TPacketGCWhisper) + len;
  531. strlcpy(pack.szNameFrom, pinfo->szNameTo, sizeof(pack.szNameFrom));
  532.  
  533. ch->GetDesc()->BufferedPacket(&pack, sizeof(pack));
  534. ch->GetDesc()->Packet(buf, len);
  535.  
  536. sys_log(0, "WHISPER: not enough %s: char: %s", pTable->szLocaleName, ch->GetName());
  537. }
  538. }
  539.  
  540. // ¸±·¡ÀÌ »óÅÂÀÏ ¼ö ÀÖÀ¸¹Ç·Î ¸±·¡À̸¦ Ç®¾îÁØ´Ù.
  541. pkDesc->SetRelay("");
  542. return (iExtraLen);
  543. }
  544.  
  545. if (ch->IsGM())
  546. bType = (bType & 0xF0) | WHISPER_TYPE_GM;
  547.  
  548. if (buflen > 0)
  549. {
  550. TPacketGCWhisper pack;
  551.  
  552. pack.bHeader = HEADER_GC_WHISPER;
  553. pack.wSize = sizeof(TPacketGCWhisper) + buflen;
  554. pack.bType = bType;
  555. strlcpy(pack.szNameFrom, ch->GetName(), sizeof(pack.szNameFrom));
  556.  
  557. // desc->BufferedPacketÀ» ÇÏÁö ¾Ê°í ¹öÆÛ¿¡ ½á¾ßÇÏ´Â ÀÌÀ¯´Â
  558. // P2P relayµÇ¾î ÆÐŶÀÌ Ä¸½¶È­ µÉ ¼ö Àֱ⠶§¹®ÀÌ´Ù.
  559. TEMP_BUFFER tmpbuf;
  560.  
  561. tmpbuf.write(&pack, sizeof(pack));
  562. tmpbuf.write(buf, buflen);
  563.  
  564. pkDesc->Packet(tmpbuf.read_peek(), tmpbuf.size());
  565.  
  566. // @warme006
  567. // sys_log(0, "WHISPER: %s -> %s : %s", ch->GetName(), pinfo->szNameTo, buf);
  568. #ifdef ENABLE_CHAT_LOGGING
  569. if (ch->IsGM())
  570. {
  571. LogManager::instance().EscapeString(__escape_string, sizeof(__escape_string), buf, buflen);
  572. LogManager::instance().EscapeString(__escape_string2, sizeof(__escape_string2), pinfo->szNameTo, sizeof(pack.szNameFrom));
  573. LogManager::instance().ChatLog(ch->GetMapIndex(), ch->GetPlayerID(), ch->GetName(), 0, __escape_string2, "WHISPER", __escape_string, ch->GetDesc() ? ch->GetDesc()->GetHostName() : "");
  574. }
  575. #endif
  576. }
  577. }
  578. }
  579. if(pkDesc)
  580. pkDesc->SetRelay("");
  581.  
  582. return (iExtraLen);
  583. }
  584.  
  585. struct RawPacketToCharacterFunc
  586. {
  587. const void * m_buf;
  588. int m_buf_len;
  589.  
  590. RawPacketToCharacterFunc(const void * buf, int buf_len) : m_buf(buf), m_buf_len(buf_len)
  591. {
  592. }
  593.  
  594. void operator () (LPCHARACTER c)
  595. {
  596. if (!c->GetDesc())
  597. return;
  598.  
  599. c->GetDesc()->Packet(m_buf, m_buf_len);
  600. }
  601. };
  602.  
  603. struct FEmpireChatPacket
  604. {
  605. packet_chat& p;
  606. const char* orig_msg;
  607. int orig_len;
  608. char converted_msg[CHAT_MAX_LEN+1];
  609.  
  610. BYTE bEmpire;
  611. int iMapIndex;
  612. int namelen;
  613.  
  614. FEmpireChatPacket(packet_chat& p, const char* chat_msg, int len, BYTE bEmpire, int iMapIndex, int iNameLen)
  615. : p(p), orig_msg(chat_msg), orig_len(len), bEmpire(bEmpire), iMapIndex(iMapIndex), namelen(iNameLen)
  616. {
  617. memset( converted_msg, 0, sizeof(converted_msg) );
  618. }
  619.  
  620. void operator () (LPDESC d)
  621. {
  622. if (!d->GetCharacter())
  623. return;
  624.  
  625. d->GetCharacter()->ChatPacket(CHAT_TYPE_SHOUT, "%s", m_str);
  626. }
  627.  
  628. d->BufferedPacket(&p, sizeof(packet_chat));
  629.  
  630. if (d->GetEmpire() == bEmpire ||
  631. bEmpire == 0 ||
  632. d->GetCharacter()->GetGMLevel() > GM_PLAYER ||
  633. d->GetCharacter()->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE))
  634. {
  635. d->Packet(orig_msg, orig_len);
  636. }
  637. else
  638. {
  639. // »ç¶÷¸¶´Ù ½ºÅ³·¹º§ÀÌ ´Ù¸£´Ï ¸Å¹ø ÇؾßÇÕ´Ï´Ù
  640. size_t len = strlcpy(converted_msg, orig_msg, sizeof(converted_msg));
  641.  
  642. if (len >= sizeof(converted_msg))
  643. len = sizeof(converted_msg) - 1;
  644.  
  645. ConvertEmpireText(bEmpire, converted_msg + namelen, len - namelen, 10 + 2 * d->GetCharacter()->GetSkillPower(SKILL_LANGUAGE1 + bEmpire - 1));
  646. d->Packet(converted_msg, orig_len);
  647. }
  648. }
  649. };
  650.  
  651. struct FYmirChatPacket
  652. {
  653. packet_chat& packet;
  654. const char* m_szChat;
  655. size_t m_lenChat;
  656. const char* m_szName;
  657.  
  658. int m_iMapIndex;
  659. BYTE m_bEmpire;
  660. bool m_ring;
  661.  
  662. char m_orig_msg[CHAT_MAX_LEN+1];
  663. int m_len_orig_msg;
  664. char m_conv_msg[CHAT_MAX_LEN+1];
  665. int m_len_conv_msg;
  666.  
  667. FYmirChatPacket(packet_chat& p, const char* chat, size_t len_chat, const char* name, size_t len_name, int iMapIndex, BYTE empire, bool ring)
  668. : packet(p),
  669. m_szChat(chat), m_lenChat(len_chat),
  670. m_szName(name),
  671. m_iMapIndex(iMapIndex), m_bEmpire(empire),
  672. m_ring(ring)
  673. {
  674. m_len_orig_msg = snprintf(m_orig_msg, sizeof(m_orig_msg), "%s : %s", m_szName, m_szChat) + 1; // ³Î ¹®ÀÚ Æ÷ÇÔ
  675.  
  676. if (m_len_orig_msg < 0 || m_len_orig_msg >= (int) sizeof(m_orig_msg))
  677. m_len_orig_msg = sizeof(m_orig_msg) - 1;
  678.  
  679. m_len_conv_msg = snprintf(m_conv_msg, sizeof(m_conv_msg), "??? : %s", m_szChat) + 1; // ³Î ¹®ÀÚ ¹ÌÆ÷ÇÔ
  680.  
  681. if (m_len_conv_msg < 0 || m_len_conv_msg >= (int) sizeof(m_conv_msg))
  682. m_len_conv_msg = sizeof(m_conv_msg) - 1;
  683.  
  684. ConvertEmpireText(m_bEmpire, m_conv_msg + 6, m_len_conv_msg - 6, 10); // 6Àº "??? : "ÀÇ ±æÀÌ
  685. }
  686.  
  687. void operator() (LPDESC d)
  688. {
  689. if (!d->GetCharacter())
  690. return;
  691.  
  692. if (d->GetCharacter()->GetMapIndex() != m_iMapIndex)
  693. return;
  694.  
  695. if (m_ring ||
  696. d->GetEmpire() == m_bEmpire ||
  697. d->GetCharacter()->GetGMLevel() > GM_PLAYER ||
  698. d->GetCharacter()->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE))
  699. {
  700. packet.size = m_len_orig_msg + sizeof(TPacketGCChat);
  701.  
  702. d->BufferedPacket(&packet, sizeof(packet_chat));
  703. d->Packet(m_orig_msg, m_len_orig_msg);
  704. }
  705. else
  706. {
  707. packet.size = m_len_conv_msg + sizeof(TPacketGCChat);
  708.  
  709. d->BufferedPacket(&packet, sizeof(packet_chat));
  710. d->Packet(m_conv_msg, m_len_conv_msg);
  711. }
  712. }
  713. };
  714.  
  715. int CInputMain::Chat(LPCHARACTER ch, const char * data, size_t uiBytes)
  716. {
  717. const TPacketCGChat* pinfo = reinterpret_cast<const TPacketCGChat*>(data);
  718.  
  719. if (uiBytes < pinfo->size)
  720. return -1;
  721.  
  722. const int iExtraLen = pinfo->size - sizeof(TPacketCGChat);
  723.  
  724. if (iExtraLen < 0)
  725. {
  726. sys_err("invalid packet length (len %d size %u buffer %u)", iExtraLen, pinfo->size, uiBytes);
  727. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  728. return -1;
  729. }
  730.  
  731. char buf[CHAT_MAX_LEN - (CHARACTER_NAME_MAX_LEN + 3) + 1];
  732. strlcpy(buf, data + sizeof(TPacketCGChat), MIN(iExtraLen + 1, sizeof(buf)));
  733. const size_t buflen = strlen(buf);
  734.  
  735. if (buflen > 1 && *buf == '/')
  736. {
  737. interpret_command(ch, buf + 1, buflen - 1);
  738. return iExtraLen;
  739. }
  740. #ifdef ENABLE_CHAT_SPAMLIMIT
  741. if (ch->IncreaseChatCounter() >= 4)
  742. {
  743. if (ch->GetChatCounter() == 10)
  744. ch->GetDesc()->DelayedDisconnect(0);
  745. return iExtraLen;
  746. }
  747. #else
  748. if (ch->IncreaseChatCounter() >= 10)
  749. {
  750. if (ch->GetChatCounter() == 10)
  751. {
  752. sys_log(0, "CHAT_HACK: %s", ch->GetName());
  753. ch->GetDesc()->DelayedDisconnect(5);
  754. }
  755.  
  756. return iExtraLen;
  757. }
  758. #endif
  759.  
  760. // äÆà ±ÝÁö Affect ó¸®
  761. const CAffect* pAffect = ch->FindAffect(AFFECT_BLOCK_CHAT);
  762.  
  763. if (pAffect != NULL)
  764. {
  765. SendBlockChatInfo(ch, pAffect->lDuration);
  766. return iExtraLen;
  767. }
  768.  
  769. if (true == SpamBlockCheck(ch, buf, buflen))
  770. {
  771. return iExtraLen;
  772. }
  773.  
  774. // @fixme133 begin
  775. CBanwordManager::instance().ConvertString(buf, buflen);
  776.  
  777. int processReturn = ProcessTextTag(ch, buf, buflen);
  778. if (0!=processReturn)
  779. {
  780. const TItemTable* pTable = ITEM_MANAGER::instance().GetTable(ITEM_PRISM);
  781.  
  782. if (NULL != pTable)
  783. {
  784. if (3==processReturn) //±³È¯Áß
  785. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ç¿ëÇÒ¼ö ¾ø½À´Ï´Ù."), pTable->szLocaleName);
  786. else
  787. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%sÀÌ ÇÊ¿äÇÕ´Ï´Ù."), pTable->szLocaleName);
  788.  
  789. }
  790.  
  791. return iExtraLen;
  792. }
  793. // @fixme133 end
  794.  
  795. char chatbuf[CHAT_MAX_LEN + 1];
  796. #ifdef ENABLE_GLOBAL_CHAT
  797. if(ch->GetGMLevel() > GM_PLAYER)
  798. {
  799.  
  800. if (strncmp("[OwN]", ch->GetName(), 5) == 0)
  801. {
  802. len = snprintf(chatbuf, sizeof(chatbuf), "[|cFF00FF00Detinator|r] %s : %s", ch->GetName(), buf);
  803. }
  804. else if (strncmp("[SGA]", ch->GetName(), 3) == 0)
  805. {
  806. len = snprintf(chatbuf, sizeof(chatbuf), "[|cFF00FF00Administrator|r] %s : %s", ch->GetName(), buf);
  807. }
  808. else
  809. {
  810. len = snprintf(chatbuf, sizeof(chatbuf), "[|cFF00FF00Staff|r] %s : %s", ch->GetName(), buf);
  811. }
  812. }
  813. else
  814. len = snprintf(chatbuf, sizeof(chatbuf), "[|cFF00FF00Lv. %d|r] %s : %s", ch->GetLevel(), ch->GetName(), buf);
  815. #else
  816. len = snprintf(chatbuf, sizeof(chatbuf), "%s : %s", ch->GetName(), buf);
  817. #endif
  818.  
  819. //Cauta/Search:
  820. if ((thecore_heart->pulse - (int) ch->GetLastShoutPulse() < passes_per_sec * 15))
  821. return (iExtraLen);
  822.  
  823. ch->SetLastShoutPulse(thecore_heart->pulse);
  824. //Adauga sub/Add bellow:
  825.  
  826. #ifdef ENABLE_GLOBAL_CHAT
  827. const char* kingdoms[3] = { "|cFFff0000|H|h[Rosu]|cFFA7FFD4|H|h", "|cFFFFFF00|H|h[Galben]|cFFA7FFD4|H|h", "|cFF0080FF|H|h[Albastru]|cFFA7FFD4|H|h" };
  828. char chatbuf_global[CHAT_MAX_LEN + 1];
  829.  
  830. if(ch->GetGMLevel() > GM_PLAYER)
  831. {
  832. if (strncmp("[Owner]", ch->GetName(), 5) == 0)
  833. {
  834. int len_global = snprintf(chatbuf_global, sizeof(chatbuf_global), "[|cFF00FF00Detinator Server|r] %s : %s", ch->GetName(), buf);
  835. }
  836. else if (strncmp("[SGA]", ch->GetName(), 3) == 0)
  837. {
  838. int len_global = snprintf(chatbuf_global, sizeof(chatbuf_global), "[|cFF00FF00Administrator|r] %s : %s", ch->GetName(), buf);
  839. }
  840. else
  841. {
  842. int len_global = snprintf(chatbuf_global, sizeof(chatbuf_global), "[|cFF00FF00[Staff]|r] %s : %s", ch->GetName(), buf);
  843. }
  844. }
  845. else
  846. int len_global = snprintf(chatbuf_global, sizeof(chatbuf_global), "%s [CH%d][|cFF00FF00Lv. %d|r] %s: %s",kingdoms[ch->GetEmpire()-1], g_bChannel, ch->GetLevel(), ch->GetName(), buf);
  847.  
  848. #else
  849. int len_global = snprintf(chatbuf_global, sizeof(chatbuf_global), "%s : %s",ch->GetName(), buf);
  850. #endif
  851. TPacketGGShout p;
  852.  
  853. p.bHeader = HEADER_GG_SHOUT;
  854. p.bEmpire = ch->GetEmpire();
  855. strlcpy(p.szText, chatbuf_global, sizeof(p.szText));
  856.  
  857. P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShout));
  858.  
  859. SendShout(chatbuf_global, ch->GetEmpire());
  860.  
  861. return (iExtraLen);
  862. }
  863.  
  864. TPacketGCChat pack_chat;
  865.  
  866. pack_chat.header = HEADER_GC_CHAT;
  867. pack_chat.size = sizeof(TPacketGCChat) + len;
  868. pack_chat.type = pinfo->type;
  869. pack_chat.id = ch->GetVID();
  870.  
  871. switch (pinfo->type)
  872. {
  873. case CHAT_TYPE_TALKING:
  874. {
  875. const DESC_MANAGER::DESC_SET & c_ref_set = DESC_MANAGER::instance().GetClientSet();
  876.  
  877. if (false)
  878. {
  879. std::for_each(c_ref_set.begin(), c_ref_set.end(),
  880. FYmirChatPacket(pack_chat,
  881. buf,
  882. strlen(buf),
  883. ch->GetName(),
  884. strlen(ch->GetName()),
  885. ch->GetMapIndex(),
  886. ch->GetEmpire(),
  887. ch->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE)));
  888. }
  889. else
  890. {
  891. std::for_each(c_ref_set.begin(), c_ref_set.end(),
  892. FEmpireChatPacket(pack_chat,
  893. chatbuf,
  894. len,
  895. (ch->GetGMLevel() > GM_PLAYER ||
  896. ch->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE)) ? 0 : ch->GetEmpire(),
  897. ch->GetMapIndex(), strlen(ch->GetName())));
  898. #ifdef ENABLE_CHAT_LOGGING
  899. if (ch->IsGM())
  900. {
  901. LogManager::instance().EscapeString(__escape_string, sizeof(__escape_string), chatbuf, len);
  902. LogManager::instance().ChatLog(ch->GetMapIndex(), ch->GetPlayerID(), ch->GetName(), 0, "", "NORMAL", __escape_string, ch->GetDesc() ? ch->GetDesc()->GetHostName() : "");
  903. }
  904. #endif
  905. }
  906. }
  907. break;
  908.  
  909. case CHAT_TYPE_PARTY:
  910. {
  911. if (!ch->GetParty())
  912. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÆÄƼ ÁßÀÌ ¾Æ´Õ´Ï´Ù."));
  913. else
  914. {
  915. TEMP_BUFFER tbuf;
  916.  
  917. tbuf.write(&pack_chat, sizeof(pack_chat));
  918. tbuf.write(chatbuf, len);
  919.  
  920. RawPacketToCharacterFunc f(tbuf.read_peek(), tbuf.size());
  921. ch->GetParty()->ForEachOnlineMember(f);
  922. #ifdef ENABLE_CHAT_LOGGING
  923. if (ch->IsGM())
  924. {
  925. LogManager::instance().EscapeString(__escape_string, sizeof(__escape_string), chatbuf, len);
  926. LogManager::instance().ChatLog(ch->GetMapIndex(), ch->GetPlayerID(), ch->GetName(), ch->GetParty()->GetLeaderPID(), "", "PARTY", __escape_string, ch->GetDesc() ? ch->GetDesc()->GetHostName() : "");
  927. }
  928. #endif
  929. }
  930. }
  931. break;
  932.  
  933. case CHAT_TYPE_GUILD:
  934. {
  935. if (!ch->GetGuild())
  936. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("±æµå¿¡ °¡ÀÔÇÏÁö ¾Ê¾Ò½À´Ï´Ù."));
  937. else
  938. {
  939. ch->GetGuild()->Chat(chatbuf);
  940. #ifdef ENABLE_CHAT_LOGGING
  941. if (ch->IsGM())
  942. {
  943. LogManager::instance().EscapeString(__escape_string, sizeof(__escape_string), chatbuf, len);
  944. LogManager::instance().ChatLog(ch->GetMapIndex(), ch->GetPlayerID(), ch->GetName(), ch->GetGuild()->GetID(), ch->GetGuild()->GetName(), "GUILD", __escape_string, ch->GetDesc() ? ch->GetDesc()->GetHostName() : "");
  945. }
  946. #endif
  947. }
  948. }
  949. break;
  950.  
  951. default:
  952. sys_err("Unknown chat type %d", pinfo->type);
  953. break;
  954. }
  955.  
  956. return (iExtraLen);
  957. }
  958.  
  959. void CInputMain::ItemUse(LPCHARACTER ch, const char * data)
  960. {
  961. ch->UseItem(((struct command_item_use *) data)->Cell);
  962. }
  963.  
  964. void CInputMain::ItemToItem(LPCHARACTER ch, const char * pcData)
  965. {
  966. TPacketCGItemUseToItem * p = (TPacketCGItemUseToItem *) pcData;
  967. if (ch)
  968. ch->UseItem(p->Cell, p->TargetCell);
  969. }
  970.  
  971. void CInputMain::ItemDrop(LPCHARACTER ch, const char * data)
  972. {
  973. struct command_item_drop * pinfo = (struct command_item_drop *) data;
  974.  
  975. //MONARCH_LIMIT
  976. //if (ch->IsMonarch())
  977. // return;
  978. //END_MONARCH_LIMIT
  979. if (!ch)
  980. return;
  981.  
  982. // ¿¤Å©°¡ 0º¸´Ù Å©¸é ¿¤Å©¸¦ ¹ö¸®´Â °Í ÀÌ´Ù.
  983. if (pinfo->gold > 0)
  984. ch->DropGold(pinfo->gold);
  985. else
  986. ch->DropItem(pinfo->Cell);
  987. }
  988.  
  989. void CInputMain::ItemDrop2(LPCHARACTER ch, const char * data)
  990. {
  991. //MONARCH_LIMIT
  992. //if (ch->IsMonarch())
  993. // return;
  994. //END_MONARCH_LIMIT
  995.  
  996. TPacketCGItemDrop2 * pinfo = (TPacketCGItemDrop2 *) data;
  997.  
  998. // ¿¤Å©°¡ 0º¸´Ù Å©¸é ¿¤Å©¸¦ ¹ö¸®´Â °Í ÀÌ´Ù.
  999.  
  1000. if (!ch)
  1001. return;
  1002. if (pinfo->gold > 0)
  1003. ch->DropGold(pinfo->gold);
  1004. else
  1005. ch->DropItem(pinfo->Cell, pinfo->count);
  1006. }
  1007.  
  1008. void CInputMain::ItemDestroy(LPCHARACTER ch, const char * data)
  1009. {
  1010. struct command_item_destroy * pinfo = (struct command_item_destroy *) data;
  1011. if (ch)
  1012. ch->DestroyItem(pinfo->Cell);
  1013. }
  1014.  
  1015. void CInputMain::ItemMove(LPCHARACTER ch, const char * data)
  1016. {
  1017. struct command_item_move * pinfo = (struct command_item_move *) data;
  1018.  
  1019. if (ch)
  1020. ch->MoveItem(pinfo->Cell, pinfo->CellTo, pinfo->count);
  1021. }
  1022.  
  1023. #ifdef NEW_ADD_INVENTORY
  1024. void CInputMain::Envanter_pakettiii(LPCHARACTER ch, const char * data)
  1025. {
  1026. if (ch)
  1027. ch->Envanter_update();
  1028. }
  1029. #endif
  1030.  
  1031. void CInputMain::ItemPickup(LPCHARACTER ch, const char * data)
  1032. {
  1033. struct command_item_pickup * pinfo = (struct command_item_pickup*) data;
  1034. if (ch)
  1035. ch->PickupItem(pinfo->vid);
  1036. }
  1037.  
  1038. void CInputMain::QuickslotAdd(LPCHARACTER ch, const char * data)
  1039. {
  1040. struct command_quickslot_add * pinfo = (struct command_quickslot_add *) data;
  1041. ch->SetQuickslot(pinfo->pos, pinfo->slot);
  1042. }
  1043.  
  1044. void CInputMain::QuickslotDelete(LPCHARACTER ch, const char * data)
  1045. {
  1046. struct command_quickslot_del * pinfo = (struct command_quickslot_del *) data;
  1047. ch->DelQuickslot(pinfo->pos);
  1048. }
  1049.  
  1050. void CInputMain::QuickslotSwap(LPCHARACTER ch, const char * data)
  1051. {
  1052. struct command_quickslot_swap * pinfo = (struct command_quickslot_swap *) data;
  1053. ch->SwapQuickslot(pinfo->pos, pinfo->change_pos);
  1054. }
  1055.  
  1056. int CInputMain::Messenger(LPCHARACTER ch, const char* c_pData, size_t uiBytes)
  1057. {
  1058. TPacketCGMessenger* p = (TPacketCGMessenger*) c_pData;
  1059.  
  1060. if (uiBytes < sizeof(TPacketCGMessenger))
  1061. return -1;
  1062.  
  1063. c_pData += sizeof(TPacketCGMessenger);
  1064. uiBytes -= sizeof(TPacketCGMessenger);
  1065.  
  1066. switch (p->subheader)
  1067. {
  1068. case MESSENGER_SUBHEADER_CG_ADD_BY_VID:
  1069. {
  1070. if (uiBytes < sizeof(TPacketCGMessengerAddByVID))
  1071. return -1;
  1072.  
  1073. TPacketCGMessengerAddByVID * p2 = (TPacketCGMessengerAddByVID *) c_pData;
  1074. LPCHARACTER ch_companion = CHARACTER_MANAGER::instance().Find(p2->vid);
  1075.  
  1076. if (!ch_companion)
  1077. return sizeof(TPacketCGMessengerAddByVID);
  1078.  
  1079. if (ch->IsObserverMode())
  1080. return sizeof(TPacketCGMessengerAddByVID);
  1081.  
  1082. if (ch_companion->IsBlockMode(BLOCK_MESSENGER_INVITE))
  1083. {
  1084. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÌ ¸Þ½ÅÁ® Ãß°¡ °ÅºÎ »óÅÂÀÔ´Ï´Ù."));
  1085. return sizeof(TPacketCGMessengerAddByVID);
  1086. }
  1087.  
  1088. LPDESC d = ch_companion->GetDesc();
  1089.  
  1090. if (!d)
  1091. return sizeof(TPacketCGMessengerAddByVID);
  1092.  
  1093. if (ch->GetGMLevel() == GM_PLAYER && ch_companion->GetGMLevel() != GM_PLAYER)
  1094. {
  1095. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<¸Þ½ÅÁ®> ¿î¿µÀÚ´Â ¸Þ½ÅÁ®¿¡ Ãß°¡ÇÒ ¼ö ¾ø½À´Ï´Ù."));
  1096. return sizeof(TPacketCGMessengerAddByVID);
  1097. }
  1098.  
  1099. if (ch->GetDesc() == d) // ÀÚ½ÅÀº Ãß°¡ÇÒ ¼ö ¾ø´Ù.
  1100. return sizeof(TPacketCGMessengerAddByVID);
  1101.  
  1102. MessengerManager::instance().RequestToAdd(ch, ch_companion);
  1103. //MessengerManager::instance().AddToList(ch->GetName(), ch_companion->GetName());
  1104. }
  1105. return sizeof(TPacketCGMessengerAddByVID);
  1106.  
  1107. case MESSENGER_SUBHEADER_CG_ADD_BY_NAME:
  1108. {
  1109. if (uiBytes < CHARACTER_NAME_MAX_LEN)
  1110. return -1;
  1111.  
  1112. char name[CHARACTER_NAME_MAX_LEN + 1];
  1113. strlcpy(name, c_pData, sizeof(name));
  1114.  
  1115. if (ch->GetGMLevel() == GM_PLAYER && gm_get_level(name) != GM_PLAYER)
  1116. {
  1117. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<¸Þ½ÅÁ®> ¿î¿µÀÚ´Â ¸Þ½ÅÁ®¿¡ Ãß°¡ÇÒ ¼ö ¾ø½À´Ï´Ù."));
  1118. return CHARACTER_NAME_MAX_LEN;
  1119. }
  1120.  
  1121. LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(name);
  1122.  
  1123. if (!tch)
  1124. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s ´ÔÀº Á¢¼ÓµÇ ÀÖÁö ¾Ê½À´Ï´Ù."), name);
  1125. else
  1126. {
  1127. if (tch == ch) // ÀÚ½ÅÀº Ãß°¡ÇÒ ¼ö ¾ø´Ù.
  1128. return CHARACTER_NAME_MAX_LEN;
  1129.  
  1130. if (tch->IsBlockMode(BLOCK_MESSENGER_INVITE) == true)
  1131. {
  1132. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÌ ¸Þ½ÅÁ® Ãß°¡ °ÅºÎ »óÅÂÀÔ´Ï´Ù."));
  1133. }
  1134. else
  1135. {
  1136. // ¸Þ½ÅÀú°¡ ij¸¯ÅÍ´ÜÀ§°¡ µÇ¸é¼­ º¯°æ
  1137. MessengerManager::instance().RequestToAdd(ch, tch);
  1138. //MessengerManager::instance().AddToList(ch->GetName(), tch->GetName());
  1139. }
  1140. }
  1141. }
  1142. return CHARACTER_NAME_MAX_LEN;
  1143.  
  1144. case MESSENGER_SUBHEADER_CG_REMOVE:
  1145. {
  1146. if (uiBytes < CHARACTER_NAME_MAX_LEN)
  1147. return -1;
  1148.  
  1149. char char_name[CHARACTER_NAME_MAX_LEN + 1];
  1150. strlcpy(char_name, c_pData, sizeof(char_name));
  1151. MessengerManager::instance().RemoveFromList(ch->GetName(), char_name);
  1152. }
  1153. return CHARACTER_NAME_MAX_LEN;
  1154.  
  1155. default:
  1156. sys_err("CInputMain::Messenger : Unknown subheader %d : %s", p->subheader, ch->GetName());
  1157. break;
  1158. }
  1159.  
  1160. return 0;
  1161. }
  1162.  
  1163. int CInputMain::Shop(LPCHARACTER ch, const char * data, size_t uiBytes)
  1164. {
  1165. TPacketCGShop * p = (TPacketCGShop *) data;
  1166.  
  1167. if (uiBytes < sizeof(TPacketCGShop))
  1168. return -1;
  1169.  
  1170. if (test_server)
  1171. sys_log(0, "CInputMain::Shop() ==> SubHeader %d", p->subheader);
  1172.  
  1173. const char * c_pData = data + sizeof(TPacketCGShop);
  1174. uiBytes -= sizeof(TPacketCGShop);
  1175.  
  1176. switch (p->subheader)
  1177. {
  1178. case SHOP_SUBHEADER_CG_END:
  1179. sys_log(1, "INPUT: %s SHOP: END", ch->GetName());
  1180. CShopManager::instance().StopShopping(ch);
  1181. return 0;
  1182.  
  1183. case SHOP_SUBHEADER_CG_BUY:
  1184. {
  1185. if (uiBytes < sizeof(BYTE) + sizeof(BYTE))
  1186. return -1;
  1187.  
  1188. BYTE bPos = *(c_pData + 1);
  1189. sys_log(1, "INPUT: %s SHOP: BUY %d", ch->GetName(), bPos);
  1190. CShopManager::instance().Buy(ch, bPos);
  1191. return (sizeof(BYTE) + sizeof(BYTE));
  1192. }
  1193.  
  1194. case SHOP_SUBHEADER_CG_SELL:
  1195. {
  1196. if (uiBytes < sizeof(BYTE))
  1197. return -1;
  1198.  
  1199. BYTE pos = *c_pData;
  1200.  
  1201. sys_log(0, "INPUT: %s SHOP: SELL", ch->GetName());
  1202. CShopManager::instance().Sell(ch, pos);
  1203. return sizeof(BYTE);
  1204. }
  1205.  
  1206. case SHOP_SUBHEADER_CG_SELL2:
  1207. {
  1208. if (uiBytes < sizeof(BYTE) + sizeof(BYTE))
  1209. return -1;
  1210.  
  1211. BYTE pos = *(c_pData++);
  1212. BYTE count = *(c_pData);
  1213.  
  1214. sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());
  1215. CShopManager::instance().Sell(ch, pos, count);
  1216. return sizeof(BYTE) + sizeof(BYTE);
  1217. }
  1218.  
  1219. default:
  1220. sys_err("CInputMain::Shop : Unknown subheader %d : %s", p->subheader, ch->GetName());
  1221. break;
  1222. }
  1223.  
  1224. return 0;
  1225. }
  1226.  
  1227. void CInputMain::OnClick(LPCHARACTER ch, const char * data)
  1228. {
  1229. struct command_on_click * pinfo = (struct command_on_click *) data;
  1230. LPCHARACTER victim;
  1231.  
  1232. if ((victim = CHARACTER_MANAGER::instance().Find(pinfo->vid)))
  1233. victim->OnClick(ch);
  1234. else if (test_server)
  1235. {
  1236. sys_err("CInputMain::OnClick %s.Click.NOT_EXIST_VID[%d]", ch->GetName(), pinfo->vid);
  1237. }
  1238. }
  1239.  
  1240. void CInputMain::Exchange(LPCHARACTER ch, const char * data)
  1241. {
  1242. struct command_exchange * pinfo = (struct command_exchange *) data;
  1243. LPCHARACTER to_ch = NULL;
  1244.  
  1245. if (!ch->CanHandleItem())
  1246. return;
  1247.  
  1248. int iPulse = thecore_pulse();
  1249.  
  1250. if ((to_ch = CHARACTER_MANAGER::instance().Find(pinfo->arg1)))
  1251. {
  1252. if (iPulse - to_ch->GetSafeboxLoadTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  1253. {
  1254. to_ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°Å·¡ ÈÄ %dÃÊ À̳»¿¡ â°í¸¦ ¿­¼ö ¾ø½À´Ï´Ù."), g_nPortalLimitTime);
  1255. return;
  1256. }
  1257.  
  1258. if( true == to_ch->IsDead() )
  1259. {
  1260. return;
  1261. }
  1262. }
  1263.  
  1264. sys_log(0, "CInputMain()::Exchange() SubHeader %d ", pinfo->sub_header);
  1265.  
  1266. if (iPulse - ch->GetSafeboxLoadTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  1267. {
  1268. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°Å·¡ ÈÄ %dÃÊ À̳»¿¡ â°í¸¦ ¿­¼ö ¾ø½À´Ï´Ù."), g_nPortalLimitTime);
  1269. return;
  1270. }
  1271.  
  1272.  
  1273. switch (pinfo->sub_header)
  1274. {
  1275. case EXCHANGE_SUBHEADER_CG_START: // arg1 == vid of target character
  1276. if (!ch->GetExchange())
  1277. {
  1278. if ((to_ch = CHARACTER_MANAGER::instance().Find(pinfo->arg1)))
  1279. {
  1280. //MONARCH_LIMIT
  1281. /*
  1282. if (to_ch->IsMonarch() || ch->IsMonarch())
  1283. {
  1284. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("±ºÁÖ¿Í´Â °Å·¡¸¦ ÇÒ¼ö°¡ ¾ø½À´Ï´Ù"), g_nPortalLimitTime);
  1285. return;
  1286. }
  1287. //END_MONARCH_LIMIT
  1288. */
  1289. if (iPulse - ch->GetSafeboxLoadTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  1290. {
  1291. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("â°í¸¦ ¿¬ÈÄ %dÃÊ À̳»¿¡´Â °Å·¡¸¦ ÇÒ¼ö ¾ø½À´Ï´Ù."), g_nPortalLimitTime);
  1292.  
  1293. if (test_server)
  1294. ch->ChatPacket(CHAT_TYPE_INFO, "[TestOnly][Safebox]Pulse %d LoadTime %d PASS %d", iPulse, ch->GetSafeboxLoadTime(), PASSES_PER_SEC(g_nPortalLimitTime));
  1295. return;
  1296. }
  1297.  
  1298. if (iPulse - to_ch->GetSafeboxLoadTime() < PASSES_PER_SEC(g_nPortalLimitTime))
  1299. {
  1300. to_ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("â°í¸¦ ¿¬ÈÄ %dÃÊ À̳»¿¡´Â °Å·¡¸¦ ÇÒ¼ö ¾ø½À´Ï´Ù."), g_nPortalLimitTime);
  1301.  
  1302.  
  1303. if (test_server)
  1304. to_ch->ChatPacket(CHAT_TYPE_INFO, "[TestOnly][Safebox]Pulse %d LoadTime %d PASS %d", iPulse, to_ch->GetSafeboxLoadTime(), PASSES_PER_SEC(g_nPortalLimitTime));
  1305. return;
  1306. }
  1307.  
  1308. if (ch->GetGold() >= GOLD_MAX)
  1309. {
  1310. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¾×¼ö°¡ 20¾ï ³ÉÀ» ÃÊ°úÇÏ¿© °Å·¡¸¦ ÇÒ¼ö°¡ ¾ø½À´Ï´Ù.."));
  1311.  
  1312. sys_err("[OVERFLOG_GOLD] START (%lld) id %u name %s ", ch->GetGold(), ch->GetPlayerID(), ch->GetName());
  1313. return;
  1314. }
  1315.  
  1316. if (to_ch->IsPC())
  1317. {
  1318. if (quest::CQuestManager::instance().GiveItemToPC(ch->GetPlayerID(), to_ch))
  1319. {
  1320. sys_log(0, "Exchange canceled by quest %s %s", ch->GetName(), to_ch->GetName());
  1321. return;
  1322. }
  1323. }
  1324.  
  1325.  
  1326. if (ch->GetMyShop() || ch->IsOpenSafebox() || ch->GetShopOwner() || ch->IsCubeOpen())
  1327. {
  1328. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ù¸¥ °Å·¡ÁßÀÏ°æ¿ì °³ÀλóÁ¡À» ¿­¼ö°¡ ¾ø½À´Ï´Ù."));
  1329. return;
  1330. }
  1331.  
  1332. ch->ExchangeStart(to_ch);
  1333. }
  1334. }
  1335. break;
  1336.  
  1337. case EXCHANGE_SUBHEADER_CG_ITEM_ADD: // arg1 == position of item, arg2 == position in exchange window
  1338. if (ch->GetExchange())
  1339. {
  1340. if (ch->GetExchange()->GetCompany()->GetAcceptStatus() != true)
  1341. ch->GetExchange()->AddItem(pinfo->Pos, pinfo->arg2);
  1342. }
  1343. break;
  1344.  
  1345. case EXCHANGE_SUBHEADER_CG_ITEM_DEL: // arg1 == position of item
  1346. if (ch->GetExchange())
  1347. {
  1348. if (ch->GetExchange()->GetCompany()->GetAcceptStatus() != true)
  1349. ch->GetExchange()->RemoveItem(pinfo->arg1);
  1350. }
  1351. break;
  1352.  
  1353. case EXCHANGE_SUBHEADER_CG_ELK_ADD: // arg1 == amount of gold
  1354. if (ch->GetExchange())
  1355. {
  1356. const long long nTotalGold = static_cast<long long>(ch->GetExchange()->GetCompany()->GetOwner()->GetGold()) + static_cast<long long>(pinfo->arg1);
  1357.  
  1358. if (GOLD_MAX <= nTotalGold)
  1359. {
  1360. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("???? ???? 20? ?? ???? ??? ??? ????.."));
  1361.  
  1362. sys_err("[OVERFLOW_GOLD] ELK_ADD (%lld) id %u name %s ",
  1363. ch->GetExchange()->GetCompany()->GetOwner()->GetGold(),
  1364. ch->GetExchange()->GetCompany()->GetOwner()->GetPlayerID(),
  1365. ch->GetExchange()->GetCompany()->GetOwner()->GetName());
  1366.  
  1367. return;
  1368. }
  1369.  
  1370. if (ch->GetExchange()->GetCompany()->GetAcceptStatus() != true)
  1371. ch->GetExchange()->AddGold(pinfo->arg1);
  1372. }
  1373. break;
  1374.  
  1375. case EXCHANGE_SUBHEADER_CG_ACCEPT: // arg1 == not used
  1376. if (ch->GetExchange())
  1377. {
  1378. sys_log(0, "CInputMain()::Exchange() ==> ACCEPT ");
  1379. ch->GetExchange()->Accept(true);
  1380. }
  1381.  
  1382. break;
  1383.  
  1384. case EXCHANGE_SUBHEADER_CG_CANCEL: // arg1 == not used
  1385. if (ch->GetExchange())
  1386. ch->GetExchange()->Cancel();
  1387. break;
  1388. }
  1389. }
  1390.  
  1391. void CInputMain::Position(LPCHARACTER ch, const char * data)
  1392. {
  1393. struct command_position * pinfo = (struct command_position *) data;
  1394.  
  1395. switch (pinfo->position)
  1396. {
  1397. case POSITION_GENERAL:
  1398. ch->Standup();
  1399. break;
  1400.  
  1401. case POSITION_SITTING_CHAIR:
  1402. ch->Sitdown(0);
  1403. break;
  1404.  
  1405. case POSITION_SITTING_GROUND:
  1406. ch->Sitdown(1);
  1407. break;
  1408. }
  1409. }
  1410.  
  1411. static const int ComboSequenceBySkillLevel[3][8] =
  1412. {
  1413. // 0 1 2 3 4 5 6 7
  1414. { 14, 15, 16, 17, 0, 0, 0, 0 },
  1415. { 14, 15, 16, 18, 20, 0, 0, 0 },
  1416. { 14, 15, 16, 18, 19, 17, 0, 0 },
  1417. };
  1418.  
  1419. #define COMBO_HACK_ALLOWABLE_MS 100
  1420.  
  1421. bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack)
  1422. {
  1423. if(!gHackCheckEnable) return false;
  1424.  
  1425. // Áװųª ±âÀý »óÅ¿¡¼­´Â °ø°ÝÇÒ ¼ö ¾øÀ¸¹Ç·Î, skipÇÑ´Ù.
  1426. // ÀÌ·¸°Ô ÇÏÁö ¸»°í, CHRACTER::CanMove()¿¡
  1427. // if (IsStun() || IsDead()) return false;
  1428. // ¸¦ Ãß°¡ÇÏ´Â°Ô ¸Â´Ù°í »ý°¢Çϳª,
  1429. // ÀÌ¹Ì ´Ù¸¥ ºÎºÐ¿¡¼­ CanMove()´Â IsStun(), IsDead()°ú
  1430. // µ¶¸³ÀûÀ¸·Î üũÇÏ°í Àֱ⠶§¹®¿¡ ¼öÁ¤¿¡ ÀÇÇÑ ¿µÇâÀ»
  1431. // ÃÖ¼ÒÈ­Çϱâ À§ÇØ ÀÌ·¸°Ô ¶«»§ Äڵ带 ½á³õ´Â´Ù.
  1432. if (ch->IsStun() || ch->IsDead())
  1433. return false;
  1434. int ComboInterval = dwTime - ch->GetLastComboTime();
  1435. int HackScalar = 0; // ±âº» ½ºÄ®¶ó ´ÜÀ§ 1
  1436. #if 0
  1437. sys_log(0, "COMBO: %s arg:%u seq:%u delta:%d checkspeedhack:%d",
  1438. ch->GetName(), bArg, ch->GetComboSequence(), ComboInterval - ch->GetValidComboInterval(), CheckSpeedHack);
  1439. #endif
  1440. // bArg 14 ~ 21¹ø ±îÁö ÃÑ 8ÄÞº¸ °¡´É
  1441. // 1. ù ÄÞº¸(14)´Â ÀÏÁ¤ ½Ã°£ ÀÌÈÄ¿¡ ¹Ýº¹ °¡´É
  1442. // 2. 15 ~ 21¹øÀº ¹Ýº¹ ºÒ°¡´É
  1443. // 3. Â÷·Ê´ë·Î Áõ°¡ÇÑ´Ù.
  1444. if (bArg == 14)
  1445. {
  1446. if (CheckSpeedHack && ComboInterval > 0 && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS)
  1447. {
  1448. // FIXME ù¹ø° ÄÞº¸´Â ÀÌ»óÇÏ°Ô »¡¸® ¿Ã ¼ö°¡ À־ 300À¸·Î ³ª´® -_-;
  1449.  
  1450. // ´Ù¼öÀÇ ¸ó½ºÅÍ¿¡ ÀÇÇØ ´Ù¿îµÇ´Â »óȲ¿¡¼­ °ø°ÝÀ» Çϸé
  1451. // ù¹ø° ÄÞº¸°¡ ¸Å¿ì ÀûÀº ÀÎÅ͹ú·Î µé¾î¿À´Â »óȲ ¹ß»ý.
  1452. // ÀÌ·Î ÀÎÇØ ÄÞº¸ÇÙÀ¸·Î ƨ±â´Â °æ¿ì°¡ ÀÖ¾î ´ÙÀ½ ÄÚµå ºñ È°¼ºÈ­.
  1453. //HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 300;
  1454.  
  1455. //sys_log(0, "COMBO_HACK: 2 %s arg:%u interval:%d valid:%u atkspd:%u riding:%s",
  1456. // ch->GetName(),
  1457. // bArg,
  1458. // ComboInterval,
  1459. // ch->GetValidComboInterval(),
  1460. // ch->GetPoint(POINT_ATT_SPEED),
  1461. // ch->IsRiding() ? "yes" : "no");
  1462. }
  1463.  
  1464. ch->SetComboSequence(1);
  1465. ch->SetValidComboInterval((int) (ani_combo_speed(ch, 1) / (ch->GetPoint(POINT_ATT_SPEED) / 100.f)));
  1466. ch->SetLastComboTime(dwTime);
  1467. }
  1468. else if (bArg > 14 && bArg < 22)
  1469. {
  1470. int idx = MIN(2, ch->GetComboIndex());
  1471.  
  1472. if (ch->GetComboSequence() > 5) // ÇöÀç 6ÄÞº¸ ÀÌ»óÀº ¾ø´Ù.
  1473. {
  1474. HackScalar = 1;
  1475. ch->SetValidComboInterval(300);
  1476. sys_log(0, "COMBO_HACK: 5 %s combo_seq:%d", ch->GetName(), ch->GetComboSequence());
  1477. }
  1478. // ÀÚ°´ ½Ö¼ö ÄÞº¸ ¿¹¿Üó¸®
  1479. else if (bArg == 21 &&
  1480. idx == 2 &&
  1481. ch->GetComboSequence() == 5 &&
  1482. ch->GetJob() == JOB_ASSASSIN &&
  1483. ch->GetWear(WEAR_WEAPON) &&
  1484. ch->GetWear(WEAR_WEAPON)->GetSubType() == WEAPON_DAGGER)
  1485. ch->SetValidComboInterval(300);
  1486. #ifdef ENABLE_WOLFMAN_CHARACTER
  1487. else if (bArg == 21 && idx == 2 && ch->GetComboSequence() == 5 && ch->GetJob() == JOB_WOLFMAN && ch->GetWear(WEAR_WEAPON) && ch->GetWear(WEAR_WEAPON)->GetSubType() == WEAPON_CLAW)
  1488. ch->SetValidComboInterval(300);
  1489. #endif
  1490. else if (ComboSequenceBySkillLevel[idx][ch->GetComboSequence()] != bArg)
  1491. {
  1492. HackScalar = 1;
  1493. ch->SetValidComboInterval(300);
  1494.  
  1495. sys_log(0, "COMBO_HACK: 3 %s arg:%u valid:%u combo_idx:%d combo_seq:%d",
  1496. ch->GetName(),
  1497. bArg,
  1498. ComboSequenceBySkillLevel[idx][ch->GetComboSequence()],
  1499. idx,
  1500. ch->GetComboSequence());
  1501. }
  1502. else
  1503. {
  1504. if (CheckSpeedHack && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS)
  1505. {
  1506. HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 100;
  1507.  
  1508. sys_log(0, "COMBO_HACK: 2 %s arg:%u interval:%d valid:%u atkspd:%u riding:%s",
  1509. ch->GetName(),
  1510. bArg,
  1511. ComboInterval,
  1512. ch->GetValidComboInterval(),
  1513. ch->GetPoint(POINT_ATT_SPEED),
  1514. ch->IsRiding() ? "yes" : "no");
  1515. }
  1516.  
  1517. // ¸»À» ÅÀÀ» ¶§´Â 15¹ø ~ 16¹øÀ» ¹Ýº¹ÇÑ´Ù
  1518. //if (ch->IsHorseRiding())
  1519. if (ch->IsRiding())
  1520. ch->SetComboSequence(ch->GetComboSequence() == 1 ? 2 : 1);
  1521. else
  1522. ch->SetComboSequence(ch->GetComboSequence() + 1);
  1523.  
  1524. ch->SetValidComboInterval((int) (ani_combo_speed(ch, bArg - 13) / (ch->GetPoint(POINT_ATT_SPEED) / 100.f)));
  1525. ch->SetLastComboTime(dwTime);
  1526. }
  1527. }
  1528. else if (bArg == 13) // ±âº» °ø°Ý (µÐ°©(Polymorph)ÇßÀ» ¶§ ¿Â´Ù)
  1529. {
  1530. if (CheckSpeedHack && ComboInterval > 0 && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS)
  1531. {
  1532. // ´Ù¼öÀÇ ¸ó½ºÅÍ¿¡ ÀÇÇØ ´Ù¿îµÇ´Â »óȲ¿¡¼­ °ø°ÝÀ» Çϸé
  1533. // ù¹ø° ÄÞº¸°¡ ¸Å¿ì ÀûÀº ÀÎÅ͹ú·Î µé¾î¿À´Â »óȲ ¹ß»ý.
  1534. // ÀÌ·Î ÀÎÇØ ÄÞº¸ÇÙÀ¸·Î ƨ±â´Â °æ¿ì°¡ ÀÖ¾î ´ÙÀ½ ÄÚµå ºñ È°¼ºÈ­.
  1535. //HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 100;
  1536.  
  1537. //sys_log(0, "COMBO_HACK: 6 %s arg:%u interval:%d valid:%u atkspd:%u",
  1538. // ch->GetName(),
  1539. // bArg,
  1540. // ComboInterval,
  1541. // ch->GetValidComboInterval(),
  1542. // ch->GetPoint(POINT_ATT_SPEED));
  1543. }
  1544.  
  1545. if (ch->GetRaceNum() >= MAIN_RACE_MAX_NUM)
  1546. {
  1547. // POLYMORPH_BUG_FIX
  1548.  
  1549. // DELETEME
  1550. /*
  1551. const CMotion * pkMotion = CMotionManager::instance().GetMotion(ch->GetRaceNum(), MAKE_MOTION_KEY(MOTION_MODE_GENERAL, MOTION_NORMAL_ATTACK));
  1552.  
  1553. if (!pkMotion)
  1554. sys_err("cannot find motion by race %u", ch->GetRaceNum());
  1555. else
  1556. {
  1557. // Á¤»óÀû °è»êÀ̶ó¸é 1000.f¸¦ °öÇØ¾ß ÇÏÁö¸¸ Ŭ¶óÀ̾ðÆ®°¡ ¾Ö´Ï¸ÞÀÌ¼Ç ¼ÓµµÀÇ 90%¿¡¼­
  1558. // ´ÙÀ½ ¾Ö´Ï¸ÞÀÌ¼Ç ºí·»µùÀ» Çã¿ëÇϹǷΠ900.f¸¦ °öÇÑ´Ù.
  1559. int k = (int) (pkMotion->GetDuration() / ((float) ch->GetPoint(POINT_ATT_SPEED) / 100.f) * 900.f);
  1560. ch->SetValidComboInterval(k);
  1561. ch->SetLastComboTime(dwTime);
  1562. }
  1563. */
  1564. float normalAttackDuration = CMotionManager::instance().GetNormalAttackDuration(ch->GetRaceNum());
  1565. int k = (int) (normalAttackDuration / ((float) ch->GetPoint(POINT_ATT_SPEED) / 100.f) * 900.f);
  1566. ch->SetValidComboInterval(k);
  1567. ch->SetLastComboTime(dwTime);
  1568. // END_OF_POLYMORPH_BUG_FIX
  1569. }
  1570. else
  1571. {
  1572. // ¸»ÀÌ ¾ÈµÇ´Â ÄÞº¸°¡ ¿Ô´Ù ÇØÄ¿ÀÏ °¡´É¼º?
  1573. //if (ch->GetDesc()->DelayedDisconnect(number(2, 9)))
  1574. //{
  1575. // LogManager::instance().HackLog("Hacker", ch);
  1576. // sys_log(0, "HACKER: %s arg %u", ch->GetName(), bArg);
  1577. //}
  1578.  
  1579. // À§ ÄÚµå·Î ÀÎÇØ, Æú¸®¸ðÇÁ¸¦ Ǫ´Â Áß¿¡ °ø°Ý Çϸé,
  1580. // °¡²û ÇÙÀ¸·Î ÀνÄÇÏ´Â °æ¿ì°¡ ÀÖ´Ù.
  1581.  
  1582. // ÀÚ¼¼È÷ ¸»Çô¸é,
  1583. // ¼­¹ö¿¡¼­ poly 0¸¦ ó¸®ÇßÁö¸¸,
  1584. // Ŭ¶ó¿¡¼­ ±× ÆÐŶÀ» ¹Þ±â Àü¿¡, ¸÷À» °ø°Ý. <- Áï, ¸÷ÀÎ »óÅ¿¡¼­ °ø°Ý.
  1585. //
  1586. // ±×·¯¸é Ŭ¶ó¿¡¼­´Â ¼­¹ö¿¡ ¸÷ »óÅ·Π°ø°ÝÇß´Ù´Â Ä¿¸Çµå¸¦ º¸³»°í (arg == 13)
  1587. //
  1588. // ¼­¹ö¿¡¼­´Â race´Â Àΰ£Àε¥ °ø°ÝÇüÅ´ ¸÷ÀÎ ³ðÀÌ´Ù! ¶ó°í ÇÏ¿© ÇÙüũ¸¦ Çß´Ù.
  1589.  
  1590. // »ç½Ç °ø°Ý ÆÐÅÏ¿¡ ´ëÇÑ °ÍÀº Ŭ¶óÀ̾ðÆ®¿¡¼­ ÆÇ´ÜÇؼ­ º¸³¾ °ÍÀÌ ¾Æ´Ï¶ó,
  1591. // ¼­¹ö¿¡¼­ ÆÇ´ÜÇØ¾ß ÇÒ °ÍÀε¥... ¿Ö ÀÌ·¸°Ô ÇسùÀ»±î...
  1592. // by rtsummit
  1593. }
  1594. }
  1595. else
  1596. {
  1597. // ¸»ÀÌ ¾ÈµÇ´Â ÄÞº¸°¡ ¿Ô´Ù ÇØÄ¿ÀÏ °¡´É¼º?
  1598. if (ch->GetDesc()->DelayedDisconnect(number(2, 9)))
  1599. {
  1600. LogManager::instance().HackLog("Hacker", ch);
  1601. sys_log(0, "HACKER: %s arg %u", ch->GetName(), bArg);
  1602. }
  1603.  
  1604. HackScalar = 10;
  1605. ch->SetValidComboInterval(300);
  1606. }
  1607.  
  1608. if (HackScalar)
  1609. {
  1610. // ¸»¿¡ Ÿ°Å³ª ³»·ÈÀ» ¶§ 1.5ÃÊ°£ °ø°ÝÀº ÇÙÀ¸·Î °£ÁÖÇÏÁö ¾ÊµÇ °ø°Ý·ÂÀº ¾ø°Ô Çϴ ó¸®
  1611. if (get_dword_time() - ch->GetLastMountTime() > 1500)
  1612. ch->IncreaseComboHackCount(1 + HackScalar);
  1613.  
  1614. ch->SkipComboAttackByTime(ch->GetValidComboInterval());
  1615. }
  1616.  
  1617. return HackScalar;
  1618.  
  1619.  
  1620. }
  1621.  
  1622. void CInputMain::Move(LPCHARACTER ch, const char * data)
  1623. {
  1624. if (!ch->CanMove())
  1625. return;
  1626.  
  1627. struct command_move * pinfo = (struct command_move *) data;
  1628.  
  1629. if (pinfo->bFunc >= FUNC_MAX_NUM && !(pinfo->bFunc & 0x80))
  1630. {
  1631. sys_err("invalid move type: %s", ch->GetName());
  1632. return;
  1633. }
  1634.  
  1635. //enum EMoveFuncType
  1636. //{
  1637. // FUNC_WAIT,
  1638. // FUNC_MOVE,
  1639. // FUNC_ATTACK,
  1640. // FUNC_COMBO,
  1641. // FUNC_MOB_SKILL,
  1642. // _FUNC_SKILL,
  1643. // FUNC_MAX_NUM,
  1644. // FUNC_SKILL = 0x80,
  1645. //};
  1646.  
  1647. // ÅÚ·¹Æ÷Æ® Ç٠üũ
  1648.  
  1649. // if (!test_server)
  1650. {
  1651. const float fDist = DISTANCE_SQRT((ch->GetX() - pinfo->lX) / 100, (ch->GetY() - pinfo->lY) / 100);
  1652. // @fixme106 (changed 40 to 60)
  1653. if (((false == ch->IsRiding() && fDist > 25) || fDist > 60) && OXEVENT_MAP_INDEX != ch->GetMapIndex())
  1654. {
  1655. #ifdef ENABLE_HACK_TELEPORT_LOG // @warme006
  1656. {
  1657. const PIXEL_POSITION & warpPos = ch->GetWarpPosition();
  1658.  
  1659. if (warpPos.x == 0 && warpPos.y == 0)
  1660. LogManager::instance().HackLog("Teleport", ch); // ºÎÁ¤È®ÇÒ ¼ö ÀÖÀ½
  1661. }
  1662. #endif
  1663. sys_log(0, "MOVE: %s trying to move too far (dist: %.1fm) Riding(%d)", ch->GetName(), fDist, ch->IsRiding());
  1664.  
  1665. ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ());
  1666. ch->Stop();
  1667. return;
  1668. }
  1669. #ifdef ENABLE_CHECK_GHOSTMODE
  1670. if (ch->IsPC() && ch->IsDead())
  1671. {
  1672. sys_log(0, "MOVE: %s trying to move as dead", ch->GetName());
  1673.  
  1674. ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ());
  1675. ch->Stop();
  1676. return;
  1677. }
  1678. #endif
  1679. //
  1680. // ½ºÇǵåÇÙ(SPEEDHACK) Check
  1681. //
  1682. DWORD dwCurTime = get_dword_time();
  1683. // ½Ã°£À» SyncÇÏ°í 7ÃÊ ÈÄ ºÎÅÍ °Ë»çÇÑ´Ù. (20090702 ÀÌÀü¿£ 5ÃÊ¿´À½)
  1684. bool CheckSpeedHack = (false == ch->GetDesc()->IsHandshaking() && dwCurTime - ch->GetDesc()->GetClientTime() > 7000);
  1685.  
  1686. if (CheckSpeedHack)
  1687. {
  1688. int iDelta = (int) (pinfo->dwTime - ch->GetDesc()->GetClientTime());
  1689. int iServerDelta = (int) (dwCurTime - ch->GetDesc()->GetClientTime());
  1690.  
  1691. iDelta = (int) (dwCurTime - pinfo->dwTime);
  1692.  
  1693. // ½Ã°£ÀÌ ´Ê°Ô°£´Ù. ÀÏ´Ü ·Î±×¸¸ ÇصдÙ. ÁøÂ¥ ÀÌ·± »ç¶÷µéÀÌ ¸¹ÀºÁö üũÇؾßÇÔ. TODO
  1694. if (iDelta >= 30000)
  1695. {
  1696. sys_log(0, "SPEEDHACK: slow timer name %s delta %d", ch->GetName(), iDelta);
  1697. ch->GetDesc()->DelayedDisconnect(3);
  1698. }
  1699. // 1ÃÊ¿¡ 20msec »¡¸® °¡´Â°Å ±îÁö´Â ÀÌÇØÇÑ´Ù.
  1700. else if (iDelta < -(iServerDelta / 50))
  1701. {
  1702. sys_log(0, "SPEEDHACK: DETECTED! %s (delta %d %d)", ch->GetName(), iDelta, iServerDelta);
  1703. ch->GetDesc()->DelayedDisconnect(3);
  1704. }
  1705. }
  1706.  
  1707. //
  1708. // ÄÞº¸ÇÙ ¹× ½ºÇǵåÇ٠üũ
  1709. //
  1710. if (pinfo->bFunc == FUNC_COMBO && g_bCheckMultiHack)
  1711. {
  1712. CheckComboHack(ch, pinfo->bArg, pinfo->dwTime, CheckSpeedHack); // ÄÞº¸ üũ
  1713. }
  1714. }
  1715.  
  1716. if (pinfo->bFunc == FUNC_MOVE)
  1717. {
  1718. if (ch->GetLimitPoint(POINT_MOV_SPEED) == 0)
  1719. return;
  1720.  
  1721. ch->SetRotation(pinfo->bRot * 5); // Áߺ¹ ÄÚµå
  1722. ch->ResetStopTime(); // ""
  1723.  
  1724. ch->Goto(pinfo->lX, pinfo->lY);
  1725. }
  1726. else
  1727. {
  1728. if (pinfo->bFunc == FUNC_ATTACK || pinfo->bFunc == FUNC_COMBO)
  1729. ch->OnMove(true);
  1730. else if (pinfo->bFunc & FUNC_SKILL)
  1731. {
  1732. const int MASK_SKILL_MOTION = 0x7F;
  1733. unsigned int motion = pinfo->bFunc & MASK_SKILL_MOTION;
  1734.  
  1735. if (!ch->IsUsableSkillMotion(motion))
  1736. {
  1737. const char* name = ch->GetName();
  1738. unsigned int job = ch->GetJob();
  1739. unsigned int group = ch->GetSkillGroup();
  1740.  
  1741. char szBuf[256];
  1742. snprintf(szBuf, sizeof(szBuf), "SKILL_HACK: name=%s, job=%d, group=%d, motion=%d", name, job, group, motion);
  1743. LogManager::instance().HackLog(szBuf, ch->GetDesc()->GetAccountTable().login, ch->GetName(), ch->GetDesc()->GetHostName());
  1744. sys_log(0, "%s", szBuf);
  1745.  
  1746. if (test_server)
  1747. {
  1748. ch->GetDesc()->DelayedDisconnect(number(2, 8));
  1749. ch->ChatPacket(CHAT_TYPE_INFO, szBuf);
  1750. }
  1751. else
  1752. {
  1753. ch->GetDesc()->DelayedDisconnect(number(150, 500));
  1754. }
  1755. }
  1756.  
  1757. ch->OnMove();
  1758. }
  1759.  
  1760. ch->SetRotation(pinfo->bRot * 5); // Áߺ¹ ÄÚµå
  1761. ch->ResetStopTime(); // ""
  1762.  
  1763. ch->Move(pinfo->lX, pinfo->lY);
  1764. ch->Stop();
  1765. ch->StopStaminaConsume();
  1766. }
  1767.  
  1768. TPacketGCMove pack;
  1769.  
  1770. pack.bHeader = HEADER_GC_MOVE;
  1771. pack.bFunc = pinfo->bFunc;
  1772. pack.bArg = pinfo->bArg;
  1773. pack.bRot = pinfo->bRot;
  1774. pack.dwVID = ch->GetVID();
  1775. pack.lX = pinfo->lX;
  1776. pack.lY = pinfo->lY;
  1777. pack.dwTime = pinfo->dwTime;
  1778. pack.dwDuration = (pinfo->bFunc == FUNC_MOVE) ? ch->GetCurrentMoveDuration() : 0;
  1779.  
  1780. ch->PacketAround(&pack, sizeof(TPacketGCMove), ch);
  1781. /*
  1782. if (pinfo->dwTime == 10653691) // µð¹ö°Å ¹ß°ß
  1783. {
  1784. if (ch->GetDesc()->DelayedDisconnect(number(15, 30)))
  1785. LogManager::instance().HackLog("Debugger", ch);
  1786.  
  1787. }
  1788. else if (pinfo->dwTime == 10653971) // Softice ¹ß°ß
  1789. {
  1790. if (ch->GetDesc()->DelayedDisconnect(number(15, 30)))
  1791. LogManager::instance().HackLog("Softice", ch);
  1792. }
  1793. */
  1794. /*
  1795. sys_log(0,
  1796. "MOVE: %s Func:%u Arg:%u Pos:%dx%d Time:%u Dist:%.1f",
  1797. ch->GetName(),
  1798. pinfo->bFunc,
  1799. pinfo->bArg,
  1800. pinfo->lX / 100,
  1801. pinfo->lY / 100,
  1802. pinfo->dwTime,
  1803. fDist);
  1804. */
  1805. }
  1806.  
  1807. void CInputMain::Attack(LPCHARACTER ch, const BYTE header, const char* data)
  1808. {
  1809. if (NULL == ch)
  1810. return;
  1811.  
  1812. struct type_identifier
  1813. {
  1814. BYTE header;
  1815. BYTE type;
  1816. };
  1817.  
  1818. const struct type_identifier* const type = reinterpret_cast<const struct type_identifier*>(data);
  1819.  
  1820. if (type->type > 0)
  1821. {
  1822. if (false == ch->CanUseSkill(type->type))
  1823. {
  1824. return;
  1825. }
  1826.  
  1827. switch (type->type)
  1828. {
  1829. case SKILL_GEOMPUNG:
  1830. case SKILL_SANGONG:
  1831. case SKILL_YEONSA:
  1832. case SKILL_KWANKYEOK:
  1833. case SKILL_HWAJO:
  1834. case SKILL_GIGUNG:
  1835. case SKILL_PABEOB:
  1836. case SKILL_MARYUNG:
  1837. case SKILL_TUSOK:
  1838. case SKILL_MAHWAN:
  1839. case SKILL_BIPABU:
  1840. case SKILL_NOEJEON:
  1841. case SKILL_CHAIN:
  1842. case SKILL_HORSE_WILDATTACK_RANGE:
  1843. if (HEADER_CG_SHOOT != type->header)
  1844. {
  1845. if (test_server)
  1846. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Attack :name[%s] Vnum[%d] can't use skill by attack(warning)"), type->type);
  1847. return;
  1848. }
  1849. break;
  1850. }
  1851. }
  1852.  
  1853. switch (header)
  1854. {
  1855. case HEADER_CG_ATTACK:
  1856. {
  1857. if (NULL == ch->GetDesc())
  1858. return;
  1859.  
  1860. const TPacketCGAttack* const packMelee = reinterpret_cast<const TPacketCGAttack*>(data);
  1861.  
  1862. ch->GetDesc()->AssembleCRCMagicCube(packMelee->bCRCMagicCubeProcPiece, packMelee->bCRCMagicCubeFilePiece);
  1863.  
  1864. LPCHARACTER victim = CHARACTER_MANAGER::instance().Find(packMelee->dwVID);
  1865.  
  1866. if (NULL == victim || ch == victim)
  1867. return;
  1868.  
  1869. switch (victim->GetCharType())
  1870. {
  1871. case CHAR_TYPE_NPC:
  1872. case CHAR_TYPE_WARP:
  1873. case CHAR_TYPE_GOTO:
  1874. return;
  1875. }
  1876.  
  1877. if (packMelee->bType > 0)
  1878. {
  1879. if (false == ch->CheckSkillHitCount(packMelee->bType, victim->GetVID()))
  1880. {
  1881. return;
  1882. }
  1883. }
  1884.  
  1885. ch->Attack(victim, packMelee->bType);
  1886. }
  1887. break;
  1888.  
  1889. case HEADER_CG_SHOOT:
  1890. {
  1891. const TPacketCGShoot* const packShoot = reinterpret_cast<const TPacketCGShoot*>(data);
  1892.  
  1893. ch->Shoot(packShoot->bType);
  1894. }
  1895. break;
  1896. }
  1897. }
  1898.  
  1899. int CInputMain::SyncPosition(LPCHARACTER ch, const char * c_pcData, size_t uiBytes)
  1900. {
  1901. const TPacketCGSyncPosition* pinfo = reinterpret_cast<const TPacketCGSyncPosition*>( c_pcData );
  1902.  
  1903. if (uiBytes < pinfo->wSize)
  1904. return -1;
  1905.  
  1906. int iExtraLen = pinfo->wSize - sizeof(TPacketCGSyncPosition);
  1907.  
  1908. if (iExtraLen < 0)
  1909. {
  1910. sys_err("invalid packet length (len %d size %u buffer %u)", iExtraLen, pinfo->wSize, uiBytes);
  1911. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  1912. return -1;
  1913. }
  1914.  
  1915. if (0 != (iExtraLen % sizeof(TPacketCGSyncPositionElement)))
  1916. {
  1917. sys_err("invalid packet length %d (name: %s)", pinfo->wSize, ch->GetName());
  1918. return iExtraLen;
  1919. }
  1920.  
  1921. int iCount = iExtraLen / sizeof(TPacketCGSyncPositionElement);
  1922.  
  1923. if (iCount <= 0)
  1924. return iExtraLen;
  1925.  
  1926. static const int nCountLimit = 16;
  1927.  
  1928. if( iCount > nCountLimit )
  1929. {
  1930. //LogManager::instance().HackLog( "SYNC_POSITION_HACK", ch );
  1931. sys_err( "Too many SyncPosition Count(%d) from Name(%s)", iCount, ch->GetName() );
  1932. //ch->GetDesc()->SetPhase(PHASE_CLOSE);
  1933. //return -1;
  1934. iCount = nCountLimit;
  1935. }
  1936.  
  1937. TEMP_BUFFER tbuf;
  1938. LPBUFFER lpBuf = tbuf.getptr();
  1939.  
  1940. TPacketGCSyncPosition * pHeader = (TPacketGCSyncPosition *) buffer_write_peek(lpBuf);
  1941. buffer_write_proceed(lpBuf, sizeof(TPacketGCSyncPosition));
  1942.  
  1943. const TPacketCGSyncPositionElement* e =
  1944. reinterpret_cast<const TPacketCGSyncPositionElement*>(c_pcData + sizeof(TPacketCGSyncPosition));
  1945.  
  1946. timeval tvCurTime;
  1947. gettimeofday(&tvCurTime, NULL);
  1948.  
  1949. for (int i = 0; i < iCount; ++i, ++e)
  1950. {
  1951. LPCHARACTER victim = CHARACTER_MANAGER::instance().Find(e->dwVID);
  1952.  
  1953. if (!victim)
  1954. continue;
  1955.  
  1956. switch (victim->GetCharType())
  1957. {
  1958. case CHAR_TYPE_NPC:
  1959. case CHAR_TYPE_WARP:
  1960. case CHAR_TYPE_GOTO:
  1961. continue;
  1962. }
  1963.  
  1964. // ¼ÒÀ¯±Ç °Ë»ç
  1965. if (!victim->SetSyncOwner(ch))
  1966. continue;
  1967.  
  1968. const float fDistWithSyncOwner = DISTANCE_SQRT( (victim->GetX() - ch->GetX()) / 100, (victim->GetY() - ch->GetY()) / 100 );
  1969. static const float fLimitDistWithSyncOwner = 2500.f + 1000.f;
  1970. // victim°úÀÇ °Å¸®°¡ 2500 + a ÀÌ»óÀ̸é ÇÙÀ¸·Î °£ÁÖ.
  1971. // °Å¸® ÂüÁ¶ : Ŭ¶óÀ̾ðÆ®ÀÇ __GetSkillTargetRange, __GetBowRange ÇÔ¼ö
  1972. // 2500 : ½ºÅ³ proto¿¡¼­ °¡Àå »ç°Å¸®°¡ ±ä ½ºÅ³ÀÇ »ç°Å¸®, ¶Ç´Â È°ÀÇ »ç°Å¸®
  1973. // a = POINT_BOW_DISTANCE °ª... Àε¥ ½ÇÁ¦·Î »ç¿ëÇÏ´Â °ªÀÎÁö´Â Àß ¸ð¸£°ÚÀ½. ¾ÆÀÌÅÛÀ̳ª Æ÷¼Ç, ½ºÅ³, Äù½ºÆ®¿¡´Â ¾ø´Âµ¥...
  1974. // ±×·¡µµ Ȥ½Ã³ª ÇÏ´Â ¸¶À½¿¡ ¹öÆÛ·Î »ç¿ëÇÒ °âÇؼ­ 1000.f ·Î µÒ...
  1975. if (fDistWithSyncOwner > fLimitDistWithSyncOwner)
  1976. {
  1977. // g_iSyncHackLimitCount¹ø ±îÁö´Â ºÁÁÜ.
  1978. if (ch->GetSyncHackCount() < g_iSyncHackLimitCount)
  1979. {
  1980. ch->SetSyncHackCount(ch->GetSyncHackCount() + 1);
  1981. continue;
  1982. }
  1983. else
  1984. {
  1985. LogManager::instance().HackLog( "SYNC_POSITION_HACK", ch );
  1986.  
  1987. sys_err( "Too far SyncPosition DistanceWithSyncOwner(%f)(%s) from Name(%s) CH(%d,%d) VICTIM(%d,%d) SYNC(%d,%d)",
  1988. fDistWithSyncOwner, victim->GetName(), ch->GetName(), ch->GetX(), ch->GetY(), victim->GetX(), victim->GetY(),
  1989. e->lX, e->lY );
  1990.  
  1991. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  1992.  
  1993. return -1;
  1994. }
  1995. }
  1996.  
  1997. const float fDist = DISTANCE_SQRT( (victim->GetX() - e->lX) / 100, (victim->GetY() - e->lY) / 100 );
  1998. static const long g_lValidSyncInterval = 100 * 1000; // 100ms
  1999. const timeval &tvLastSyncTime = victim->GetLastSyncTime();
  2000. timeval *tvDiff = timediff(&tvCurTime, &tvLastSyncTime);
  2001.  
  2002. // SyncPositionÀ» ¾Ç¿ëÇÏ¿© ŸÀ¯Àú¸¦ ÀÌ»óÇÑ °÷À¸·Î º¸³»´Â ÇÙ ¹æ¾îÇϱâ À§ÇÏ¿©,
  2003. // °°Àº À¯Àú¸¦ g_lValidSyncInterval ms À̳»¿¡ ´Ù½Ã SyncPositionÇÏ·Á°í Çϸé ÇÙÀ¸·Î °£ÁÖ.
  2004. if (tvDiff->tv_sec == 0 && tvDiff->tv_usec < g_lValidSyncInterval)
  2005. {
  2006. // g_iSyncHackLimitCount¹ø ±îÁö´Â ºÁÁÜ.
  2007. if (ch->GetSyncHackCount() < g_iSyncHackLimitCount)
  2008. {
  2009. ch->SetSyncHackCount(ch->GetSyncHackCount() + 1);
  2010. continue;
  2011. }
  2012. else
  2013. {
  2014. LogManager::instance().HackLog( "SYNC_POSITION_HACK", ch );
  2015.  
  2016. sys_err( "Too often SyncPosition Interval(%ldms)(%s) from Name(%s) VICTIM(%d,%d) SYNC(%d,%d)",
  2017. tvDiff->tv_sec * 1000 + tvDiff->tv_usec / 1000, victim->GetName(), ch->GetName(), victim->GetX(), victim->GetY(),
  2018. e->lX, e->lY );
  2019.  
  2020. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  2021.  
  2022. return -1;
  2023. }
  2024. }
  2025. else if( fDist > 25.0f )
  2026. {
  2027. LogManager::instance().HackLog( "SYNC_POSITION_HACK", ch );
  2028.  
  2029. sys_err( "Too far SyncPosition Distance(%f)(%s) from Name(%s) CH(%d,%d) VICTIM(%d,%d) SYNC(%d,%d)",
  2030. fDist, victim->GetName(), ch->GetName(), ch->GetX(), ch->GetY(), victim->GetX(), victim->GetY(),
  2031. e->lX, e->lY );
  2032.  
  2033. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  2034.  
  2035. return -1;
  2036. }
  2037. else
  2038. {
  2039. victim->SetLastSyncTime(tvCurTime);
  2040. victim->Sync(e->lX, e->lY);
  2041. buffer_write(lpBuf, e, sizeof(TPacketCGSyncPositionElement));
  2042. }
  2043. }
  2044.  
  2045. if (buffer_size(lpBuf) != sizeof(TPacketGCSyncPosition))
  2046. {
  2047. pHeader->bHeader = HEADER_GC_SYNC_POSITION;
  2048. pHeader->wSize = buffer_size(lpBuf);
  2049.  
  2050. ch->PacketAround(buffer_read_peek(lpBuf), buffer_size(lpBuf), ch);
  2051. }
  2052.  
  2053. return iExtraLen;
  2054. }
  2055.  
  2056. void CInputMain::FlyTarget(LPCHARACTER ch, const char * pcData, BYTE bHeader)
  2057. {
  2058. TPacketCGFlyTargeting * p = (TPacketCGFlyTargeting *) pcData;
  2059. ch->FlyTarget(p->dwTargetVID, p->x, p->y, bHeader);
  2060. }
  2061.  
  2062. void CInputMain::UseSkill(LPCHARACTER ch, const char * pcData)
  2063. {
  2064. TPacketCGUseSkill * p = (TPacketCGUseSkill *) pcData;
  2065. ch->UseSkill(p->dwVnum, CHARACTER_MANAGER::instance().Find(p->dwVID));
  2066. }
  2067.  
  2068. void CInputMain::ScriptButton(LPCHARACTER ch, const void* c_pData)
  2069. {
  2070. TPacketCGScriptButton * p = (TPacketCGScriptButton *) c_pData;
  2071. sys_log(0, "QUEST ScriptButton pid %d idx %u", ch->GetPlayerID(), p->idx);
  2072.  
  2073. quest::PC* pc = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());
  2074. if (pc && pc->IsConfirmWait())
  2075. {
  2076. quest::CQuestManager::instance().Confirm(ch->GetPlayerID(), quest::CONFIRM_TIMEOUT);
  2077. }
  2078. else if (p->idx & 0x80000000)
  2079. {
  2080. //Äù½ºÆ® â¿¡¼­ Ŭ¸¯½Ã(__SelectQuest) ¿©±â·Î
  2081. quest::CQuestManager::Instance().QuestInfo(ch->GetPlayerID(), p->idx & 0x7fffffff);
  2082. }
  2083. else
  2084. {
  2085. quest::CQuestManager::Instance().QuestButton(ch->GetPlayerID(), p->idx);
  2086. }
  2087. }
  2088.  
  2089. void CInputMain::ScriptAnswer(LPCHARACTER ch, const void* c_pData)
  2090. {
  2091. TPacketCGScriptAnswer * p = (TPacketCGScriptAnswer *) c_pData;
  2092. sys_log(0, "QUEST ScriptAnswer pid %d answer %d", ch->GetPlayerID(), p->answer);
  2093.  
  2094. if (p->answer > 250) // ´ÙÀ½ ¹öÆ°¿¡ ´ëÇÑ ÀÀ´äÀ¸·Î ¿Â ÆÐŶÀÎ °æ¿ì
  2095. {
  2096. quest::CQuestManager::Instance().Resume(ch->GetPlayerID());
  2097. }
  2098. else // ¼±Åà ¹öÆ°À» °ñ¶ó¼­ ¿Â ÆÐŶÀÎ °æ¿ì
  2099. {
  2100. quest::CQuestManager::Instance().Select(ch->GetPlayerID(), p->answer);
  2101. }
  2102. }
  2103.  
  2104.  
  2105. // SCRIPT_SELECT_ITEM
  2106. void CInputMain::ScriptSelectItem(LPCHARACTER ch, const void* c_pData)
  2107. {
  2108. TPacketCGScriptSelectItem* p = (TPacketCGScriptSelectItem*) c_pData;
  2109. sys_log(0, "QUEST ScriptSelectItem pid %d answer %d", ch->GetPlayerID(), p->selection);
  2110. quest::CQuestManager::Instance().SelectItem(ch->GetPlayerID(), p->selection);
  2111. }
  2112. // END_OF_SCRIPT_SELECT_ITEM
  2113.  
  2114. void CInputMain::QuestInputString(LPCHARACTER ch, const void* c_pData)
  2115. {
  2116. TPacketCGQuestInputString * p = (TPacketCGQuestInputString*) c_pData;
  2117.  
  2118. char msg[65];
  2119. strlcpy(msg, p->msg, sizeof(msg));
  2120. sys_log(0, "QUEST InputString pid %u msg %s", ch->GetPlayerID(), msg);
  2121.  
  2122. quest::CQuestManager::Instance().Input(ch->GetPlayerID(), msg);
  2123. }
  2124.  
  2125. void CInputMain::QuestConfirm(LPCHARACTER ch, const void* c_pData)
  2126. {
  2127. TPacketCGQuestConfirm* p = (TPacketCGQuestConfirm*) c_pData;
  2128. LPCHARACTER ch_wait = CHARACTER_MANAGER::instance().FindByPID(p->requestPID);
  2129. if (p->answer)
  2130. p->answer = quest::CONFIRM_YES;
  2131. sys_log(0, "QuestConfirm from %s pid %u name %s answer %d", ch->GetName(), p->requestPID, (ch_wait)?ch_wait->GetName():"", p->answer);
  2132. if (ch_wait)
  2133. {
  2134. quest::CQuestManager::Instance().Confirm(ch_wait->GetPlayerID(), (quest::EQuestConfirmType) p->answer, ch->GetPlayerID());
  2135. }
  2136. }
  2137.  
  2138. void CInputMain::Target(LPCHARACTER ch, const char * pcData)
  2139. {
  2140. TPacketCGTarget * p = (TPacketCGTarget *) pcData;
  2141.  
  2142. building::LPOBJECT pkObj = building::CManager::instance().FindObjectByVID(p->dwVID);
  2143.  
  2144. if (pkObj)
  2145. {
  2146. TPacketGCTarget pckTarget;
  2147. pckTarget.header = HEADER_GC_TARGET;
  2148. pckTarget.dwVID = p->dwVID;
  2149. ch->GetDesc()->Packet(&pckTarget, sizeof(TPacketGCTarget));
  2150. }
  2151. else
  2152. ch->SetTarget(CHARACTER_MANAGER::instance().Find(p->dwVID));
  2153. }
  2154.  
  2155. void CInputMain::Warp(LPCHARACTER ch, const char * pcData)
  2156. {
  2157. ch->WarpEnd();
  2158. }
  2159.  
  2160. void CInputMain::SafeboxCheckin(LPCHARACTER ch, const char * c_pData)
  2161. {
  2162. if (quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID())->IsRunning() == true)
  2163. return;
  2164.  
  2165. TPacketCGSafeboxCheckin * p = (TPacketCGSafeboxCheckin *) c_pData;
  2166.  
  2167. if (!ch->CanHandleItem())
  2168. return;
  2169.  
  2170. CSafebox * pkSafebox = ch->GetSafebox();
  2171. LPITEM pkItem = ch->GetItem(p->ItemPos);
  2172.  
  2173. if (!pkSafebox || !pkItem)
  2174. return;
  2175.  
  2176. if (pkItem->GetCell() >= INVENTORY_MAX_NUM && IS_SET(pkItem->GetFlag(), ITEM_FLAG_IRREMOVABLE))
  2177. {
  2178. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> â°í·Î ¿Å±æ ¼ö ¾ø´Â ¾ÆÀÌÅÛ ÀÔ´Ï´Ù."));
  2179. return;
  2180. }
  2181.  
  2182. if (!pkSafebox->IsEmpty(p->bSafePos, pkItem->GetSize()))
  2183. {
  2184. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> ¿Å±æ ¼ö ¾ø´Â À§Ä¡ÀÔ´Ï´Ù."));
  2185. return;
  2186. }
  2187.  
  2188. if (pkItem->GetVnum() == UNIQUE_ITEM_SAFEBOX_EXPAND)
  2189. {
  2190. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> ÀÌ ¾ÆÀÌÅÛÀº ³ÖÀ» ¼ö ¾ø½À´Ï´Ù."));
  2191. return;
  2192. }
  2193.  
  2194. if( IS_SET(pkItem->GetAntiFlag(), ITEM_ANTIFLAG_SAFEBOX) )
  2195. {
  2196. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> ÀÌ ¾ÆÀÌÅÛÀº ³ÖÀ» ¼ö ¾ø½À´Ï´Ù."));
  2197. return;
  2198. }
  2199.  
  2200. if (true == pkItem->isLocked())
  2201. {
  2202. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> ÀÌ ¾ÆÀÌÅÛÀº ³ÖÀ» ¼ö ¾ø½À´Ï´Ù."));
  2203. return;
  2204. }
  2205.  
  2206. // @fixme140 BEGIN
  2207. if (ITEM_BELT == pkItem->GetType() && CBeltInventoryHelper::IsExistItemInBeltInventory(ch))
  2208. {
  2209. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("º§Æ® Àκ¥Å丮¿¡ ¾ÆÀÌÅÛÀÌ Á¸ÀçÇϸé ÇØÁ¦ÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2210. return;
  2211. }
  2212. // @fixme140 END
  2213.  
  2214. pkItem->RemoveFromCharacter();
  2215. if (!pkItem->IsDragonSoul())
  2216. ch->SyncQuickslot(QUICKSLOT_TYPE_ITEM, p->ItemPos.cell, 255);
  2217. pkSafebox->Add(p->bSafePos, pkItem);
  2218.  
  2219. char szHint[128];
  2220. snprintf(szHint, sizeof(szHint), "%s %u", pkItem->GetName(), pkItem->GetCount());
  2221. LogManager::instance().ItemLog(ch, pkItem, "SAFEBOX PUT", szHint);
  2222. }
  2223.  
  2224. void CInputMain::SafeboxCheckout(LPCHARACTER ch, const char * c_pData, bool bMall)
  2225. {
  2226. TPacketCGSafeboxCheckout * p = (TPacketCGSafeboxCheckout *) c_pData;
  2227.  
  2228. if (!ch->CanHandleItem())
  2229. return;
  2230.  
  2231. CSafebox * pkSafebox;
  2232.  
  2233. if (bMall)
  2234. pkSafebox = ch->GetMall();
  2235. else
  2236. pkSafebox = ch->GetSafebox();
  2237.  
  2238. if (!pkSafebox)
  2239. return;
  2240.  
  2241. LPITEM pkItem = pkSafebox->Get(p->bSafePos);
  2242.  
  2243. if (!pkItem)
  2244. return;
  2245.  
  2246. if (!ch->IsEmptyItemGrid(p->ItemPos, pkItem->GetSize()))
  2247. return;
  2248.  
  2249. // ¾ÆÀÌÅÛ ¸ô¿¡¼­ Àκ¥À¸·Î ¿Å±â´Â ºÎºÐ¿¡¼­ ¿ëÈ¥¼® Ư¼ö ó¸®
  2250. // (¸ô¿¡¼­ ¸¸µå´Â ¾ÆÀÌÅÛÀº item_proto¿¡ Á¤Àǵȴë·Î ¼Ó¼ºÀÌ ºÙ±â ¶§¹®¿¡,
  2251. // ¿ëÈ¥¼®ÀÇ °æ¿ì, ÀÌ Ã³¸®¸¦ ÇÏÁö ¾ÊÀ¸¸é ¼Ó¼ºÀÌ Çϳªµµ ºÙÁö ¾Ê°Ô µÈ´Ù.)
  2252. if (pkItem->IsDragonSoul())
  2253. {
  2254. if (bMall)
  2255. {
  2256. DSManager::instance().DragonSoulItemInitialize(pkItem);
  2257. }
  2258.  
  2259. if (DRAGON_SOUL_INVENTORY != p->ItemPos.window_type)
  2260. {
  2261. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> ¿Å±æ ¼ö ¾ø´Â À§Ä¡ÀÔ´Ï´Ù."));
  2262. return;
  2263. }
  2264.  
  2265. TItemPos DestPos = p->ItemPos;
  2266. if (!DSManager::instance().IsValidCellForThisItem(pkItem, DestPos))
  2267. {
  2268. int iCell = ch->GetEmptyDragonSoulInventory(pkItem);
  2269. if (iCell < 0)
  2270. {
  2271. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> ¿Å±æ ¼ö ¾ø´Â À§Ä¡ÀÔ´Ï´Ù."));
  2272. return ;
  2273. }
  2274. DestPos = TItemPos (DRAGON_SOUL_INVENTORY, iCell);
  2275. }
  2276.  
  2277. pkSafebox->Remove(p->bSafePos);
  2278. pkItem->AddToCharacter(ch, DestPos);
  2279. ITEM_MANAGER::instance().FlushDelayedSave(pkItem);
  2280. }
  2281. else
  2282. {
  2283. if (DRAGON_SOUL_INVENTORY == p->ItemPos.window_type)
  2284. {
  2285. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> ¿Å±æ ¼ö ¾ø´Â À§Ä¡ÀÔ´Ï´Ù."));
  2286. return;
  2287. }
  2288. // @fixme119
  2289. if (p->ItemPos.IsBeltInventoryPosition() && false == CBeltInventoryHelper::CanMoveIntoBeltInventory(pkItem))
  2290. {
  2291. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀÌ ¾ÆÀÌÅÛÀº º§Æ® Àκ¥Å丮·Î ¿Å±æ ¼ö ¾ø½À´Ï´Ù."));
  2292. return;
  2293. }
  2294.  
  2295. pkSafebox->Remove(p->bSafePos);
  2296. pkItem->AddToCharacter(ch, p->ItemPos);
  2297. ITEM_MANAGER::instance().FlushDelayedSave(pkItem);
  2298. }
  2299.  
  2300. DWORD dwID = pkItem->GetID();
  2301. db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_FLUSH, 0, sizeof(DWORD));
  2302. db_clientdesc->Packet(&dwID, sizeof(DWORD));
  2303.  
  2304. char szHint[128];
  2305. snprintf(szHint, sizeof(szHint), "%s %u", pkItem->GetName(), pkItem->GetCount());
  2306. if (bMall)
  2307. LogManager::instance().ItemLog(ch, pkItem, "MALL GET", szHint);
  2308. else
  2309. LogManager::instance().ItemLog(ch, pkItem, "SAFEBOX GET", szHint);
  2310. }
  2311.  
  2312. void CInputMain::SafeboxItemMove(LPCHARACTER ch, const char * data)
  2313. {
  2314. struct command_item_move * pinfo = (struct command_item_move *) data;
  2315.  
  2316. if (!ch->CanHandleItem())
  2317. return;
  2318.  
  2319. if (!ch->GetSafebox())
  2320. return;
  2321.  
  2322. ch->GetSafebox()->MoveItem(pinfo->Cell.cell, pinfo->CellTo.cell, pinfo->count);
  2323. }
  2324.  
  2325. // PARTY_JOIN_BUG_FIX
  2326. void CInputMain::PartyInvite(LPCHARACTER ch, const char * c_pData)
  2327. {
  2328. if (ch->GetArena())
  2329. {
  2330. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´ë·ÃÀå¿¡¼­ »ç¿ëÇÏ½Ç ¼ö ¾ø½À´Ï´Ù."));
  2331. return;
  2332. }
  2333.  
  2334. TPacketCGPartyInvite * p = (TPacketCGPartyInvite*) c_pData;
  2335.  
  2336. LPCHARACTER pInvitee = CHARACTER_MANAGER::instance().Find(p->vid);
  2337.  
  2338. if (!pInvitee || !ch->GetDesc() || !pInvitee->GetDesc())
  2339. {
  2340. sys_err("PARTY Cannot find invited character");
  2341. return;
  2342. }
  2343.  
  2344. ch->PartyInvite(pInvitee);
  2345. }
  2346.  
  2347. void CInputMain::PartyInviteAnswer(LPCHARACTER ch, const char * c_pData)
  2348. {
  2349. if (ch->GetArena())
  2350. {
  2351. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´ë·ÃÀå¿¡¼­ »ç¿ëÇÏ½Ç ¼ö ¾ø½À´Ï´Ù."));
  2352. return;
  2353. }
  2354.  
  2355. TPacketCGPartyInviteAnswer * p = (TPacketCGPartyInviteAnswer*) c_pData;
  2356.  
  2357. LPCHARACTER pInviter = CHARACTER_MANAGER::instance().Find(p->leader_vid);
  2358.  
  2359. // pInviter °¡ ch ¿¡°Ô ÆÄƼ ¿äûÀ» Çß¾ú´Ù.
  2360.  
  2361. if (!pInviter)
  2362. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ÆÄƼ¿äûÀ» ÇÑ Ä³¸¯Å͸¦ ãÀ»¼ö ¾ø½À´Ï´Ù."));
  2363. else if (!p->accept)
  2364. pInviter->PartyInviteDeny(ch->GetPlayerID());
  2365. else
  2366. pInviter->PartyInviteAccept(ch);
  2367. }
  2368. // END_OF_PARTY_JOIN_BUG_FIX
  2369.  
  2370. void CInputMain::PartySetState(LPCHARACTER ch, const char* c_pData)
  2371. {
  2372. if (!CPartyManager::instance().IsEnablePCParty())
  2373. {
  2374. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ¼­¹ö ¹®Á¦·Î ÆÄƼ °ü·Ã 󸮸¦ ÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2375. return;
  2376. }
  2377.  
  2378. TPacketCGPartySetState* p = (TPacketCGPartySetState*) c_pData;
  2379.  
  2380. if (!ch->GetParty())
  2381. return;
  2382.  
  2383. if (ch->GetParty()->GetLeaderPID() != ch->GetPlayerID())
  2384. {
  2385. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ¸®´õ¸¸ º¯°æÇÒ ¼ö ÀÖ½À´Ï´Ù."));
  2386. return;
  2387. }
  2388.  
  2389. if (!ch->GetParty()->IsMember(p->pid))
  2390. {
  2391. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> »óŸ¦ º¯°æÇÏ·Á´Â »ç¶÷ÀÌ ÆÄƼ¿øÀÌ ¾Æ´Õ´Ï´Ù."));
  2392. return;
  2393. }
  2394.  
  2395. DWORD pid = p->pid;
  2396. sys_log(0, "PARTY SetRole pid %d to role %d state %s", pid, p->byRole, p->flag ? "on" : "off");
  2397.  
  2398. switch (p->byRole)
  2399. {
  2400. case PARTY_ROLE_NORMAL:
  2401. break;
  2402.  
  2403. case PARTY_ROLE_ATTACKER:
  2404. case PARTY_ROLE_TANKER:
  2405. case PARTY_ROLE_BUFFER:
  2406. case PARTY_ROLE_SKILL_MASTER:
  2407. case PARTY_ROLE_HASTE:
  2408. case PARTY_ROLE_DEFENDER:
  2409. if (ch->GetParty()->SetRole(pid, p->byRole, p->flag))
  2410. {
  2411. TPacketPartyStateChange pack;
  2412. pack.dwLeaderPID = ch->GetPlayerID();
  2413. pack.dwPID = p->pid;
  2414. pack.bRole = p->byRole;
  2415. pack.bFlag = p->flag;
  2416. db_clientdesc->DBPacket(HEADER_GD_PARTY_STATE_CHANGE, 0, &pack, sizeof(pack));
  2417. }
  2418. /* else
  2419. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ¾îÅÂÄ¿ ¼³Á¤¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.")); */
  2420. break;
  2421.  
  2422. default:
  2423. sys_err("wrong byRole in PartySetState Packet name %s state %d", ch->GetName(), p->byRole);
  2424. break;
  2425. }
  2426. }
  2427.  
  2428. void CInputMain::PartyRemove(LPCHARACTER ch, const char* c_pData)
  2429. {
  2430. if (ch->GetArena())
  2431. {
  2432. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´ë·ÃÀå¿¡¼­ »ç¿ëÇÏ½Ç ¼ö ¾ø½À´Ï´Ù."));
  2433. return;
  2434. }
  2435.  
  2436. if (!CPartyManager::instance().IsEnablePCParty())
  2437. {
  2438. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ¼­¹ö ¹®Á¦·Î ÆÄƼ °ü·Ã 󸮸¦ ÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2439. return;
  2440. }
  2441.  
  2442. if (ch->GetDungeon())
  2443. {
  2444. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ´øÀü ¾È¿¡¼­´Â ÆÄƼ¿¡¼­ Ãß¹æÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2445. return;
  2446. }
  2447.  
  2448. TPacketCGPartyRemove* p = (TPacketCGPartyRemove*) c_pData;
  2449.  
  2450. if (!ch->GetParty())
  2451. return;
  2452.  
  2453. LPPARTY pParty = ch->GetParty();
  2454. if (pParty->GetLeaderPID() == ch->GetPlayerID())
  2455. {
  2456. if (ch->GetDungeon())
  2457. {
  2458. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ´øÁ¯³»¿¡¼­´Â ÆÄƼ¿øÀ» Ãß¹æÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2459. }
  2460. else
  2461. {
  2462. // Àû·æ¼º¿¡¼­ ÆÄƼÀåÀÌ ´øÁ¯ ¹Û¿¡¼­ ÆÄƼ ÇØ»ê ¸øÇÏ°Ô ¸·ÀÚ
  2463. if(pParty->IsPartyInDungeon(351))
  2464. {
  2465. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ>´øÀü ¾È¿¡ ÆÄƼ¿øÀÌ ÀÖ¾î ÆÄƼ¸¦ ÇØ»ê ÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2466. return;
  2467. }
  2468.  
  2469. // leader can remove any member
  2470. if (p->pid == ch->GetPlayerID() || pParty->GetMemberCount() == 2)
  2471. {
  2472. // party disband
  2473. CPartyManager::instance().DeleteParty(pParty);
  2474. }
  2475. else
  2476. {
  2477. LPCHARACTER B = CHARACTER_MANAGER::instance().FindByPID(p->pid);
  2478. if (B)
  2479. {
  2480. //pParty->SendPartyRemoveOneToAll(B);
  2481. B->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ÆÄƼ¿¡¼­ Ãß¹æ´çÇϼ̽À´Ï´Ù."));
  2482. //pParty->Unlink(B);
  2483. //CPartyManager::instance().SetPartyMember(B->GetPlayerID(), NULL);
  2484. }
  2485. pParty->Quit(p->pid);
  2486. }
  2487. }
  2488. }
  2489. else
  2490. {
  2491. // otherwise, only remove itself
  2492. if (p->pid == ch->GetPlayerID())
  2493. {
  2494. if (ch->GetDungeon())
  2495. {
  2496. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ´øÁ¯³»¿¡¼­´Â ÆÄƼ¸¦ ³ª°¥ ¼ö ¾ø½À´Ï´Ù."));
  2497. }
  2498. else
  2499. {
  2500. if (pParty->GetMemberCount() == 2)
  2501. {
  2502. // party disband
  2503. CPartyManager::instance().DeleteParty(pParty);
  2504. }
  2505. else
  2506. {
  2507. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ÆÄƼ¿¡¼­ ³ª°¡¼Ì½À´Ï´Ù."));
  2508. //pParty->SendPartyRemoveOneToAll(ch);
  2509. pParty->Quit(ch->GetPlayerID());
  2510. //pParty->SendPartyRemoveAllToOne(ch);
  2511. //CPartyManager::instance().SetPartyMember(ch->GetPlayerID(), NULL);
  2512. }
  2513. }
  2514. }
  2515. else
  2516. {
  2517. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ´Ù¸¥ ÆÄƼ¿øÀ» Å»Åð½Ãų ¼ö ¾ø½À´Ï´Ù."));
  2518. }
  2519. }
  2520. }
  2521.  
  2522. void CInputMain::AnswerMakeGuild(LPCHARACTER ch, const char* c_pData)
  2523. {
  2524. TPacketCGAnswerMakeGuild* p = (TPacketCGAnswerMakeGuild*) c_pData;
  2525.  
  2526. if (ch->GetGold() < 200000)
  2527. return;
  2528.  
  2529. if (get_global_time() - ch->GetQuestFlag("guild_manage.new_disband_time") <
  2530. CGuildManager::instance().GetDisbandDelay())
  2531. {
  2532. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ÇØ»êÇÑ ÈÄ %dÀÏ À̳»¿¡´Â ±æµå¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù."),
  2533. quest::CQuestManager::instance().GetEventFlag("guild_disband_delay"));
  2534. return;
  2535. }
  2536.  
  2537. if (get_global_time() - ch->GetQuestFlag("guild_manage.new_withdraw_time") <
  2538. CGuildManager::instance().GetWithdrawDelay())
  2539. {
  2540. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> Å»ÅðÇÑ ÈÄ %dÀÏ À̳»¿¡´Â ±æµå¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù."),
  2541. quest::CQuestManager::instance().GetEventFlag("guild_withdraw_delay"));
  2542. return;
  2543. }
  2544.  
  2545. if (ch->GetGuild())
  2546. return;
  2547.  
  2548. CGuildManager& gm = CGuildManager::instance();
  2549.  
  2550. TGuildCreateParameter cp;
  2551. memset(&cp, 0, sizeof(cp));
  2552.  
  2553. cp.master = ch;
  2554. strlcpy(cp.name, p->guild_name, sizeof(cp.name));
  2555.  
  2556. if (cp.name[0] == 0 || !check_name(cp.name))
  2557. {
  2558. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀûÇÕÇÏÁö ¾ÊÀº ±æµå À̸§ ÀÔ´Ï´Ù."));
  2559. return;
  2560. }
  2561.  
  2562. DWORD dwGuildID = gm.CreateGuild(cp);
  2563.  
  2564. if (dwGuildID)
  2565. {
  2566. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> [%s] ±æµå°¡ »ý¼ºµÇ¾ú½À´Ï´Ù."), cp.name);
  2567.  
  2568. int GuildCreateFee = 200000;
  2569.  
  2570. ch->PointChange(POINT_GOLD, -GuildCreateFee);
  2571. DBManager::instance().SendMoneyLog(MONEY_LOG_GUILD, ch->GetPlayerID(), -GuildCreateFee);
  2572.  
  2573. char Log[128];
  2574. snprintf(Log, sizeof(Log), "GUILD_NAME %s MASTER %s", cp.name, ch->GetName());
  2575. LogManager::instance().CharLog(ch, 0, "MAKE_GUILD", Log);
  2576.  
  2577. ch->RemoveSpecifyItem(GUILD_CREATE_ITEM_VNUM, 1);
  2578. //ch->SendGuildName(dwGuildID);
  2579. }
  2580. else
  2581. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµå »ý¼º¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."));
  2582. }
  2583.  
  2584. void CInputMain::PartyUseSkill(LPCHARACTER ch, const char* c_pData)
  2585. {
  2586. TPacketCGPartyUseSkill* p = (TPacketCGPartyUseSkill*) c_pData;
  2587. if (!ch->GetParty())
  2588. return;
  2589.  
  2590. if (ch->GetPlayerID() != ch->GetParty()->GetLeaderPID())
  2591. {
  2592. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ÆÄƼ ±â¼úÀº ÆÄƼÀ常 »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù."));
  2593. return;
  2594. }
  2595.  
  2596. switch (p->bySkillIndex)
  2597. {
  2598. case PARTY_SKILL_HEAL:
  2599. ch->GetParty()->HealParty();
  2600. break;
  2601. case PARTY_SKILL_WARP:
  2602. {
  2603. LPCHARACTER pch = CHARACTER_MANAGER::instance().Find(p->vid);
  2604. if (pch)
  2605. ch->GetParty()->SummonToLeader(pch->GetPlayerID());
  2606. else
  2607. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ÆÄƼ> ¼ÒȯÇÏ·Á´Â ´ë»óÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù."));
  2608. }
  2609. break;
  2610. }
  2611. }
  2612.  
  2613. void CInputMain::PartyParameter(LPCHARACTER ch, const char * c_pData)
  2614. {
  2615. TPacketCGPartyParameter * p = (TPacketCGPartyParameter *) c_pData;
  2616.  
  2617. if (ch->GetParty())
  2618. ch->GetParty()->SetParameter(p->bDistributeMode);
  2619. }
  2620.  
  2621. size_t GetSubPacketSize(const GUILD_SUBHEADER_CG& header)
  2622. {
  2623. switch (header)
  2624. {
  2625. case GUILD_SUBHEADER_CG_DEPOSIT_MONEY: return sizeof(int);
  2626. case GUILD_SUBHEADER_CG_WITHDRAW_MONEY: return sizeof(int);
  2627. case GUILD_SUBHEADER_CG_ADD_MEMBER: return sizeof(DWORD);
  2628. case GUILD_SUBHEADER_CG_REMOVE_MEMBER: return sizeof(DWORD);
  2629. case GUILD_SUBHEADER_CG_CHANGE_GRADE_NAME: return 10;
  2630. case GUILD_SUBHEADER_CG_CHANGE_GRADE_AUTHORITY: return sizeof(BYTE) + sizeof(BYTE);
  2631. case GUILD_SUBHEADER_CG_OFFER: return sizeof(DWORD);
  2632. case GUILD_SUBHEADER_CG_CHARGE_GSP: return sizeof(int);
  2633. case GUILD_SUBHEADER_CG_POST_COMMENT: return 1;
  2634. case GUILD_SUBHEADER_CG_DELETE_COMMENT: return sizeof(DWORD);
  2635. case GUILD_SUBHEADER_CG_REFRESH_COMMENT: return 0;
  2636. case GUILD_SUBHEADER_CG_CHANGE_MEMBER_GRADE: return sizeof(DWORD) + sizeof(BYTE);
  2637. case GUILD_SUBHEADER_CG_USE_SKILL: return sizeof(TPacketCGGuildUseSkill);
  2638. case GUILD_SUBHEADER_CG_CHANGE_MEMBER_GENERAL: return sizeof(DWORD) + sizeof(BYTE);
  2639. case GUILD_SUBHEADER_CG_GUILD_INVITE_ANSWER: return sizeof(DWORD) + sizeof(BYTE);
  2640. }
  2641.  
  2642. return 0;
  2643. }
  2644.  
  2645. int CInputMain::Guild(LPCHARACTER ch, const char * data, size_t uiBytes)
  2646. {
  2647. if (uiBytes < sizeof(TPacketCGGuild))
  2648. return -1;
  2649.  
  2650. const TPacketCGGuild* p = reinterpret_cast<const TPacketCGGuild*>(data);
  2651. const char* c_pData = data + sizeof(TPacketCGGuild);
  2652.  
  2653. uiBytes -= sizeof(TPacketCGGuild);
  2654.  
  2655. const GUILD_SUBHEADER_CG SubHeader = static_cast<GUILD_SUBHEADER_CG>(p->subheader);
  2656. const size_t SubPacketLen = GetSubPacketSize(SubHeader);
  2657.  
  2658. if (uiBytes < SubPacketLen)
  2659. {
  2660. return -1;
  2661. }
  2662.  
  2663. CGuild* pGuild = ch->GetGuild();
  2664.  
  2665. if (NULL == pGuild)
  2666. {
  2667. if (SubHeader != GUILD_SUBHEADER_CG_GUILD_INVITE_ANSWER)
  2668. {
  2669. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµå¿¡ ¼ÓÇØÀÖÁö ¾Ê½À´Ï´Ù."));
  2670. return SubPacketLen;
  2671. }
  2672. }
  2673.  
  2674. switch (SubHeader)
  2675. {
  2676. case GUILD_SUBHEADER_CG_DEPOSIT_MONEY:
  2677. {
  2678. // by mhh : ±æµåÀÚ±ÝÀº ´çºÐ°£ ³ÖÀ» ¼ö ¾ø´Ù.
  2679. return SubPacketLen;
  2680.  
  2681. const int gold = MIN(*reinterpret_cast<const int*>(c_pData), __deposit_limit());
  2682.  
  2683. if (gold < 0)
  2684. {
  2685. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> À߸øµÈ ±Ý¾×ÀÔ´Ï´Ù."));
  2686. return SubPacketLen;
  2687. }
  2688.  
  2689. if (ch->GetGold() < gold)
  2690. {
  2691. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> °¡Áö°í ÀÖ´Â µ·ÀÌ ºÎÁ·ÇÕ´Ï´Ù."));
  2692. return SubPacketLen;
  2693. }
  2694.  
  2695. pGuild->RequestDepositMoney(ch, gold);
  2696. }
  2697. return SubPacketLen;
  2698.  
  2699. case GUILD_SUBHEADER_CG_WITHDRAW_MONEY:
  2700. {
  2701. // by mhh : ±æµåÀÚ±ÝÀº ´çºÐ°£ »¬ ¼ö ¾ø´Ù.
  2702. return SubPacketLen;
  2703.  
  2704. const int gold = MIN(*reinterpret_cast<const int*>(c_pData), 500000);
  2705.  
  2706. if (gold < 0)
  2707. {
  2708. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> À߸øµÈ ±Ý¾×ÀÔ´Ï´Ù."));
  2709. return SubPacketLen;
  2710. }
  2711.  
  2712. pGuild->RequestWithdrawMoney(ch, gold);
  2713. }
  2714. return SubPacketLen;
  2715.  
  2716. case GUILD_SUBHEADER_CG_ADD_MEMBER:
  2717. {
  2718. const DWORD vid = *reinterpret_cast<const DWORD*>(c_pData);
  2719. LPCHARACTER newmember = CHARACTER_MANAGER::instance().Find(vid);
  2720.  
  2721. if (!newmember)
  2722. {
  2723. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±×·¯ÇÑ »ç¶÷À» ãÀ» ¼ö ¾ø½À´Ï´Ù."));
  2724. return SubPacketLen;
  2725. }
  2726.  
  2727. if (!newmember->IsPC())
  2728. {
  2729. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("THE ACTION HAS BEEN STOPED - EXPLOIT DETECTED"));
  2730. return SubPacketLen;
  2731. }
  2732.  
  2733. if (!ch->IsPC())
  2734. return SubPacketLen;
  2735.  
  2736.  
  2737. if (!newmember->IsPC())
  2738. return SubPacketLen;
  2739.  
  2740. if (LC_IsCanada() == true)
  2741. {
  2742. if (newmember->GetQuestFlag("change_guild_master.be_other_member") > get_global_time())
  2743. {
  2744. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ¾ÆÁ÷ °¡ÀÔÇÒ ¼ö ¾ø´Â ij¸¯ÅÍÀÔ´Ï´Ù"));
  2745. return SubPacketLen;
  2746. }
  2747. }
  2748.  
  2749. pGuild->Invite(ch, newmember);
  2750. }
  2751. return SubPacketLen;
  2752.  
  2753. case GUILD_SUBHEADER_CG_REMOVE_MEMBER:
  2754. {
  2755. if (pGuild->UnderAnyWar() != 0)
  2756. {
  2757. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµåÀü Áß¿¡´Â ±æµå¿øÀ» Å»Åð½Ãų ¼ö ¾ø½À´Ï´Ù."));
  2758. return SubPacketLen;
  2759. }
  2760.  
  2761. const DWORD pid = *reinterpret_cast<const DWORD*>(c_pData);
  2762. const TGuildMember* m = pGuild->GetMember(ch->GetPlayerID());
  2763.  
  2764. if (NULL == m)
  2765. return -1;
  2766.  
  2767. LPCHARACTER member = CHARACTER_MANAGER::instance().FindByPID(pid);
  2768.  
  2769. if (member)
  2770. {
  2771. if (member->GetGuild() != pGuild)
  2772. {
  2773. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> »ó´ë¹æÀÌ °°Àº ±æµå°¡ ¾Æ´Õ´Ï´Ù."));
  2774. return SubPacketLen;
  2775. }
  2776.  
  2777. if (!pGuild->HasGradeAuth(m->grade, GUILD_AUTH_REMOVE_MEMBER))
  2778. {
  2779. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµå¿øÀ» °­Á¦ Å»Åð ½Ãų ±ÇÇÑÀÌ ¾ø½À´Ï´Ù."));
  2780. return SubPacketLen;
  2781. }
  2782.  
  2783. member->SetQuestFlag("guild_manage.new_withdraw_time", get_global_time());
  2784. pGuild->RequestRemoveMember(member->GetPlayerID());
  2785.  
  2786. if (g_bGuildInviteLimit)
  2787. {
  2788. DBManager::instance().Query("REPLACE INTO guild_invite_limit VALUES(%d, %d)", pGuild->GetID(), get_global_time());
  2789. }
  2790. }
  2791. else
  2792. {
  2793. if (!pGuild->HasGradeAuth(m->grade, GUILD_AUTH_REMOVE_MEMBER))
  2794. {
  2795. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµå¿øÀ» °­Á¦ Å»Åð ½Ãų ±ÇÇÑÀÌ ¾ø½À´Ï´Ù."));
  2796. return SubPacketLen;
  2797. }
  2798.  
  2799. if (pGuild->RequestRemoveMember(pid))
  2800. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµå¿øÀ» °­Á¦ Å»Åð ½ÃÄ×½À´Ï´Ù."));
  2801. else
  2802. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±×·¯ÇÑ »ç¶÷À» ãÀ» ¼ö ¾ø½À´Ï´Ù."));
  2803. }
  2804. }
  2805. return SubPacketLen;
  2806.  
  2807. case GUILD_SUBHEADER_CG_CHANGE_GRADE_NAME:
  2808. {
  2809. char gradename[GUILD_GRADE_NAME_MAX_LEN + 1];
  2810. strlcpy(gradename, c_pData + 1, sizeof(gradename));
  2811.  
  2812. const TGuildMember * m = pGuild->GetMember(ch->GetPlayerID());
  2813.  
  2814. if (NULL == m)
  2815. return -1;
  2816.  
  2817. if (m->grade != GUILD_LEADER_GRADE)
  2818. {
  2819. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> Á÷À§ À̸§À» º¯°æÇÒ ±ÇÇÑÀÌ ¾ø½À´Ï´Ù."));
  2820. }
  2821. else if (*c_pData == GUILD_LEADER_GRADE)
  2822. {
  2823. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµåÀåÀÇ Á÷À§ À̸§Àº º¯°æÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2824. }
  2825. else if (!check_name(gradename))
  2826. {
  2827. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ÀûÇÕÇÏÁö ¾ÊÀº Á÷À§ À̸§ ÀÔ´Ï´Ù."));
  2828. }
  2829. else
  2830. {
  2831. pGuild->ChangeGradeName(*c_pData, gradename);
  2832. }
  2833. }
  2834. return SubPacketLen;
  2835.  
  2836. case GUILD_SUBHEADER_CG_CHANGE_GRADE_AUTHORITY:
  2837. {
  2838. const TGuildMember* m = pGuild->GetMember(ch->GetPlayerID());
  2839.  
  2840. if (NULL == m)
  2841. return -1;
  2842.  
  2843. if (m->grade != GUILD_LEADER_GRADE)
  2844. {
  2845. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> Á÷À§ ±ÇÇÑÀ» º¯°æÇÒ ±ÇÇÑÀÌ ¾ø½À´Ï´Ù."));
  2846. }
  2847. else if (*c_pData == GUILD_LEADER_GRADE)
  2848. {
  2849. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµåÀåÀÇ ±ÇÇÑÀº º¯°æÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2850. }
  2851. else
  2852. {
  2853. pGuild->ChangeGradeAuth(*c_pData, *(c_pData + 1));
  2854. }
  2855. }
  2856. return SubPacketLen;
  2857.  
  2858. case GUILD_SUBHEADER_CG_OFFER:
  2859. {
  2860. DWORD offer = *reinterpret_cast<const DWORD*>(c_pData);
  2861.  
  2862. if (pGuild->GetLevel() >= GUILD_MAX_LEVEL)
  2863. {
  2864. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµå°¡ ÀÌ¹Ì ÃÖ°í ·¹º§ÀÔ´Ï´Ù."));
  2865. }
  2866. else
  2867. {
  2868. offer /= 100;
  2869. offer *= 100;
  2870.  
  2871. if (pGuild->OfferExp(ch, offer))
  2872. {
  2873. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> %uÀÇ °æÇèÄ¡¸¦ ÅõÀÚÇÏ¿´½À´Ï´Ù."), offer);
  2874. }
  2875. else
  2876. {
  2877. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> °æÇèÄ¡ ÅõÀÚ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."));
  2878. }
  2879. }
  2880. }
  2881. return SubPacketLen;
  2882.  
  2883. case GUILD_SUBHEADER_CG_CHARGE_GSP:
  2884. {
  2885. const int offer = *reinterpret_cast<const int*>(c_pData);
  2886. const int gold = offer * 100;
  2887.  
  2888. if (offer < 0 || gold < offer || gold < 0 || ch->GetGold() < gold)
  2889. {
  2890. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> µ·ÀÌ ºÎÁ·ÇÕ´Ï´Ù."));
  2891. return SubPacketLen;
  2892. }
  2893.  
  2894. if (!pGuild->ChargeSP(ch, offer))
  2895. {
  2896. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ¿ë½Å·Â ȸº¹¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."));
  2897. }
  2898. }
  2899. return SubPacketLen;
  2900.  
  2901. case GUILD_SUBHEADER_CG_POST_COMMENT:
  2902. {
  2903. const size_t length = *c_pData;
  2904.  
  2905. if (length > GUILD_COMMENT_MAX_LEN)
  2906. {
  2907. // À߸øµÈ ±æÀÌ.. ²÷¾îÁÖÀÚ.
  2908. sys_err("POST_COMMENT: %s comment too long (length: %u)", ch->GetName(), length);
  2909. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  2910. return -1;
  2911. }
  2912.  
  2913. if (uiBytes < 1 + length)
  2914. return -1;
  2915.  
  2916. const TGuildMember* m = pGuild->GetMember(ch->GetPlayerID());
  2917.  
  2918. if (NULL == m)
  2919. return -1;
  2920.  
  2921. if (length && !pGuild->HasGradeAuth(m->grade, GUILD_AUTH_NOTICE) && *(c_pData + 1) == '!')
  2922. {
  2923. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> °øÁö±ÛÀ» ÀÛ¼ºÇÒ ±ÇÇÑÀÌ ¾ø½À´Ï´Ù."));
  2924. }
  2925. else
  2926. {
  2927. std::string str(c_pData + 1, length);
  2928. pGuild->AddComment(ch, str);
  2929. }
  2930.  
  2931. return (1 + length);
  2932. }
  2933.  
  2934. case GUILD_SUBHEADER_CG_DELETE_COMMENT:
  2935. {
  2936. const DWORD comment_id = *reinterpret_cast<const DWORD*>(c_pData);
  2937.  
  2938. pGuild->DeleteComment(ch, comment_id);
  2939. }
  2940. return SubPacketLen;
  2941.  
  2942. case GUILD_SUBHEADER_CG_REFRESH_COMMENT:
  2943. pGuild->RefreshComment(ch);
  2944. return SubPacketLen;
  2945.  
  2946. case GUILD_SUBHEADER_CG_CHANGE_MEMBER_GRADE:
  2947. {
  2948. const DWORD pid = *reinterpret_cast<const DWORD*>(c_pData);
  2949. const BYTE grade = *(c_pData + sizeof(DWORD));
  2950. const TGuildMember* m = pGuild->GetMember(ch->GetPlayerID());
  2951.  
  2952. if (NULL == m)
  2953. return -1;
  2954.  
  2955. if (m->grade != GUILD_LEADER_GRADE)
  2956. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> Á÷À§¸¦ º¯°æÇÒ ±ÇÇÑÀÌ ¾ø½À´Ï´Ù."));
  2957. else if (ch->GetPlayerID() == pid)
  2958. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµåÀåÀÇ Á÷À§´Â º¯°æÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2959. else if (grade == 1)
  2960. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ±æµåÀåÀ¸·Î Á÷À§¸¦ º¯°æÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2961. else
  2962. pGuild->ChangeMemberGrade(pid, grade);
  2963. }
  2964. return SubPacketLen;
  2965.  
  2966. case GUILD_SUBHEADER_CG_USE_SKILL:
  2967. {
  2968. const TPacketCGGuildUseSkill* p = reinterpret_cast<const TPacketCGGuildUseSkill*>(c_pData);
  2969.  
  2970. pGuild->UseSkill(p->dwVnum, ch, p->dwPID);
  2971. }
  2972. return SubPacketLen;
  2973.  
  2974. case GUILD_SUBHEADER_CG_CHANGE_MEMBER_GENERAL:
  2975. {
  2976. const DWORD pid = *reinterpret_cast<const DWORD*>(c_pData);
  2977. const BYTE is_general = *(c_pData + sizeof(DWORD));
  2978. const TGuildMember* m = pGuild->GetMember(ch->GetPlayerID());
  2979.  
  2980. if (NULL == m)
  2981. return -1;
  2982.  
  2983. if (m->grade != GUILD_LEADER_GRADE)
  2984. {
  2985. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> À屺À» ÁöÁ¤ÇÒ ±ÇÇÑÀÌ ¾ø½À´Ï´Ù."));
  2986. }
  2987. else
  2988. {
  2989. if (!pGuild->ChangeMemberGeneral(pid, is_general))
  2990. {
  2991. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> ´õÀÌ»ó Àå¼ö¸¦ ÁöÁ¤ÇÒ ¼ö ¾ø½À´Ï´Ù."));
  2992. }
  2993. }
  2994. }
  2995. return SubPacketLen;
  2996.  
  2997. case GUILD_SUBHEADER_CG_GUILD_INVITE_ANSWER:
  2998. {
  2999. const DWORD guild_id = *reinterpret_cast<const DWORD*>(c_pData);
  3000. const BYTE accept = *(c_pData + sizeof(DWORD));
  3001.  
  3002. CGuild * g = CGuildManager::instance().FindGuild(guild_id);
  3003.  
  3004. if (g)
  3005. {
  3006. if (accept)
  3007. g->InviteAccept(ch);
  3008. else
  3009. g->InviteDeny(ch->GetPlayerID());
  3010. }
  3011. }
  3012. return SubPacketLen;
  3013.  
  3014. }
  3015.  
  3016. return 0;
  3017. }
  3018.  
  3019. void CInputMain::Fishing(LPCHARACTER ch, const char* c_pData)
  3020. {
  3021. TPacketCGFishing* p = (TPacketCGFishing*)c_pData;
  3022. ch->SetRotation(p->dir * 5);
  3023. ch->fishing();
  3024. return;
  3025. }
  3026.  
  3027. void CInputMain::ItemGive(LPCHARACTER ch, const char* c_pData)
  3028. {
  3029. TPacketCGGiveItem* p = (TPacketCGGiveItem*) c_pData;
  3030. LPCHARACTER to_ch = CHARACTER_MANAGER::instance().Find(p->dwTargetVID);
  3031.  
  3032. if (to_ch)
  3033. ch->GiveItem(to_ch, p->ItemPos);
  3034. else
  3035. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¾ÆÀÌÅÛÀ» °Ç³×ÁÙ ¼ö ¾ø½À´Ï´Ù."));
  3036. }
  3037.  
  3038. void CInputMain::Hack(LPCHARACTER ch, const char * c_pData)
  3039. {
  3040. TPacketCGHack * p = (TPacketCGHack *) c_pData;
  3041.  
  3042. char buf[sizeof(p->szBuf)];
  3043. strlcpy(buf, p->szBuf, sizeof(buf));
  3044.  
  3045. sys_err("HACK_DETECT: %s %s", ch->GetName(), buf);
  3046.  
  3047. // ÇöÀç Ŭ¶óÀ̾ðÆ®¿¡¼­ ÀÌ ÆÐŶÀ» º¸³»´Â °æ¿ì°¡ ¾øÀ¸¹Ç·Î ¹«Á¶°Ç ²÷µµ·Ï ÇÑ´Ù
  3048. ch->GetDesc()->SetPhase(PHASE_CLOSE);
  3049. }
  3050.  
  3051. #ifdef ENABLE_SHOW_CHEST_DROP
  3052. void CInputMain::ChestDropInfo(LPCHARACTER ch, const char* c_pData)
  3053. {
  3054. TPacketCGChestDropInfo* p = (TPacketCGChestDropInfo*) c_pData;
  3055.  
  3056. if(p->wInventoryCell >= INVENTORY_MAX_NUM)
  3057. return;
  3058.  
  3059. LPITEM pkItem = ch->GetInventoryItem(p->wInventoryCell);
  3060.  
  3061. if (!pkItem)
  3062. return;
  3063.  
  3064. std::vector<TChestDropInfoTable> vec_ItemList;
  3065. ITEM_MANAGER::instance().GetChestItemList(pkItem->GetVnum(), vec_ItemList);
  3066.  
  3067. TPacketGCChestDropInfo packet;
  3068. packet.bHeader = HEADER_GC_CHEST_DROP_INFO;
  3069. packet.wSize = sizeof(packet) + sizeof(TChestDropInfoTable) * vec_ItemList.size();
  3070. packet.dwChestVnum = pkItem->GetVnum();
  3071.  
  3072. ch->GetDesc()->BufferedPacket(&packet, sizeof(packet));
  3073. ch->GetDesc()->Packet(&vec_ItemList[0], sizeof(TChestDropInfoTable) * vec_ItemList.size());
  3074. }
  3075. #endif
  3076.  
  3077. int CInputMain::MyShop(LPCHARACTER ch, const char * c_pData, size_t uiBytes)
  3078. {
  3079. TPacketCGMyShop * p = (TPacketCGMyShop *) c_pData;
  3080. int iExtraLen = p->bCount * sizeof(TShopItemTable);
  3081. #ifdef SHOP_BLOCK_GAME99
  3082. if (g_bChannel >= 99 & ch->GetGMLevel() <= 0) {
  3083. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "SHOP_OX_ERROR"));
  3084. return (iExtraLen);
  3085. }
  3086. #endif
  3087.  
  3088. #ifdef OFFLINE_SHOP
  3089. if (quest::CQuestManager::instance().GetEventFlag("shop_off")==1)
  3090. if (ch)
  3091. {
  3092. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "SHOP_TEMP_OFF"));
  3093. return (iExtraLen);
  3094. }
  3095. #endif
  3096. #ifdef SHOP_GM_PRIVILEGES
  3097. if (GM_PLAYER < ch->GetGMLevel() && SHOP_GM_PRIVILEGES >ch->GetGMLevel()) {
  3098. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("SHOP_PRIV_ERROR"));
  3099. return (iExtraLen);
  3100. }
  3101. #endif
  3102. if (uiBytes < sizeof(TPacketCGMyShop) + iExtraLen)
  3103. return -1;
  3104. #ifndef FULL_YANG
  3105. if (ch->GetGold() >= GOLD_MAX)
  3106. {
  3107. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼ÒÀ¯ µ·ÀÌ 20¾ï³ÉÀ» ³Ñ¾î °Å·¡¸¦ ÇÛ¼ö°¡ ¾ø½À´Ï´Ù."));
  3108. sys_log(0, "MyShop ==> OverFlow Gold id %u name %s ", ch->GetPlayerID(), ch->GetName());
  3109. return (iExtraLen);
  3110. }
  3111. #endif
  3112. if (ch->IsStun() || ch->IsDead())
  3113. return (iExtraLen);
  3114.  
  3115. if (ch->GetExchange() || ch->IsOpenSafebox() || ch->GetShopOwner() || ch->IsCubeOpen())
  3116. {
  3117. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ù¸¥ °Å·¡ÁßÀÏ°æ¿ì °³ÀλóÁ¡À» ¿­¼ö°¡ ¾ø½À´Ï´Ù."));
  3118. return (iExtraLen);
  3119. }
  3120.  
  3121. sys_log(0, "MyShop count %d", p->bCount);
  3122. #ifdef OFFLINE_SHOP
  3123. ch->OpenMyShop(p->szSign, (TShopItemTable *)(c_pData + sizeof(TPacketCGMyShop)), p->bCount, p->days);
  3124. #else
  3125. ch->OpenMyShop(p->szSign, (TShopItemTable *)(c_pData + sizeof(TPacketCGMyShop)), p->bCount);
  3126. #endif
  3127. return (iExtraLen);
  3128. }
  3129.  
  3130. void CInputMain::Refine(LPCHARACTER ch, const char* c_pData)
  3131. {
  3132. const TPacketCGRefine* p = reinterpret_cast<const TPacketCGRefine*>(c_pData);
  3133.  
  3134. if (ch->GetExchange() || ch->IsOpenSafebox() || ch->GetShopOwner() || ch->GetMyShop() || ch->IsCubeOpen())
  3135. {
  3136. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("â°í,°Å·¡Ã¢µîÀÌ ¿­¸° »óÅ¿¡¼­´Â °³·®À» ÇÒ¼ö°¡ ¾ø½À´Ï´Ù"));
  3137. ch->ClearRefineMode();
  3138. return;
  3139. }
  3140.  
  3141. if (p->type == 255)
  3142. {
  3143. // DoRefine Cancel
  3144. ch->ClearRefineMode();
  3145. return;
  3146. }
  3147.  
  3148. if (p->pos >= INVENTORY_MAX_NUM)
  3149. {
  3150. ch->ClearRefineMode();
  3151. return;
  3152. }
  3153.  
  3154. LPITEM item = ch->GetInventoryItem(p->pos);
  3155.  
  3156. if (!item)
  3157. {
  3158. ch->ClearRefineMode();
  3159. return;
  3160. }
  3161.  
  3162. ch->SetRefineTime();
  3163.  
  3164. if (p->type == REFINE_TYPE_NORMAL)
  3165. {
  3166. sys_log (0, "refine_type_noraml");
  3167. ch->DoRefine(item);
  3168. }
  3169. else if (p->type == REFINE_TYPE_SCROLL || p->type == REFINE_TYPE_HYUNIRON || p->type == REFINE_TYPE_MUSIN || p->type == REFINE_TYPE_BDRAGON)
  3170. {
  3171. sys_log (0, "refine_type_scroll, ...");
  3172. ch->DoRefineWithScroll(item);
  3173. }
  3174. else if (p->type == REFINE_TYPE_MONEY_ONLY)
  3175. {
  3176. const LPITEM item = ch->GetInventoryItem(p->pos);
  3177.  
  3178. if (NULL != item)
  3179. {
  3180. if (500 <= item->GetRefineSet())
  3181. {
  3182. LogManager::instance().HackLog("DEVIL_TOWER_REFINE_HACK", ch);
  3183. }
  3184. else
  3185. {
  3186. if (ch->GetQuestFlag("deviltower_zone.can_refine"))
  3187. {
  3188. ch->DoRefine(item, true);
  3189. ch->SetQuestFlag("deviltower_zone.can_refine", 0);
  3190. }
  3191. else
  3192. {
  3193. ch->ChatPacket(CHAT_TYPE_INFO, "»ç±Í Ÿ¿ö ¿Ï·á º¸»óÀº Çѹø±îÁö »ç¿ë°¡´ÉÇÕ´Ï´Ù.");
  3194. }
  3195. }
  3196. }
  3197. }
  3198.  
  3199. ch->ClearRefineMode();
  3200. }
  3201.  
  3202. #ifdef __SASH_SYSTEM__
  3203. void CInputMain::Sash(LPCHARACTER pkChar, const char* c_pData)
  3204. {
  3205. quest::PC * pPC = quest::CQuestManager::instance().GetPCForce(pkChar->GetPlayerID());
  3206. if (pPC->IsRunning())
  3207. return;
  3208.  
  3209. TPacketSash * sPacket = (TPacketSash*) c_pData;
  3210. switch (sPacket->subheader)
  3211. {
  3212. case SASH_SUBHEADER_CG_CLOSE:
  3213. {
  3214. pkChar->CloseSash();
  3215. }
  3216. break;
  3217. case SASH_SUBHEADER_CG_ADD:
  3218. {
  3219. pkChar->AddSashMaterial(sPacket->tPos, sPacket->bPos);
  3220. }
  3221. break;
  3222. case SASH_SUBHEADER_CG_REMOVE:
  3223. {
  3224. pkChar->RemoveSashMaterial(sPacket->bPos);
  3225. }
  3226. break;
  3227. case SASH_SUBHEADER_CG_REFINE:
  3228. {
  3229. pkChar->RefineSashMaterials();
  3230. }
  3231. break;
  3232. default:
  3233. break;
  3234. }
  3235. }
  3236. #endif
  3237.  
  3238. #ifdef __CHANGELOOK_SYSTEM__
  3239. void CInputMain::ChangeLook(LPCHARACTER pkChar, const char* c_pData)
  3240. {
  3241. quest::PC * pPC = quest::CQuestManager::instance().GetPCForce(pkChar->GetPlayerID());
  3242. if (pPC->IsRunning())
  3243. return;
  3244.  
  3245. TPacketChangeLook * sPacket = (TPacketChangeLook*) c_pData;
  3246. switch (sPacket->subheader)
  3247. {
  3248. case CL_SUBHEADER_CLOSE:
  3249. {
  3250. pkChar->ChangeLookWindow(false);
  3251. }
  3252. break;
  3253. case CL_SUBHEADER_ADD:
  3254. {
  3255. pkChar->AddClMaterial(sPacket->tPos, sPacket->bPos);
  3256. }
  3257. break;
  3258. case CL_SUBHEADER_REMOVE:
  3259. {
  3260. pkChar->RemoveClMaterial(sPacket->bPos);
  3261. }
  3262. break;
  3263. case CL_SUBHEADER_REFINE:
  3264. {
  3265. pkChar->RefineClMaterials();
  3266. }
  3267. break;
  3268. default:
  3269. break;
  3270. }
  3271. }
  3272. #endif
  3273.  
  3274. int CInputMain::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
  3275. {
  3276. LPCHARACTER ch;
  3277.  
  3278. if (!(ch = d->GetCharacter()))
  3279. {
  3280. sys_err("no character on desc");
  3281. d->SetPhase(PHASE_CLOSE);
  3282. return (0);
  3283. }
  3284.  
  3285. int iExtraLen = 0;
  3286.  
  3287. if (test_server && bHeader != HEADER_CG_MOVE)
  3288. sys_log(0, "CInputMain::Analyze() ==> Header [%d] ", bHeader);
  3289.  
  3290. switch (bHeader)
  3291. {
  3292. case HEADER_CG_PONG:
  3293. Pong(d);
  3294. break;
  3295.  
  3296. case HEADER_CG_TIME_SYNC:
  3297. Handshake(d, c_pData);
  3298. break;
  3299.  
  3300. case HEADER_CG_CHAT:
  3301. if (test_server)
  3302. {
  3303. char* pBuf = (char*)c_pData;
  3304. sys_log(0, "%s", pBuf + sizeof(TPacketCGChat));
  3305. }
  3306.  
  3307. if ((iExtraLen = Chat(ch, c_pData, m_iBufferLeft)) < 0)
  3308. return -1;
  3309. break;
  3310.  
  3311. case HEADER_CG_WHISPER:
  3312. if ((iExtraLen = Whisper(ch, c_pData, m_iBufferLeft)) < 0)
  3313. return -1;
  3314. break;
  3315.  
  3316. case HEADER_CG_MOVE:
  3317. Move(ch, c_pData);
  3318. // @fixme103 (removed CheckClientVersion since useless in here)
  3319. break;
  3320.  
  3321. case HEADER_CG_CHARACTER_POSITION:
  3322. Position(ch, c_pData);
  3323. break;
  3324.  
  3325. case HEADER_CG_ITEM_USE:
  3326. if (!ch->IsObserverMode())
  3327. ItemUse(ch, c_pData);
  3328. break;
  3329.  
  3330. case HEADER_CG_ITEM_DROP:
  3331. if (!ch->IsObserverMode())
  3332. {
  3333. ItemDrop(ch, c_pData);
  3334. }
  3335. break;
  3336.  
  3337. case HEADER_CG_ITEM_DROP2:
  3338. if (!ch->IsObserverMode())
  3339. ItemDrop2(ch, c_pData);
  3340. break;
  3341.  
  3342. case HEADER_CG_ITEM_DESTROY:
  3343. if (!ch->IsObserverMode())
  3344. ItemDestroy(ch, c_pData);
  3345. break;
  3346.  
  3347. case HEADER_CG_ITEM_MOVE:
  3348. if (!ch->IsObserverMode())
  3349. ItemMove(ch, c_pData);
  3350. break;
  3351.  
  3352. #ifdef NEW_ADD_INVENTORY
  3353. case ENVANTER_BLACK:
  3354. if (!ch->IsObserverMode())
  3355. Envanter_pakettiii(ch, c_pData);
  3356. break;
  3357. #endif
  3358.  
  3359. case HEADER_CG_ITEM_PICKUP:
  3360. if (!ch->IsObserverMode())
  3361. ItemPickup(ch, c_pData);
  3362. break;
  3363.  
  3364. case HEADER_CG_ITEM_USE_TO_ITEM:
  3365. if (!ch->IsObserverMode())
  3366. ItemToItem(ch, c_pData);
  3367. break;
  3368.  
  3369. case HEADER_CG_ITEM_GIVE:
  3370. if (!ch->IsObserverMode())
  3371. ItemGive(ch, c_pData);
  3372. break;
  3373.  
  3374. case HEADER_CG_EXCHANGE:
  3375. if (!ch->IsObserverMode())
  3376. Exchange(ch, c_pData);
  3377. break;
  3378.  
  3379. case HEADER_CG_ATTACK:
  3380. case HEADER_CG_SHOOT:
  3381. if (!ch->IsObserverMode())
  3382. {
  3383. Attack(ch, bHeader, c_pData);
  3384. }
  3385. break;
  3386.  
  3387. case HEADER_CG_USE_SKILL:
  3388. if (!ch->IsObserverMode())
  3389. UseSkill(ch, c_pData);
  3390. break;
  3391.  
  3392. case HEADER_CG_QUICKSLOT_ADD:
  3393. QuickslotAdd(ch, c_pData);
  3394. break;
  3395.  
  3396. case HEADER_CG_QUICKSLOT_DEL:
  3397. QuickslotDelete(ch, c_pData);
  3398. break;
  3399.  
  3400. case HEADER_CG_QUICKSLOT_SWAP:
  3401. QuickslotSwap(ch, c_pData);
  3402. break;
  3403.  
  3404. case HEADER_CG_SHOP:
  3405. if ((iExtraLen = Shop(ch, c_pData, m_iBufferLeft)) < 0)
  3406. return -1;
  3407. break;
  3408.  
  3409. case HEADER_CG_MESSENGER:
  3410. if ((iExtraLen = Messenger(ch, c_pData, m_iBufferLeft))<0)
  3411. return -1;
  3412. break;
  3413.  
  3414. case HEADER_CG_ON_CLICK:
  3415. OnClick(ch, c_pData);
  3416. break;
  3417.  
  3418. case HEADER_CG_SYNC_POSITION:
  3419. if ((iExtraLen = SyncPosition(ch, c_pData, m_iBufferLeft)) < 0)
  3420. return -1;
  3421. break;
  3422.  
  3423. case HEADER_CG_ADD_FLY_TARGETING:
  3424. case HEADER_CG_FLY_TARGETING:
  3425. FlyTarget(ch, c_pData, bHeader);
  3426. break;
  3427.  
  3428. case HEADER_CG_SCRIPT_BUTTON:
  3429. ScriptButton(ch, c_pData);
  3430. break;
  3431.  
  3432. // SCRIPT_SELECT_ITEM
  3433. case HEADER_CG_SCRIPT_SELECT_ITEM:
  3434. ScriptSelectItem(ch, c_pData);
  3435. break;
  3436. // END_OF_SCRIPT_SELECT_ITEM
  3437.  
  3438. case HEADER_CG_SCRIPT_ANSWER:
  3439. ScriptAnswer(ch, c_pData);
  3440. break;
  3441.  
  3442. case HEADER_CG_QUEST_INPUT_STRING:
  3443. QuestInputString(ch, c_pData);
  3444. break;
  3445.  
  3446. case HEADER_CG_QUEST_CONFIRM:
  3447. QuestConfirm(ch, c_pData);
  3448. break;
  3449.  
  3450. case HEADER_CG_TARGET:
  3451. Target(ch, c_pData);
  3452. break;
  3453.  
  3454. case HEADER_CG_WARP:
  3455. Warp(ch, c_pData);
  3456. break;
  3457.  
  3458. case HEADER_CG_SAFEBOX_CHECKIN:
  3459. SafeboxCheckin(ch, c_pData);
  3460. break;
  3461.  
  3462. case HEADER_CG_SAFEBOX_CHECKOUT:
  3463. SafeboxCheckout(ch, c_pData, false);
  3464. break;
  3465.  
  3466. case HEADER_CG_SAFEBOX_ITEM_MOVE:
  3467. SafeboxItemMove(ch, c_pData);
  3468. break;
  3469.  
  3470. case HEADER_CG_MALL_CHECKOUT:
  3471. SafeboxCheckout(ch, c_pData, true);
  3472. break;
  3473.  
  3474. case HEADER_CG_PARTY_INVITE:
  3475. PartyInvite(ch, c_pData);
  3476. break;
  3477.  
  3478. case HEADER_CG_PARTY_REMOVE:
  3479. PartyRemove(ch, c_pData);
  3480. break;
  3481.  
  3482. case HEADER_CG_PARTY_INVITE_ANSWER:
  3483. PartyInviteAnswer(ch, c_pData);
  3484. break;
  3485.  
  3486. case HEADER_CG_PARTY_SET_STATE:
  3487. PartySetState(ch, c_pData);
  3488. break;
  3489.  
  3490. case HEADER_CG_PARTY_USE_SKILL:
  3491. PartyUseSkill(ch, c_pData);
  3492. break;
  3493.  
  3494. case HEADER_CG_PARTY_PARAMETER:
  3495. PartyParameter(ch, c_pData);
  3496. break;
  3497.  
  3498. case HEADER_CG_ANSWER_MAKE_GUILD:
  3499. #ifdef ENABLE_NEWGUILDMAKE
  3500. ch->ChatPacket(CHAT_TYPE_INFO, "<%s> AnswerMakeGuild disabled", __FUNCTION__);
  3501. #else
  3502. AnswerMakeGuild(ch, c_pData);
  3503. #endif
  3504. break;
  3505.  
  3506. case HEADER_CG_GUILD:
  3507. if ((iExtraLen = Guild(ch, c_pData, m_iBufferLeft)) < 0)
  3508. return -1;
  3509. break;
  3510.  
  3511. case HEADER_CG_FISHING:
  3512. Fishing(ch, c_pData);
  3513. break;
  3514.  
  3515. case HEADER_CG_HACK:
  3516. Hack(ch, c_pData);
  3517. break;
  3518.  
  3519. case HEADER_CG_MYSHOP:
  3520. if ((iExtraLen = MyShop(ch, c_pData, m_iBufferLeft)) < 0)
  3521. return -1;
  3522. break;
  3523.  
  3524. case HEADER_CG_REFINE:
  3525. Refine(ch, c_pData);
  3526. break;
  3527. #ifdef ENABLE_SHOW_CHEST_DROP
  3528. case HEADER_CG_CHEST_DROP_INFO:
  3529. ChestDropInfo(ch, c_pData);
  3530. break;
  3531. #endif
  3532.  
  3533. #ifdef __CHANGELOOK_SYSTEM__
  3534. case HEADER_CG_CL:
  3535. {
  3536. ChangeLook(ch, c_pData);
  3537. }
  3538. break;
  3539. #endif
  3540.  
  3541. #ifdef __SASH_SYSTEM__
  3542. case HEADER_CG_SASH:
  3543. {
  3544. Sash(ch, c_pData);
  3545. }
  3546. break;
  3547. #endif
  3548.  
  3549. case HEADER_CG_CLIENT_VERSION:
  3550. Version(ch, c_pData);
  3551. break;
  3552.  
  3553. case HEADER_CG_HS_ACK:
  3554. if (isHackShieldEnable)
  3555. {
  3556. CHackShieldManager::instance().VerifyAck(d->GetCharacter(), c_pData);
  3557. }
  3558. break;
  3559.  
  3560. case HEADER_CG_XTRAP_ACK:
  3561. {
  3562. TPacketXTrapCSVerify* p = reinterpret_cast<TPacketXTrapCSVerify*>((void*)c_pData);
  3563. CXTrapManager::instance().Verify_CSStep3(d->GetCharacter(), p->bPacketData);
  3564. }
  3565. break;
  3566. #ifdef __SEND_TARGET_INFO__
  3567. case HEADER_CG_TARGET_INFO_LOAD:
  3568. {
  3569. TargetInfoLoad(ch, c_pData);
  3570. }
  3571. break;
  3572. #endif
  3573. case HEADER_CG_DRAGON_SOUL_REFINE:
  3574. {
  3575. TPacketCGDragonSoulRefine* p = reinterpret_cast <TPacketCGDragonSoulRefine*>((void*)c_pData);
  3576. switch(p->bSubType)
  3577. {
  3578. case DS_SUB_HEADER_CLOSE:
  3579. ch->DragonSoul_RefineWindow_Close();
  3580. break;
  3581. case DS_SUB_HEADER_DO_REFINE_GRADE:
  3582. {
  3583. DSManager::instance().DoRefineGrade(ch, p->ItemGrid);
  3584. }
  3585. break;
  3586. case DS_SUB_HEADER_DO_REFINE_STEP:
  3587. {
  3588. DSManager::instance().DoRefineStep(ch, p->ItemGrid);
  3589. }
  3590. break;
  3591. case DS_SUB_HEADER_DO_REFINE_STRENGTH:
  3592. {
  3593. DSManager::instance().DoRefineStrength(ch, p->ItemGrid);
  3594. }
  3595. break;
  3596. }
  3597. }
  3598.  
  3599. break;
  3600. }
  3601. return (iExtraLen);
  3602. }
  3603.  
  3604. int CInputDead::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
  3605. {
  3606. LPCHARACTER ch;
  3607.  
  3608. if (!(ch = d->GetCharacter()))
  3609. {
  3610. sys_err("no character on desc");
  3611. return 0;
  3612. }
  3613.  
  3614. int iExtraLen = 0;
  3615.  
  3616. switch (bHeader)
  3617. {
  3618. case HEADER_CG_PONG:
  3619. Pong(d);
  3620. break;
  3621.  
  3622. case HEADER_CG_TIME_SYNC:
  3623. Handshake(d, c_pData);
  3624. break;
  3625.  
  3626. case HEADER_CG_CHAT:
  3627. if ((iExtraLen = Chat(ch, c_pData, m_iBufferLeft)) < 0)
  3628. return -1;
  3629.  
  3630. break;
  3631.  
  3632. case HEADER_CG_WHISPER:
  3633. if ((iExtraLen = Whisper(ch, c_pData, m_iBufferLeft)) < 0)
  3634. return -1;
  3635.  
  3636. break;
  3637.  
  3638. case HEADER_CG_HACK:
  3639. Hack(ch, c_pData);
  3640. break;
  3641.  
  3642. default:
  3643. return (0);
  3644. }
  3645.  
  3646. return (iExtraLen);
  3647. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement