Guest User

Untitled

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