Advertisement
Wered

Untitled

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