Advertisement
SergiuAndreiM

input_main.cpp

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