#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // WORK_LIST 2.3 °èÁ¤ ±¹Àû º¯°æ ±â´É ±¸Çö #include #include #include #include #include #include #include #include #include #include "ParseCharManage.h" #include #ifdef AUTH_MY #include "NFAuthClient/AuthClient.h" #endif namespace DBAgent { namespace ParseCharManage { bool StartSession(CSendStream& SendStream, unsigned long dwServerID, PktSSD* lpPktSSD); bool UserLogin(CSendStream& SendStream, PktULD* lpPktULD); bool UserLogout(CSendStream& SendStream, PktULoD* lpPktULoD); bool UserMove(CSendStream& SendStream, PktUMvD* lpPktUMvD); bool CharSelect(CSendStream& SendStream, PktCSD* lpPktCSD); bool CharCreate(CSendStream& SendStream, PktCCD* lpPktCCD); bool CharDelete(CSendStream& SendStream, PktCDD* lpPktCDD); bool CreateItem(CSendStream& SendStream, unsigned long dwServerID, Item::CItemSerialMgr& itemSerialMgr, PktCCID* lpPktCCID); // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ bool SelectAccountNation(CSendStream& SendStream, PktSAND* lpPktSAND); bool Parse(CSendStream& SendStream, unsigned long dwServerID, Item::CItemSerialMgr& itemSerialMgr, PktDD* lpPktDD) { #ifdef ENABLE_PACKET_LOG unsigned short shCmd = lpPktDD->m_wCmd; unsigned long dwRequestKey = lpPktDD->m_dwRequestKey; unsigned long dwSessionID = 0; unsigned long dwUID = 0; unsigned long dwCID = 0; bool bLog = true; switch (lpPktDD->m_wCmd) { case PktDD::SCmdStartSession: // ¼¼¼Ç ½ÃÀÛ { PktSSD* lpPktSSD = static_cast(lpPktDD); dwSessionID = lpPktSSD->m_dwSessionID; dwUID = lpPktSSD->m_dwUserID; } break; case PktDD::SCmdUserLogin: // À¯Àú ·Î±×ÀÎ - ÇÏ´Â ÀÏÀº ij¸¯ÅÍ ºä ¾ò±â Á¤µµÀÌ´Ù. { PktULD* lpPktULD = static_cast(lpPktDD); dwSessionID = lpPktULD->m_dwSessionID; dwUID = lpPktULD->m_dwUserID; } break; case PktDD::SCmdUserLogout: // À¯Àú ·Î±×¾Æ¿ô - ¼¼¼Ç ´Ý±â. { PktULoD* lpPktULoD = static_cast(lpPktDD); dwSessionID = lpPktULoD->m_dwSessionID; dwUID = lpPktULoD->m_dwUserID; } break; case PktDD::SCmdUserMove: // À¯Àú À̵¿ { PktUMvD* lpPktUMvD = static_cast(lpPktDD); dwSessionID = lpPktUMvD->m_dwSessionID; dwUID = lpPktUMvD->m_dwUserID; } break; // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ case PktDD::SCmdSelectNation: // °èÁ¤ ±¹Àû ¼³Á¤ ¹× º¯°æ { PktSAND* lpPktSAND = static_cast(lpPktDD); dwUID = lpPktSAND->m_dwUserID; } break; case PktDD::SCmdCharSelect: // ij¸¯ÅÍ ¼±Åà { PktCSD* lpPktCSD = static_cast(lpPktDD); dwUID = lpPktCSD->m_dwUserID; dwCID = lpPktCSD->m_dwCharID; } break; case PktDD::SCmdCharCreate: // ij¸¯ÅÍ »ý¼º { PktCCD* lpPktCCD = static_cast(lpPktDD); dwUID = lpPktCCD->m_dwUserID; } break; case PktDD::SCmdCharDelete: // ij¸¯ÅÍ »èÁ¦ { PktCDD* lpPktCCD = static_cast(lpPktDD); dwUID = lpPktCCD->m_dwUserID; dwCID = lpPktCCD->m_dwCharID; } break; case PktDD::SCmdCharCreateItem: // ij¸¯ÅÍ »ý¼º ¾ÆÀÌÅÛ { PktCCID* lpPktCCID = static_cast(lpPktDD); dwCID = lpPktCCID->m_dwCharID; } break; default: bLog = false; break; } if(bLog) { DETLOG5(g_PacketLog, "ParseCharManage::Parse %d : UID:%10u / CID:%10u / SessionID:%10u / ServerID:0x%08X / ", shCmd, dwUID, dwCID, dwSessionID, dwServerID); } #endif // ¿©±â´Â ij¸¯ÅÍ ¼±ÅÃ,»èÁ¦ È­¸é¿¡¼­ // °ÔÀÓ½ÃÀÛ Çϱâ Àü±îÁö Çϴ°÷Àεí. bool bResult = false; switch (lpPktDD->m_wCmd) { case PktDD::SCmdStartSession: // ¼¼¼Ç ½ÃÀÛ // SERLOG0(g_Log, "¼¼¼Ç½ÃÀÛ"); bResult = StartSession(SendStream, dwServerID, static_cast(lpPktDD)); SERLOG0(g_Log, "¼¼¼Ç½ÃÀÛ ¿Ï·á"); break; case PktDD::SCmdUserLogin: // À¯Àú ·Î±×ÀÎ - ÇÏ´Â ÀÏÀº ij¸¯ÅÍ ºä ¾ò±â Á¤µµÀÌ´Ù. // SERLOG0(g_Log, "À¯Àú·Î±×ÀÎ ½Ãµµ"); bResult = UserLogin(SendStream, static_cast(lpPktDD)); SERLOG0(g_Log, "À¯Àú·Î±×ÀÎ ¿Ï·á"); break; case PktDD::SCmdUserLogout: // À¯Àú ·Î±×¾Æ¿ô - ¼¼¼Ç ´Ý±â. // SERLOG0(g_Log, "À¯Àú·Î±×¾Æ¿ô ½Ãµµ"); bResult = UserLogout(SendStream, static_cast(lpPktDD)); SERLOG0(g_Log, "À¯Àú·Î±×¾Æ¿ô ¿Ï·á"); break; case PktDD::SCmdUserMove: // À¯Àú À̵¿ bResult = UserMove(SendStream, static_cast(lpPktDD)); break; // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ case PktDD::SCmdSelectNation: // °èÁ¤ ±¹Àû ¼³Á¤ ¹× º¯°æ bResult = SelectAccountNation(SendStream, static_cast(lpPktDD)); break; case PktDD::SCmdCharSelect: // ij¸¯ÅÍ ¼±Åà bResult = CharSelect(SendStream, static_cast(lpPktDD)); break; case PktDD::SCmdCharCreate: // ij¸¯ÅÍ »ý¼º bResult = CharCreate(SendStream, static_cast(lpPktDD)); break; case PktDD::SCmdCharDelete: // ij¸¯ÅÍ »èÁ¦ bResult = CharDelete(SendStream, static_cast(lpPktDD)); break; case PktDD::SCmdCharCreateItem: // ij¸¯ÅÍ »ý¼º ¾ÆÀÌÅÛ bResult = CreateItem(SendStream, dwServerID, itemSerialMgr, static_cast(lpPktDD)); break; default: ERRLOG1(g_Log, "CharacterManage ÆÐŶ ó¸® ¿¡·¯ : ¾Ë ¼ö ¾ø´Â ÆÐŶ CMD:0x%02X¸¦ ¹Þ¾Ò½À´Ï´Ù.", lpPktDD->m_wCmd); bResult = true; break; } return bResult; } bool StartSession(CSendStream& SendStream, unsigned long dwServerID, PktSSD* lpPktSSD) { // edith 2008.01.15 Auth ¿¡¼­ ¼¼¼Ç ½ÃÀÛÆÐŶÀÌ ³¯¶ó¿Ô´Ù. unsigned long dwSessionID = lpPktSSD->m_dwSessionID; unsigned long dwUID = lpPktSSD->m_dwUserID; unsigned long dwRequestKey = lpPktSSD->m_dwRequestKey; IN_ADDR peerAddress = lpPktSSD->m_Address; const char* szAccountName = lpPktSSD->m_AccountName; const char* szPassword = lpPktSSD->m_Password; unsigned short usFlag = lpPktSSD->GetError(); // Á¢¼Ó ²÷±â. unsigned short usStartSessionError = 0; using namespace DataStorage; // ¼¼¼Ç ¿­±â CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); if(0 != lpSessionData && (CSessionData::SE_USER_ENABLED == lpSessionData->GetSessionState() || CSessionData::SE_CHAR_ENABLED == lpSessionData->GetSessionState())) { // ÀÌ¹Ì ·Î±×ÀÎ ÇØ ÀÖÀ¸¹Ç·Î Á¢¼Ó ²÷±â ·çƾ ¼öÇà if(0 == usFlag) { // Á¢¼Ó ²÷±â º¸³»¶ó°í ¿äû usStartSessionError = 41; } else if(1 == usFlag) { // °°Àº ¼­¹ö±º¿¡¼­ Á¢¼Ó ²÷±â 󸮸¦ ÇÑ´Ù. DETLOG5(g_Log, "UID:%10u / CID:%10u / ServerID:0x%08X / Account:%s / IP:%15s / Á¢¼Ó ²÷±â Àü¼Û : ÀÎÁõ ¼­¹ö ¸í·ÉÀ¸·Î Á¢¼Ó ²÷±â º¸³¿.", lpSessionData->GetUID(), lpSessionData->GetCID(), lpSessionData->GetServerID(), lpSessionData->GetAccountName(), inet_ntoa(peerAddress)); SendPacket::UserKill(*lpSessionData); // ÀçÁ¢¼Ó ½Ãµµ ¿äû usStartSessionError = 42; } else { // ¾Ë ¼ö ¾ø´Â °æ¿ì. ±×³É ¼¼¼Ç ¿­±â ½ÇÆÐ·Î °£´Ù. ERRLOG4(g_Log, "UID:%10u / CID:%10u / ServerID:0x%08X / usFlag:%d / ¼¼¼Ç ¿­±â ½ÇÆÐ : Ŭ¶óÀÌ¾ðÆ®°¡ ¾Ë ¼ö ¾ø´Â Ç÷¡±×¸¦ º¸³Â½À´Ï´Ù.", lpSessionData->GetUID(), lpSessionData->GetCID(), lpSessionData->GetServerID(), usFlag); usStartSessionError = 40; } } else if(0 == (lpSessionData = CSessionDataMgr::GetInstance().SessionOpen(dwUID))) { // ¼¼¼Ç ¿­±â ½ÇÆÐ usStartSessionError = 40; } else { #ifdef AUTH_MY // edith 2009.09.11 MY¸¦ À§ÇÑ AllowIP ó¸®ÀÛ¾÷ char* szAdd = inet_ntoa(peerAddress); if(!g_IPSec.IsAliveIP(szAdd)) { usStartSessionError = 57; ERRLOG4(g_Log, "DBAgent Error. IPSEC Error:%d Account:%s UID:%d (%s)", usStartSessionError, lpSessionData->GetAccountName(), lpSessionData->GetUID(), szAdd); } #endif if(usStartSessionError == 0) { SERLOG4(g_Log, "UID:%10u / CID:%10u / ServerID:0x%08X / %s / UID·Î ÀÎÁõ ½Ãµµ", lpSessionData->GetUID(), lpSessionData->GetCID(), lpSessionData->GetServerID(), szAccountName); // ÀÎÁõ¼­¹ö·Î ¼­¹ö±º ID¼¼ÆÃÇÑ´Ù. SERVER_ID serverID; serverID.sID.ID = 0; serverID.sID.Channel = 0; serverID.sID.Group = CServerSetup::GetInstance().GetServerGroup(); serverID.sID.Type = CServerSetup::AuthServer; dwServerID = serverID.dwID; // edith 2008.01.15 ¼¼¼ÇÀ» ¿­±â¿¡ ¼º°øÇß´Ù. ¸®Äù½ºÆ® µ¥ÀÌŸ¸¦ ¼¼¼Ç¿¡ ÀÔ·ÂÇÑ´Ù. ¼³Á¤ÈÄ UID·Î ·Î±×Àνõµ. // ÆÐ½º¿öµå¸¦ ÀúÀåÇÏ·Á¸é ¿©±â±îÁö ³¯¾Æ¿Í¾ßÇÑ´Ù. // ¼¼¼Ç ¿­±â ¼º°ø lpSessionData->PushRequest( RequestData(dwRequestKey, 0, dwServerID, dwSessionID, peerAddress, szAccountName, szPassword)); // edith 2008.01.15 UID¼­¹ö·Î À¯Àú ·Î±×ÀÎÀ» Àü¼ÛÇÑ´Ù. if (!SendPacket::UpdateUIDTable(PktUUT::UpdateUIDTableUserLogin, szAccountName, szPassword, dwUID, 0, dwSessionID, dwServerID, peerAddress, (1 == usFlag) ? PktUUT::DISCONNECT_USER : 0)) { ERRLOG1(g_Log, "UID:%10u / UID¼­¹ö¿¡ À¯Àú ·Î±×ÀÎ Àü¼Û ½ÇÆÐ", dwUID); lpSessionData->PopRequest(); usStartSessionError = 1; } // ³ªÁß¿¡ »©ÀÚ // INFLOG5(g_Log, "UID:%10u / Account:%s, Pass:%s, Session:0x%08X, ServerID:0x%08X ", // dwUID, szAccountName, szPassword, dwSessionID, dwServerID); } } if(0 != usStartSessionError) { if(!SendPacket::StartSession(SendStream, dwRequestKey, dwUID, dwSessionID, 0, usStartSessionError)) { ERRLOG2(g_Log, "UID:%10u / ÀÎÁõ¼­¹ö¿¡ ¼¼¼Ç ½ÃÀÛ ½ÇÆÐ ¿¡·¯ Àü¼Û ½ÇÆÐ : %u", dwUID, usStartSessionError); } } return true; } bool UserLogin(CSendStream& SendStream, PktULD* lpPktULD) { unsigned long dwSessionID = lpPktULD->m_dwSessionID; unsigned long dwUID = lpPktULD->m_dwUserID; IN_ADDR peerAddress = lpPktULD->m_Address; unsigned char cLoginType = lpPktULD->m_cLoginType; unsigned long dwRequestKey = lpPktULD->m_dwRequestKey; unsigned short usError = 0; int nPlayTime = 0; unsigned char cBillingUser = 0; unsigned char cBillingType = 0; unsigned char cAdminLevel = 0; const CHAR_VIEW* lpCharView = 0; unsigned long dwCharViewNum = 0; // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ unsigned char cAccountNation = 0; sGuildData GuildData[PktULDAck::MAX_CHAR_VIEW]; memset(&GuildData[0], 0, sizeof(sGuildData) * PktULDAck::MAX_CHAR_VIEW); STORE_INFO storeInfo; memset(&storeInfo, 0, sizeof(STORE_INFO)); using namespace DataStorage; CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); // ¼¼¼Ç ¾ò±â if(0 == lpSessionData) { ERRLOG1(g_Log, "UID:%10u / À¯Àú ·Î±×ÀÎ ½ÇÆÐ : ¼¼¼ÇÀÌ ¾ø½À´Ï´Ù", dwUID); usError = 1; } // ¼¼¼Ç ID°Ë»ç else if(dwSessionID != lpSessionData->GetSessionID()) { ERRLOG3(g_Log, "UID:%10u / SessionID:%10u / ReceivedSessionID:%10u / " "À¯Àú ·Î±×ÀÎ ½ÇÆÐ : - ¼¼¼ÇID°¡ ´Ù¸¨´Ï´Ù", dwUID, lpSessionData->GetSessionID(), dwSessionID); usError = 1; } else { unsigned char cAgentServerType = static_cast( CServerSetup::GetInstance().GetAgentServerType()); switch(cAgentServerType) { case UnifiedConst::Part1: case UnifiedConst::Part1Unified: // ÀÖÀ» ¼ö ¾ø´Ù. ÀÌ°Ç ÆÄÆ® 2¼­¹ö¶ó±¸! usError = 1; SERLOG0(g_Log, "Part2 ¼­¹ö¸¦ Part1¼³Á¤À¸·Î ÄÑ·Á°í Çϼ̽À´Ï´Ù. ¼­¹ö¸¦ ´Ù½Ã ÄÑ ÁֽʽÿÀ"); break; case UnifiedConst::ROW: case UnifiedConst::Part2Unified: // Part2 / Part2 ÅëÇÕ¼­¹ö´Â, Àоî¿Ã UserInfo°¡ Çϳª»ÓÀÌ´Ù. lpSessionData->SetOldServerGroupID(cAgentServerType); break; case UnifiedConst::Part2Selectable: // ¼±ÅÃÀ» ¾È ÇÏ°í ±×³É UserLoginÀ» º¸³»¸é, ½Å±Ô/±âÁ¸Àΰ¡¿¡ µû¶ó // UnifiedConst::Part2Selectable ¹ø ȤÀº 1¹ø¿¡¼­ µ¥ÀÌÅ͸¦ Àоî¿Â´Ù. break; } // À¯Àú ·Î±×ÀÎ if(0 == usError) { if (!(lpSessionData->GetFirstLogin() & UnifiedConst::SELECTED_PART2)) { /* ERRLOG2(g_Log, "UID:%10u / FirstLogin:%d / " "UserLogin ±îÁö ÁøÀÔÇߴµ¥, Part2 ¿¡¼­ â°í ¼±ÅÃÇÑ Àû ¾ø´Â °Íó·³ µÇ¾î ÀÖÀ½. °ªÀ» ¼¼ÆÃÇÔ.", lpSessionData->GetUID(), lpSessionData->GetFirstLogin()); */ lpSessionData->SetFirstLogin( lpSessionData->GetFirstLogin() | UnifiedConst::SELECTED_PART2); DBComponent::GameDB::UpdateUserFirstLogin(CDBSingleObject::GetInstance(), lpSessionData->GetUID(), lpSessionData->GetFirstLogin()); } CBilling& Billing = lpSessionData->GetBilling(); nPlayTime = Billing.GetPlayTime(); cBillingUser = (0 == Billing.GetCRMData()) ? 0 : 1; cBillingType = Billing.GetBillingType(); cAdminLevel = lpSessionData->GetAdminLevel(); lpCharView = lpSessionData->GetCharView(0); dwCharViewNum = USER_INFO::MAX_CHAR_NUM; // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ cAccountNation = lpSessionData->GetAccountNation(); // ±æµå ¹× ±¹Àû Á¤º¸ ¼ÂÆÃ for (int i=0; i< USER_INFO::MAX_CHAR_NUM; ++i) { if (0 != lpCharView[i].CID) { if (lpCharView[i].GID) { Guild::CGuildDB* lpGuild = static_cast( Guild::CGuildDBMgr::GetInstance().GetGuild( lpCharView[i].GID )); if (lpGuild) { GuildData[i].m_cNation = lpGuild->GetNation(); strcpy(GuildData[i].m_szName, lpGuild->GetName()); } } else { // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ GuildData[i].m_cNation = 0; strcpy(GuildData[i].m_szName, ""); // switch (lpCharView[i].Race) // { // case CClass::RaceType::HUMAN: GuildData[i].m_cNation = Creature::KARTERANT; break; // case CClass::RaceType::AKHAN: GuildData[i].m_cNation = Creature::MERKADIA; break; // default: GuildData[i].m_cNation = Creature::STATELESS; break; // } } } } // ·Î±×ÀÎÇÑ´Ù. // PlayTimeÀ» Login »óÅ·Π¹Ù²Û´Ù. using namespace DBComponent; GameDB::GetUnifiedItemStoreInfo(CDBSingleObject::GetInstance(), dwUID, lpSessionData->GetOldServerGroupID(), &storeInfo, true); KeyInfo* pKeyInfo = lpSessionData->GetKeyInfo(); memset(pKeyInfo, 0, sizeof(KeyInfo)); //GameDB::GetKeyInfo(CDBSingleObject::GetInstance(), pKeyInfo, dwUID); lpSessionData->LogUserData("ij¸¯ÅÍ ºä ¾ò±â ¼º°ø"); } } // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ if(!SendPacket::UserLogin(SendStream, dwRequestKey, dwUID, lpCharView, GuildData, &storeInfo, dwCharViewNum, cAccountNation, nPlayTime, cAdminLevel, cBillingUser, cBillingType, cLoginType, usError)) { ERRLOG1(g_Log, "UID:%10u / ij¸¯ÅÍ ºä ¾ò±â ½ÇÆÐ : ij¸¯ÅÍ ºä Àü¼Û ½ÇÆÐ", dwUID); return false; } return true; } bool UserLogout(CSendStream& SendStream, PktULoD* lpPktULoD) { unsigned long dwSessionID = lpPktULoD->m_dwSessionID; unsigned long dwUID = lpPktULoD->m_dwUserID; // Á¢¼Ó DB¿¡¼­ À¯Àú °Ë»ç using namespace DataStorage; CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); // ¼¼¼Ç ¾ò±â if(0 == lpSessionData) { ERRLOG1(g_Log, "UID:%10u / À¯Àú ·Î±×¾Æ¿ô ½ÇÆÐ : ¼¼¼ÇÀÌ ¾ø½À´Ï´Ù", dwUID); } // ¼¼¼Ç ID°Ë»ç else if(dwSessionID != lpSessionData->GetSessionID()) { ERRLOG3(g_Log, "UID:%10u / SessionID:%10u / RSessionID:%10u / À¯Àú ·Î±×¾Æ¿ô ½ÇÆÐ : ¼¼¼ÇID°¡ ´Ù¸¨´Ï´Ù", dwUID, lpSessionData->GetSessionID(), dwSessionID); } else if(!lpSessionData->UserDisable()) { ERRLOG1(g_Log, "UID:%10u / À¯Àú ·Î±×¾Æ¿ô ½ÇÆÐ : À¯Àú ºñȰ¼ºÈ­ ½ÇÆÐ", dwUID); } else { // °ÔÀÓŸÀÓÀ» ¾÷µ¥ÀÌÆ®ÇÑ´Ù. // ·Î±×¾Æ¿ôÇÑ´Ù. // PlayTimeÀ» Logout »óÅ·Π¹Ù²Û´Ù. INFLOG1(g_Log, "UID:%10u / À¯Àú ·Î±×¾Æ¿ô ¼º°ø : À¯Àú¸¦ ºñȰ¼ºÈ­Çß½À´Ï´Ù.", dwUID); return true; } return false; } bool UserMove(CSendStream& SendStream, PktUMvD* lpPktUMvD) { unsigned long dwSessionID = lpPktUMvD->m_dwSessionID; unsigned long dwUID = lpPktUMvD->m_dwUserID; // Á¢¼Ó DB¿¡¼­ À¯Àú °Ë»ç using namespace DataStorage; CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); // ¼¼¼Ç ¾ò±â if(0 == lpSessionData) { ERRLOG1(g_Log, "UID:%10u / À¯Àú À̵¿(ij¸¯ÅÍ ¼±ÅÃ) ½ÇÆÐ : ¼¼¼ÇÀÌ ¾ø½À´Ï´Ù", dwUID); } // ¼¼¼Ç ID°Ë»ç else if(dwSessionID != lpSessionData->GetSessionID()) { ERRLOG3(g_Log, "UID:%10u / SessionID:%10u / ReceivedSessionID:%10u / " "À¯Àú À̵¿(ij¸¯ÅÍ ¼±ÅÃ) ½ÇÆÐ : ¼¼¼ÇID°¡ ´Ù¸¨´Ï´Ù", dwUID, lpSessionData->GetSessionID(), dwSessionID); } else if(!lpSessionData->UserMove()) { ERRLOG1(g_Log, "UID:%10u / À¯Àú À̵¿(ij¸¯ÅÍ ¼±ÅÃ) ½ÇÆÐ : À¯Àú À̵¿ ½ÇÆÐ", dwUID); } else { return true; } return false; } // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ bool SelectAccountNation(CSendStream& SendStream, PktSAND* lpPktSAND) { unsigned long dwUID = lpPktSAND->m_dwUserID; unsigned char cType = lpPktSAND->m_cType; unsigned char cAccountNation = lpPktSAND->m_cAccountNation; unsigned long dwRequestKey = lpPktSAND->m_dwRequestKey; unsigned short usError = 0; using namespace DataStorage; CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); // ¼¼¼Ç ¾ò±â if(0 == lpSessionData) { ERRLOG1(g_Log, "UID:%10u / °èÁ¤ ±¹Àû ¼³Á¤ ¹× º¯°æ ½ÇÆÐ : ¼¼¼ÇÀÌ ¾ø½À´Ï´Ù", dwUID); usError = 4; } else { unsigned char cOldServerGroupID = lpSessionData->GetOldServerGroupID(); // °èÁ¤ ±¹°¡ ¼³Á¤ if ( PktSAND::TYPE_SET == cType ) { if (!DBComponent::GameDB::UpdateAccountNation( CDBSingleObject::GetInstance(), dwUID, cAccountNation, cOldServerGroupID)) { ERRLOG3(g_Log, "UID:%10u / AccountNation:%d / ServerGroupID:%d / °èÁ¤ ±¹Àû ¼³Á¤ ½ÇÆÐ : UpdateAccountNation DB¿¡·¯", dwUID, cAccountNation, cOldServerGroupID); usError = 2; } } // WORK_LIST 2.3 °èÁ¤ ±¹Àû º¯°æ ±â´É ±¸Çö // °èÁ¤ ±¹°¡ º¯°æ else if ( PktSAND::TYPE_CHANGE == cType ) { if ( lpSessionData->GetAccountNation() != cAccountNation ) { if ( !DBComponent::GameDB::UpdateAccountNation( CDBSingleObject::GetInstance(), dwUID, cAccountNation, cOldServerGroupID ) ) { ERRLOG3(g_Log, "UID:%10u / AccountNation:%d / ServerGroupID:%d / °èÁ¤ ±¹Àû ¼³Á¤ ½ÇÆÐ : UpdateAccountNation DB¿¡·¯", dwUID, cAccountNation, cOldServerGroupID); usError = 2; } else { unsigned char cOldAccountNation = lpSessionData->GetAccountNation(); unsigned long aryGID[ USER_INFO::MAX_CHAR_NUM ] = { 0, 0, 0, 0, 0 }; unsigned long aryFame[ USER_INFO::MAX_CHAR_NUM ] = { 0, 0, 0, 0, 0 }; unsigned long aryOldFame[ USER_INFO::MAX_CHAR_NUM ] = { 0, 0, 0, 0, 0 }; unsigned long aryOldGID[ USER_INFO::MAX_CHAR_NUM ] = { 0, 0, 0, 0, 0 }; for (int i=0; i < USER_INFO::MAX_CHAR_NUM; ++i) { const CHAR_VIEW* pCharView = lpSessionData->GetCharView(i); if ( 0 != pCharView->CID ) { aryOldFame[ i ] = pCharView->Fame; aryOldGID[ i ] = pCharView->GID; Guild::CGuildDB* lpGuild = static_cast( Guild::CGuildDBMgr::GetInstance().GetGuild( pCharView->GID )); if (NULL != lpGuild) { // ¸í¼ºÀÌ 5000(¹Ì±¹Àº 1000) ÀÌ»óÀ̾ú´Ù¸é, ¸í¼ºÄ¡¿¡ ÆÐ³ÎƼ Àû¿ë const unsigned short wFamePaneltyValue1st = CSessionData::FAME_PANELTY_VALUE_1ST; if ( pCharView->Fame > wFamePaneltyValue1st ) { if ( pCharView->Fame < CSessionData::FAME_PANELTY_VALUE_2ND ) { lpGuild->AddMemberFame( Guild::TYPE_VALUE, pCharView->CID, int(wFamePaneltyValue1st - pCharView->Fame) ); lpSessionData->SetCharViewFame( pCharView->CID, wFamePaneltyValue1st ); } else { lpGuild->AddMemberFame( Guild::TYPE_HALF, pCharView->CID, 0 ); lpSessionData->SetCharViewFame( pCharView->CID, pCharView->Fame / 2 ); } } if ( 1 < lpGuild->GetCurrentMemberNum() ) { bool bLeaveGuild = true; // ±æµå ¸¶½ºÅÍÀÇ °æ¿ì ±ÇÇÑÀ» ¾çµµÇÑ ÈÄ Å»Åð½ÃŲ´Ù. if (pCharView->CID == lpGuild->GetMaster().m_dwCID) { unsigned long dwNewMaster = lpGuild->SetNewMaster(); if (0 != dwNewMaster) { SendPacket::GuildCmd(&SendStream, lpGuild->GetGID(), dwNewMaster, MASTER, PktGuildCmd::GC_SETUP_TITLE, NULL, NULL, PktBase::NO_SERVER_ERR); DETLOG3(g_Log, "GID:%10u ±æµå¸¶½ºÅÍ(ÀÌÀü:%10u, ÇöÀç:%10u)°¡ º¯°æµÇ¾ú½À´Ï´Ù. - ±æµå¸¶½ºÅÍ ±¹Àû º¯°æ", lpGuild->GetGID(), pCharView->CID, dwNewMaster); } else { DETLOG1(g_Log, "GID:%10u ±æµå°¡ ÇØÃ¼µÇ¾ú½À´Ï´Ù. - ±æµå¸¶½ºÅÍ ±¹Àû º¯°æ(¾çµµÇÒ ±æ¿ø ¾øÀ½)", lpGuild->GetGID()); CGuildDBMgr::GetInstance().DissolveGuild(lpGuild->GetGID(), PktCreateGuild::NONE_NEXT_GUILDMASTER_BY_GUILDMASTER_OUT); bLeaveGuild = false; } } if (true == bLeaveGuild) { // ±æµå ±¹Àû°ú º¯°æµÈ °èÁ¤ ±¹ÀûÀÌ ´Ù¸£¹Ç·Î, Å»Åð ó¸® ½ÃŲ´Ù. if ( lpGuild->LeaveMember( pCharView->CID ) ) { // ±æµå Å»Åð Á¤º¸¸¦ ¸ðµç °ÔÀÓ ¼­¹ö·Î Àü¼Û SendPacket::GuildCmd( NULL, pCharView->GID, pCharView->CID, 0, PktGuildCmd::GC_KICK, NULL, NULL, PktBase::NO_SERVER_ERR ); } else { // ±æµå Å»Åð ½ÇÆÐ ERRLOG3(g_Log, "UID:%10u / CID:%10u / GID:%10u ±æµå °­Á¦ Å»Åð ½ÇÆÐ : °èÁ¤ ±¹Àû º¯°æÀ¸·Î ÀÎÇÑ Å»Åð ½ÇÆÐ", dwUID, pCharView->CID, pCharView->GID); } } } else { // ±æµå¿øÀÌ ÇѸí»ÓÀ̹ǷÎ, ±æµå¸¦ ÇØÃ¼ÇÑ´Ù. DETLOG1(g_Log, "GID:%10u ±æµå°¡ ÇØÃ¼µÇ¾ú½À´Ï´Ù. - ±æµå¸¶½ºÅÍ ±¹Àû º¯°æ(±æ¸¶»ÓÀÎ ±æµå)", lpGuild->GetGID()); CGuildDBMgr::GetInstance().DissolveGuild( lpGuild->GetGID(), PktCreateGuild::NONE_NEXT_GUILDMASTER_BY_GUILDMASTER_OUT); } lpSessionData->SetCharViewGID( pCharView->CID, 0 ); } else { // ¸í¼ºÀÌ 5000(¹Ì±¹Àº 1000) ÀÌ»óÀ̾ú´Ù¸é, ¸í¼ºÄ¡¿¡ ÆÐ³ÎƼ Àû¿ë const unsigned short wFamePaneltyValue1st = CSessionData::FAME_PANELTY_VALUE_1ST; if ( pCharView->Fame > wFamePaneltyValue1st ) { CCharacterData* lpCharacterData = 0; CSessionData* lpCharSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession( pCharView->CID ); if ( 0 == lpCharSessionData || 0 == (lpCharacterData = lpCharSessionData->GetCharacterData()) ) { // ij¸¯ÅͰ¡ ¾È¸Å´Þ·ÁÀÖ´Â °æ¿ì, ij¸¯Å͸¦ ºÒ·¯¿Â´Ù. lpCharacterData = static_cast( CCharacterDataMgr::GetInstance().GetLogoutData( pCharView->CID )); if ( 0 != lpCharacterData ) { CHAR_INFOST charInfoST = lpCharacterData->GetInfo(); if ( pCharView->Fame < CSessionData::FAME_PANELTY_VALUE_2ND ) { charInfoST.Fame = wFamePaneltyValue1st; lpSessionData->SetCharViewFame( pCharView->CID, wFamePaneltyValue1st ); } else { charInfoST.Fame /= 2; lpSessionData->SetCharViewFame( pCharView->CID, pCharView->Fame / 2 ); } lpCharacterData->SetInfo( charInfoST ); } } else if( CSessionData::SE_CHAR_ENABLED == lpCharSessionData->GetSessionState() ) { ERRLOG1( g_Log, "CID:%10u ij¸¯ÅÍ ¼±ÅÃÈ­¸é¿¡¼­ °èÁ¤ ±¹Àû º¯°æ½Ã, ÀÌ¹Ì °ÔÀÓ¿¡ ·ÎµåµÈ ij¸¯ÅͰ¡ Á¸ÀçÇÕ´Ï´Ù.", pCharView->CID ); } } lpSessionData->SetCharViewGID( pCharView->CID, 0 ); } aryGID[ i ] = pCharView->GID; aryFame[ i ] = pCharView->Fame; /* - ±¹Àûº¯°æ °ü·Ã ·Î±× UID CID ij¸¯ÅÍ¸í º¯°æÀü±¹°¡ º¯°æÈı¹°¡ ±âÁ¸¸í¼º º¯°æ¸í¼º ÇöÀç·¹º§ ÀÌÀü±æµåID »õ±æµåID ÆÄƼID */ INFLOG11(g_Log, "±¹Àû·Î±×\t%10u\t%10u\t%s\t%s\t%s\t%u\t%u\t%u\t%u\t%u\t%u\t", dwUID, pCharView->CID, pCharView->Name, Creature::GetShortNationName(cOldAccountNation), Creature::GetShortNationName(cAccountNation), aryOldFame[ i ], aryFame[ i ], pCharView->Level, aryOldGID[ i ], aryGID[ i ], pCharView->PID); } } // ±¹Àû º¯°æÀ¸·Î ÀÎÇØ ±æµå ID°¡ ¹Ù²ï Á¤º¸¸¦ Auth ¼­¹ö·Î º¸³»¼­, Client °¡ °»½ÅÇϵµ·Ï ÇÑ´Ù. SendPacket::NationChangeResult(SendStream, dwRequestKey, dwUID, aryGID, aryFame); } } else { ERRLOG3(g_Log, "UID:%10u / Old_AccountNation:%d / New_AccountNation:%d / °èÁ¤ ±¹Àû º¯°æ ½ÇÆÐ : °°Àº ±¹ÀûÀÓ", dwUID, lpSessionData->GetAccountNation(), cAccountNation); usError = 5; // ÀÌ¹Ì º¯°æÇÒ·Á´Â ±¹ÀûÀÌ´Ù. } } if (0 == usError) { // °èÁ¤ ±¹°¡ ¼³Á¤ ¹× º¯°æ ¼º°ø RULLOG2(g_Log, "UID:%10u / AccountNation:%d °èÁ¤ ±¹°¡ ¼³Á¤", dwUID, cAccountNation); // °èÁ¤ ±¹°¡ ¼³Á¤ lpSessionData->SetAccountNation( cAccountNation ); } } return SendPacket::SelectAccountNation(SendStream, dwRequestKey, dwUID, cType, cAccountNation, usError); } bool CharSelect(CSendStream& SendStream, PktCSD* lpPktCSD) { // ¼­¹ö ¼¼¼Ç ¾ò±â unsigned long dwUID = lpPktCSD->m_dwUserID; unsigned long dwCID = lpPktCSD->m_dwCharID; unsigned long dwRequestKey = lpPktCSD->m_dwRequestKey; unsigned short usError = 0; unsigned char cZone = 1; using namespace DataStorage; CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); CCharacterData* lpCharacterData = 0; // ¼¼¼Ç ¾ò±â if(0 == lpSessionData) { ERRLOG1(g_Log, "UID:%10u / ij¸¯ÅÍ ¼±Åà ½ÇÆÐ : ¼¼¼ÇÀÌ ¾ø½À´Ï´Ù", dwUID); usError = 5; } // ij¸¯ÅÍ ¾ÆÀ̵ð °Ë»ç else if (!lpSessionData->HasCharacter(dwCID)) { const USER_INFO& userInfo = lpSessionData->GetUserInfo(); // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ ERRLOG8(g_Log, "UID:%10u / SelectedCID:%10u / Char1:%10u / Char2:%10u / Char3:%10u / Char4:%10u / Char5:%10u / Nation:%d" "ij¸¯ÅÍ ¼±Åà ½ÇÆÐ : ¼ÒÀ¯Çϰí ÀÖÁö ¾ÊÀº ij¸¯ÅÍÀÔ´Ï´Ù.", dwUID, dwCID, userInfo.CharID[0], userInfo.CharID[1], userInfo.CharID[2], userInfo.CharID[3], userInfo.CharID[4], userInfo.Nation); usError = 3; } else { if (!lpSessionData->LoadData(dwCID)) { ERRLOG2(g_Log, "UID:%10u / SelectedCID:%10u / ij¸¯ÅÍ ¼±Åà ½ÇÆÐ : ij¸¯ÅÍ ·Îµå ½ÇÆÐ", dwUID, dwCID); usError = 3; } else { CCharacterData* lpCharacterData = lpSessionData->GetCharacterData(); lpCharacterData->SetUID(dwUID); SERVER_ID serverID; serverID.dwID = lpCharacterData->GetInfoEx().ServerID; // ±¹°¡ÀüÀï ¹Ì Âü¿©½Ã °øÇåÈÆÀå Æ÷ÀÎÆ® »è°¨. unsigned char cRealmPoint = lpCharacterData->GetRealmPoint(); unsigned long dwRealmCount_Out = 0; // ¼­¹ö ¼¼¼ÇÀÌ ½ÃÀ۵Ǹé // ·Î±×¾Æ¿ô ½Ã°£À» ±âÁ¡À¸·Î °øÇåÈÆÀåÀÇ Æ÷ÀÎÆ® Ãß°¡ »è°¨À» // °è»êÇÑ´Ù. TIME* pTime = lpCharacterData->GetLogoutTime(); if(pTime) { CTime timeLoggout(pTime->Year, pTime->Month, pTime->Day, pTime->Hour, pTime->Minute, pTime->Second); CGameTimeDBMgr::GetInstance().CheckRealmCount(timeLoggout, &dwRealmCount_Out); if(lpCharacterData->GetRealmCheckPoint() && dwRealmCount_Out) { dwRealmCount_Out -= 1; lpCharacterData->SetRealmCheckPoint(0); lpCharacterData->SetRealmMinute(0); if(cRealmPoint<=dwRealmCount_Out) { lpCharacterData->SetRealmPoint(0); } else { cRealmPoint -= static_cast(dwRealmCount_Out); lpCharacterData->SetRealmPoint(cRealmPoint); } } else if(dwRealmCount_Out) { if(cRealmPoint<=dwRealmCount_Out) { lpCharacterData->SetRealmPoint(0); } else { cRealmPoint -= static_cast(dwRealmCount_Out); lpCharacterData->SetRealmPoint(cRealmPoint); } lpCharacterData->SetRealmMinute(0); } else if(lpCharacterData->GetRealmCheckPoint() && !dwRealmCount_Out) { if(CGameTimeDBMgr::GetInstance().GetCurrentGameTime(GameTime::REALM)!=GameTime::RT_REALM_WAR) { unsigned char cRealmPoint = lpCharacterData->GetRealmPoint(); lpCharacterData->SetRealmCheckPoint(0); lpCharacterData->SetRealmMinute(0); if(cRealmPointSetRealmPoint(cRealmPoint); } } } CTime timeLogin = CTime::GetCurrentTime(); pTime->Year = timeLogin.GetYear(); pTime->Month = timeLogin.GetMonth(); pTime->Day = timeLogin.GetDay(); pTime->Hour = timeLogin.GetHour(); pTime->Minute = timeLogin.GetMinute(); pTime->Second = timeLogin.GetSecond(); } // edith 2010.01.02 °øÇåÆ÷ÀÎÆ®¸¦ ±æµå¿ø Á¤º¸¿¡ µû¶ó ó¸®ÇØÁÖ´Â ÇÔ¼ö. unsigned int GID = lpCharacterData->GetGID(); Guild::CGuildDB* lpGuild = static_cast( Guild::CGuildDBMgr::GetInstance().GetGuild( GID )); if(lpGuild) { unsigned char MaxNum = lpGuild->GetMaxMemberNum(); unsigned char CurNum = lpGuild->GetCurrentMemberNum(); lpCharacterData->SetRealmPoint(MaxNum/10); } else lpCharacterData->SetRealmPoint(0); if (CServerSetup::AuthServer == serverID.GetType() || 0 == serverID.dwID) { // ÃʱâÈ­µÇ¾î ÀÖÁö ¾ÊÀº ij¸¯ÅÍ // cZone = CServerSetup::GetInstance().IsBattleAgentServer() // ? SERVER_ID::BATTLE_SERVER : SERVER_ID::ZONE12; if(CServerSetup::GetInstance().IsBattleAgentServer()) cZone = SERVER_ID::BATTLE_SERVER; else { unsigned char cRace = (0 != lpCharacterData) ? lpCharacterData->GetRace() : -1; if(cRace == CHAR_CREATE::HUMAN) cZone = SERVER_ID::ZONE1; else cZone = SERVER_ID::ZONE2; } } else { cZone = serverID.sID.ID; if (SERVER_ID::BATTLE_ZONE == cZone) { cZone = SERVER_ID::ZONE3; } // edith 2009.06.13 // ÇØ´ç Á¾Á· °Ë»ç if (!lpSessionData->CheckCharZone(cZone)) { // 0 : Human // 1 : Akhan // -1 : ij¸¯ÅÍ µ¥ÀÌÅÍ ¿¬°á ¾ÈµÊ unsigned char cRace = (0 != lpCharacterData) ? lpCharacterData->GetRace() : -1; unsigned char cStartZone = lpSessionData->GetCharStartZone(cRace); /* if(cRace == CHAR_CREATE::HUMAN) cStartZone = SERVER_ID::ZONE1; else cStartZone = SERVER_ID::ZONE2; */ /* if(SERVER_ID::ZONE5 == cZone && !CGameTimeDBMgr::GetInstance().IsEnterTime()) { // Å×¼·¿ë ½Å±ÔÁ¸ ÁøÀÔÁ¦ÇÑ¿¡ °É·ÈÀ½. DETLOG5(g_Log, "UID:%10u / CID:%10u / Zone:%u / StartZone:%u / Race:%u / ½Å±ÔÁ¸ ÁøÀÔÁ¦ÇÑ : ½ÃÀÛ Á¸À¸·Î À̵¿ÇÕ´Ï´Ù", dwUID, dwCID, cZone, cStartZone, cRace); } else { DETLOG5(g_Log, "UID:%10u / CID:%10u / Zone:%u / StartZone:%u / Race:%u / À߸øµÈ Á¸ üũ : ½ÃÀÛ Á¸À¸·Î À̵¿ÇÕ´Ï´Ù", dwUID, dwCID, cZone, cStartZone, cRace); } */ DETLOG5(g_Log, "UID:%10u / CID:%10u / Zone:%u / StartZone:%u / Race:%u / À߸øµÈ Á¸ üũ : ½ÃÀÛ Á¸À¸·Î À̵¿ÇÕ´Ï´Ù", dwUID, dwCID, cZone, cStartZone, cRace); cZone = cStartZone; } /* // edith 2009.06.13 Character Select GameTime Over if(CGameTimeDBMgr::GetInstance().IsGuildWarTime() && cZone == SERVER_ID::CAPITAL) { DETLOG5(g_Log, "UID:%10u / CID:%10u / Zone:%u / StartZone:%u / Race:%u / IsGuildWarTime Á¸ üũ : ½ÃÀÛ Á¸À¸·Î À̵¿ÇÕ´Ï´Ù", dwUID, dwCID, cZone, cStartZone, cRace); cZone = cStartZone; } else if(CGameTimeDBMgr::GetInstance().IsRealmWarTime() && (SERVER_ID::STONE_WAR1 <= cZone && cZone <= SERVER_ID::STONE_WAR3)) { DETLOG5(g_Log, "UID:%10u / CID:%10u / Zone:%u / StartZone:%u / Race:%u / IsRealmWarTime Á¸ üũ : ½ÃÀÛ Á¸À¸·Î À̵¿ÇÕ´Ï´Ù", dwUID, dwCID, cZone, cStartZone, cRace); cZone = cStartZone; } */ } INFLOG2(g_Log, "UID:%10u / SelectedCID:%10u / ij¸¯ÅÍ ¼±Åà ¼º°ø", dwUID, dwCID); lpSessionData->UnloadData(); } } return SendPacket::CharSelect(SendStream, dwRequestKey, cZone, usError); } bool CharCreate(CSendStream& SendStream, PktCCD* lpPktCCD) { unsigned long dwUID = lpPktCCD->m_dwUserID; unsigned long dwSlot = lpPktCCD->m_dwSlot; unsigned long dwGold = lpPktCCD->m_dwGold; unsigned long dwRequestKey = lpPktCCD->m_dwRequestKey; unsigned long dwCID = 0; CHAR_VIEW CharView = {0,}; unsigned short usError = 0; using namespace DataStorage; CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); // ¼¼¼Ç ¾ò±â if(0 == lpSessionData) { ERRLOG1(g_Log, "UID:%10u / ij¸¯ÅÍ »ý¼º ½ÇÆÐ : ¼¼¼ÇÀÌ ¾ø½À´Ï´Ù", dwUID); usError = PktCCAck::NULL_SESSION; } else { // ½ºÅ³ ¼¼ÆÃ SKILL Skill(1, 1); switch(lpPktCCD->m_CharCreate.Class) { case CClass::Fighter: Skill.SSlot[0] = SKILLSLOT(0x8104, 0, 1); break; case CClass::Rogue: Skill.SSlot[0] = SKILLSLOT(0x8205, 0, 1); break; case CClass::Mage: Skill.SSlot[0] = SKILLSLOT(0x8303, 0, 1); break; case CClass::Acolyte: Skill.SSlot[0] = SKILLSLOT(0x8405, 0, 1); break; case CClass::Combatant: Skill.SSlot[0] = SKILLSLOT(0x9104, 0, 1); break; case CClass::Officiator: Skill.SSlot[0] = SKILLSLOT(0x9202, 0, 1); break; default: ERRLOG3(g_Log, "UID:%10u / CID:%10u / Class:%u/ ij¸¯ÅÍ »ý¼º : ½ºÅ³ ³Ö±â ½ÇÆÐ - À߸øµÈ Ŭ·¡½ºÀÔ´Ï´Ù", dwUID, dwCID, lpPktCCD->m_CharCreate.Class); usError = PktCCAck::FAIL_INSERT_DATA; break; } // Edith 2008.06.14 ij¸¯ÅÍ »ý¼º½Ã »ý¼º°ª ¹®Á¦ °ËÃâ if(dwGold > 0) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Gold:%u/ ij¸¯ÅÍ »ý¼º : °ñµå°ª ÀÌ»ó", dwUID, dwCID, dwGold); usError = PktCCAck::FAIL_INSERT_DATA; } else if(lpPktCCD->m_CharCreate.Face < 0 && lpPktCCD->m_CharCreate.Face >= 7) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Face:%u/ ij¸¯ÅÍ »ý¼º : ¾ó±¼ ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Hair); usError = PktCCAck::FAIL_INSERT_DATA; } else if(lpPktCCD->m_CharCreate.Race == 0) { if(lpPktCCD->m_CharCreate.Sex == 1) // Àΰ£ ³²ÀÚ { if(lpPktCCD->m_CharCreate.Hair < 0 && lpPktCCD->m_CharCreate.Hair >= 5) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Hair:%u/ ij¸¯ÅÍ »ý¼º : Çì¾î ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Hair); usError = PktCCAck::FAIL_INSERT_DATA; } } else if(lpPktCCD->m_CharCreate.Sex == 2)// Àΰ£ ¿©ÀÚ { if(lpPktCCD->m_CharCreate.Hair < 0 && lpPktCCD->m_CharCreate.Hair >= 7) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Hair:%u/ ij¸¯ÅÍ »ý¼º : Çì¾î ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Hair); usError = PktCCAck::FAIL_INSERT_DATA; } } else { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Sex:%u/ ij¸¯ÅÍ »ý¼º : ¼ºº° ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Sex); usError = PktCCAck::FAIL_INSERT_DATA; } } else if(lpPktCCD->m_CharCreate.Race == 1) { if(lpPktCCD->m_CharCreate.Sex == 1) // ¾ÆÄ­³²ÀÚ { if(lpPktCCD->m_CharCreate.Hair < 0 && lpPktCCD->m_CharCreate.Hair >= 7) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Hair:%u/ ij¸¯ÅÍ »ý¼º : Çì¾î ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Hair); usError = PktCCAck::FAIL_INSERT_DATA; } } else if(lpPktCCD->m_CharCreate.Sex == 2) // ¾ÆÄ­¿©ÀÚ { if(lpPktCCD->m_CharCreate.Hair < 0 && lpPktCCD->m_CharCreate.Hair >= 7) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Hair:%u/ ij¸¯ÅÍ »ý¼º : Çì¾î ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Hair); usError = PktCCAck::FAIL_INSERT_DATA; } } else { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Sex:%u/ ij¸¯ÅÍ »ý¼º : ¼ºº° ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Sex); usError = PktCCAck::FAIL_INSERT_DATA; } } else { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Race:%u/ ij¸¯ÅÍ »ý¼º : Á¾Á· ÀÌ»ó", dwUID, dwCID, lpPktCCD->m_CharCreate.Race); usError = PktCCAck::FAIL_INSERT_DATA; } int iStat = lpPktCCD->m_CharCreate.STR+lpPktCCD->m_CharCreate.DEX +lpPktCCD->m_CharCreate.CON+lpPktCCD->m_CharCreate.INT+lpPktCCD->m_CharCreate.WIS - 100; if(iStat != 5) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / iStat:%u/ ij¸¯ÅÍ »ý¼º : ½ºÅÝ ÀÌ»ó", dwUID, dwCID, iStat+100); usError = PktCCAck::FAIL_INSERT_DATA; } if (usError != 0) { ; } // DB¿¡ ij¸¯ÅÍ »ý¼º else if (!DBComponent::GameDB::InsertChar(CDBSingleObject::GetInstance(), dwUID, dwSlot, lpPktCCD->m_CharCreate, dwGold, lpPktCCD->m_Pos, Skill, lpSessionData->GetOldServerGroupID(), dwCID)) { ERRLOG1(g_Log, "UID:%10u / ij¸¯ÅÍ »ý¼º ½ÇÆÐ : DB¿¡·¯", dwUID); // ij¸¯ÅÍ »ý¼º ½ÇÆÐ usError = PktCCAck::FAIL_INSERT_DATA; } else if (-1 == dwCID) { // µ¿ÀÏÇÑ À̸§À» °¡Áö°í Àִ ij¸¯ÅͰ¡ ÀÖ´Â °æ¿ì usError = PktCCAck::EXIST_CHAR_NAME; } else if (-2 == dwCID) { // µ¿ÀÏÇÑ À̸§À» °¡Áö°í Àִ ij¸¯ÅͰ¡ ÀÖ´Â °æ¿ì usError = PktCCAck::EXIST_SLOT; } else if (!lpSessionData->GetUserInfoFromDB(CDBSingleObject::GetInstance())) { // ij¸¯Å͸¦ »ý¼ºÇßÀ¸´Ï. ºä¸¦ ´Ù½ÃÇѹø ·ÎµåÇÑ´Ù. ERRLOG1(g_Log, "UID:%10u / ij¸¯ÅÍ »ý¼º ½ÇÆÐ : ij¸¯ÅÍ ºä Àç·Îµå ½ÇÆÐ.", dwUID); usError = PktCCAck::VIEW_RELOAD_FAILED; } else if (!lpSessionData->GetCharView(dwCID, CharView)) { // ºä¸¦ ¾ò¾î¼­ º¸³» ÁØ´Ù. ERRLOG1(g_Log, "UID:%10u / ij¸¯ÅÍ »ý¼º ½ÇÆÐ : ij¸¯ÅÍ ºä ¾ò±â ½ÇÆÐ.", dwUID); usError = PktCCAck::VIEW_RELOAD_FAILED; } else { // ij¸¯ÅÍ »ý¼º ¼º°ø. RULLOG4(g_Log, "UID:%10u / CID:%10u / ij¸¯ÅÍ [%s]%s »ý¼º", dwUID, dwCID, (CharView.Race == 0) ? "Human" : "Akhan", CharView.Name); /* - ±¹Àûº¯°æ °ü·Ã ·Î±× UID CID ij¸¯ÅÍ¸í º¯°æÀü±¹°¡ º¯°æÈı¹°¡ ±âÁ¸¸í¼º º¯°æ¸í¼º ÇöÀç·¹º§ ÀÌÀü±æµåID »õ±æµåID ÆÄƼID */ INFLOG11(g_Log, "±¹Àû·Î±×\t%10u\t%10u\t%s\t%s\t%s\t%u\t%u\t%u\t%u\t%u\t%u\t", dwUID, dwCID, CharView.Name, Creature::GetShortNationName(lpSessionData->GetUserInfo().Nation), Creature::GetShortNationName(lpSessionData->GetUserInfo().Nation), 0, CharView.Fame, CharView.Level, 0, CharView.GID, CharView.PID); } } return SendPacket::CharCreate(SendStream, dwRequestKey, dwCID, dwSlot, CharView, usError); } bool CharDelete(CSendStream& SendStream, PktCDD* lpPktCDD) { unsigned long dwUID = lpPktCDD->m_dwUserID; unsigned long dwCID = lpPktCDD->m_dwCharID; unsigned long dwSlot = lpPktCDD->m_dwSlotNum; unsigned long dwRequestKey = lpPktCDD->m_dwRequestKey; unsigned short usError = 0; using namespace DataStorage; CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID); // ¼¼¼Ç ¾ò±â if(0 == lpSessionData) { ERRLOG1(g_Log, "UID:%10u / ij¸¯ÅÍ »èÁ¦ ½ÇÆÐ : ¼¼¼ÇÀÌ ¾ø½À´Ï´Ù", dwUID); usError = 4; } else if (CCharacterDataMgr::GetInstance().IsDataLoginDB(dwCID) || CSessionData::SE_CHAR_ENABLED == lpSessionData->GetSessionState()) { // Ȱ¼ºÈ­µÈ ij¸¯ÅÍ »èÁ¦ ½Ãµµ ERRLOG2(g_Log, "UID:%10u / CID:%10u / ij¸¯ÅÍ »èÁ¦ ½ÇÆÐ : Ȱ¼ºÈ­µÈ ij¸¯ÅÍ »èÁ¦ ½Ãµµ", dwUID, dwCID); usError = 3; } else { const CHAR_VIEW* lpCharView = lpSessionData->GetCharView(static_cast(dwSlot)); if(0 == lpCharView) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Slot:%u / ij¸¯ÅÍ »èÁ¦ ½ÇÆÐ : ¿øÇÏ´Â ½½·Ô¿¡ ºä ¾øÀ½", dwUID, dwCID, dwSlot); usError = 2; } else if(lpCharView->CID != dwCID) { ERRLOG4(g_Log, "UID:%10u / CID:%10u / DeleteCID:%10u / Slot:%u / ij¸¯ÅÍ »èÁ¦ ½ÇÆÐ : ºäÀÇ CID¿Í Áö¿ì·Á´Â ij¸¯ÅÍÀÇ CID´Ù¸§", dwUID, lpCharView->CID, dwCID, dwSlot); usError = 2; } else { // DB·Î ºÎÅÍ Ä³¸¯ÅÍ »èÁ¦ if(CServerSetup::GetInstance().IsBattleAgentServer()) { if(!DBComponent::GameDB::DeleteCharBattleServer( CDBSingleObject::GetInstance(), dwUID, dwCID, static_cast(dwSlot), CServerSetup::GetInstance().GetServerGroup(), lpSessionData->GetOldServerGroupID())) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Slot:%u / ij¸¯ÅÍ »èÁ¦ ½ÇÆÐ : DeleteCharBattleServer DB¿¡·¯", dwUID, dwCID, dwSlot); usError = 2; } } else { if (!DBComponent::GameDB::DeleteChar( CDBSingleObject::GetInstance(), dwUID, dwCID, static_cast(dwSlot), CServerSetup::GetInstance().GetServerGroup(), lpSessionData->GetOldServerGroupID())) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / Slot:%u / ij¸¯ÅÍ »èÁ¦ ½ÇÆÐ : DeleteChar DB¿¡·¯", dwUID, dwCID, dwSlot); usError = 2; } } if(0 == usError) { // ij¸¯ÅÍ »èÁ¦ ¼º°ø RULLOG4(g_Log, "UID:%10u / CID:%10u / ij¸¯ÅÍ [%s]%s »èÁ¦", dwUID, dwCID, (lpCharView->Race == 0) ? "Human" : "Akhan", lpCharView->Name); // ij¸¯ÅÍ ÃʱâÈ­ lpSessionData->UnloadData(); lpSessionData->DelUnifiedCharData(dwCID); } } } return SendPacket::CharDelete(SendStream, dwRequestKey, dwUID, dwSlot, dwCID, usError); } bool CreateItem(CSendStream& SendStream, unsigned long dwServerID, Item::CItemSerialMgr& itemSerialMgr, PktCCID* lpPktCCID) { if (sizeof(PktCCID) < lpPktCCID->GetLen()) { EQUIP Equip; memset(&Equip, 0, sizeof(EQUIP)); Equip.dwSize = lpPktCCID->m_dwSize; memcpy(Equip.Data, lpPktCCID + 1, lpPktCCID->m_dwSize); if(!DBComponent::GameDB::UpdateEquip( CDBSingleObject::GetInstance(), lpPktCCID->m_dwCharID, &Equip)) { ERRLOG1(g_Log, "CID:%10u / Àåºñ ¾÷µ¥ÀÌÆ® ½ÇÆÐ", lpPktCCID->m_dwCharID); } else { // ¾ÆÀÌÅÛ ½Ã¸®¾ó ¾÷µ¥ÀÌÆ® if(itemSerialMgr.SetItemSerial(lpPktCCID->m_dwItemSerial)) { // ½Ã¸®¾óÀÌ ¹Ù²î¾úÀ¸¹Ç·Î DB¿¡ ¾÷µ¥ÀÌÆ®ÇÑ´Ù. if(!itemSerialMgr.SaveItemSerial(CDBSingleObject::GetInstance(), dwServerID)) { ERRLOG3(g_Log, "CID:%10u / ServerID:0x%08X / Serial:0x%016I64X / ¾ÆÀÌÅÛ ½Ã¸®¾ó ¾÷µ¥ÀÌÆ® ½ÇÆÐ", lpPktCCID->m_dwCharID, dwServerID, itemSerialMgr.GetItemSerial()); } } } return true; } return false; } // TODO : FIX FOR BATTLEGROUND! bool BGServerCharSlot(CSendStream& SendStream, PktBase* lpPktBase) { PktBGServerCharSlot* lpPktBGServerCharSlot = static_cast(lpPktBase); unsigned long dwUID = lpPktBGServerCharSlot->m_dwUID; unsigned long dwCID = lpPktBGServerCharSlot->m_dwCID; unsigned char cGroup = lpPktBGServerCharSlot->m_cGroup; unsigned short usError = 0; char* lpBuffer = SendStream.GetBuffer(sizeof(PktBGServerCharSlotAck)); if(0 != lpBuffer) { PktBGServerCharSlotAck* lpPktBGServerCharSlotAck = reinterpret_cast(lpBuffer); lpPktBGServerCharSlotAck->m_dwCID = dwCID; lpPktBGServerCharSlotAck->m_cGroup = cGroup; memset(lpPktBGServerCharSlotAck->m_dwSlotCID, 0, sizeof(unsigned long) * USER_INFO::MAX_CHAR_NUM); memset(lpPktBGServerCharSlotAck->m_szSlotName, 0, sizeof(char) * USER_INFO::MAX_CHAR_NUM * CHAR_INFOST::MAX_NAME_LEN); unsigned char cOldServerGroupID = 0; switch(CServerSetup::GetInstance().GetAgentServerType()) { case UnifiedConst::Part1: case UnifiedConst::Part1Unified: default: cOldServerGroupID = 0; break; case UnifiedConst::ROW: case UnifiedConst::Part2Unified: case UnifiedConst::Part2Selectable: cOldServerGroupID = static_cast( CServerSetup::GetInstance().GetAgentServerType()); break; } USER_INFO userInfo; memset(&userInfo, 0, sizeof(USER_INFO)); if (!DBComponent::GameDB::GetUserInfo(CDBSingleObject::GetInstance(), dwUID, userInfo, cOldServerGroupID)) { ERRLOG2(g_Log, "UID:%10u / ¹èƲ·ÎÇÑÀ¸·Î ij¸¯ÅÍ Á¤º¸ ÁÖ±â ½ÇÆÐ : À¯Àú Á¤º¸ ¾ò±â ½ÇÆÐ : %s", dwUID, CDBSingleObject::GetInstance().GetErrorString()); usError = PktBGServerCharSlotAck::FAIL_NOT_USER; } else { CHAR_VIEW charView; // WORK_LIST 2.1 °èÁ¤ ±¹Àû Ãß°¡ (¹èƲ ·ÎÇÑ¿¡ Nation Á¤º¸¸¦ Áà¾ßÇϳª? ¾ÆÁ÷ Ãß°¡¾ÈÇßÀ½) for (unsigned int nIndex = 0; nIndex < USER_INFO::MAX_CHAR_NUM; ++nIndex) { unsigned long dwLoadViewCID = userInfo.CharID[nIndex]; lpPktBGServerCharSlotAck->m_dwSlotCID[nIndex] = dwLoadViewCID; if (0 != dwLoadViewCID) { memset(&charView, 0, sizeof(CHAR_VIEW)); if (!DBComponent::GameDB::GetCharView(CDBSingleObject::GetInstance(), dwLoadViewCID, &charView)) { ERRLOG3(g_Log, "UID:%10u / CID:%10u / ¹èƲ·ÎÇÑÀ¸·Î ij¸¯ÅÍ Á¤º¸ ÁÖ±â ½ÇÆÐ : ij¸¯ÅÍ ºä ¾ò±â ½ÇÆÐ : %s", dwUID, dwLoadViewCID, CDBSingleObject::GetInstance().GetErrorString()); usError = PktBGServerCharSlotAck::FAIL_NOT_CHAR; break; } strncpy(lpPktBGServerCharSlotAck->m_szSlotName[nIndex], charView.Name, CHAR_INFOST::MAX_NAME_LEN); lpPktBGServerCharSlotAck->m_szSlotName[nIndex][CHAR_INFOST::MAX_NAME_LEN - 1] = 0; } } } return SendStream.WrapHeader(sizeof(PktBGServerCharSlotAck), CmdBGServerCharSlot, 0, usError); } return false; } bool UnifiedCharSelect(CSendStream& SendStream, PktBase* lpPktBase) { PktUnifiedCharSelectReq* lpUnifiedSelectReq = static_cast(lpPktBase); /* Part2Unified 0 : â°í °¡Á®¿Â Àû ¾ø´Ù 1 : Part1 ÅëÇÕ¿¡¼­ â°í °¡Á®¿Ô´Ù 2 : Part2 ÅëÇÕ¿¡¼­ â°í °¡Á®¿Ô´Ù. Part2Selectable */ unsigned char cAgentServerType = static_cast( CServerSetup::GetInstance().GetAgentServerType()); using namespace DBAgent::DataStorage; CSessionData* lpSessionData = 0; unsigned long dwUID = lpUnifiedSelectReq->dwUID; unsigned long dwRequestKey = lpUnifiedSelectReq->dwRequestKey; unsigned short usError = 0; unsigned char cSelectedServerGroupID = lpUnifiedSelectReq->cSelectedServerGroupID; unsigned char cSelectedNation = lpUnifiedSelectReq->cSelectedNation; bool bSupressSendAck = false; switch(cAgentServerType) { case UnifiedConst::Part2Unified: if(0 == (lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID))) { // ÇØ´ç UID°¡ ¾ø´Ù. ERRLOG1(g_Log, "UID:%10u / Part2Unified ij¸¯ÅÍ ¼±Åà ½ÇÆÐ - ¼¼¼ÇÀÌ ´ÝÇô ÀÖ½À´Ï´Ù", dwUID); usError = PktUnifiedCharSelectAck::SERVER_ERROR; } else { // ÀÏ´Ü µ¥ÀÌÅ͸¦ È®ÀÎÇϰí, Á¤¸®ÇÑ ÈÄ¿¡, Part1 DBÁß°è¼­¹ö¿¡ ¼±Åà °á°ú¸¦ ¾Ë·ÁÁØ´Ù. // Part1 DBÁß°è¼­¹ö´Â ÇØ´ç °èÁ¤/ij¸¯ÅͰ¡ ij½¬¿¡ ÀÖÀ¸¸é, ¾ð·ÎµåÇϰí, // ÇØ´ç ij¸¯Å͸¦ ÆÄƼ/±æµå¿¡¼­ Å»Åð½ÃŲ ÈÄ Ack¸¦ º¸³»ÁØ´Ù. // Ack¸¦ ¹ÞÀ¸¸é â°í/ij¸¯ÅÍ ¼±ÅÃÀ» ½ÃÀÛÇÑ´Ù. if (!(lpSessionData->GetFirstLogin() & UnifiedConst::SELECTED_PART2)) { // Á¸ÀçÇϴ â°í¸¦ ¼±ÅÃÇß´ÂÁö °ËÁõ if (!lpSessionData->HasUnifiedStoreInfo(cSelectedServerGroupID)) { usError = PktUnifiedCharSelectAck::WRONG_STORE_SELECTED; } } if(0 == usError) { // °¡Á®¿Ã ´ë»ó ij¸¯Å͸¦ °ËÁõÇÑ´Ù. USER_INFO userInfo = lpSessionData->GetUserInfo(); unsigned long dwSelectedCID[USER_INFO::MAX_CHAR_NUM]; unsigned long* lpdwRequestedCID = lpUnifiedSelectReq->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 == lpSessionData->CheckUnifiedCharRace(dwSelectedCID)) { // ij¸¯ÅͰ¡ Àִµ¥ Á¾Á·ÀÌ ´Ù¸£¸é ¿¡·¯! usError = PktUnifiedCharSelectAck::PACKET_ERROR; } else if (CServerSetup::GetInstance().GetMaxTransferPart1ToPart2Count() < nSelectedCount + lpSessionData->GetTransferedCharCount(CDBSingleObject::GetInstance())) { // ÃÖ´ë ij¸¯ÅÍ ¼±Åà ȸ¼ö ÀÌ»ó ¼±ÅÃÇÏ¸é ¿¡·¯ usError = PktUnifiedCharSelectAck::TRANSFER_COUNT_OVER; } else if (0 < nSelectedCount || !(lpSessionData->GetFirstLogin() & UnifiedConst::SELECTED_PART2)) { // Part1Áß°è¼­¹ö·Î '°ËÁõµÈ' µ¥ÀÌÅ͸¦ º¸³½´Ù. GET_SINGLE_DISPATCH(lpPart1DBAgentDispatch, CPart1DBAgentDispatch, CPart1DBAgentDispatch::GetDispatchTable()); if (0 != lpPart1DBAgentDispatch) { bSupressSendAck = SendPacket::UnifiedCharSelectReq(lpPart1DBAgentDispatch->GetSendStream(), dwUID, dwRequestKey, dwSelectedCID, USER_INFO::MAX_CHAR_NUM, cSelectedServerGroupID, cSelectedNation); usError = bSupressSendAck ? 0 : PktUnifiedCharSelectAck::SERVER_ERROR; } } } } break; case UnifiedConst::Part2Selectable: if(0 == (lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID))) { // ÇØ´ç UID°¡ ¾ø´Ù. ERRLOG1(g_Log, "UID:%10u / Part2Selectable ij¸¯ÅÍ ¼±Åà ½ÇÆÐ - ¼¼¼ÇÀÌ ´ÝÇô ÀÖ½À´Ï´Ù", dwUID); usError = PktUnifiedCharSelectAck::SERVER_ERROR; } else { if (0 < cSelectedServerGroupID && cSelectedServerGroupID <= CServerSetup::GetInstance().GetSelectableUnifiedServerNum()) { // ¿©±â¼­´Â µ¥ÀÌÅ͸¦ ÄÁ¹öÆÃ ÇÒ Çʿ䰡 ¾ø´Ù. // ÀÌ¹Ì ÄÁ¹öÆÃ µÈ µ¥ÀÌÅ͸¦ ³ÖÀ» ¿¹Á¤ÀÌ´Ù. // ¼­¹ö±ºÀ» ¼±ÅÃÇß´Ù. ¼±ÅÃÇÑ ¼­¹ö±ºÀ» ¼¼ÆÃÇÑ´Ù. lpSessionData->SetOldServerGroupID(cSelectedServerGroupID); if(!lpSessionData->GetUserInfoFromDB(CDBSingleObject::GetInstance())) { ERRLOG3(g_Log, "UID:%10u / FirstLogin:%d / SelectedServerGroupID:%d / " "Part2Selectable ij¸¯ÅÍ ¼±Åà ½ÇÆÐ - À¯Àú Á¤º¸ DB¿¡¼­ ÀÐ±â ½ÇÆÐ.", dwUID, lpSessionData->GetFirstLogin(), cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::SERVER_ERROR; } } else { ERRLOG3(g_Log, "UID:%10u / FirstLogin:%d / SelectedServerGroupID:%d / " "Part2Selectable ij¸¯ÅÍ ¼±Åà ½ÇÆÐ - FirstLoginÀ̳ª SelectedServerGroupID°ªÀÌ ´Ù¸¨´Ï´Ù.", dwUID, lpSessionData->GetFirstLogin(), cSelectedServerGroupID); usError = PktUnifiedCharSelectAck::PACKET_ERROR; } } break; default: usError = PktUnifiedCharSelectAck::PACKET_ERROR; break; } return !bSupressSendAck ? SendPacket::UnifiedCharSelectAck(SendStream, dwUID, dwRequestKey, usError) : true; } } }