Advertisement
Guest User

Untitled

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