backtop 17 Posted June 20 Share Posted June 20 Hey Com, i implemented 5th Slot per Account and its working fine just got the problem when i log in into game i always have to select the empire... this happens on every log in... Syserr server and client are empty Can someone help me here please? Maybe there is an error in this function in ClientManager.cpp Spoiler void CClientManager::QUERY_EMPIRE_SELECT(CPeer * pkPeer, DWORD dwHandle, TEmpireSelectPacket * p) { char szQuery[QUERY_MAX_LEN]; snprintf(szQuery, sizeof(szQuery), "UPDATE player_index%s SET empire=%u WHERE id=%u", GetTablePostfix(), p->bEmpire, p->dwAccountID); delete CDBManager::instance().DirectQuery(szQuery); sys_log(0, "EmpireSelect: %s", szQuery); { snprintf(szQuery, sizeof(szQuery), #ifdef __PLAYER_PER_ACCOUNT5__ "SELECT pid1, pid2, pid3, pid4, pid5 FROM player_index%s WHERE id=%u", GetTablePostfix(), p->dwAccountID); #else "SELECT pid1, pid2, pid3, pid4 FROM player_index%s WHERE id=%u", GetTablePostfix(), p->dwAccountID); #endif std::unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery)); SQLResult * pRes = pmsg->Get(); if (pRes->uiNumRows) { sys_log(0, "EMPIRE %lu", pRes->uiNumRows); MYSQL_ROW row = mysql_fetch_row(pRes->pSQLResult); DWORD pids[3]; UINT g_start_map[4] = { 0, // reserved 1, // 신수국 21, // 천조국 41 // 진노국 }; // FIXME share with game DWORD g_start_position[4][2]= { { 0, 0 }, { 469300, 964200 }, // 신수국 { 55700, 157900 }, // 천조국 { 969600, 278400 } // 진노국 }; for (int i = 0; i < 3; ++i) { str_to_number(pids[i], row[i]); sys_log(0, "EMPIRE PIDS[%d]", pids[i]); if (pids[i]) { sys_log(0, "EMPIRE move to pid[%d] to villiage of %u, map_index %d", pids[i], p->bEmpire, g_start_map[p->bEmpire]); snprintf(szQuery, sizeof(szQuery), "UPDATE player%s SET map_index=%u,x=%u,y=%u WHERE id=%u", GetTablePostfix(), g_start_map[p->bEmpire], g_start_position[p->bEmpire][0], g_start_position[p->bEmpire][1], pids[i]); std::unique_ptr<SQLMsg> pmsg2(CDBManager::instance().DirectQuery(szQuery)); } } } } pkPeer->EncodeHeader(HEADER_DG_EMPIRE_SELECT, dwHandle, sizeof(BYTE)); pkPeer->EncodeBYTE(p->bEmpire); } pid5 is implemented in player_index in db... Link to comment Share on other sites More sharing options...
Contributor Amun 1921 Posted Friday at 09:52 PM Contributor Share Posted Friday at 09:52 PM You should have PLAYER_PER_ACCOUNT in length iirc, but the problem isn't from here(should still fix them though) DWORD pids[PLAYER_PER_ACCOUNT]{}; for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i) The problem is probably from root. If you're using the new UI, look for this def LoadCharacterData(self) : self.RefreshData() self.MainStream.All_ButtonInfoHide() for i in xrange(net.CHARACTER_SLOT_COUNT_MAX) : # This should be 5 If you're using the old UI, then it's probably this def __AreAllSlotEmpty(self): for iSlot in xrange(self.SLOT_COUNT): if 0!=net.GetAccountCharacterSlotDataInteger(iSlot, net.ACCOUNT_CHARACTER_SLOT_ID): return 0 return 1 Note: there could be other parts that need to be updated, but this is just what I found at first glance. If it's not from the root, then check your queries and your packets. Link to comment Share on other sites More sharing options...
backtop 17 Posted Saturday at 06:35 AM Author Share Posted Saturday at 06:35 AM (edited) 8 hours ago, Amun said: You should have PLAYER_PER_ACCOUNT in length iirc, but the problem isn't from here(should still fix them though) DWORD pids[PLAYER_PER_ACCOUNT]{}; for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i) The problem is probably from root. If you're using the new UI, look for this def LoadCharacterData(self) : self.RefreshData() self.MainStream.All_ButtonInfoHide() for i in xrange(net.CHARACTER_SLOT_COUNT_MAX) : # This should be 5 If you're using the old UI, then it's probably this def __AreAllSlotEmpty(self): for iSlot in xrange(self.SLOT_COUNT): if 0!=net.GetAccountCharacterSlotDataInteger(iSlot, net.ACCOUNT_CHARACTER_SLOT_ID): return 0 return 1 Note: there could be other parts that need to be updated, but this is just what I found at first glance. If it's not from the root, then check your queries and your packets. Hey thank you for your time. I change this: DWORD pids[3]; to this: DWORD pids[PLAYER_PER_ACCOUNT]{}; and this: for (int i = 0; i < 3; ++i) to this: for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i) and it doesn't work... error is still there I'm using the old UI and this: def __AreAllSlotEmpty(self): for iSlot in xrange(self.SLOT_COUNT): if 0!=net.GetAccountCharacterSlotDataInteger(iSlot, net.ACCOUNT_CHARACTER_SLOT_ID): return 0 return 1 is already implemented... do i have to change something there? I edited only packets.h in client source, and Queries only in db source... it looks fine to me but can post the functions here Edited Saturday at 06:37 AM by backtop Link to comment Share on other sites More sharing options...
Contributor Amun 1921 Posted Saturday at 08:22 AM Contributor Share Posted Saturday at 08:22 AM For this: def __AreAllSlotEmpty(self): for iSlot in xrange(self.SLOT_COUNT): if 0!=net.GetAccountCharacterSlotDataInteger(iSlot, net.ACCOUNT_CHARACTER_SLOT_ID): return 0 return 1 SLOT_COUNT should be 5, yes Have a look at what the empire is for that account in player_index. If it's 0, then your query isn't updating the table. If it's over 0, then the problem is either from the query that loads the player, a packet that you forgot to update, the client source or the root(but the root should be fine if you said you updated it). It's difficult to tell you exactly what to check because you have to check both sources and the root, so the problem could be anywhere. What you need to do is to go to the select empire part of the root and work your way up through the sources, then back down through the login path to make sure that everything's updated. Can't tell you more than that Link to comment Share on other sites More sharing options...
backtop 17 Posted Saturday at 01:29 PM Author Share Posted Saturday at 01:29 PM 2 hours ago, Amun said: SLOT_COUNT should be 5, yes Haha yeah its already changed xD 2 hours ago, Amun said: Have a look at what the empire is for that account in player_index. Empire is 2 in player_index... means the yellow empire 2 hours ago, Amun said: If it's 0, then your query isn't updating the table. If it's over 0, then the problem is either from the query that loads the player, a packet that you forgot to update, the client source or the root(but the root should be fine if you said you updated it). When i change the empire on login to blue the empire in player_index changes to 3, even i already select the empire (yellow = 2) when creating the account... could be the player load query but i didn't touched it... which packet? i only edited the client source packet.h Player Load Query: Spoiler void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket * packet) { CPlayerTableCache * c; TPlayerTable * pTab; // // 한 계정에 속한 모든 캐릭터들 캐쉬처리 // 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 " #ifdef ENABLE_SOULBIND_SYSTEM ",sealbind " #endif "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]; //-------------------------------------------------------------- // 캐릭터 정보 얻어오기 : 무조건 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,envanter 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 " #ifdef ENABLE_SOULBIND_SYSTEM ",sealbind " #endif "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)); } } Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now