#include "stdafx.h" #include "AuthDispatch.h" #include "Part1DBAgentDispatch.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DBAgent { class CCharBackupItemData { public: CCharBackupItemData() : m_bBackupData(false), m_cOldServerGroupID(0) { memset(&m_CharInfo, 0, sizeof(CHAR_INFOST)); // ±âº» Á¤º¸ memset(&m_Skill, 0, sizeof(SKILL)); // ½ºÅ³ Á¤º¸ memset(&m_Equip, 0, sizeof(EQUIP)); // Àåºñ memset(&m_Inven, 0, sizeof(INVEN)); // Àκ¥ memset(&m_Extra, 0, sizeof(EXTRA)); // ¿©ºÐ memset(&m_Exchange, 0, sizeof(EXCHANGE)); // ±³È¯ memset(&m_TempInven, 0, sizeof(TEMPINVEN)); // Àӽà Àκ¥Å丮 memset(&m_Quest, 0, sizeof(QUEST)); // Äù½ºÆ® memset(&m_History, 0, sizeof(HISTORY)); // È÷½ºÅ丮 } bool IsBackupedData() const { return m_bBackupData; } unsigned char GetOldServerGroupID() const { return m_cOldServerGroupID; } void BackupData(DataStorage::CSessionData& sessionData, DataStorage::CCharacterData& charData) { m_CharInfo = charData.GetInfo(); m_Skill = charData.GetSkill(); m_Equip = charData.GetEquip(); m_Inven = charData.GetInven(); m_Extra = charData.GetExtra(); m_Exchange = charData.GetExchange(); m_TempInven = charData.GetTempInven(); m_Quest = charData.GetQuest(); m_History = charData.GetHistory(); const UnifiedCharData* lpUnifiedCharData = sessionData.GetUnifiedCharData(charData.GetCID()); if(0 != lpUnifiedCharData) { m_cOldServerGroupID = lpUnifiedCharData->cOldServerGroupID; } m_bBackupData = true; } void RestoreData(DataStorage::CCharacterData& charData) { if (m_bBackupData) { charData.SetInfo(m_CharInfo); charData.SetSkill(m_Skill); charData.SetEquip(m_Equip.Data, m_Equip.dwSize); charData.SetInven(m_Inven.Data, m_Inven.dwSize); charData.SetExtra(m_Extra.Data, m_Extra.dwSize); charData.SetExchange(m_Exchange.Data, m_Exchange.dwSize); charData.SetTempInven(m_TempInven.Data, m_TempInven.dwSize); charData.SetQuest(m_Quest); charData.SetHistory(m_History); } } private: CHAR_INFOST m_CharInfo; // ±âº» Á¤º¸ SKILL m_Skill; // ½ºÅ³ Á¤º¸ EQUIP m_Equip; // Àåºñ INVEN m_Inven; // Àκ¥ EXTRA m_Extra; // ¿©ºÐ EXCHANGE m_Exchange; // ±³È¯ TEMPINVEN m_TempInven; // Àӽà Àκ¥Å丮 QUEST m_Quest; // Äù½ºÆ® HISTORY m_History; // History unsigned char m_cOldServerGroupID; // ¿¹Àü ¼­¹ö±×·ì ID bool m_bBackupData; // µ¥ÀÌÅÍ ¹é¾÷µÇ¾ú´ÂÁö ¿©ºÎ }; void ProcessUnifiedCharSelect(CSendStream& SendStream, PktBase* lpPktBase); CSingleDispatch& CPart1DBAgentDispatch::GetDispatchTable() { static CSingleDispatch part1DBAgentDispatch; return part1DBAgentDispatch; } CPart1DBAgentDispatch::CPart1DBAgentDispatch(CSession& Session) : CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE) { } CPart1DBAgentDispatch::~CPart1DBAgentDispatch() { } void CPart1DBAgentDispatch::Connected() { DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Part1 DBAgentServer Connected", &GetSession(), this, GetRemoteAddr().get_addr_string()); GetDispatchTable().SetDispatch(this); SendPacket::ServerLogin(GetSendStream(), CServerSetup::GetInstance().GetServerID()); } void CPart1DBAgentDispatch::Disconnected() { DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Part1 DBAgentServer Disconnected", &GetSession(), this, GetRemoteAddr().get_addr_string()); GetDispatchTable().RemoveDispatch(this); } bool CPart1DBAgentDispatch::DispatchPacket(PktBase* lpPktBase) { switch(lpPktBase->GetCmd()) { case CmdUnifiedCharSelect: ProcessUnifiedCharSelect(GetSendStream(), lpPktBase); break; } return true; } bool CPart1DBAgentDispatch::TransferCharPart1ToPart2(CSendStream& SendStream, unsigned long dwUID, unsigned char cSelectedServerGroup, unsigned char cSelectedNation, unsigned long* lpdwSelectedCID, unsigned char cSelectedCharNum) { char* lpBuffer = SendStream.GetBuffer(sizeof(PktUnifiedCharSelectReq)); if(0 != lpBuffer) { PktUnifiedCharSelectReq* lpPktUnifiedCharSelectReq = reinterpret_cast(lpBuffer); memset(lpPktUnifiedCharSelectReq->szPassword, 0, sizeof(char) * PktUnifiedCharSelectReq::MAX_PASSWORD_LEN); lpPktUnifiedCharSelectReq->cSelectedNation = cSelectedNation; lpPktUnifiedCharSelectReq->cSelectedServerGroupID = cSelectedServerGroup; lpPktUnifiedCharSelectReq->dwRequestKey = 0; lpPktUnifiedCharSelectReq->dwUID = dwUID; memcpy(lpPktUnifiedCharSelectReq->dwCID, lpdwSelectedCID, sizeof(unsigned long) * std::min(int(cSelectedCharNum), int(USER_INFO::MAX_CHAR_NUM))); return SendStream.WrapHeader(sizeof(PktUnifiedCharSelectReq), CmdUnifiedCharSelect, 0, 0); } return false; } void ProcessUnifiedCharSelect(CSendStream& SendStream, PktBase* lpPktBase) { PktUnifiedCharSelectReq* lpPktUnifiedCharSelectReq = reinterpret_cast(lpPktBase); unsigned long dwUID = lpPktUnifiedCharSelectReq->dwUID; unsigned long dwRequestKey = lpPktUnifiedCharSelectReq->dwRequestKey; unsigned char cSelectedServerGroupID = lpPktUnifiedCharSelectReq->cSelectedServerGroupID; unsigned char cSelectedNation = lpPktUnifiedCharSelectReq->cSelectedNation; unsigned short usError = 0; using namespace DBAgent::DataStorage; unsigned char cAgentServerType = static_cast( CServerSetup::GetInstance().GetAgentServerType()); CStoreDataMgr& storeDataMgr = CStoreDataMgr::GetInstance(); CCharacterDataMgr& charDataMgr = CCharacterDataMgr::GetInstance(); CDBComponent& dbComponent = CDBSingleObject::GetInstance(); UnifiedStoreKey srcStoreKey(dwUID, cSelectedServerGroupID); UnifiedStoreKey dstStoreKey(dwUID, cAgentServerType); CSessionData* lpSessionData = 0; CStoreData* lpStoreData = 0; CCharacterData* lpCharacterData = 0; if(0 != lpPktBase->GetError()) { // ÇØ´ç UID°¡ ¾ø´Ù. ERRLOG2(g_Log, "UID:%10u / Part2Unified ij¸¯ÅÍ ¼±Åà ½ÇÆÐ - Part1 DBÁß°è¼­¹ö¿¡¼­ %d¿¡·¯¸¦ Àü¼ÛÇß½À´Ï´Ù.", dwUID, lpPktBase->GetError()); usError = lpPktBase->GetError(); } else if(0 == (lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID))) { // ÇØ´ç UID°¡ ¾ø´Ù. ERRLOG1(g_Log, "UID:%10u / Part2Unified ij¸¯ÅÍ ¼±Åà ½ÇÆÐ - ¼¼¼ÇÀÌ ´ÝÇô ÀÖ½À´Ï´Ù", dwUID); usError = PktUnifiedCharSelectAck::SERVER_ERROR; } else { // â°í ¼±ÅÃÇÑ Àû ¾øÀ½ if (!(lpSessionData->GetFirstLogin() & UnifiedConst::SELECTED_PART2)) { // Ȥ½Ã ij½¬³ª loginDB¿¡ µ¥ÀÌÅͰ¡ µé¾îÀÖ´ÂÁö »ìÇÉ´Ù. ÀÖÀ¸¸é ÀüºÎ Á¦°ÅÇÑ´Ù. if(storeDataMgr.IsDataLoginDB(srcStoreKey)) { ERRLOG2(g_Log, "UID:%10u / SrcServerGroupID:%d / Part2Unified â°í ¼±Åà ½ÇÆÐ - ÇØ´ç â°í°¡ ·Î±×ÀÎÇØ ÀÖ½À´Ï´Ù.", srcStoreKey.first, srcStoreKey.second); usError = PktUnifiedCharSelectAck::SERVER_ERROR; } else if(storeDataMgr.IsDataLoginDB(dstStoreKey)) { ERRLOG2(g_Log, "UID:%10u / DstServerGroupID:%d / Part2Unified â°í ¼±Åà ½ÇÆÐ - ÇØ´ç â°í°¡ ·Î±×ÀÎÇØ ÀÖ½À´Ï´Ù.", dstStoreKey.first, dstStoreKey.second); usError = PktUnifiedCharSelectAck::SERVER_ERROR; } else { // ÀÏ´Ü Ä³½¬¿¡¼­ µ¥ÀÌÅ͸¦ ³»¸°´Ù. if(storeDataMgr.RemoveLogoutData(srcStoreKey)) { ERRLOG2(g_Log, "UID:%10u / SrcServerGroupID:%d / " "Part2Unified â°í ¼±Åà ÀÌ»ó - ÇØ´ç µ¥ÀÌÅͰ¡ ij½¬¿¡ µé¾î ÀÖ¾î °­Á¦·Î ³»¸³´Ï´Ù.", srcStoreKey.first, srcStoreKey.second); } if(storeDataMgr.RemoveLogoutData(dstStoreKey)) { ERRLOG2(g_Log, "UID:%10u / DstServerGroupID:%d / " "Part2Unified â°í ¼±Åà ÀÌ»ó - ÇØ´ç µ¥ÀÌÅͰ¡ ij½¬¿¡ µé¾î ÀÖ¾î °­Á¦·Î ³»¸³´Ï´Ù.", dstStoreKey.first, dstStoreKey.second); } // ¼±ÅÃÇÑ ¼­¹ö±º â°í¸¦ ³» ¼­¹ö±×·ì â°í·Î º¹»çÇÑ´Ù! if (!lpSessionData->ChangeUnifiedStoreInfoGroup( dbComponent, cSelectedServerGroupID, cAgentServerType)) { usError = PktUnifiedCharSelectAck::UNIFIED_STORE_READ_ERROR; } // º¹»ç Àß µÆÀ¸¸é ij½¬·Î ·ÎµåÇØ¼­ ÄÁ¹öÆÃÀ» ÇÑ´Ù. else { if(0 == (lpStoreData = storeDataMgr.GetLogoutData(dstStoreKey))) { ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : â°í ij½¬·Î µ¥ÀÌÅÍ ·Îµå ½ÇÆÐ", dwUID, cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::UNIFIED_STORE_READ_ERROR; } // â°í µ¥ÀÌÅ͸¦ Part2¾ÆÀÌÅÛÀ¸·Î ÄÁ¹öÆÃÇÑ´Ù. else if (!lpStoreData->ConvertToPart2Item(true)) { ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : â°í ÆÄÆ®2 ¾ÆÀÌÅÛÀ¸·Î ¾ÆÀÌÅÛ ÄÁ¹öÆÃ ½ÇÆÐ", dwUID, cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::UNIFIED_STORE_WRITE_ERROR; } // â°í µ¥ÀÌÅ͸¦ ÀúÀåÇÑ´Ù. else if(!lpStoreData->ForceUpdateDBAllData(dbComponent)) { ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : ÄÁ¹öÆÃµÈ â°í µ¥ÀÌÅ͸¦ ÀúÀå ½ÇÆÐ", dwUID, cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::UNIFIED_STORE_WRITE_ERROR; } else if(!DBComponent::GameDB::UpdateUserFirstLogin(dbComponent, dwUID, lpSessionData->GetFirstLogin() | UnifiedConst::SELECTED_PART2)) { ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : â°í °¡Á®¿ÔÀ½À» ±â·Ï ½ÇÆÐ", dwUID, cSelectedServerGroupID); } if(0 != usError) { // ¿¡·¯°¡ ³­ °Ç â°í µ¥ÀÌÅ͸¦ ÀúÀåÀ» ¸ø Ç߱⠶§¹®ÀÌ´Ï, // ±×³É ij½¬¿¡¼­ ³¯¸®°í ´Ù½Ã ¼¼ÆÃÇÏ¸é µÈ´Ù. storeDataMgr.RemoveLogoutData(dstStoreKey); if(!lpSessionData->ChangeUnifiedStoreInfoGroup( dbComponent, cAgentServerType, cSelectedServerGroupID)) { ERRLOG3(g_Log, "UID:%10u / ServerGroupID:%d -> %d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : â°í µ¥ÀÌÅÍ ·Ñ¹é ½ÇÆÐ", dwUID, cAgentServerType, cSelectedServerGroupID); } } else { lpSessionData->SetFirstLogin( lpSessionData->GetFirstLogin() | UnifiedConst::SELECTED_PART2); INFLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ¼º°ø", dwUID, cSelectedServerGroupID); } } } } // ij¸¯ÅÍ ¼±Åà ÂÊÀ» ó¸®ÇÑ´Ù. // 1. ij¸¯Å͸¦ ¹ÞÀ¸¸é, ÀÏ´Ü UserInfo¸¦ ·ÎµåÇÑ ÈÄ¿¡, // ¿Ã¹Ù¸¥ ½½·Ô¿¡ ³ÖÀº Áߺ¹µÇÁö ¾Ê´Â ij¸¯Å͸¦ ã´Â´Ù. // 2. Á¤¸®°¡ ³¡³ª¸é Part1 DBÁß°è¼­¹ö¿¡, ÇØ´ç ij¸¯Å͸¦ ij½¬¿¡¼­ ¾ð·ÎµåÇϰí // ±æµå / ÆÄƼ¸¦ Å»Åð½Ã۶ó°í ¿äûÇÑ´Ù. // 3. ¿äû °á°ú°¡ ¼º°øÀ¸·Î µ¹¾Æ¿À¸é, ÇØ´ç ij¸¯Å͸¦ DB¿¡¼­ ·ÎµåÇϰí // µ¥ÀÌÅ͸¦ ÄÁ¹öÆÃ ÇÑ ÈÄ¿¡ ÀúÀåÇÑ´Ù. ÄÁ¹öÆÃÀ̳ª ÀúÀåÀÌ ½ÇÆÐÇÏ¸é µ¥ÀÌÅ͸¦ ·Ñ¹éÇÑ´Ù. // 4. ¸ðµç ÀÛ¾÷ÀÌ ¹«»çÈ÷ ³¡³ª¸é, DBÀÇ UserInfo¸¦ °»½ÅÇÑ´Ù. CClass::RaceType eRace = lpSessionData->CheckUnifiedCharRace(lpPktUnifiedCharSelectReq->dwCID); USER_INFO userInfo = lpSessionData->GetUserInfo(); // À¯Àú ¹ÙÀεù °Ë»ç¸¦ Çѹø ´õ ÇÑ´Ù. unsigned long dwSelectedCID[USER_INFO::MAX_CHAR_NUM]; unsigned long* lpdwRequestedCID = lpPktUnifiedCharSelectReq->dwCID; int nSelectedCount = 0; std::fill_n(dwSelectedCID, size_t(USER_INFO::MAX_CHAR_NUM), 0); // µ¥ÀÌÅ͸¦ Á¦´ë·Î ¾ò¾î ¿Ô´Ù. // ÇöÀç ¹ÙÀεù µÈ ij¸¯ÅÍÀÎÁö ¾Æ´ÑÁö ÆÇ´ÜÇÑ´Ù. unsigned char cRestrictedPart1ToPart2Level = CServerSetup::GetInstance().GetRestrictedPart1ToPart2Level(); for(int nCount = 0; nCount < USER_INFO::MAX_CHAR_NUM; ++nCount) { unsigned long dwBindCID = lpdwRequestedCID[nCount]; const UnifiedCharData* lpUnifiedCharData = 0; if (0 == userInfo.CharID[nCount] && 0 != dwBindCID && !userInfo.HasCharacter(dwBindCID) && 0 != (lpUnifiedCharData = lpSessionData->GetUnifiedCharData(dwBindCID)) && (lpUnifiedCharData->cOldServerGroupID < UnifiedConst::Part1 || (lpUnifiedCharData->cOldServerGroupID == UnifiedConst::Part1Unified && cRestrictedPart1ToPart2Level <= lpUnifiedCharData->cLevel))) { dwSelectedCID[nCount] = dwBindCID; ++nSelectedCount; } } if (0 < nSelectedCount && CClass::MAX_RACE == eRace) { usError = PktUnifiedCharSelectAck::PACKET_ERROR; } else if(0 == usError) { // ÇѹÙÄû µ¹¸é¼­ ¾ÆÀÌÅÛ ÄÁ¹öÆÃ / ½ºÅ³ºÏ ÄÁ¹öÆÃ µîÀ» ¼öÇàÇÑ´Ù. CCharBackupItemData backupData[USER_INFO::MAX_CHAR_NUM]; for(int nCount = 0; nCount < USER_INFO::MAX_CHAR_NUM; ++nCount) { if(0 != dwSelectedCID[nCount]) { if(0 == (lpCharacterData = charDataMgr.GetLogoutData(dwSelectedCID[nCount]))) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : ij¸¯ÅÍ Ä³½¬·Î µ¥ÀÌÅÍ ·Îµå ½ÇÆÐ", dwUID, dwSelectedCID[nCount], cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_READ_ERROR; } else { // µ¥ÀÌÅ͸¦ ¹é¾÷ÇÑ´Ù. backupData[nCount].BackupData(*lpSessionData, *lpCharacterData); // Part2 ¾ÆÀÌÅÛÀ¸·Î ÄÁ¹öÆÃÇÑ´Ù. if (!lpCharacterData->ConvertToPart2Item(true)) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : ij¸¯ÅÍ Part2¾ÆÀÌÅÛÀ¸·Î ÄÁ¹öÆÃ ½ÇÆÐ", dwUID, dwSelectedCID[nCount], cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR; } // UnifiedCharInfo¿¡¼­, ij¸¯ÅÍ ¼­¹ö±º ¹øÈ£¸¦ ¼öÁ¤ÇÑ´Ù. else if (!lpSessionData->ChangeUnifiedCharServerGroupID( dbComponent, dwUID, dwSelectedCID[nCount], cAgentServerType)) { usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR; } else if (!lpCharacterData->ForceUpdateDBAllData(dbComponent)) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : ij¸¯ÅÍ ¾ÆÀÌÅÛ ÀúÀå ½ÇÆÐ", dwUID, dwSelectedCID[nCount], cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR; } if(0 != usError) { // ¿¡·¯°¡ ÀÖÀ¸¸é ¹Ù·Î ·Ñ¹é;; break; } // ¾ç±¹Ã¼Á¦·Î º¯°æ // if(lpSessionData->GetAccountNation()==Creature::ALMIGHTY_PIRATE) { /* ±¹ÀûÀÌ ½ÅÀÇ ÇØÀû´ÜÀ̸鼭, Á¾Á·ÀÌ ÈÞ¸ÕÀÎ »ç¶÷µéÀÇ ±¹ÀûÀ» Ä«¸£Å×¶õÆ®·Î ¹Ù²ãÁØ´Ù. */ if(lpCharacterData->GetRace()==CClass::HUMAN) { lpSessionData->SetAccountNation(Creature::KARTERANT); } /* ±¹ÀûÀÌ ½ÅÀÇ ÇØÀû´ÜÀ̸鼭, Á¾Á·ÀÌ ¾ÆÄ­ÀÎ »ç¶÷µéÀÇ ±¹ÀûÀ» ¸Þ¸£Ä«µð¾Æ·Î ¹Ù²ãÁØ´Ù. */ else if(lpCharacterData->GetRace()==CClass::AKHAN) { lpSessionData->SetAccountNation(Creature::MERKADIA); } } // Ä£±¸¸®½ºÆ®, °ÅºÎ ¸®½ºÆ® »èÁ¦ // /*unsigned long dwMemberCID[CFriendList::MAX_FRIENDS_NUM] = {0,}; unsigned long dwDeleteCID[CFriendList::MAX_FRIENDS_NUM] = {0,}; // Ä£±¸¸®½ºÆ®¿¡ CID ¸¸ °¡Áö°í ¿Â´Ù. // CFriendList friendList = lpCharacterData->GetFriendList(); friendList.GetCIDList(dwMemberCID); for(unsigned char cIndex = 0; cIndex < friendList.GetFriendNum(); cIndex++) { CFriendList::Rebind* lpRebind = friendList.GetFriend(dwMemberCID[cIndex]); if(lpCharacterData->GetRace()==CClass::HUMAN) { if(lpRebind->GetClass()>=CClass::Combatant) { dwDeleteCID[cIndex] = dwMemberCID[cIndex]; } } else if(lpCharacterData->GetRace()==CClass::AKHAN) { if(lpRebind->GetClass()GetBanList(); banList.GetCIDList(dwMemberCID); for(unsigned char cIndex = 0; cIndex < banList.GetBanNum(); cIndex++) { CBanList::Rebind* lpRebind = banList.GetBan(dwMemberCID[cIndex]); if(lpCharacterData->GetRace()==CClass::HUMAN) { if(lpRebind->GetClass()>=CClass::Combatant) { dwDeleteCID[cIndex] = dwMemberCID[cIndex]; } } else if(lpCharacterData->GetRace()==CClass::AKHAN) { if(lpRebind->GetClass()GetAccountNation(); // ¼±ÅÃÇÑ ±¹°¡°¡ Á¾Á·°ú ¸Â´ÂÁö üũÇÑ ÈÄ ¼¼ÆÃÇÑ´Ù. if(Creature::ALMIGHTY_PIRATE == cSelectedNation) { lpSessionData->SetAccountNation(Creature::ALMIGHTY_PIRATE); } else { lpSessionData->SetAccountNation( CClass::HUMAN == eRace ? Creature::KARTERANT : Creature::MERKADIA); } if (cOldAccountNation != lpSessionData->GetAccountNation()) { INFLOG3(g_Log, "UID:%10u / OldAccountNation:%s / AccountNation:%s / ±¹Àû º¯°æ", dwUID, Creature::GetShortNationName(cOldAccountNation), Creature::GetShortNationName(lpSessionData->GetAccountNation())); } } if(!lpSessionData->UpdateCharacterBinding(dbComponent, dwSelectedCID)) { ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ : ÃÖÁ¾ ij¸¯ÅÍ ¹ÙÀεù¿¡ ½ÇÆÐÇß½À´Ï´Ù", dwUID, cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR; } else { // â°í/ij¸¯ÅÍ ÀÌÀü¿¡ ¼º°øÇß´Ù! lpSessionData->SetOldServerGroupID(cAgentServerType); } } if(0 != usError) { // ¹®Á¦°¡ »ý°å´Ù. µ¥ÀÌÅ͸¦ ÀüºÎ RollbackÇÑ´Ù. for(int nCount = 0; nCount < USER_INFO::MAX_CHAR_NUM; ++nCount) { if(0 != dwSelectedCID[nCount] && backupData[nCount].IsBackupedData()) { if(0 == (lpCharacterData = charDataMgr.GetLogoutData(dwSelectedCID[nCount]))) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / ÅëÇÕ¼­¹ö ¼±Åà ½ÇÆÐ - µ¥ÀÌÅÍ º¹±¸ ½ÇÆÐ : ij¸¯ÅÍ Ä³½¬·Î µ¥ÀÌÅÍ ·Îµå ½ÇÆÐ", dwUID, dwSelectedCID[nCount], cSelectedServerGroupID); } else { backupData[nCount].RestoreData(*lpCharacterData); lpCharacterData->ForceUpdateDBAllData(dbComponent); lpSessionData->ChangeUnifiedCharServerGroupID(dbComponent, dwUID, dwSelectedCID[nCount], backupData[nCount].GetOldServerGroupID()); } } } } } } GET_SINGLE_DISPATCH(lpAuthDispatch, CAuthDispatch, CAuthDispatch::GetDispatchTable()); if(0 != lpAuthDispatch && SendPacket::UnifiedCharSelectAck( lpAuthDispatch->GetSendStream(), dwUID, dwRequestKey, usError)) { if(0 == usError) { INFLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ij¸¯ÅÍ ¹× â°í ¼±Åà ¼º°ø", dwUID, cSelectedServerGroupID); } } else { ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / ij¸¯ÅÍ ¼±Åà ½ÇÆÐ : " "ÀÎÁõ¼­¹ö¿Í Á¢¼ÓÀÌ ²÷±â°Å³ª Àü¼Û¿¡ ½ÇÆÐÇß½À´Ï´Ù.", dwUID, cSelectedServerGroupID); } } }