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

INPUT_MAIN.CPP