SHARE
TWEET

clientmanagerplayer.cpp

a guest Mar 20th, 2019 85 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include "stdafx.h"
  3.  
  4. #include "ClientManager.h"
  5.  
  6. #include "Main.h"
  7. #include "QID.h"
  8. #include "ItemAwardManager.h"
  9. #include "HB.h"
  10. #include "Cache.h"
  11.  
  12. extern bool g_bHotBackup;
  13.  
  14. extern std::string g_stLocale;
  15. extern int g_test_server;
  16. extern int g_log;
  17.  
  18. bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DWORD dwPID)
  19. {
  20.     if (!res)
  21.     {
  22.         pVec->clear();
  23.         return true;
  24.     }
  25.  
  26.     int rows;
  27.  
  28.     if ((rows = mysql_num_rows(res)) <= 0)  // ๋ฐ์ดํ„ฐ ์—†์Œ
  29.     {
  30.         pVec->clear();
  31.         return true;
  32.     }
  33.  
  34.     pVec->resize(rows);
  35.  
  36.     for (int i = 0; i < rows; ++i)
  37.     {
  38.         MYSQL_ROW row = mysql_fetch_row(res);
  39.         TPlayerItem & item = pVec->at(i);
  40.  
  41.         int cur = 0;
  42.  
  43.         // Check all SELECT syntax on item table before change this function!!!
  44.         // Check all SELECT syntax on item table before change this function!!!
  45.         // Check all SELECT syntax on item table before change this function!!!
  46.         str_to_number(item.id, row[cur++]);
  47.         str_to_number(item.window, row[cur++]);
  48.         str_to_number(item.pos, row[cur++]);
  49.         str_to_number(item.count, row[cur++]);
  50.         str_to_number(item.vnum, row[cur++]);
  51.         str_to_number(item.alSockets[0], row[cur++]);
  52.         str_to_number(item.alSockets[1], row[cur++]);
  53.         str_to_number(item.alSockets[2], row[cur++]);
  54.  
  55.         for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++)
  56.         {
  57.             str_to_number(item.aAttr[j].bType, row[cur++]);
  58.             str_to_number(item.aAttr[j].sValue, row[cur++]);
  59.         }
  60.  
  61.         item.owner      = dwPID;
  62.     }
  63.  
  64.     return true;
  65. }
  66.  
  67. size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * pkTab)
  68. {
  69.     size_t queryLen;
  70.     queryLen = snprintf(pszQuery, querySize,
  71.             "UPDATE player%s SET "
  72.             "job = %d, "
  73.             "voice = %d, "
  74.             "dir = %d, "
  75.             "x = %d, "
  76.             "y = %d, "
  77.             "z = %d, "
  78.             "map_index = %d, "
  79.             "exit_x = %ld, "
  80.             "exit_y = %ld, "
  81.             "exit_map_index = %ld, "
  82.             "hp = %d, "
  83.             "mp = %d, "
  84.             "stamina = %d, "
  85.             "random_hp = %d, "
  86.             "random_sp = %d, "
  87.             "playtime = %d, "
  88.             "level = %d, "
  89.             "level_step = %d, "
  90.             "st = %d, "
  91.             "ht = %d, "
  92.             "dx = %d, "
  93.             "iq = %d, "
  94.             "gold = %lld, "
  95.             "exp = %u, "
  96.             "stat_point = %d, "
  97.             "skill_point = %d, "
  98.             "sub_skill_point = %d, "
  99.             "stat_reset_count = %d, "
  100.             "ip = '%s', "
  101.             "part_main = %d, "
  102.             "part_hair = %d, "
  103.             "part_sash = %d, "
  104.             "last_play = NOW(), "
  105.             "skill_group = %d, "
  106.             "alignment = %ld, "
  107.             "horse_level = %d, "
  108.             "horse_riding = %d, "
  109.             "horse_hp = %d, "
  110.             "horse_hp_droptime = %u, "
  111.             "horse_stamina = %d, "
  112.             "horse_skill_point = %d, "
  113. #ifdef __TITLE_SYSTEM__
  114.             "t_choosed = %d, "
  115.             "t_available = '%s', "
  116. #endif
  117.         , GetTablePostfix(),
  118.         pkTab->job,
  119.         pkTab->voice,
  120.         pkTab->dir,
  121.         pkTab->x,
  122.         pkTab->y,
  123.         pkTab->z,
  124.         pkTab->lMapIndex,
  125.         pkTab->lExitX,
  126.         pkTab->lExitY,
  127.         pkTab->lExitMapIndex,
  128.         pkTab->hp,
  129.         pkTab->sp,
  130.         pkTab->stamina,
  131.         pkTab->sRandomHP,
  132.         pkTab->sRandomSP,
  133.         pkTab->playtime,
  134.         pkTab->level,
  135.         pkTab->level_step,
  136.         pkTab->st,
  137.         pkTab->ht,
  138.         pkTab->dx,
  139.         pkTab->iq,
  140.         pkTab->gold,
  141.         pkTab->exp,
  142.         pkTab->stat_point,
  143.         pkTab->skill_point,
  144.         pkTab->sub_skill_point,
  145.         pkTab->stat_reset_count,
  146.         pkTab->ip,
  147.         pkTab->parts[PART_MAIN],
  148.         pkTab->parts[PART_HAIR],
  149.         pkTab->parts[PART_SASH],
  150.         pkTab->skill_group,
  151.         pkTab->lAlignment,
  152.         pkTab->horse.bLevel,
  153.         pkTab->horse.bRiding,
  154.         pkTab->horse.sHealth,
  155.         pkTab->horse.dwHorseHealthDropTime,
  156.         pkTab->horse.sStamina,
  157.         pkTab->horse_skill_point
  158. #ifdef __TITLE_SYSTEM__
  159.         ,pkTab->iTChoosed
  160.         ,pkTab->cTAvailable
  161. #endif
  162.         );
  163.    
  164.     static char text[8192 + 1];
  165.     CDBManager::instance().EscapeString(text, pkTab->skills, sizeof(pkTab->skills));
  166.     queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, "skill_level = '%s', ", text);
  167.    
  168.     CDBManager::instance().EscapeString(text, pkTab->quickslot, sizeof(pkTab->quickslot));
  169.     queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, "quickslot = '%s' ", text);
  170.    
  171.     queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, " WHERE id=%d", pkTab->id);
  172.     return queryLen;
  173. }
  174.  
  175. CPlayerTableCache * CClientManager::GetPlayerCache(DWORD id)
  176. {
  177.     TPlayerTableCacheMap::iterator it = m_map_playerCache.find(id);
  178.  
  179.     if (it == m_map_playerCache.end())
  180.         return NULL;
  181.  
  182.     TPlayerTable* pTable = it->second->Get(false);
  183.     pTable->logoff_interval = GetCurrentTime() - it->second->GetLastUpdateTime();
  184.     return it->second;
  185. }
  186.  
  187. void CClientManager::PutPlayerCache(TPlayerTable * pNew)
  188. {
  189.     CPlayerTableCache * c;
  190.  
  191.     c = GetPlayerCache(pNew->id);
  192.  
  193.     if (!c)
  194.     {
  195.         c = new CPlayerTableCache;
  196.         m_map_playerCache.insert(TPlayerTableCacheMap::value_type(pNew->id, c));
  197.     }
  198.  
  199.     if (g_bHotBackup)
  200.         PlayerHB::instance().Put(pNew->id);
  201.  
  202.     c->Put(pNew);
  203. }
  204.  
  205. /*
  206.  * PLAYER LOAD
  207.  */
  208. void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket * packet)
  209. {
  210.     CPlayerTableCache * c;
  211.     TPlayerTable * pTab;
  212.    
  213.     //
  214.     // ํ•œ ๊ณ„์ •์— ์†ํ•œ ๋ชจ๋“  ์บ๋ฆญํ„ฐ๋“ค ์บ์‰ฌ์ฒ˜๋ฆฌ
  215.     //
  216.     CLoginData * pLoginData = GetLoginDataByAID(packet->account_id);
  217.  
  218.     if (pLoginData)
  219.     {
  220.         for (int n = 0; n < PLAYER_PER_ACCOUNT; ++n)
  221.             if (pLoginData->GetAccountRef().players[n].dwID != 0)
  222.                 DeleteLogoutPlayer(pLoginData->GetAccountRef().players[n].dwID);
  223.     }
  224.  
  225.     //----------------------------------------------------------------
  226.     // 1. ์œ ์ €์ •๋ณด๊ฐ€ DBCache ์— ์กด์žฌ : DBCache์—์„œ
  227.     // 2. ์œ ์ €์ •๋ณด๊ฐ€ DBCache ์— ์—†์Œ : DB์—์„œ
  228.     // ---------------------------------------------------------------
  229.    
  230.     //----------------------------------
  231.     // 1. ์œ ์ €์ •๋ณด๊ฐ€ DBCache ์— ์กด์žฌ : DBCache์—์„œ
  232.     //----------------------------------
  233.     if ((c = GetPlayerCache(packet->player_id)))
  234.     {
  235.         CLoginData * pkLD = GetLoginDataByAID(packet->account_id);
  236.  
  237.         if (!pkLD || pkLD->IsPlay())
  238.         {
  239.             sys_log(0, "PLAYER_LOAD_ERROR: LoginData %p IsPlay %d", pkLD, pkLD ? pkLD->IsPlay() : 0);
  240.             peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, dwHandle, 0);
  241.             return;
  242.         }
  243.  
  244.         pTab = c->Get();
  245.  
  246.         pkLD->SetPlay(true);
  247.         SendLoginToBilling(pkLD, true);
  248.         thecore_memcpy(pTab->aiPremiumTimes, pkLD->GetPremiumPtr(), sizeof(pTab->aiPremiumTimes));
  249.  
  250.         peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_SUCCESS, dwHandle, sizeof(TPlayerTable));
  251.         peer->Encode(pTab, sizeof(TPlayerTable));
  252.  
  253.         if (packet->player_id != pkLD->GetLastPlayerID())
  254.         {
  255.             TPacketNeedLoginLogInfo logInfo;
  256.             logInfo.dwPlayerID = packet->player_id;
  257.  
  258.             pkLD->SetLastPlayerID( packet->player_id );
  259.  
  260.             peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, dwHandle, sizeof(TPacketNeedLoginLogInfo) );
  261.             peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) );
  262.         }
  263.  
  264.         char szQuery[1024] = { 0, };
  265.  
  266.         TItemCacheSet * pSet = GetItemCacheSet(pTab->id);
  267.  
  268.         sys_log(0, "[PLAYER_LOAD] ID %s pid %d gold %lld ", pTab->name, pTab->id, pTab->gold);
  269.  
  270.         //--------------------------------------------
  271.         // ์•„์ดํ…œ & AFFECT & QUEST ๋กœ๋”ฉ :
  272.         //--------------------------------------------
  273.         // 1) ์•„์ดํ…œ์ด DBCache ์— ์กด์žฌ : DBCache ์—์„œ ๊ฐ€์ ธ์˜ด
  274.         // 2) ์•„์ดํ…œ์ด DBCache ์— ์—†์Œ : DB ์—์„œ ๊ฐ€์ ธ์˜ด
  275.  
  276.         /////////////////////////////////////////////
  277.         // 1) ์•„์ดํ…œ์ด DBCache ์— ์กด์žฌ : DBCache ์—์„œ ๊ฐ€์ ธ์˜ด
  278.         /////////////////////////////////////////////
  279.         if (pSet)
  280.         {
  281.             static std::vector<TPlayerItem> s_items;
  282.             s_items.resize(pSet->size());
  283.  
  284.             DWORD dwCount = 0;
  285.             TItemCacheSet::iterator it = pSet->begin();
  286.  
  287.             while (it != pSet->end())
  288.             {
  289.                 CItemCache * c = *it++;
  290.                 TPlayerItem * p = c->Get();
  291.  
  292.                 if (p->vnum) // vnum์ด ์—†์œผ๋ฉด ์‚ญ์ œ๋œ ์•„์ดํ…œ์ด๋‹ค.
  293.                     thecore_memcpy(&s_items[dwCount++], p, sizeof(TPlayerItem));
  294.             }
  295.  
  296.             if (g_test_server)
  297.                 sys_log(0, "ITEM_CACHE: HIT! %s count: %u", pTab->name, dwCount);
  298.  
  299.             peer->EncodeHeader(HEADER_DG_ITEM_LOAD, dwHandle, sizeof(DWORD) + sizeof(TPlayerItem) * dwCount);
  300.             peer->EncodeDWORD(dwCount);
  301.  
  302.             if (dwCount)
  303.                 peer->Encode(&s_items[0], sizeof(TPlayerItem) * dwCount);
  304.  
  305.             // Quest
  306.             snprintf(szQuery, sizeof(szQuery),
  307.                     "SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d AND lValue<>0",
  308.                     GetTablePostfix(), pTab->id);
  309.            
  310.             CDBManager::instance().ReturnQuery(szQuery, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle,0,packet->account_id));
  311.  
  312.             // Affect
  313.             snprintf(szQuery, sizeof(szQuery),
  314.                     "SELECT dwPID,bType,bApplyOn,lApplyValue,dwFlag,lDuration,lSPCost FROM affect%s WHERE dwPID=%d",
  315.                     GetTablePostfix(), pTab->id);
  316.             CDBManager::instance().ReturnQuery(szQuery, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle));
  317.         }
  318.         /////////////////////////////////////////////
  319.         // 2) ์•„์ดํ…œ์ด DBCache ์— ์—†์Œ : DB ์—์„œ ๊ฐ€์ ธ์˜ด
  320.         /////////////////////////////////////////////
  321.         else
  322.         {
  323.             snprintf(szQuery, sizeof(szQuery),
  324.                     "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
  325.                     "FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)",
  326.                     GetTablePostfix(), pTab->id, SAFEBOX, DRAGON_SOUL_INVENTORY);
  327.  
  328.             CDBManager::instance().ReturnQuery(szQuery,
  329.                     QID_ITEM,
  330.                     peer->GetHandle(),
  331.                     new ClientHandleInfo(dwHandle, pTab->id));
  332.             snprintf(szQuery, sizeof(szQuery),
  333.                     "SELECT dwPID, szName, szState, lValue FROM quest%s WHERE dwPID=%d",
  334.                     GetTablePostfix(), pTab->id);
  335.  
  336.             CDBManager::instance().ReturnQuery(szQuery,
  337.                     QID_QUEST,
  338.                     peer->GetHandle(),
  339.                     new ClientHandleInfo(dwHandle, pTab->id));
  340.             snprintf(szQuery, sizeof(szQuery),
  341.                     "SELECT dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost FROM affect%s WHERE dwPID=%d",
  342.                     GetTablePostfix(), pTab->id);
  343.  
  344.             CDBManager::instance().ReturnQuery(szQuery,
  345.                     QID_AFFECT,
  346.                     peer->GetHandle(),
  347.                     new ClientHandleInfo(dwHandle, pTab->id));
  348.         }
  349.         //return;
  350.     }
  351.     else
  352.     {
  353.         sys_log(0, "[PLAYER_LOAD] Load from PlayerDB pid[%d]", packet->player_id);
  354.  
  355.         char queryStr[QUERY_MAX_LEN];
  356.  
  357.         snprintf(queryStr, sizeof(queryStr),
  358.                 "SELECT "
  359.                 "id, "
  360.                 "name, "
  361.                 "job, "
  362.                 "voice, "
  363.                 "dir, "
  364.                 "x, "
  365.                 "y, "
  366.                 "z, "
  367.                 "map_index, "
  368.                 "exit_x, "
  369.                 "exit_y, "
  370.                 "exit_map_index, "
  371.                 "hp, "
  372.                 "mp, "
  373.                 "stamina, "
  374.                 "random_hp, "
  375.                 "random_sp, "
  376.                 "playtime, "
  377.                 "gold, "
  378.                 "level, "
  379.                 "level_step, "
  380.                 "st, "
  381.                 "ht, "
  382.                 "dx, "
  383.                 "iq, "
  384.                 "exp, "
  385.                 "stat_point, "
  386.                 "skill_point, "
  387.                 "sub_skill_point, "
  388.                 "stat_reset_count, "
  389.                 "part_base, "
  390.                 "part_hair, "
  391.                 "part_sash, "
  392.                 "skill_level, "
  393.                 "quickslot, "
  394.                 "skill_group, "
  395.                 "alignment, "
  396.                 "mobile, "
  397.                 "horse_level, "
  398.                 "horse_riding, "
  399.                 "horse_hp, "
  400.                 "horse_hp_droptime, "
  401.                 "horse_stamina, "
  402.                 "UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play), "
  403.                 "horse_skill_point "
  404. #ifdef __TITLE_SYSTEM__
  405.                 ",t_choosed "
  406.                 ",t_available "
  407. #endif
  408.                 "FROM player%s WHERE id=%d", GetTablePostfix(), packet->player_id);
  409.  
  410.         ClientHandleInfo * pkInfo = new ClientHandleInfo(dwHandle, packet->player_id);
  411.         pkInfo->account_id = packet->account_id;
  412.         CDBManager::instance().ReturnQuery(queryStr, QID_PLAYER, peer->GetHandle(), pkInfo);
  413.  
  414.         //--------------------------------------------------------------
  415.         // ์•„์ดํ…œ ๊ฐ€์ ธ์˜ค๊ธฐ
  416.         //--------------------------------------------------------------
  417.         snprintf(queryStr, sizeof(queryStr),
  418.                 "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
  419.                 "FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)",
  420.                 GetTablePostfix(), packet->player_id, SAFEBOX, DRAGON_SOUL_INVENTORY);
  421.         CDBManager::instance().ReturnQuery(queryStr, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id));
  422.  
  423.         //--------------------------------------------------------------
  424.         // QUEST ๊ฐ€์ ธ์˜ค๊ธฐ
  425.         //--------------------------------------------------------------
  426.         snprintf(queryStr, sizeof(queryStr),
  427.                 "SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d",
  428.                 GetTablePostfix(), packet->player_id);
  429.         CDBManager::instance().ReturnQuery(queryStr, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id,packet->account_id));
  430.         //๋…์ผ ์„ ๋ฌผ ๊ธฐ๋Šฅ์—์„œ item_awardํ…Œ์ด๋ธ”์—์„œ login ์ •๋ณด๋ฅผ ์–ป๊ธฐ์œ„ํ•ด account id๋„ ๋„˜๊ฒจ์ค€๋‹ค
  431.         //--------------------------------------------------------------
  432.         // AFFECT ๊ฐ€์ ธ์˜ค๊ธฐ
  433.         //--------------------------------------------------------------
  434.         snprintf(queryStr, sizeof(queryStr),
  435.                 "SELECT dwPID,bType,bApplyOn,lApplyValue,dwFlag,lDuration,lSPCost FROM affect%s WHERE dwPID=%d",
  436.                 GetTablePostfix(), packet->player_id);
  437.         CDBManager::instance().ReturnQuery(queryStr, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id));
  438.     }
  439.    
  440.    
  441. }
  442. void CClientManager::ItemAward(CPeer * peer,char* login)
  443. {
  444.     char login_t[LOGIN_MAX_LEN + 1] = "";
  445.     strlcpy(login_t,login,LOGIN_MAX_LEN + 1);  
  446.     std::set<TItemAward *> * pSet = ItemAwardManager::instance().GetByLogin(login_t);  
  447.     if(pSet == NULL)
  448.         return;
  449.     typeof(pSet->begin()) it = pSet->begin();   //taken_time์ด NULL์ธ๊ฒƒ๋“ค ์ฝ์–ด์˜ด
  450.     while(it != pSet->end() )
  451.     {              
  452.         TItemAward * pItemAward = *(it++);     
  453.         char* whyStr = pItemAward->szWhy;   //why ์ฝœ๋ฃธ ์ฝ๊ธฐ
  454.         char cmdStr[100] = "";  //why์ฝœ๋ฃธ์—์„œ ์ฝ์€ ๊ฐ’์„ ์ž„์‹œ ๋ฌธ์ž์—ด์— ๋ณต์‚ฌํ•ด๋‘ 
  455.         strcpy(cmdStr,whyStr);  //๋ช…๋ น์–ด ์–ป๋Š” ๊ณผ์ •์—์„œ ํ† ํฐ์“ฐ๋ฉด ์›๋ณธ๋„ ํ† ํฐํ™” ๋˜๊ธฐ ๋•Œ๋ฌธ
  456.         char command[20] = "";
  457.         strcpy(command,GetCommand(cmdStr)); // command ์–ป๊ธฐ      
  458.         if( !(strcmp(command,"GIFT") )) // command ๊ฐ€ GIFT์ด๋ฉด
  459.         {
  460.             TPacketItemAwardInfromer giftData;
  461.             strcpy(giftData.login, pItemAward->szLogin);    //๋กœ๊ทธ์ธ ์•„์ด๋”” ๋ณต์‚ฌ
  462.             strcpy(giftData.command, command);                  //๋ช…๋ น์–ด ๋ณต์‚ฌ
  463.             giftData.vnum = pItemAward->dwVnum;             //์•„์ดํ…œ vnum๋„ ๋ณต์‚ฌ
  464.             ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
  465.         }
  466.     }
  467. }
  468. char* CClientManager::GetCommand(char* str)
  469. {
  470.     static char command[20] = "";
  471.     char* tok;
  472.  
  473.     if( str[0] == '[' )
  474.     {
  475.         tok = strtok(str,"]");         
  476.         strcat(command,&tok[1]);       
  477.     }
  478.  
  479.     return command;
  480. }
  481.  
  482. bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab)
  483. {
  484.     if (mysql_num_rows(res) == 0)   // ๋ฐ์ดํ„ฐ ์—†์Œ
  485.         return false;
  486.  
  487.     memset(pkTab, 0, sizeof(TPlayerTable));
  488.  
  489.     MYSQL_ROW row = mysql_fetch_row(res);
  490.  
  491.     int col = 0;
  492.  
  493.     // "id,name,job,voice,dir,x,y,z,map_index,exit_x,exit_y,exit_map_index,hp,mp,stamina,random_hp,random_sp,playtime,"
  494.     // "gold,level,level_step,st,ht,dx,iq,exp,"
  495.     // "stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair,"
  496.     // "skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_stamina FROM player%s WHERE id=%d",
  497.     str_to_number(pkTab->id, row[col++]);
  498.     strlcpy(pkTab->name, row[col++], sizeof(pkTab->name));
  499.     str_to_number(pkTab->job, row[col++]);
  500.     str_to_number(pkTab->voice, row[col++]);
  501.     str_to_number(pkTab->dir, row[col++]);
  502.     str_to_number(pkTab->x, row[col++]);
  503.     str_to_number(pkTab->y, row[col++]);
  504.     str_to_number(pkTab->z, row[col++]);
  505.     str_to_number(pkTab->lMapIndex, row[col++]);
  506.     str_to_number(pkTab->lExitX, row[col++]);
  507.     str_to_number(pkTab->lExitY, row[col++]);
  508.     str_to_number(pkTab->lExitMapIndex,  row[col++]);
  509.     str_to_number(pkTab->hp, row[col++]);
  510.     str_to_number(pkTab->sp, row[col++]);
  511.     str_to_number(pkTab->stamina, row[col++]);
  512.     str_to_number(pkTab->sRandomHP, row[col++]);
  513.     str_to_number(pkTab->sRandomSP, row[col++]);
  514.     str_to_number(pkTab->playtime, row[col++]);
  515.     str_to_number(pkTab->gold, row[col++]);
  516.     str_to_number(pkTab->level, row[col++]);
  517.     str_to_number(pkTab->level_step, row[col++]);
  518.     str_to_number(pkTab->st, row[col++]);
  519.     str_to_number(pkTab->ht, row[col++]);
  520.     str_to_number(pkTab->dx, row[col++]);
  521.     str_to_number(pkTab->iq, row[col++]);
  522.     str_to_number(pkTab->exp, row[col++]);
  523.     str_to_number(pkTab->stat_point, row[col++]);
  524.     str_to_number(pkTab->skill_point, row[col++]);
  525.     str_to_number(pkTab->sub_skill_point, row[col++]);
  526.     str_to_number(pkTab->stat_reset_count, row[col++]);
  527.     str_to_number(pkTab->part_base, row[col++]);
  528.     str_to_number(pkTab->parts[PART_HAIR], row[col++]);
  529.     str_to_number(pkTab->parts[PART_SASH], row[col++]);
  530.  
  531.     if (row[col])
  532.         thecore_memcpy(pkTab->skills, row[col], sizeof(pkTab->skills));
  533.     else
  534.         memset(&pkTab->skills, 0, sizeof(pkTab->skills));
  535.  
  536.     col++;
  537.  
  538.     if (row[col])
  539.         thecore_memcpy(pkTab->quickslot, row[col], sizeof(pkTab->quickslot));
  540.     else
  541.         memset(pkTab->quickslot, 0, sizeof(pkTab->quickslot));
  542.  
  543.     col++;
  544.  
  545.     str_to_number(pkTab->skill_group, row[col++]);
  546.     str_to_number(pkTab->lAlignment, row[col++]);
  547.  
  548.     if (row[col])
  549.     {
  550.         strlcpy(pkTab->szMobile, row[col], sizeof(pkTab->szMobile));
  551.     }
  552.  
  553.     col++;
  554.  
  555.     str_to_number(pkTab->horse.bLevel, row[col++]);
  556.     str_to_number(pkTab->horse.bRiding, row[col++]);
  557.     str_to_number(pkTab->horse.sHealth, row[col++]);
  558.     str_to_number(pkTab->horse.dwHorseHealthDropTime, row[col++]);
  559.     str_to_number(pkTab->horse.sStamina, row[col++]);
  560.     str_to_number(pkTab->logoff_interval, row[col++]);
  561.     str_to_number(pkTab->horse_skill_point, row[col++]);
  562.  
  563.     // reset sub_skill_point
  564.     {
  565.         pkTab->skills[123].bLevel = 0; // SKILL_CREATE
  566.  
  567.         if (pkTab->level > 9)
  568.         {
  569.             int max_point = pkTab->level - 9;
  570.  
  571.             int skill_point =
  572.                 MIN(20, pkTab->skills[121].bLevel) +    // SKILL_LEADERSHIP         ํ†ต์†”๋ ฅ
  573.                 MIN(20, pkTab->skills[124].bLevel) +    // SKILL_MINING             ์ฑ„๊ด‘
  574.                 MIN(10, pkTab->skills[131].bLevel) +    // SKILL_HORSE_SUMMON       ๋ง์†Œํ™˜
  575.                 MIN(20, pkTab->skills[141].bLevel) +    // SKILL_ADD_HP             HP๋ณด๊ฐ•
  576.                 MIN(20, pkTab->skills[142].bLevel);     // SKILL_RESIST_PENETRATE   ๊ด€ํ†ต์ €ํ•ญ
  577.  
  578.             pkTab->sub_skill_point = max_point - skill_point;
  579.         }
  580.         else
  581.             pkTab->sub_skill_point = 0;
  582.     }
  583.  
  584.     str_to_number(pkTab->iTChoosed, row[col++]);
  585.     if (row[col])
  586.         strlcpy(pkTab->cTAvailable, row[col], sizeof(pkTab->cTAvailable));
  587.    
  588.     return true;
  589. }
  590.  
  591. void CClientManager::RESULT_COMPOSITE_PLAYER(CPeer * peer, SQLMsg * pMsg, DWORD dwQID)
  592. {
  593.     CQueryInfo * qi = (CQueryInfo *) pMsg->pvUserData;
  594.     std::auto_ptr<ClientHandleInfo> info((ClientHandleInfo *) qi->pvData);
  595.    
  596.     MYSQL_RES * pSQLResult = pMsg->Get()->pSQLResult;
  597.     if (!pSQLResult)
  598.     {
  599.         sys_err("null MYSQL_RES QID %u", dwQID);
  600.         return;
  601.     }
  602.  
  603.     switch (dwQID)
  604.     {
  605.         case QID_PLAYER:
  606.             sys_log(0, "QID_PLAYER %u %u", info->dwHandle, info->player_id);
  607.             RESULT_PLAYER_LOAD(peer, pSQLResult, info.get());
  608.  
  609.             break;
  610.  
  611.         case QID_ITEM:
  612.             sys_log(0, "QID_ITEM %u", info->dwHandle);
  613.             RESULT_ITEM_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
  614.             break;
  615.  
  616.         case QID_QUEST:
  617.             {
  618.                 sys_log(0, "QID_QUEST %u", info->dwHandle);
  619.                 RESULT_QUEST_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
  620.                 //aid์–ป๊ธฐ
  621.                 ClientHandleInfo*  temp1 = info.get();
  622.                 if (temp1 == NULL)
  623.                     break;
  624.                
  625.                 CLoginData* pLoginData1 = GetLoginDataByAID(temp1->account_id); //             
  626.                 //๋…์ผ ์„ ๋ฌผ ๊ธฐ๋Šฅ
  627.                 if( pLoginData1->GetAccountRef().login == NULL)
  628.                     break;
  629.                 if( pLoginData1 == NULL )
  630.                     break;
  631.                 sys_log(0,"info of pLoginData1 before call ItemAwardfunction %d",pLoginData1);
  632.                 ItemAward(peer,pLoginData1->GetAccountRef().login);
  633.             }
  634.             break;
  635.  
  636.         case QID_AFFECT:
  637.             sys_log(0, "QID_AFFECT %u", info->dwHandle);
  638.             RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle);
  639.             break;
  640.             /*
  641.                case QID_PLAYER_ITEM_QUEST_AFFECT:
  642.                sys_log(0, "QID_PLAYER_ITEM_QUEST_AFFECT %u", info->dwHandle);
  643.                RESULT_PLAYER_LOAD(peer, pSQLResult, info->dwHandle);
  644.  
  645.                if (!pMsg->Next())
  646.                {
  647.                sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: ITEM FAILED");
  648.                return;
  649.                }
  650.  
  651.                case QID_ITEM_QUEST_AFFECT:
  652.                sys_log(0, "QID_ITEM_QUEST_AFFECT %u", info->dwHandle);
  653.                RESULT_ITEM_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
  654.  
  655.                if (!pMsg->Next())
  656.                {
  657.                sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: QUEST FAILED");
  658.                return;
  659.                }
  660.  
  661.                case QID_QUEST_AFFECT:
  662.                sys_log(0, "QID_QUEST_AFFECT %u", info->dwHandle);
  663.                RESULT_QUEST_LOAD(peer, pSQLResult, info->dwHandle);
  664.  
  665.                if (!pMsg->Next())
  666.                sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: AFFECT FAILED");
  667.                else
  668.                RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle);
  669.  
  670.                break;
  671.                */
  672.     }
  673.    
  674. }
  675.  
  676. void CClientManager::RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHandleInfo * pkInfo)
  677. {
  678.     TPlayerTable tab;
  679.  
  680.     if (!CreatePlayerTableFromRes(pRes, &tab))
  681.     {
  682.         peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, pkInfo->dwHandle, 0);
  683.         return;
  684.     }
  685.  
  686.     CLoginData * pkLD = GetLoginDataByAID(pkInfo->account_id);
  687.    
  688.     if (!pkLD || pkLD->IsPlay())
  689.     {
  690.         sys_log(0, "PLAYER_LOAD_ERROR: LoginData %p IsPlay %d", pkLD, pkLD ? pkLD->IsPlay() : 0);
  691.         peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, pkInfo->dwHandle, 0);
  692.         return;
  693.     }
  694.  
  695.     pkLD->SetPlay(true);
  696.     SendLoginToBilling(pkLD, true);
  697.     thecore_memcpy(tab.aiPremiumTimes, pkLD->GetPremiumPtr(), sizeof(tab.aiPremiumTimes));
  698.  
  699.     peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_SUCCESS, pkInfo->dwHandle, sizeof(TPlayerTable));
  700.     peer->Encode(&tab, sizeof(TPlayerTable));
  701.  
  702.     if (tab.id != pkLD->GetLastPlayerID())
  703.     {
  704.         TPacketNeedLoginLogInfo logInfo;
  705.         logInfo.dwPlayerID = tab.id;
  706.  
  707.         pkLD->SetLastPlayerID( tab.id );
  708.  
  709.         peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, pkInfo->dwHandle, sizeof(TPacketNeedLoginLogInfo) );
  710.         peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) );
  711.     }
  712. }
  713.  
  714. void CClientManager::RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwPID)
  715. {
  716.     static std::vector<TPlayerItem> s_items;
  717.     //DB์—์„œ ์•„์ดํ…œ ์ •๋ณด๋ฅผ ์ฝ์–ด์˜จ๋‹ค.
  718.     CreateItemTableFromRes(pRes, &s_items, dwPID);
  719.     DWORD dwCount = s_items.size();
  720.  
  721.     peer->EncodeHeader(HEADER_DG_ITEM_LOAD, dwHandle, sizeof(DWORD) + sizeof(TPlayerItem) * dwCount);
  722.     peer->EncodeDWORD(dwCount);
  723.  
  724.     //CacheSet์„ ๋งŒ๋“ ๋‹ค  
  725.     CreateItemCacheSet(dwPID);
  726.  
  727.     // ITEM_LOAD_LOG_ATTACH_PID
  728.     sys_log(0, "ITEM_LOAD: count %u pid %u", dwCount, dwPID);
  729.     // END_OF_ITEM_LOAD_LOG_ATTACH_PID
  730.  
  731.     if (dwCount)
  732.     {
  733.         peer->Encode(&s_items[0], sizeof(TPlayerItem) * dwCount);
  734.  
  735.         for (DWORD i = 0; i < dwCount; ++i)
  736.             PutItemCache(&s_items[i], true); // ๋กœ๋“œํ•œ ๊ฒƒ์€ ๋”ฐ๋กœ ์ €์žฅํ•  ํ•„์š” ์—†์œผ๋ฏ€๋กœ, ์ธ์ž bSkipQuery์— true๋ฅผ ๋„ฃ๋Š”๋‹ค.
  737.     }
  738. }
  739.  
  740. void CClientManager::RESULT_AFFECT_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle)
  741. {
  742.     int iNumRows;
  743.  
  744.     if ((iNumRows = mysql_num_rows(pRes)) == 0) // ๋ฐ์ดํ„ฐ ์—†์Œ
  745.         return;
  746.  
  747.     static std::vector<TPacketAffectElement> s_elements;
  748.     s_elements.resize(iNumRows);
  749.  
  750.     DWORD dwPID = 0;
  751.  
  752.     MYSQL_ROW row;
  753.  
  754.     for (int i = 0; i < iNumRows; ++i)
  755.     {
  756.         TPacketAffectElement & r = s_elements[i];
  757.         row = mysql_fetch_row(pRes);
  758.  
  759.         if (dwPID == 0)
  760.             str_to_number(dwPID, row[0]);
  761.  
  762.         str_to_number(r.dwType, row[1]);
  763.         str_to_number(r.bApplyOn, row[2]);
  764.         str_to_number(r.lApplyValue, row[3]);
  765.         str_to_number(r.dwFlag, row[4]);
  766.         str_to_number(r.lDuration, row[5]);
  767.         str_to_number(r.lSPCost, row[6]);
  768.     }
  769.  
  770.     sys_log(0, "AFFECT_LOAD: count %d PID %u", s_elements.size(), dwPID);
  771.  
  772.     DWORD dwCount = s_elements.size();
  773.  
  774.     peer->EncodeHeader(HEADER_DG_AFFECT_LOAD, dwHandle, sizeof(DWORD) + sizeof(DWORD) + sizeof(TPacketAffectElement) * dwCount);
  775.     peer->Encode(&dwPID, sizeof(DWORD));
  776.     peer->Encode(&dwCount, sizeof(DWORD));
  777.     peer->Encode(&s_elements[0], sizeof(TPacketAffectElement) * dwCount);
  778. }
  779.  
  780. void CClientManager::RESULT_QUEST_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD pid)
  781. {
  782.     int iNumRows;
  783.  
  784.     if ((iNumRows = mysql_num_rows(pRes)) == 0)
  785.     {
  786.         DWORD dwCount = 0;
  787.         peer->EncodeHeader(HEADER_DG_QUEST_LOAD, dwHandle, sizeof(DWORD));
  788.         peer->Encode(&dwCount, sizeof(DWORD));
  789.         return;
  790.     }
  791.  
  792.     static std::vector<TQuestTable> s_table;
  793.     s_table.resize(iNumRows);
  794.  
  795.     MYSQL_ROW row;
  796.  
  797.     for (int i = 0; i < iNumRows; ++i)
  798.     {
  799.         TQuestTable & r = s_table[i];
  800.  
  801.         row = mysql_fetch_row(pRes);
  802.  
  803.         str_to_number(r.dwPID, row[0]);
  804.         strlcpy(r.szName, row[1], sizeof(r.szName));
  805.         strlcpy(r.szState, row[2], sizeof(r.szState));
  806.         str_to_number(r.lValue, row[3]);
  807.     }
  808.  
  809.     sys_log(0, "QUEST_LOAD: count %d PID %u", s_table.size(), s_table[0].dwPID);
  810.  
  811.     DWORD dwCount = s_table.size();
  812.  
  813.     peer->EncodeHeader(HEADER_DG_QUEST_LOAD, dwHandle, sizeof(DWORD) + sizeof(TQuestTable) * dwCount);
  814.     peer->Encode(&dwCount, sizeof(DWORD));
  815.     peer->Encode(&s_table[0], sizeof(TQuestTable) * dwCount);
  816. }
  817.  
  818. /*
  819.  * PLAYER SAVE
  820.  */
  821. void CClientManager::QUERY_PLAYER_SAVE(CPeer * peer, DWORD dwHandle, TPlayerTable * pkTab)
  822. {
  823.     if (g_test_server)
  824.         sys_log(0, "PLAYER_SAVE: %s", pkTab->name);
  825.  
  826.     PutPlayerCache(pkTab);
  827. }
  828.  
  829. typedef std::map<DWORD, time_t> time_by_id_map_t;
  830. static time_by_id_map_t s_createTimeByAccountID;
  831.  
  832. /*
  833.  * PLAYER CREATE
  834.  */
  835. void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket* packet)
  836. {
  837.     char    queryStr[QUERY_MAX_LEN];
  838.     int     queryLen;
  839.     int     player_id;
  840.  
  841.     // ํ•œ ๊ณ„์ •์— X์ดˆ ๋‚ด๋กœ ์บ๋ฆญํ„ฐ ์ƒ์„ฑ์„ ํ•  ์ˆ˜ ์—†๋‹ค.
  842.     time_by_id_map_t::iterator it = s_createTimeByAccountID.find(packet->account_id);
  843.  
  844.     if (it != s_createTimeByAccountID.end())
  845.     {
  846.         time_t curtime = time(0);
  847.  
  848.         if (curtime - it->second < 30)
  849.         {
  850.             peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
  851.             return;
  852.         }
  853.     }
  854.  
  855.     queryLen = snprintf(queryStr, sizeof(queryStr),
  856.             "SELECT pid%u FROM player_index%s WHERE id=%d", packet->account_index + 1, GetTablePostfix(), packet->account_id);
  857.  
  858.     std::auto_ptr<SQLMsg> pMsg0(CDBManager::instance().DirectQuery(queryStr));
  859.  
  860.     if (pMsg0->Get()->uiNumRows != 0)
  861.     {
  862.         if (!pMsg0->Get()->pSQLResult)
  863.         {
  864.             peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
  865.             return;
  866.         }
  867.  
  868.         MYSQL_ROW row = mysql_fetch_row(pMsg0->Get()->pSQLResult);
  869.  
  870.         DWORD dwPID = 0; str_to_number(dwPID, row[0]);
  871.         if (row[0] && dwPID > 0)
  872.         {
  873.             peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
  874.             sys_log(0, "ALREADY EXIST AccountChrIdx %d ID %d", packet->account_index, dwPID);
  875.             return;
  876.         }
  877.     }
  878.     else
  879.     {
  880.         peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
  881.         return;
  882.     }
  883.  
  884.     if (g_stLocale == "sjis")
  885.         snprintf(queryStr, sizeof(queryStr),
  886.             "SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci",
  887.             GetTablePostfix(), packet->player_table.name); 
  888.     else
  889.     snprintf(queryStr, sizeof(queryStr),
  890.             "SELECT COUNT(*) as count FROM player%s WHERE name='%s'", GetTablePostfix(), packet->player_table.name);
  891.  
  892.     std::auto_ptr<SQLMsg> pMsg1(CDBManager::instance().DirectQuery(queryStr));
  893.  
  894.     if (pMsg1->Get()->uiNumRows)
  895.     {
  896.         if (!pMsg1->Get()->pSQLResult)
  897.         {
  898.             peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
  899.             return;
  900.         }
  901.  
  902.         MYSQL_ROW row = mysql_fetch_row(pMsg1->Get()->pSQLResult);
  903.  
  904.         if (*row[0] != '0')
  905.         {
  906.             sys_log(0, "ALREADY EXIST name %s, row[0] %s query %s", packet->player_table.name, row[0], queryStr);
  907.             peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
  908.             return;
  909.         }
  910.     }
  911.     else
  912.     {
  913.         peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
  914.         return;
  915.     }
  916.  
  917.     queryLen = snprintf(queryStr, sizeof(queryStr),
  918.             "INSERT INTO player%s "
  919.             "(id, account_id, name, level, st, ht, dx, iq, "
  920.             "job, voice, dir, x, y, z, "
  921.             "hp, mp, random_hp, random_sp, stat_point, stamina, part_base, part_main, part_hair, part_sash, gold, playtime, "
  922.             "skill_level, quickslot) "
  923.             "VALUES(0, %u, '%s', %d, %d, %d, %d, %d, "
  924.             "%d, %d, %d, %d, %d, %d, %d, "
  925.             "%d, %d, %d, %d, %d, %d, %d, 0, 0, %lld, 0, ",
  926.             GetTablePostfix(),
  927.             packet->account_id, packet->player_table.name, packet->player_table.level, packet->player_table.st, packet->player_table.ht, packet->player_table.dx, packet->player_table.iq,
  928.             packet->player_table.job, packet->player_table.voice, packet->player_table.dir, packet->player_table.x, packet->player_table.y, packet->player_table.z,
  929.             packet->player_table.hp, packet->player_table.sp, packet->player_table.sRandomHP, packet->player_table.sRandomSP, packet->player_table.stat_point, packet->player_table.stamina, packet->player_table.part_base, packet->player_table.part_base, packet->player_table.gold);
  930.  
  931.     sys_log(0, "PlayerCreate accountid %d name %s level %d gold %lld, st %d ht %d job %d",
  932.             packet->account_id,
  933.             packet->player_table.name,
  934.             packet->player_table.level,
  935.             packet->player_table.gold,
  936.             packet->player_table.st,
  937.             packet->player_table.ht,
  938.             packet->player_table.job);
  939.  
  940.     static char text[4096 + 1];
  941.  
  942.     CDBManager::instance().EscapeString(text, packet->player_table.skills, sizeof(packet->player_table.skills));
  943.     queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s', ", text);
  944.     if (g_test_server)
  945.         sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text);
  946.  
  947.     CDBManager::instance().EscapeString(text, packet->player_table.quickslot, sizeof(packet->player_table.quickslot));
  948.     queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s')", text);
  949.  
  950.     std::auto_ptr<SQLMsg> pMsg2(CDBManager::instance().DirectQuery(queryStr));
  951.     if (g_test_server)
  952.         sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text);
  953.  
  954.     if (pMsg2->Get()->uiAffectedRows <= 0)
  955.     {
  956.         peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
  957.         sys_log(0, "ALREADY EXIST3 query: %s AffectedRows %lu", queryStr, pMsg2->Get()->uiAffectedRows);
  958.         return;
  959.     }
  960.  
  961.     player_id = pMsg2->Get()->uiInsertID;
  962.  
  963.     snprintf(queryStr, sizeof(queryStr), "UPDATE player_index%s SET pid%d=%d WHERE id=%d",
  964.             GetTablePostfix(), packet->account_index + 1, player_id, packet->account_id);
  965.     std::auto_ptr<SQLMsg> pMsg3(CDBManager::instance().DirectQuery(queryStr));
  966.  
  967.     if (pMsg3->Get()->uiAffectedRows <= 0)
  968.     {
  969.         sys_err("QUERY_ERROR: %s", queryStr);
  970.  
  971.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), player_id);
  972.         CDBManager::instance().DirectQuery(queryStr);
  973.  
  974.         peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
  975.         return;
  976.     }
  977.  
  978.     TPacketDGCreateSuccess pack;
  979.     memset(&pack, 0, sizeof(pack));
  980.  
  981.     pack.bAccountCharacterIndex = packet->account_index;
  982.  
  983.     pack.player.dwID            = player_id;
  984.     strlcpy(pack.player.szName, packet->player_table.name, sizeof(pack.player.szName));
  985.     pack.player.byJob           = packet->player_table.job;
  986.     pack.player.byLevel         = 1;
  987.     pack.player.dwPlayMinutes   = 0;
  988.     pack.player.byST            = packet->player_table.st;
  989.     pack.player.byHT            = packet->player_table.ht;
  990.     pack.player.byDX            = packet->player_table.dx;
  991.     pack.player.byIQ            = packet->player_table.iq;
  992.     pack.player.wMainPart       = packet->player_table.part_base;
  993.     pack.player.x           = packet->player_table.x;
  994.     pack.player.y           = packet->player_table.y;
  995.  
  996.     peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_SUCCESS, dwHandle, sizeof(TPacketDGCreateSuccess));
  997.     peer->Encode(&pack, sizeof(TPacketDGCreateSuccess));
  998.  
  999.     sys_log(0, "7 name %s job %d", pack.player.szName, pack.player.byJob);
  1000.  
  1001.     s_createTimeByAccountID[packet->account_id] = time(0);
  1002. }
  1003.  
  1004. /*
  1005.  * PLAYER DELETE
  1006.  */
  1007. void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerDeletePacket* packet)
  1008. {
  1009.     if (!packet->login[0] || !packet->player_id || packet->account_index >= PLAYER_PER_ACCOUNT)
  1010.         return;
  1011.  
  1012.     CLoginData * ld = GetLoginDataByLogin(packet->login);
  1013.  
  1014.     if (!ld)
  1015.     {
  1016.         peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
  1017.         peer->EncodeBYTE(packet->account_index);
  1018.         return;
  1019.     }
  1020.  
  1021.     TAccountTable & r = ld->GetAccountRef();
  1022.  
  1023.     // block for japan
  1024.     if (g_stLocale != "sjis")
  1025.     {
  1026.         if (!IsChinaEventServer())
  1027.         {
  1028.             if (strlen(r.social_id) < 7 || strncmp(packet->private_code, r.social_id + strlen(r.social_id) - 7, 7))
  1029.             {
  1030.                 sys_log(0, "PLAYER_DELETE FAILED len(%d)", strlen(r.social_id));
  1031.                 peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
  1032.                 peer->EncodeBYTE(packet->account_index);
  1033.                 return;
  1034.             }
  1035.  
  1036.             CPlayerTableCache * pkPlayerCache = GetPlayerCache(packet->player_id);
  1037.             if (pkPlayerCache)
  1038.             {
  1039.                 TPlayerTable * pTab = pkPlayerCache->Get();
  1040.  
  1041.                 if (pTab->level >= m_iPlayerDeleteLevelLimit)
  1042.                 {
  1043.                     sys_log(0, "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d", pTab->level, m_iPlayerDeleteLevelLimit);
  1044.                     peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
  1045.                     peer->EncodeBYTE(packet->account_index);
  1046.                     return;
  1047.                 }
  1048.  
  1049.                 if (pTab->level < m_iPlayerDeleteLevelLimitLower)
  1050.                 {
  1051.                     sys_log(0, "PLAYER_DELETE FAILED LEVEL %u < DELETE LIMIT %d", pTab->level, m_iPlayerDeleteLevelLimitLower);
  1052.                     peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
  1053.                     peer->EncodeBYTE(packet->account_index);
  1054.                     return;
  1055.                 }
  1056.             }
  1057.         }
  1058.     }
  1059.  
  1060.     char szQuery[128];
  1061.     snprintf(szQuery, sizeof(szQuery), "SELECT p.id, p.level, p.name FROM player_index%s AS i, player%s AS p WHERE pid%u=%u AND pid%u=p.id",
  1062.             GetTablePostfix(), GetTablePostfix(), packet->account_index + 1, packet->player_id, packet->account_index + 1);
  1063.  
  1064.     ClientHandleInfo * pi = new ClientHandleInfo(dwHandle, packet->player_id);
  1065.     pi->account_index = packet->account_index;
  1066.  
  1067.     sys_log(0, "PLAYER_DELETE TRY: %s %d pid%d", packet->login, packet->player_id, packet->account_index + 1);
  1068.     CDBManager::instance().ReturnQuery(szQuery, QID_PLAYER_DELETE, peer->GetHandle(), pi);
  1069. }
  1070.  
  1071. //
  1072. // @version 05/06/10 Bang2ni - ํ”Œ๋ ˆ์ด์–ด ์‚ญ์ œ์‹œ ๊ฐ€๊ฒฉ์ •๋ณด ๋ฆฌ์ŠคํŠธ ์‚ญ์ œ ์ถ”๊ฐ€.
  1073. //
  1074. void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
  1075. {
  1076.     CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
  1077.     ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData;
  1078.  
  1079.     if (msg->Get() && msg->Get()->uiNumRows)
  1080.     {
  1081.         MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult);
  1082.  
  1083.         DWORD dwPID = 0;
  1084.         str_to_number(dwPID, row[0]);
  1085.  
  1086.         int deletedLevelLimit = 0;
  1087.         str_to_number(deletedLevelLimit, row[1]);
  1088.  
  1089.         char szName[64];
  1090.         strlcpy(szName, row[2], sizeof(szName));
  1091.  
  1092.         if (deletedLevelLimit >= m_iPlayerDeleteLevelLimit && !IsChinaEventServer())
  1093.         {
  1094.             sys_log(0, "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d", deletedLevelLimit, m_iPlayerDeleteLevelLimit);
  1095.             peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
  1096.             peer->EncodeBYTE(pi->account_index);
  1097.             return;
  1098.         }
  1099.  
  1100.         if (deletedLevelLimit < m_iPlayerDeleteLevelLimitLower)
  1101.         {
  1102.             sys_log(0, "PLAYER_DELETE FAILED LEVEL %u < DELETE LIMIT %d", deletedLevelLimit, m_iPlayerDeleteLevelLimitLower);
  1103.             peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
  1104.             peer->EncodeBYTE(pi->account_index);
  1105.             return;
  1106.         }
  1107.  
  1108.         char queryStr[QUERY_MAX_LEN];
  1109.  
  1110.         snprintf(queryStr, sizeof(queryStr), "INSERT INTO player%s_deleted SELECT * FROM player%s WHERE id=%d",
  1111.                 GetTablePostfix(), GetTablePostfix(), pi->player_id);
  1112.         std::auto_ptr<SQLMsg> pIns(CDBManager::instance().DirectQuery(queryStr));
  1113.  
  1114.         if (pIns->Get()->uiAffectedRows == 0 || pIns->Get()->uiAffectedRows == (uint32_t)-1)
  1115.         {
  1116.             sys_log(0, "PLAYER_DELETE FAILED %u CANNOT INSERT TO player%s_deleted", dwPID, GetTablePostfix());
  1117.  
  1118.             peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
  1119.             peer->EncodeBYTE(pi->account_index);
  1120.             return;
  1121.         }
  1122.  
  1123.         // ์‚ญ์ œ ์„ฑ๊ณต
  1124.         sys_log(0, "PLAYER_DELETE SUCCESS %u", dwPID);
  1125.  
  1126.         char account_index_string[16];
  1127.  
  1128.         snprintf(account_index_string, sizeof(account_index_string), "player_id%d", m_iPlayerIDStart + pi->account_index);
  1129.  
  1130.         // ํ”Œ๋ ˆ์ด์–ด ํ…Œ์ด๋ธ”์„ ์บ์‰ฌ์—์„œ ์‚ญ์ œํ•œ๋‹ค.
  1131.         CPlayerTableCache * pkPlayerCache = GetPlayerCache(pi->player_id);
  1132.  
  1133.         if (pkPlayerCache)
  1134.         {
  1135.             m_map_playerCache.erase(pi->player_id);
  1136.             delete pkPlayerCache;
  1137.         }
  1138.  
  1139.         // ์•„์ดํ…œ๋“ค์„ ์บ์‰ฌ์—์„œ ์‚ญ์ œํ•œ๋‹ค.
  1140.         TItemCacheSet * pSet = GetItemCacheSet(pi->player_id);
  1141.  
  1142.         if (pSet)
  1143.         {
  1144.             TItemCacheSet::iterator it = pSet->begin();
  1145.  
  1146.             while (it != pSet->end())
  1147.             {
  1148.                 CItemCache * pkItemCache = *it++;
  1149.                 DeleteItemCache(pkItemCache->Get()->id);
  1150.             }
  1151.  
  1152.             pSet->clear();
  1153.             delete pSet;
  1154.  
  1155.             m_map_pkItemCacheSetPtr.erase(pi->player_id);
  1156.         }
  1157.  
  1158.         snprintf(queryStr, sizeof(queryStr), "UPDATE player_index%s SET pid%u=0 WHERE pid%u=%d",
  1159.                 GetTablePostfix(),
  1160.                 pi->account_index + 1,
  1161.                 pi->account_index + 1,
  1162.                 pi->player_id);
  1163.  
  1164.         std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(queryStr));
  1165.  
  1166.         if (pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1)
  1167.         {
  1168.             sys_log(0, "PLAYER_DELETE FAIL WHEN UPDATE account table");
  1169.             peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
  1170.             peer->EncodeBYTE(pi->account_index);
  1171.             return;
  1172.         }
  1173.  
  1174.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), pi->player_id);
  1175.         delete CDBManager::instance().DirectQuery(queryStr);
  1176.  
  1177.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)", GetTablePostfix(), pi->player_id, SAFEBOX, DRAGON_SOUL_INVENTORY);
  1178.         delete CDBManager::instance().DirectQuery(queryStr);
  1179.  
  1180.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM quest%s WHERE dwPID=%d", GetTablePostfix(), pi->player_id);
  1181.         CDBManager::instance().AsyncQuery(queryStr);
  1182.  
  1183.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM affect%s WHERE dwPID=%d", GetTablePostfix(), pi->player_id);
  1184.         CDBManager::instance().AsyncQuery(queryStr);
  1185.  
  1186.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM guild_member%s WHERE pid=%d", GetTablePostfix(), pi->player_id);
  1187.         CDBManager::instance().AsyncQuery(queryStr);
  1188.  
  1189.         // MYSHOP_PRICE_LIST
  1190.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM myshop_pricelist%s WHERE owner_id=%d", GetTablePostfix(), pi->player_id);
  1191.         CDBManager::instance().AsyncQuery(queryStr);
  1192.         // END_OF_MYSHOP_PRICE_LIST
  1193.  
  1194.         snprintf(queryStr, sizeof(queryStr), "DELETE FROM messenger_list%s WHERE account='%s' OR companion='%s'", GetTablePostfix(), szName, szName);
  1195.         CDBManager::instance().AsyncQuery(queryStr);
  1196.  
  1197.         peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_SUCCESS, pi->dwHandle, 1);
  1198.         peer->EncodeBYTE(pi->account_index);
  1199.     }
  1200.     else
  1201.     {
  1202.         // ์‚ญ์ œ ์‹คํŒจ
  1203.         sys_log(0, "PLAYER_DELETE FAIL NO ROW");
  1204.         peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
  1205.         peer->EncodeBYTE(pi->account_index);
  1206.     }
  1207. }
  1208.  
  1209. void CClientManager::QUERY_ADD_AFFECT(CPeer * peer, TPacketGDAddAffect * p)
  1210. {
  1211.     char queryStr[QUERY_MAX_LEN];
  1212.     /*
  1213.        snprintf(queryStr, sizeof(queryStr),
  1214.        "INSERT INTO affect%s (dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost) "
  1215.        "VALUES(%u, %u, %u, %d, %u, %d, %d) "
  1216.        "ON DUPLICATE KEY UPDATE lApplyValue=%d, dwFlag=%u, lDuration=%d, lSPCost=%d",
  1217.        GetTablePostfix(),
  1218.        p->dwPID,
  1219.        p->elem.dwType,
  1220.        p->elem.bApplyOn,
  1221.        p->elem.lApplyValue,
  1222.        p->elem.dwFlag,
  1223.        p->elem.lDuration,
  1224.        p->elem.lSPCost,
  1225.        p->elem.lApplyValue,
  1226.        p->elem.dwFlag,
  1227.        p->elem.lDuration,
  1228.        p->elem.lSPCost);
  1229.        */
  1230.     snprintf(queryStr, sizeof(queryStr),
  1231.             "REPLACE INTO affect%s (dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost) "
  1232.             "VALUES(%u, %u, %u, %ld, %u, %ld, %ld)",
  1233.             GetTablePostfix(),
  1234.             p->dwPID,
  1235.             p->elem.dwType,
  1236.             p->elem.bApplyOn,
  1237.             p->elem.lApplyValue,
  1238.             p->elem.dwFlag,
  1239.             p->elem.lDuration,
  1240.             p->elem.lSPCost);
  1241.  
  1242.     CDBManager::instance().AsyncQuery(queryStr);
  1243. }
  1244.  
  1245. void CClientManager::QUERY_REMOVE_AFFECT(CPeer * peer, TPacketGDRemoveAffect * p)
  1246. {
  1247.     char queryStr[QUERY_MAX_LEN];
  1248.  
  1249.     snprintf(queryStr, sizeof(queryStr),
  1250.             "DELETE FROM affect%s WHERE dwPID=%u AND bType=%u AND bApplyOn=%u",
  1251.             GetTablePostfix(), p->dwPID, p->dwType, p->bApplyOn);
  1252.  
  1253.     CDBManager::instance().AsyncQuery(queryStr);
  1254. }
  1255.  
  1256.  
  1257. void CClientManager::QUERY_HIGHSCORE_REGISTER(CPeer* peer, TPacketGDHighscore * data)
  1258. {
  1259.     char szQuery[128];
  1260.     snprintf(szQuery, sizeof(szQuery), "SELECT value FROM highscore%s WHERE board='%s' AND pid = %u", GetTablePostfix(), data->szBoard, data->dwPID);
  1261.  
  1262.     sys_log(0, "HEADER_GD_HIGHSCORE_REGISTER: PID %u", data->dwPID);
  1263.  
  1264.     ClientHandleInfo * pi = new ClientHandleInfo(0);
  1265.     strlcpy(pi->login, data->szBoard, sizeof(pi->login));
  1266.     pi->account_id = (DWORD)data->lValue;
  1267.     pi->player_id = data->dwPID;
  1268.     pi->account_index = (data->cDir > 0);
  1269.  
  1270.     CDBManager::instance().ReturnQuery(szQuery, QID_HIGHSCORE_REGISTER, peer->GetHandle(), pi);
  1271. }
  1272.  
  1273. void CClientManager::RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg)
  1274. {
  1275.     CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
  1276.     ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData;
  1277.     //DWORD dwHandle = pi->dwHandle;
  1278.  
  1279.     char szBoard[21];
  1280.     strlcpy(szBoard, pi->login, sizeof(szBoard));
  1281.     int value = (int)pi->account_id;
  1282.  
  1283.     SQLResult * res = msg->Get();
  1284.  
  1285.     if (res->uiNumRows == 0)
  1286.     {
  1287.         // ์ƒˆ๋กœ์šด ํ•˜์ด์Šค์ฝ”์–ด๋ฅผ ์‚ฝ์ž…
  1288.         char buf[256];
  1289.         snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value);
  1290.         CDBManager::instance().AsyncQuery(buf);
  1291.     }
  1292.     else
  1293.     {
  1294.         if (!res->pSQLResult)
  1295.         {
  1296.             delete pi;
  1297.             return;
  1298.         }
  1299.  
  1300.         MYSQL_ROW row = mysql_fetch_row(res->pSQLResult);
  1301.         if (row && row[0])
  1302.         {
  1303.             int current_value = 0; str_to_number(current_value, row[0]);
  1304.             if (pi->account_index && current_value >= value || !pi->account_index && current_value <= value)
  1305.             {
  1306.                 value = current_value;
  1307.             }
  1308.             else
  1309.             {
  1310.                 char buf[256];
  1311.                 snprintf(buf, sizeof(buf), "REPLACE INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value);
  1312.                 CDBManager::instance().AsyncQuery(buf);
  1313.             }
  1314.         }
  1315.         else
  1316.         {
  1317.             char buf[256];
  1318.             snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value);
  1319.             CDBManager::instance().AsyncQuery(buf);
  1320.         }
  1321.     }
  1322.     // TODO: ์ด๊ณณ์—์„œ ํ•˜์ด์Šค์ฝ”์–ด๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜์—ˆ๋Š”์ง€ ์ฒดํฌํ•˜์—ฌ ๊ณต์ง€๋ฅผ ๋ฟŒ๋ ค์•ผํ•œ๋‹ค.
  1323.     delete pi;
  1324. }
  1325.  
  1326. void CClientManager::InsertLogoutPlayer(DWORD pid)
  1327. {
  1328.     TLogoutPlayerMap::iterator it = m_map_logout.find(pid);
  1329.  
  1330.     // ์กด์žฌํ•˜์ง€ ์•Š์„๊ฒฝ์šฐ ์ถ”๊ฐ€
  1331.     if (it != m_map_logout.end())
  1332.     {
  1333.         // ์กด์žฌํ• ๊ฒฝ์šฐ ์‹œ๊ฐ„๋งŒ ๊ฐฑ์‹ 
  1334.         if (g_log)
  1335.             sys_log(0, "LOGOUT: Update player time pid(%d)", pid);
  1336.  
  1337.         it->second->time = time(0);
  1338.         return;
  1339.     }
  1340.        
  1341.     TLogoutPlayer * pLogout = new TLogoutPlayer;
  1342.     pLogout->pid = pid;
  1343.     pLogout->time = time(0);
  1344.     m_map_logout.insert(std::make_pair(pid, pLogout));
  1345.  
  1346.     if (g_log)
  1347.         sys_log(0, "LOGOUT: Insert player pid(%d)", pid);
  1348. }
  1349.  
  1350. void CClientManager::DeleteLogoutPlayer(DWORD pid)
  1351. {
  1352.     TLogoutPlayerMap::iterator it = m_map_logout.find(pid);
  1353.  
  1354.     if (it != m_map_logout.end())
  1355.     {
  1356.         delete it->second;
  1357.         m_map_logout.erase(it);
  1358.     }
  1359. }
  1360.  
  1361. extern int g_iLogoutSeconds;
  1362.  
  1363. void CClientManager::UpdateLogoutPlayer()
  1364. {
  1365.     time_t now = time(0);
  1366.  
  1367.     TLogoutPlayerMap::iterator it = m_map_logout.begin();
  1368.  
  1369.     while (it != m_map_logout.end())
  1370.     {
  1371.         TLogoutPlayer* pLogout = it->second;
  1372.  
  1373.         if (now - g_iLogoutSeconds > pLogout->time)
  1374.         {
  1375.             FlushItemCacheSet(pLogout->pid);
  1376.             FlushPlayerCacheSet(pLogout->pid);
  1377.  
  1378.             delete pLogout;
  1379.             m_map_logout.erase(it++);
  1380.         }
  1381.         else
  1382.             ++it;
  1383.     }
  1384. }
  1385.  
  1386. void CClientManager::FlushPlayerCacheSet(DWORD pid)
  1387. {
  1388.     TPlayerTableCacheMap::iterator it = m_map_playerCache.find(pid);
  1389.  
  1390.     if (it != m_map_playerCache.end())
  1391.     {
  1392.         CPlayerTableCache * c = it->second;
  1393.         m_map_playerCache.erase(it);
  1394.  
  1395.         c->Flush();
  1396.         delete c;
  1397.     }
  1398. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top