server/db/src/ClientManagerPlayer.cpp

1358 lines
41 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdafx.h"
#include "ClientManager.h"
#include "Main.h"
#include "QID.h"
#include "ItemAwardManager.h"
#include "HB.h"
#include "Cache.h"
extern bool g_bHotBackup;
extern std::string g_stLocale;
extern int g_test_server;
extern int g_log;
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!! IMPORTANT !!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// Check all SELECT syntax on item table before change this function!!!
//
bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DWORD dwPID)
{
if (!res)
{
pVec->clear();
return true;
}
int rows;
if ((rows = mysql_num_rows(res)) <= 0) // µ¥ÀÌÅÍ ¾øÀ½
{
pVec->clear();
return true;
}
pVec->resize(rows);
for (int i = 0; i < rows; ++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
TPlayerItem & item = pVec->at(i);
int cur = 0;
// Check all SELECT syntax on item table before change this function!!!
// Check all SELECT syntax on item table before change this function!!!
// Check all SELECT syntax on item table before change this function!!!
str_to_number(item.id, row[cur++]);
str_to_number(item.window, row[cur++]);
str_to_number(item.pos, row[cur++]);
str_to_number(item.count, row[cur++]);
str_to_number(item.vnum, row[cur++]);
str_to_number(item.alSockets[0], row[cur++]);
str_to_number(item.alSockets[1], row[cur++]);
str_to_number(item.alSockets[2], row[cur++]);
for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++)
{
str_to_number(item.aAttr[j].bType, row[cur++]);
str_to_number(item.aAttr[j].sValue, row[cur++]);
}
item.owner = dwPID;
}
return true;
}
size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * pkTab)
{
size_t queryLen;
queryLen = snprintf(pszQuery, querySize,
"UPDATE player%s SET "
"job = %d, "
"voice = %d, "
"dir = %d, "
"x = %d, "
"y = %d, "
"z = %d, "
"map_index = %d, "
"exit_x = %ld, "
"exit_y = %ld, "
"exit_map_index = %ld, "
"hp = %d, "
"mp = %d, "
"stamina = %d, "
"random_hp = %d, "
"random_sp = %d, "
"playtime = %d, "
"level = %d, "
"level_step = %d, "
"st = %d, "
"ht = %d, "
"dx = %d, "
"iq = %d, "
"gold = %d, "
"exp = %u, "
"stat_point = %d, "
"skill_point = %d, "
"sub_skill_point = %d, "
"stat_reset_count = %d, "
"ip = '%s', "
"part_main = %d, "
"part_hair = %d, "
"last_play = NOW(), "
"skill_group = %d, "
"alignment = %ld, "
"horse_level = %d, "
"horse_riding = %d, "
"horse_hp = %d, "
"horse_hp_droptime = %u, "
"horse_stamina = %d, "
"horse_skill_point = %d, "
,
GetTablePostfix(),
pkTab->job,
pkTab->voice,
pkTab->dir,
pkTab->x,
pkTab->y,
pkTab->z,
pkTab->lMapIndex,
pkTab->lExitX,
pkTab->lExitY,
pkTab->lExitMapIndex,
pkTab->hp,
pkTab->sp,
pkTab->stamina,
pkTab->sRandomHP,
pkTab->sRandomSP,
pkTab->playtime,
pkTab->level,
pkTab->level_step,
pkTab->st,
pkTab->ht,
pkTab->dx,
pkTab->iq,
pkTab->gold,
pkTab->exp,
pkTab->stat_point,
pkTab->skill_point,
pkTab->sub_skill_point,
pkTab->stat_reset_count,
pkTab->ip,
pkTab->parts[PART_MAIN],
pkTab->parts[PART_HAIR],
pkTab->skill_group,
pkTab->lAlignment,
pkTab->horse.bLevel,
pkTab->horse.bRiding,
pkTab->horse.sHealth,
pkTab->horse.dwHorseHealthDropTime,
pkTab->horse.sStamina,
pkTab->horse_skill_point);
// Binary ·Î ¹Ù²Ù±â À§ÇÑ Àӽà °ø°£
static char text[8192 + 1];
CDBManager::instance().EscapeString(text, pkTab->skills, sizeof(pkTab->skills));
queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, "skill_level = '%s', ", text);
CDBManager::instance().EscapeString(text, pkTab->quickslot, sizeof(pkTab->quickslot));
queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, "quickslot = '%s' ", text);
queryLen += snprintf(pszQuery + queryLen, querySize - queryLen, " WHERE id=%d", pkTab->id);
return queryLen;
}
CPlayerTableCache * CClientManager::GetPlayerCache(DWORD id)
{
TPlayerTableCacheMap::iterator it = m_map_playerCache.find(id);
if (it == m_map_playerCache.end())
return NULL;
TPlayerTable* pTable = it->second->Get(false);
pTable->logoff_interval = GetCurrentTime() - it->second->GetLastUpdateTime();
return it->second;
}
void CClientManager::PutPlayerCache(TPlayerTable * pNew)
{
CPlayerTableCache * c;
c = GetPlayerCache(pNew->id);
if (!c)
{
c = new CPlayerTableCache;
m_map_playerCache.insert(TPlayerTableCacheMap::value_type(pNew->id, c));
}
if (g_bHotBackup)
PlayerHB::instance().Put(pNew->id);
c->Put(pNew);
}
/*
* PLAYER LOAD
*/
void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket * packet)
{
CPlayerTableCache * c;
TPlayerTable * pTab;
//
// ÇÑ °èÁ¤¿¡ ¼ÓÇÑ ¸ðµç ij¸¯Å͵é ij½¬Ã³¸®
//
CLoginData * pLoginData = GetLoginDataByAID(packet->account_id);
if (pLoginData)
{
for (int n = 0; n < PLAYER_PER_ACCOUNT; ++n)
if (pLoginData->GetAccountRef().players[n].dwID != 0)
DeleteLogoutPlayer(pLoginData->GetAccountRef().players[n].dwID);
}
//----------------------------------------------------------------
// 1. À¯ÀúÁ¤º¸°¡ DBCache ¿¡ Á¸Àç : DBCache¿¡¼­
// 2. À¯ÀúÁ¤º¸°¡ DBCache ¿¡ ¾øÀ½ : DB¿¡¼­
// ---------------------------------------------------------------
//----------------------------------
// 1. À¯ÀúÁ¤º¸°¡ DBCache ¿¡ Á¸Àç : DBCache¿¡¼­
//----------------------------------
if ((c = GetPlayerCache(packet->player_id)))
{
CLoginData * pkLD = GetLoginDataByAID(packet->account_id);
if (!pkLD || pkLD->IsPlay())
{
sys_log(0, "PLAYER_LOAD_ERROR: LoginData %p IsPlay %d", pkLD, pkLD ? pkLD->IsPlay() : 0);
peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, dwHandle, 0);
return;
}
pTab = c->Get();
pkLD->SetPlay(true);
SendLoginToBilling(pkLD, true);
thecore_memcpy(pTab->aiPremiumTimes, pkLD->GetPremiumPtr(), sizeof(pTab->aiPremiumTimes));
peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_SUCCESS, dwHandle, sizeof(TPlayerTable));
peer->Encode(pTab, sizeof(TPlayerTable));
if (packet->player_id != pkLD->GetLastPlayerID())
{
TPacketNeedLoginLogInfo logInfo;
logInfo.dwPlayerID = packet->player_id;
pkLD->SetLastPlayerID( packet->player_id );
peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, dwHandle, sizeof(TPacketNeedLoginLogInfo) );
peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) );
}
char szQuery[1024] = { 0, };
TItemCacheSet * pSet = GetItemCacheSet(pTab->id);
sys_log(0, "[PLAYER_LOAD] ID %s pid %d gold %d ", pTab->name, pTab->id, pTab->gold);
//--------------------------------------------
// ¾ÆÀÌÅÛ & AFFECT & QUEST ·Îµù :
//--------------------------------------------
// 1) ¾ÆÀÌÅÛÀÌ DBCache ¿¡ Á¸Àç : DBCache ¿¡¼­ °¡Á®¿È
// 2) ¾ÆÀÌÅÛÀÌ DBCache ¿¡ ¾øÀ½ : DB ¿¡¼­ °¡Á®¿È
/////////////////////////////////////////////
// 1) ¾ÆÀÌÅÛÀÌ DBCache ¿¡ Á¸Àç : DBCache ¿¡¼­ °¡Á®¿È
/////////////////////////////////////////////
if (pSet)
{
static std::vector<TPlayerItem> s_items;
s_items.resize(pSet->size());
DWORD dwCount = 0;
TItemCacheSet::iterator it = pSet->begin();
while (it != pSet->end())
{
CItemCache * c = *it++;
TPlayerItem * p = c->Get();
if (p->vnum) // vnumÀÌ ¾øÀ¸¸é »èÁ¦µÈ ¾ÆÀÌÅÛÀÌ´Ù.
thecore_memcpy(&s_items[dwCount++], p, sizeof(TPlayerItem));
}
if (g_test_server)
sys_log(0, "ITEM_CACHE: HIT! %s count: %u", pTab->name, dwCount);
peer->EncodeHeader(HEADER_DG_ITEM_LOAD, dwHandle, sizeof(DWORD) + sizeof(TPlayerItem) * dwCount);
peer->EncodeDWORD(dwCount);
if (dwCount)
peer->Encode(&s_items[0], sizeof(TPlayerItem) * dwCount);
// Quest
snprintf(szQuery, sizeof(szQuery),
"SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d AND lValue<>0",
GetTablePostfix(), pTab->id);
CDBManager::instance().ReturnQuery(szQuery, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle,0,packet->account_id));
// Affect
snprintf(szQuery, sizeof(szQuery),
"SELECT dwPID,bType,bApplyOn,lApplyValue,dwFlag,lDuration,lSPCost FROM affect%s WHERE dwPID=%d",
GetTablePostfix(), pTab->id);
CDBManager::instance().ReturnQuery(szQuery, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle));
}
/////////////////////////////////////////////
// 2) ¾ÆÀÌÅÛÀÌ DBCache ¿¡ ¾øÀ½ : DB ¿¡¼­ °¡Á®¿È
/////////////////////////////////////////////
else
{
snprintf(szQuery, sizeof(szQuery),
"SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
"FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)",
GetTablePostfix(), pTab->id, SAFEBOX, DRAGON_SOUL_INVENTORY);
CDBManager::instance().ReturnQuery(szQuery,
QID_ITEM,
peer->GetHandle(),
new ClientHandleInfo(dwHandle, pTab->id));
snprintf(szQuery, sizeof(szQuery),
"SELECT dwPID, szName, szState, lValue FROM quest%s WHERE dwPID=%d",
GetTablePostfix(), pTab->id);
CDBManager::instance().ReturnQuery(szQuery,
QID_QUEST,
peer->GetHandle(),
new ClientHandleInfo(dwHandle, pTab->id));
snprintf(szQuery, sizeof(szQuery),
"SELECT dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost FROM affect%s WHERE dwPID=%d",
GetTablePostfix(), pTab->id);
CDBManager::instance().ReturnQuery(szQuery,
QID_AFFECT,
peer->GetHandle(),
new ClientHandleInfo(dwHandle, pTab->id));
}
//ljw
//return;
}
//----------------------------------
// 2. À¯ÀúÁ¤º¸°¡ DBCache ¿¡ ¾øÀ½ : DB¿¡¼­
//----------------------------------
else
{
sys_log(0, "[PLAYER_LOAD] Load from PlayerDB pid[%d]", packet->player_id);
char queryStr[QUERY_MAX_LEN];
//--------------------------------------------------------------
// ij¸¯ÅÍ Á¤º¸ ¾ò¾î¿À±â : ¹«Á¶°Ç DB¿¡¼­
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT "
"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,level,level_step,st,ht,dx,iq,exp,"
"stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair,"
"skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_hp_droptime,horse_stamina,"
"UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play),horse_skill_point FROM player%s WHERE id=%d",
GetTablePostfix(), packet->player_id);
ClientHandleInfo * pkInfo = new ClientHandleInfo(dwHandle, packet->player_id);
pkInfo->account_id = packet->account_id;
CDBManager::instance().ReturnQuery(queryStr, QID_PLAYER, peer->GetHandle(), pkInfo);
//--------------------------------------------------------------
// ¾ÆÀÌÅÛ °¡Á®¿À±â
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
"FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)",
GetTablePostfix(), packet->player_id, SAFEBOX, DRAGON_SOUL_INVENTORY);
CDBManager::instance().ReturnQuery(queryStr, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id));
//--------------------------------------------------------------
// QUEST °¡Á®¿À±â
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d",
GetTablePostfix(), packet->player_id);
CDBManager::instance().ReturnQuery(queryStr, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id,packet->account_id));
//µ¶ÀÏ ¼±¹° ±â´É¿¡¼­ item_awardÅ×ÀÌºí¿¡¼­ login Á¤º¸¸¦ ¾ò±âÀ§ÇØ account idµµ ³Ñ°ÜÁØ´Ù
//--------------------------------------------------------------
// AFFECT °¡Á®¿À±â
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT dwPID,bType,bApplyOn,lApplyValue,dwFlag,lDuration,lSPCost FROM affect%s WHERE dwPID=%d",
GetTablePostfix(), packet->player_id);
CDBManager::instance().ReturnQuery(queryStr, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id));
}
}
void CClientManager::ItemAward(CPeer * peer,char* login)
{
char login_t[LOGIN_MAX_LEN + 1] = "";
strncpy(login_t,login,LOGIN_MAX_LEN + 1);
std::set<TItemAward *> * pSet = ItemAwardManager::instance().GetByLogin(login_t);
if(pSet == NULL)
return;
typeof(pSet->begin()) it = pSet->begin(); //taken_timeÀÌ NULLÀΰ͵é Àоî¿È
while(it != pSet->end() )
{
TItemAward * pItemAward = *(it++);
char* whyStr = pItemAward->szWhy; //why ÄÝ·ë Àбâ
char cmdStr[100] = ""; //whyÄÝ·ë¿¡¼­ ÀÐÀº °ªÀ» Àӽà ¹®ÀÚ¿­¿¡ º¹»çÇصÒ
strcpy(cmdStr,whyStr); //¸í·É¾î ¾ò´Â °úÁ¤¿¡¼­ ÅäÅ«¾²¸é ¿øº»µµ ÅäÅ«È­ µÇ±â ¶§¹®
char command[20] = "";
strcpy(command,GetCommand(cmdStr)); // command ¾ò±â
if( !(strcmp(command,"GIFT") )) // command °¡ GIFTÀ̸é
{
TPacketItemAwardInfromer giftData;
strcpy(giftData.login, pItemAward->szLogin); //·Î±×ÀÎ ¾ÆÀ̵𠺹»ç
strcpy(giftData.command, command); //¸í·É¾î º¹»ç
giftData.vnum = pItemAward->dwVnum; //¾ÆÀÌÅÛ vnumµµ º¹»ç
ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
}
}
}
char* CClientManager::GetCommand(char* str)
{
char command[20] = "";
char* tok;
if( str[0] == '[' )
{
tok = strtok(str,"]");
strcat(command,&tok[1]);
}
return command;
}
bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab)
{
if (mysql_num_rows(res) == 0) // µ¥ÀÌÅÍ ¾øÀ½
return false;
memset(pkTab, 0, sizeof(TPlayerTable));
MYSQL_ROW row = mysql_fetch_row(res);
int col = 0;
// "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,level,level_step,st,ht,dx,iq,exp,"
// "stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair,"
// "skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_stamina FROM player%s WHERE id=%d",
str_to_number(pkTab->id, row[col++]);
strncpy(pkTab->name, row[col++], sizeof(pkTab->name));
str_to_number(pkTab->job, row[col++]);
str_to_number(pkTab->voice, row[col++]);
str_to_number(pkTab->dir, row[col++]);
str_to_number(pkTab->x, row[col++]);
str_to_number(pkTab->y, row[col++]);
str_to_number(pkTab->z, row[col++]);
str_to_number(pkTab->lMapIndex, row[col++]);
str_to_number(pkTab->lExitX, row[col++]);
str_to_number(pkTab->lExitY, row[col++]);
str_to_number(pkTab->lExitMapIndex, row[col++]);
str_to_number(pkTab->hp, row[col++]);
str_to_number(pkTab->sp, row[col++]);
str_to_number(pkTab->stamina, row[col++]);
str_to_number(pkTab->sRandomHP, row[col++]);
str_to_number(pkTab->sRandomSP, row[col++]);
str_to_number(pkTab->playtime, row[col++]);
str_to_number(pkTab->gold, row[col++]);
str_to_number(pkTab->level, row[col++]);
str_to_number(pkTab->level_step, row[col++]);
str_to_number(pkTab->st, row[col++]);
str_to_number(pkTab->ht, row[col++]);
str_to_number(pkTab->dx, row[col++]);
str_to_number(pkTab->iq, row[col++]);
str_to_number(pkTab->exp, row[col++]);
str_to_number(pkTab->stat_point, row[col++]);
str_to_number(pkTab->skill_point, row[col++]);
str_to_number(pkTab->sub_skill_point, row[col++]);
str_to_number(pkTab->stat_reset_count, row[col++]);
str_to_number(pkTab->part_base, row[col++]);
str_to_number(pkTab->parts[PART_HAIR], row[col++]);
if (row[col])
thecore_memcpy(pkTab->skills, row[col], sizeof(pkTab->skills));
else
memset(&pkTab->skills, 0, sizeof(pkTab->skills));
col++;
if (row[col])
thecore_memcpy(pkTab->quickslot, row[col], sizeof(pkTab->quickslot));
else
memset(pkTab->quickslot, 0, sizeof(pkTab->quickslot));
col++;
str_to_number(pkTab->skill_group, row[col++]);
str_to_number(pkTab->lAlignment, row[col++]);
if (row[col])
{
strncpy(pkTab->szMobile, row[col], sizeof(pkTab->szMobile));
}
col++;
str_to_number(pkTab->horse.bLevel, row[col++]);
str_to_number(pkTab->horse.bRiding, row[col++]);
str_to_number(pkTab->horse.sHealth, row[col++]);
str_to_number(pkTab->horse.dwHorseHealthDropTime, row[col++]);
str_to_number(pkTab->horse.sStamina, row[col++]);
str_to_number(pkTab->logoff_interval, row[col++]);
str_to_number(pkTab->horse_skill_point, row[col++]);
// reset sub_skill_point
{
pkTab->skills[123].bLevel = 0; // SKILL_CREATE
if (pkTab->level > 9)
{
int max_point = pkTab->level - 9;
int skill_point =
MIN(20, pkTab->skills[121].bLevel) + // SKILL_LEADERSHIP Åë¼Ö·Â
MIN(20, pkTab->skills[124].bLevel) + // SKILL_MINING 䱤
MIN(10, pkTab->skills[131].bLevel) + // SKILL_HORSE_SUMMON ¸»¼Òȯ
MIN(20, pkTab->skills[141].bLevel) + // SKILL_ADD_HP HPº¸°­
MIN(20, pkTab->skills[142].bLevel); // SKILL_RESIST_PENETRATE °üÅëÀúÇ×
pkTab->sub_skill_point = max_point - skill_point;
}
else
pkTab->sub_skill_point = 0;
}
return true;
}
void CClientManager::RESULT_COMPOSITE_PLAYER(CPeer * peer, SQLMsg * pMsg, DWORD dwQID)
{
CQueryInfo * qi = (CQueryInfo *) pMsg->pvUserData;
std::auto_ptr<ClientHandleInfo> info((ClientHandleInfo *) qi->pvData);
MYSQL_RES * pSQLResult = pMsg->Get()->pSQLResult;
if (!pSQLResult)
{
sys_err("null MYSQL_RES QID %u", dwQID);
return;
}
switch (dwQID)
{
case QID_PLAYER:
sys_log(0, "QID_PLAYER %u %u", info->dwHandle, info->player_id);
RESULT_PLAYER_LOAD(peer, pSQLResult, info.get());
break;
case QID_ITEM:
sys_log(0, "QID_ITEM %u", info->dwHandle);
RESULT_ITEM_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
break;
case QID_QUEST:
{
sys_log(0, "QID_QUEST %u", info->dwHandle);
RESULT_QUEST_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
//aid¾ò±â
ClientHandleInfo* temp1 = info.get();
if (temp1 == NULL)
break;
CLoginData* pLoginData1 = GetLoginDataByAID(temp1->account_id); //
//µ¶ÀÏ ¼±¹° ±â´É
if( pLoginData1->GetAccountRef().login == NULL)
break;
if( pLoginData1 == NULL )
break;
sys_log(0,"info of pLoginData1 before call ItemAwardfunction %d",pLoginData1);
ItemAward(peer,pLoginData1->GetAccountRef().login);
}
break;
case QID_AFFECT:
sys_log(0, "QID_AFFECT %u", info->dwHandle);
RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle);
break;
/*
case QID_PLAYER_ITEM_QUEST_AFFECT:
sys_log(0, "QID_PLAYER_ITEM_QUEST_AFFECT %u", info->dwHandle);
RESULT_PLAYER_LOAD(peer, pSQLResult, info->dwHandle);
if (!pMsg->Next())
{
sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: ITEM FAILED");
return;
}
case QID_ITEM_QUEST_AFFECT:
sys_log(0, "QID_ITEM_QUEST_AFFECT %u", info->dwHandle);
RESULT_ITEM_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
if (!pMsg->Next())
{
sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: QUEST FAILED");
return;
}
case QID_QUEST_AFFECT:
sys_log(0, "QID_QUEST_AFFECT %u", info->dwHandle);
RESULT_QUEST_LOAD(peer, pSQLResult, info->dwHandle);
if (!pMsg->Next())
sys_err("RESULT_COMPOSITE_PLAYER: QID_PLAYER_ITEM_QUEST_AFFECT: AFFECT FAILED");
else
RESULT_AFFECT_LOAD(peer, pSQLResult, info->dwHandle);
break;
*/
}
}
void CClientManager::RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHandleInfo * pkInfo)
{
TPlayerTable tab;
if (!CreatePlayerTableFromRes(pRes, &tab))
{
peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, pkInfo->dwHandle, 0);
return;
}
CLoginData * pkLD = GetLoginDataByAID(pkInfo->account_id);
if (!pkLD || pkLD->IsPlay())
{
sys_log(0, "PLAYER_LOAD_ERROR: LoginData %p IsPlay %d", pkLD, pkLD ? pkLD->IsPlay() : 0);
peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, pkInfo->dwHandle, 0);
return;
}
pkLD->SetPlay(true);
SendLoginToBilling(pkLD, true);
thecore_memcpy(tab.aiPremiumTimes, pkLD->GetPremiumPtr(), sizeof(tab.aiPremiumTimes));
peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_SUCCESS, pkInfo->dwHandle, sizeof(TPlayerTable));
peer->Encode(&tab, sizeof(TPlayerTable));
if (tab.id != pkLD->GetLastPlayerID())
{
TPacketNeedLoginLogInfo logInfo;
logInfo.dwPlayerID = tab.id;
pkLD->SetLastPlayerID( tab.id );
peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, pkInfo->dwHandle, sizeof(TPacketNeedLoginLogInfo) );
peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) );
}
}
void CClientManager::RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwPID)
{
static std::vector<TPlayerItem> s_items;
//DB¿¡¼­ ¾ÆÀÌÅÛ Á¤º¸¸¦ Àоî¿Â´Ù.
CreateItemTableFromRes(pRes, &s_items, dwPID);
DWORD dwCount = s_items.size();
peer->EncodeHeader(HEADER_DG_ITEM_LOAD, dwHandle, sizeof(DWORD) + sizeof(TPlayerItem) * dwCount);
peer->EncodeDWORD(dwCount);
//CacheSetÀ» ¸¸µç´Ù
CreateItemCacheSet(dwPID);
// ITEM_LOAD_LOG_ATTACH_PID
sys_log(0, "ITEM_LOAD: count %u pid %u", dwCount, dwPID);
// END_OF_ITEM_LOAD_LOG_ATTACH_PID
if (dwCount)
{
peer->Encode(&s_items[0], sizeof(TPlayerItem) * dwCount);
for (DWORD i = 0; i < dwCount; ++i)
PutItemCache(&s_items[i], true); // ·ÎµåÇÑ °ÍÀº µû·Î ÀúÀåÇÒ ÇÊ¿ä ¾øÀ¸¹Ç·Î, ÀÎÀÚ bSkipQuery¿¡ true¸¦ ³Ö´Â´Ù.
}
}
void CClientManager::RESULT_AFFECT_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle)
{
int iNumRows;
if ((iNumRows = mysql_num_rows(pRes)) == 0) // µ¥ÀÌÅÍ ¾øÀ½
return;
static std::vector<TPacketAffectElement> s_elements;
s_elements.resize(iNumRows);
DWORD dwPID = 0;
MYSQL_ROW row;
for (int i = 0; i < iNumRows; ++i)
{
TPacketAffectElement & r = s_elements[i];
row = mysql_fetch_row(pRes);
if (dwPID == 0)
str_to_number(dwPID, row[0]);
str_to_number(r.dwType, row[1]);
str_to_number(r.bApplyOn, row[2]);
str_to_number(r.lApplyValue, row[3]);
str_to_number(r.dwFlag, row[4]);
str_to_number(r.lDuration, row[5]);
str_to_number(r.lSPCost, row[6]);
}
sys_log(0, "AFFECT_LOAD: count %d PID %u", s_elements.size(), dwPID);
DWORD dwCount = s_elements.size();
peer->EncodeHeader(HEADER_DG_AFFECT_LOAD, dwHandle, sizeof(DWORD) + sizeof(DWORD) + sizeof(TPacketAffectElement) * dwCount);
peer->Encode(&dwPID, sizeof(DWORD));
peer->Encode(&dwCount, sizeof(DWORD));
peer->Encode(&s_elements[0], sizeof(TPacketAffectElement) * dwCount);
}
void CClientManager::RESULT_QUEST_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD pid)
{
int iNumRows;
if ((iNumRows = mysql_num_rows(pRes)) == 0)
{
DWORD dwCount = 0;
peer->EncodeHeader(HEADER_DG_QUEST_LOAD, dwHandle, sizeof(DWORD));
peer->Encode(&dwCount, sizeof(DWORD));
return;
}
static std::vector<TQuestTable> s_table;
s_table.resize(iNumRows);
MYSQL_ROW row;
for (int i = 0; i < iNumRows; ++i)
{
TQuestTable & r = s_table[i];
row = mysql_fetch_row(pRes);
str_to_number(r.dwPID, row[0]);
strncpy(r.szName, row[1], sizeof(r.szName));
strncpy(r.szState, row[2], sizeof(r.szState));
str_to_number(r.lValue, row[3]);
}
sys_log(0, "QUEST_LOAD: count %d PID %u", s_table.size(), s_table[0].dwPID);
DWORD dwCount = s_table.size();
peer->EncodeHeader(HEADER_DG_QUEST_LOAD, dwHandle, sizeof(DWORD) + sizeof(TQuestTable) * dwCount);
peer->Encode(&dwCount, sizeof(DWORD));
peer->Encode(&s_table[0], sizeof(TQuestTable) * dwCount);
}
/*
* PLAYER SAVE
*/
void CClientManager::QUERY_PLAYER_SAVE(CPeer * peer, DWORD dwHandle, TPlayerTable * pkTab)
{
if (g_test_server)
sys_log(0, "PLAYER_SAVE: %s", pkTab->name);
PutPlayerCache(pkTab);
}
typedef std::map<DWORD, time_t> time_by_id_map_t;
static time_by_id_map_t s_createTimeByAccountID;
/*
* PLAYER CREATE
*/
void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket* packet)
{
char queryStr[QUERY_MAX_LEN];
int queryLen;
int player_id;
// ÇÑ °èÁ¤¿¡ XÃÊ ³»·Î ij¸¯ÅÍ »ý¼ºÀ» ÇÒ ¼ö ¾ø´Ù.
time_by_id_map_t::iterator it = s_createTimeByAccountID.find(packet->account_id);
if (it != s_createTimeByAccountID.end())
{
time_t curtime = time(0);
if (curtime - it->second < 30)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
}
queryLen = snprintf(queryStr, sizeof(queryStr),
"SELECT pid%u FROM player_index%s WHERE id=%d", packet->account_index + 1, GetTablePostfix(), packet->account_id);
std::auto_ptr<SQLMsg> pMsg0(CDBManager::instance().DirectQuery(queryStr));
if (pMsg0->Get()->uiNumRows != 0)
{
if (!pMsg0->Get()->pSQLResult)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg0->Get()->pSQLResult);
DWORD dwPID = 0; str_to_number(dwPID, row[0]);
if (row[0] && dwPID > 0)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
sys_log(0, "ALREADY EXIST AccountChrIdx %d ID %d", packet->account_index, dwPID);
return;
}
}
else
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
if (g_stLocale == "sjis")
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci",
GetTablePostfix(), packet->player_table.name);
else
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s'", GetTablePostfix(), packet->player_table.name);
std::auto_ptr<SQLMsg> pMsg1(CDBManager::instance().DirectQuery(queryStr));
if (pMsg1->Get()->uiNumRows)
{
if (!pMsg1->Get()->pSQLResult)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg1->Get()->pSQLResult);
if (*row[0] != '0')
{
sys_log(0, "ALREADY EXIST name %s, row[0] %s query %s", packet->player_table.name, row[0], queryStr);
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
return;
}
}
else
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
queryLen = snprintf(queryStr, sizeof(queryStr),
"INSERT INTO player%s "
"(id, account_id, name, level, st, ht, dx, iq, "
"job, voice, dir, x, y, z, "
"hp, mp, random_hp, random_sp, stat_point, stamina, part_base, part_main, part_hair, gold, playtime, "
"skill_level, quickslot) "
"VALUES(0, %u, '%s', %d, %d, %d, %d, %d, "
"%d, %d, %d, %d, %d, %d, %d, "
"%d, %d, %d, %d, %d, %d, %d, 0, %d, 0, ",
GetTablePostfix(),
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,
packet->player_table.job, packet->player_table.voice, packet->player_table.dir, packet->player_table.x, packet->player_table.y, packet->player_table.z,
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);
sys_log(0, "PlayerCreate accountid %d name %s level %d gold %d, st %d ht %d job %d",
packet->account_id,
packet->player_table.name,
packet->player_table.level,
packet->player_table.gold,
packet->player_table.st,
packet->player_table.ht,
packet->player_table.job);
static char text[4096 + 1];
CDBManager::instance().EscapeString(text, packet->player_table.skills, sizeof(packet->player_table.skills));
queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s', ", text);
if (g_test_server)
sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text);
CDBManager::instance().EscapeString(text, packet->player_table.quickslot, sizeof(packet->player_table.quickslot));
queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s')", text);
std::auto_ptr<SQLMsg> pMsg2(CDBManager::instance().DirectQuery(queryStr));
if (g_test_server)
sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text);
if (pMsg2->Get()->uiAffectedRows <= 0)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
sys_log(0, "ALREADY EXIST3 query: %s AffectedRows %lu", queryStr, pMsg2->Get()->uiAffectedRows);
return;
}
player_id = pMsg2->Get()->uiInsertID;
snprintf(queryStr, sizeof(queryStr), "UPDATE player_index%s SET pid%d=%d WHERE id=%d",
GetTablePostfix(), packet->account_index + 1, player_id, packet->account_id);
std::auto_ptr<SQLMsg> pMsg3(CDBManager::instance().DirectQuery(queryStr));
if (pMsg3->Get()->uiAffectedRows <= 0)
{
sys_err("QUERY_ERROR: %s", queryStr);
snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), player_id);
CDBManager::instance().DirectQuery(queryStr);
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
TPacketDGCreateSuccess pack;
memset(&pack, 0, sizeof(pack));
pack.bAccountCharacterIndex = packet->account_index;
pack.player.dwID = player_id;
strncpy(pack.player.szName, packet->player_table.name, sizeof(pack.player.szName));
pack.player.byJob = packet->player_table.job;
pack.player.byLevel = 1;
pack.player.dwPlayMinutes = 0;
pack.player.byST = packet->player_table.st;
pack.player.byHT = packet->player_table.ht;
pack.player.byDX = packet->player_table.dx;
pack.player.byIQ = packet->player_table.iq;
pack.player.wMainPart = packet->player_table.part_base;
pack.player.x = packet->player_table.x;
pack.player.y = packet->player_table.y;
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_SUCCESS, dwHandle, sizeof(TPacketDGCreateSuccess));
peer->Encode(&pack, sizeof(TPacketDGCreateSuccess));
sys_log(0, "7 name %s job %d", pack.player.szName, pack.player.byJob);
s_createTimeByAccountID[packet->account_id] = time(0);
}
/*
* PLAYER DELETE
*/
void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerDeletePacket* packet)
{
if (!packet->login[0] || !packet->player_id || packet->account_index >= PLAYER_PER_ACCOUNT)
return;
CLoginData * ld = GetLoginDataByLogin(packet->login);
if (!ld)
{
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
peer->EncodeBYTE(packet->account_index);
return;
}
TAccountTable & r = ld->GetAccountRef();
// block for japan
if (g_stLocale != "sjis")
{
if (!IsChinaEventServer())
{
if (strlen(r.social_id) < 7 || strncmp(packet->private_code, r.social_id + strlen(r.social_id) - 7, 7))
{
sys_log(0, "PLAYER_DELETE FAILED len(%d)", strlen(r.social_id));
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
peer->EncodeBYTE(packet->account_index);
return;
}
CPlayerTableCache * pkPlayerCache = GetPlayerCache(packet->player_id);
if (pkPlayerCache)
{
TPlayerTable * pTab = pkPlayerCache->Get();
if (pTab->level >= m_iPlayerDeleteLevelLimit)
{
sys_log(0, "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d", pTab->level, m_iPlayerDeleteLevelLimit);
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
peer->EncodeBYTE(packet->account_index);
return;
}
if (pTab->level < m_iPlayerDeleteLevelLimitLower)
{
sys_log(0, "PLAYER_DELETE FAILED LEVEL %u < DELETE LIMIT %d", pTab->level, m_iPlayerDeleteLevelLimitLower);
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, dwHandle, 1);
peer->EncodeBYTE(packet->account_index);
return;
}
}
}
}
char szQuery[128];
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",
GetTablePostfix(), GetTablePostfix(), packet->account_index + 1, packet->player_id, packet->account_index + 1);
ClientHandleInfo * pi = new ClientHandleInfo(dwHandle, packet->player_id);
pi->account_index = packet->account_index;
sys_log(0, "PLAYER_DELETE TRY: %s %d pid%d", packet->login, packet->player_id, packet->account_index + 1);
CDBManager::instance().ReturnQuery(szQuery, QID_PLAYER_DELETE, peer->GetHandle(), pi);
}
//
// @version 05/06/10 Bang2ni - Ç÷¹ÀÌ¾î »èÁ¦½Ã °¡°ÝÁ¤º¸ ¸®½ºÆ® »èÁ¦ Ãß°¡.
//
void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData;
if (msg->Get() && msg->Get()->uiNumRows)
{
MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult);
DWORD dwPID = 0;
str_to_number(dwPID, row[0]);
int deletedLevelLimit = 0;
str_to_number(deletedLevelLimit, row[1]);
char szName[64];
strncpy(szName, row[2], sizeof(szName));
if (deletedLevelLimit >= m_iPlayerDeleteLevelLimit && !IsChinaEventServer())
{
sys_log(0, "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d", deletedLevelLimit, m_iPlayerDeleteLevelLimit);
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
peer->EncodeBYTE(pi->account_index);
return;
}
if (deletedLevelLimit < m_iPlayerDeleteLevelLimitLower)
{
sys_log(0, "PLAYER_DELETE FAILED LEVEL %u < DELETE LIMIT %d", deletedLevelLimit, m_iPlayerDeleteLevelLimitLower);
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
peer->EncodeBYTE(pi->account_index);
return;
}
char queryStr[QUERY_MAX_LEN];
snprintf(queryStr, sizeof(queryStr), "INSERT INTO player%s_deleted SELECT * FROM player%s WHERE id=%d",
GetTablePostfix(), GetTablePostfix(), pi->player_id);
std::auto_ptr<SQLMsg> pIns(CDBManager::instance().DirectQuery(queryStr));
if (pIns->Get()->uiAffectedRows == 0 || pIns->Get()->uiAffectedRows == (uint32_t)-1)
{
sys_log(0, "PLAYER_DELETE FAILED %u CANNOT INSERT TO player%s_deleted", dwPID, GetTablePostfix());
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
peer->EncodeBYTE(pi->account_index);
return;
}
// »èÁ¦ ¼º°ø
sys_log(0, "PLAYER_DELETE SUCCESS %u", dwPID);
char account_index_string[16];
snprintf(account_index_string, sizeof(account_index_string), "player_id%d", m_iPlayerIDStart + pi->account_index);
// Ç÷¹À̾î Å×À̺íÀ» ij½¬¿¡¼­ »èÁ¦ÇÑ´Ù.
CPlayerTableCache * pkPlayerCache = GetPlayerCache(pi->player_id);
if (pkPlayerCache)
{
m_map_playerCache.erase(pi->player_id);
delete pkPlayerCache;
}
// ¾ÆÀÌÅÛµéÀ» ij½¬¿¡¼­ »èÁ¦ÇÑ´Ù.
TItemCacheSet * pSet = GetItemCacheSet(pi->player_id);
if (pSet)
{
TItemCacheSet::iterator it = pSet->begin();
while (it != pSet->end())
{
CItemCache * pkItemCache = *it++;
DeleteItemCache(pkItemCache->Get()->id);
}
pSet->clear();
delete pSet;
m_map_pkItemCacheSetPtr.erase(pi->player_id);
}
snprintf(queryStr, sizeof(queryStr), "UPDATE player_index%s SET pid%u=0 WHERE pid%u=%d",
GetTablePostfix(),
pi->account_index + 1,
pi->account_index + 1,
pi->player_id);
std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(queryStr));
if (pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1)
{
sys_log(0, "PLAYER_DELETE FAIL WHEN UPDATE account table");
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
peer->EncodeBYTE(pi->account_index);
return;
}
snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), pi->player_id);
delete CDBManager::instance().DirectQuery(queryStr);
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);
delete CDBManager::instance().DirectQuery(queryStr);
snprintf(queryStr, sizeof(queryStr), "DELETE FROM quest%s WHERE dwPID=%d", GetTablePostfix(), pi->player_id);
CDBManager::instance().AsyncQuery(queryStr);
snprintf(queryStr, sizeof(queryStr), "DELETE FROM affect%s WHERE dwPID=%d", GetTablePostfix(), pi->player_id);
CDBManager::instance().AsyncQuery(queryStr);
snprintf(queryStr, sizeof(queryStr), "DELETE FROM guild_member%s WHERE pid=%d", GetTablePostfix(), pi->player_id);
CDBManager::instance().AsyncQuery(queryStr);
// MYSHOP_PRICE_LIST
snprintf(queryStr, sizeof(queryStr), "DELETE FROM myshop_pricelist%s WHERE owner_id=%d", GetTablePostfix(), pi->player_id);
CDBManager::instance().AsyncQuery(queryStr);
// END_OF_MYSHOP_PRICE_LIST
snprintf(queryStr, sizeof(queryStr), "DELETE FROM messenger_list%s WHERE account='%s' OR companion='%s'", GetTablePostfix(), szName, szName);
CDBManager::instance().AsyncQuery(queryStr);
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_SUCCESS, pi->dwHandle, 1);
peer->EncodeBYTE(pi->account_index);
}
else
{
// »èÁ¦ ½ÇÆÐ
sys_log(0, "PLAYER_DELETE FAIL NO ROW");
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
peer->EncodeBYTE(pi->account_index);
}
}
void CClientManager::QUERY_ADD_AFFECT(CPeer * peer, TPacketGDAddAffect * p)
{
char queryStr[QUERY_MAX_LEN];
/*
snprintf(queryStr, sizeof(queryStr),
"INSERT INTO affect%s (dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost) "
"VALUES(%u, %u, %u, %d, %u, %d, %d) "
"ON DUPLICATE KEY UPDATE lApplyValue=%d, dwFlag=%u, lDuration=%d, lSPCost=%d",
GetTablePostfix(),
p->dwPID,
p->elem.dwType,
p->elem.bApplyOn,
p->elem.lApplyValue,
p->elem.dwFlag,
p->elem.lDuration,
p->elem.lSPCost,
p->elem.lApplyValue,
p->elem.dwFlag,
p->elem.lDuration,
p->elem.lSPCost);
*/
snprintf(queryStr, sizeof(queryStr),
"REPLACE INTO affect%s (dwPID, bType, bApplyOn, lApplyValue, dwFlag, lDuration, lSPCost) "
"VALUES(%u, %u, %u, %ld, %u, %ld, %ld)",
GetTablePostfix(),
p->dwPID,
p->elem.dwType,
p->elem.bApplyOn,
p->elem.lApplyValue,
p->elem.dwFlag,
p->elem.lDuration,
p->elem.lSPCost);
CDBManager::instance().AsyncQuery(queryStr);
}
void CClientManager::QUERY_REMOVE_AFFECT(CPeer * peer, TPacketGDRemoveAffect * p)
{
char queryStr[QUERY_MAX_LEN];
snprintf(queryStr, sizeof(queryStr),
"DELETE FROM affect%s WHERE dwPID=%u AND bType=%u AND bApplyOn=%u",
GetTablePostfix(), p->dwPID, p->dwType, p->bApplyOn);
CDBManager::instance().AsyncQuery(queryStr);
}
void CClientManager::QUERY_HIGHSCORE_REGISTER(CPeer* peer, TPacketGDHighscore * data)
{
char szQuery[128];
snprintf(szQuery, sizeof(szQuery), "SELECT value FROM highscore%s WHERE board='%s' AND pid = %u", GetTablePostfix(), data->szBoard, data->dwPID);
sys_log(0, "HEADER_GD_HIGHSCORE_REGISTER: PID %u", data->dwPID);
ClientHandleInfo * pi = new ClientHandleInfo(0);
strncpy(pi->login, data->szBoard, sizeof(pi->login));
pi->account_id = (DWORD)data->lValue;
pi->player_id = data->dwPID;
pi->account_index = (data->cDir > 0);
CDBManager::instance().ReturnQuery(szQuery, QID_HIGHSCORE_REGISTER, peer->GetHandle(), pi);
}
void CClientManager::RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData;
//DWORD dwHandle = pi->dwHandle;
char szBoard[21];
strncpy(szBoard, pi->login, sizeof(szBoard));
int value = (int)pi->account_id;
SQLResult * res = msg->Get();
if (res->uiNumRows == 0)
{
// »õ·Î¿î ÇÏÀ̽ºÄھ »ðÀÔ
char buf[256];
snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value);
CDBManager::instance().AsyncQuery(buf);
}
else
{
if (!res->pSQLResult)
{
delete pi;
return;
}
MYSQL_ROW row = mysql_fetch_row(res->pSQLResult);
if (row && row[0])
{
int current_value = 0; str_to_number(current_value, row[0]);
if (pi->account_index && current_value >= value || !pi->account_index && current_value <= value)
{
value = current_value;
}
else
{
char buf[256];
snprintf(buf, sizeof(buf), "REPLACE INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value);
CDBManager::instance().AsyncQuery(buf);
}
}
else
{
char buf[256];
snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value);
CDBManager::instance().AsyncQuery(buf);
}
}
// TODO: ÀÌ°÷¿¡¼­ ÇÏÀ̽ºÄھ ¾÷µ¥ÀÌÆ® µÇ¾ú´ÂÁö üũÇÏ¿© °øÁö¸¦ »Ñ·Á¾ßÇÑ´Ù.
delete pi;
}
void CClientManager::InsertLogoutPlayer(DWORD pid)
{
TLogoutPlayerMap::iterator it = m_map_logout.find(pid);
// Á¸ÀçÇÏÁö ¾ÊÀ»°æ¿ì Ãß°¡
if (it != m_map_logout.end())
{
// Á¸ÀçÇÒ°æ¿ì ½Ã°£¸¸ °»½Å
if (g_log)
sys_log(0, "LOGOUT: Update player time pid(%d)", pid);
it->second->time = time(0);
return;
}
TLogoutPlayer * pLogout = new TLogoutPlayer;
pLogout->pid = pid;
pLogout->time = time(0);
m_map_logout.insert(std::make_pair(pid, pLogout));
if (g_log)
sys_log(0, "LOGOUT: Insert player pid(%d)", pid);
}
void CClientManager::DeleteLogoutPlayer(DWORD pid)
{
TLogoutPlayerMap::iterator it = m_map_logout.find(pid);
if (it != m_map_logout.end())
{
delete it->second;
m_map_logout.erase(it);
}
}
extern int g_iLogoutSeconds;
void CClientManager::UpdateLogoutPlayer()
{
time_t now = time(0);
TLogoutPlayerMap::iterator it = m_map_logout.begin();
while (it != m_map_logout.end())
{
TLogoutPlayer* pLogout = it->second;
if (now - g_iLogoutSeconds > pLogout->time)
{
FlushItemCacheSet(pLogout->pid);
FlushPlayerCacheSet(pLogout->pid);
delete pLogout;
m_map_logout.erase(it++);
}
else
++it;
}
}
void CClientManager::FlushPlayerCacheSet(DWORD pid)
{
TPlayerTableCacheMap::iterator it = m_map_playerCache.find(pid);
if (it != m_map_playerCache.end())
{
CPlayerTableCache * c = it->second;
m_map_playerCache.erase(it);
c->Flush();
delete c;
}
}