Advertisement
Guest User

Untitled

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