Advertisement
Guest User

Untitled

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