#include "stdafx.h" #include "Character.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CCharacter::DBUpdate(DBUpdateData::UpdateType eUpdateType) { if(!IsOperationFlagSet(CHAR_INFO_LOADED) || (m_bLogout && DBUpdateData::LOGOUT != eUpdateType)) { return false; } if(--m_nDBUpdateCount > 0) { return false; } m_nDBUpdateCount = DBUPDATE_COUNT; int nTotalSize = sizeof(PktDBUpdate) + DBUpdateData::MAX_DBUPDATE_SIZE; char szCharInfo[sizeof(PktDBUpdate) + DBUpdateData::MAX_DBUPDATE_SIZE]; char* lpCharacterInfo = szCharInfo + sizeof(PktDBUpdate); PktDBUpdate* lpPktDBUpdate = reinterpret_cast(szCharInfo); memset(lpPktDBUpdate, 0, sizeof(PktDBUpdate)); unsigned short usLogError = 0; unsigned char cLogCMD = (DBUpdateData::LOGOUT == eUpdateType) ? GAMELOG::CMD::CHAR_LOGOUT : GAMELOG::CMD::CHAR_DBUPDATE; unsigned char cAdmin = (true == IsAdmin()) ? 1 : 0; if(!GetCharacterInfo(lpCharacterInfo, &nTotalSize, lpPktDBUpdate->m_usUpdate)) { nTotalSize = 0; usLogError = 1; ERRLOG1(g_Log, "CID:0x%08x DBUpdate½ÇÆÐ : µ¥ÀÌÅ͸¦ º¹»çÇØ ¿Ã ¼ö ¾ø½À´Ï´Ù.", m_dwCID); } else { GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (0 == lpDBAgentDispatch) { usLogError = 2; ERRLOG1(g_Log, "CID:0x%08x DBUpdate½ÇÆÐ : DBAgentDispatch ¸¦ ¾òÀ» ¼ö ¾ø½À´Ï´Ù.", m_dwCID); } else { CSendStream& AgentSendStream = lpDBAgentDispatch->GetSendStream(); // â°í µ¥ÀÌÅÍ ¾÷µ¥ÀÌÆ®(â°í°¡ ¿­·Á ÀÖÀ¸¸é ¾÷µ¥ÀÌÆ®ÇÑ´Ù.) // ¼ø¼­ ÁÖÀÇ! DB¿¡ UpdateÇÒ ¶§´Â â°í ¾÷µ¥ÀÌÆ® ÈÄ Ä³¸¯Å͸¦ ¾÷µ¥ÀÌÆ®ÇÑ´Ù. if(!m_Deposit.DBUpdate(AgentSendStream)) { ERRLOG1(g_Log, "CID:0x%08x â°í ¾÷µ¥ÀÌÆ® ½ÇÆÐ", m_dwCID); } lpPktDBUpdate->m_dlItemSerial = Item::CItemFactory::GetInstance().GetItemUID(); lpPktDBUpdate->m_dwSessionID = m_dwSessionID; lpPktDBUpdate->m_dwUserID = m_dwUID; lpPktDBUpdate->m_dwCharID = m_dwCID; lpPktDBUpdate->m_TypeCode = eUpdateType; lpPktDBUpdate->m_dwRequestKey = 0; lpPktDBUpdate->m_Address.S_un.S_addr = 0; lpPktDBUpdate->m_cAdminLevel = 0; // WORK_LIST 2.4 °èÁ¤ ±¹ÀûÀ» °ÔÀÓ¼­¹öÀÇ Ä³¸¯ÅͰ¡ °¡Áöµµ·Ï ±¸Çö lpPktDBUpdate->m_cAccountNation = 0; lpPktDBUpdate->m_cNameChangeCount = 0; lpPktDBUpdate->m_cGuildWarFlag = 0; lpPktDBUpdate->m_cRealmWarFlag = 0; lpPktDBUpdate->m_cRealmPoint = 0; lpPktDBUpdate->m_cTacticsFlag = 0; if(!AgentSendStream.WrapCompress(reinterpret_cast(lpPktDBUpdate), static_cast(sizeof(PktDBUpdate) + nTotalSize), CmdDBUpdateData, 0, 0)) { usLogError = 3; ERRLOG1(g_Log, "CID:0x%08x DBUpdate½ÇÆÐ : WrapCompress¸¦ ½ÇÆÐÇß½À´Ï´Ù.", m_dwCID); } } } if(DBUpdateData::LOGOUT == eUpdateType || 0 != usLogError) { SOCKADDR_IN remoteAddr; if (0 != m_lpGameClientDispatch) { remoteAddr = m_lpGameClientDispatch->GetRemoteAddr().get_addr_in(); } else { memset(&remoteAddr, 0, sizeof(SOCKADDR_IN)); } GAMELOG::LogCharLoginOut(m_dwUID, this, &remoteAddr, lpCharacterInfo, nTotalSize, lpPktDBUpdate->m_usUpdate, cLogCMD, usLogError); } LOG_INOUT( char szExp[64]; const char* szUpdateType = "Unknown"; switch (eUpdateType) { case DBUpdateData::LOGIN: szUpdateType = "Login"; break; case DBUpdateData::LOGOUT: szUpdateType = "Logout"; break; case DBUpdateData::UPDATE: szUpdateType = "Update"; break; case DBUpdateData::ADMIN_LOGIN: szUpdateType = "AdminLogin"; break; case DBUpdateData::ZONEMOVE: szUpdateType = "ZoneMove"; break; } unsigned long dwDispatchUID = (NULL != m_lpGameClientDispatch) ? m_lpGameClientDispatch->GetUID() : 0; Math::Convert::Hex64ToStr(szExp, m_DBData.m_Info.Exp); DETLOG8(g_Log, "UID:%d/CID:0x%08x(0x%p)/DispatchUID:%d ÀÇ Ä³¸¯ÅÍ Á¤º¸¸¦ DBAgent¿¡ ¾÷µ¥ÀÌÆ®ÇÕ´Ï´Ù. " " ¾÷µ¥ÀÌÆ® ŸÀÔÀº %sÀÔ´Ï´Ù. ¸î°¡Áö ±âº» Á¤º¸¸¦ Âï½À´Ï´Ù. %s(lev:%2d, exp:%s)", m_dwUID, m_dwCID, this, dwDispatchUID, szUpdateType, m_DBData.m_Info.Name, m_DBData.m_Info.Level, szExp) ); return true; } bool CCharacter::GetCharacterInfo(char* pBuffer, int* nBufferSize_InOut, unsigned short* lpUpdateLen) { unsigned long dwSize = 0; unsigned short usTotalSize = 0; if(!IsOperationFlagSet(CHAR_INFO_LOADED)) { ERRLOG1(g_Log, "CID:0x%08x ij¸¯ÅÍ Á¤º¸°¡ ¼¼ÆÃµÇÁö ¾ÊÀº »óÅ¿¡¼­ ij¸¯ÅÍ Á¤º¸¸¦ ¾òÀ¸·Á ÇÏ¿´½À´Ï´Ù.", m_dwCID); return false; } SaveToDBData(); for (int nCount = 0; nCount < DBUpdateData::MAX_UPDATE_DB; ++nCount) { switch (nCount) { case DBUpdateData::STATUS_UPDATE: { *reinterpret_cast(pBuffer) = m_DBData.m_Info; lpUpdateLen[nCount] = sizeof(CHAR_INFOST); } break; case DBUpdateData::POSITION_UPDATE: *reinterpret_cast(pBuffer) = m_DBData.m_Pos; lpUpdateLen[nCount] = sizeof(CHAR_POS); break; case DBUpdateData::SKILL_UPDATE: *reinterpret_cast(pBuffer) = m_DBData.m_Skill; lpUpdateLen[nCount] = sizeof(SKILL); break; case DBUpdateData::QUICKSLOT_UPDATE: *reinterpret_cast(pBuffer) = m_DBData.m_Quick; lpUpdateLen[nCount] = sizeof(QUICK); break; case DBUpdateData::SPELL_UPDATE: *reinterpret_cast(pBuffer) = m_DBData.m_Spell; lpUpdateLen[nCount] = sizeof(SPELL); break; case DBUpdateData::ITEM_EQUIP_UPDATE: dwSize = *nBufferSize_InOut; m_Equipments.SerializeOut(pBuffer, dwSize); lpUpdateLen[nCount] = static_cast(dwSize); break; case DBUpdateData::ITEM_INVEN_UPDATE: dwSize = *nBufferSize_InOut; m_Inventory.SerializeOut(pBuffer, dwSize); lpUpdateLen[nCount] = static_cast(dwSize); break; case DBUpdateData::ITEM_EXTRA_UPDATE: dwSize = *nBufferSize_InOut; m_ExtraSpace.SerializeOut(pBuffer, dwSize); lpUpdateLen[nCount] = static_cast(dwSize); break; case DBUpdateData::ITEM_EXCHANGE_UPDATE: dwSize = *nBufferSize_InOut; m_Exchange.SerializeOut(pBuffer, dwSize); lpUpdateLen[nCount] = static_cast(dwSize); break; case DBUpdateData::ITEM_TEMPINVEN_UPDATE: dwSize = *nBufferSize_InOut; m_TempInven.SerializeOut(pBuffer, dwSize); lpUpdateLen[nCount] = static_cast(dwSize); break; } pBuffer += lpUpdateLen[nCount]; usTotalSize += lpUpdateLen[nCount]; *nBufferSize_InOut -= dwSize; } *nBufferSize_InOut = usTotalSize; return true; } bool CCharacter::SetCharacterInfo(char* pBuffer, unsigned short usUpdateLen[DBUpdateData::MAX_UPDATE_DB]) { for (int nCount = 0; nCount < DBUpdateData::MAX_UPDATE_DB; ++nCount) { unsigned long dwUpdateLen = usUpdateLen[nCount]; switch (nCount) { case DBUpdateData::STATUS_UPDATE: m_DBData.m_Info = *reinterpret_cast(pBuffer); break; case DBUpdateData::POSITION_UPDATE: m_DBData.m_Pos = *reinterpret_cast(pBuffer); break; case DBUpdateData::SKILL_UPDATE: m_DBData.m_Skill = *reinterpret_cast(pBuffer); break; case DBUpdateData::QUICKSLOT_UPDATE: m_DBData.m_Quick = *reinterpret_cast(pBuffer); break; case DBUpdateData::SPELL_UPDATE: m_DBData.m_Spell = *reinterpret_cast(pBuffer); break; case DBUpdateData::ITEM_EQUIP_UPDATE: m_Equipments.SerializeIn(pBuffer, dwUpdateLen); break; case DBUpdateData::ITEM_INVEN_UPDATE: m_Inventory.SerializeIn(pBuffer, dwUpdateLen); break; case DBUpdateData::ITEM_EXTRA_UPDATE: m_ExtraSpace.SerializeIn(pBuffer, dwUpdateLen); break; case DBUpdateData::ITEM_EXCHANGE_UPDATE: m_Exchange.SerializeIn(pBuffer, dwUpdateLen); break; case DBUpdateData::ITEM_TEMPINVEN_UPDATE: m_TempInven.SerializeIn(pBuffer, dwUpdateLen); break; } pBuffer += dwUpdateLen; } m_CreatureStatus.Init(m_DBData.m_Info); m_CurrentPos.m_fPointX = m_DBData.m_Pos.LastPoint.fPointX; m_CurrentPos.m_fPointY = m_DBData.m_Pos.LastPoint.fPointY; m_CurrentPos.m_fPointZ = m_DBData.m_Pos.LastPoint.fPointZ; return CalculateStatusData(false); } bool CCharacter::MoveZoneProcess(unsigned long dwServerID) { // ÆÄƼ¿¡ Á¸À̵¿ÇßÀ½À» º¸³¿ if (0 != m_pParty) { CCharacterParty* lpParty = static_cast(m_pParty); lpParty->SendPartyMemberDataToDBAgent(m_dwCID, 0, 0, dwServerID, 0, GetCharacterName(), PktDD::SCmdMoveZonePartyMem); } // Ä£±¸ ¸®½ºÆ®¿¡ Á¸À̵¿ ¸Þ¼¼Áö¸¦ º¸³½´Ù // FriendInfoUpdate(GetUID(), GetCID(), GetGID(), GetClass(), GetLevel(), dwServerID); m_bLogout = true; SetOperationFlag(CHAR_ZONE_MOVED); return Logout(DBUpdateData::ZONEMOVE); } void CCharacter::FriendInfoUpdate(unsigned long dwUID, unsigned long dwCID, unsigned long dwGID, unsigned short wClass, char cLevel, unsigned long dwServerID) { // Ä£±¸ ¸®½ºÆ®¿¡ ¾÷µ¥ÀÌÆ® ¸Þ¼¼Áö¸¦ º¸³½´Ù // GET_SINGLE_DISPATCH(lpChatDispatch, CChatDispatch, CChatDispatch::GetDispatchTable()); if(lpChatDispatch) { char* lpBuffer = lpChatDispatch->GetSendStream().GetBuffer(sizeof(PktFriendDB)); if(lpBuffer) { PktFriendDB* lpPktFriendDB = reinterpret_cast(lpBuffer); lpPktFriendDB->m_dwOwnerUID = dwUID; lpPktFriendDB->m_dwOwnerCID = dwCID; lpPktFriendDB->m_dwReferenceUID = 0; lpPktFriendDB->m_dwReferenceCID = 0; lpPktFriendDB->m_dwData = 0; lpPktFriendDB->m_cCmd = PktFriendDB::FRIEND_INFO_UPDATE; lpPktFriendDB->m_dwGID = dwGID; lpPktFriendDB->m_wClass = wClass; lpPktFriendDB->m_cLevel = cLevel; lpPktFriendDB->m_dwServerID = dwServerID; lpChatDispatch->GetSendStream().WrapCrypt(sizeof(PktFriendDB), CmdFriendDB, 0, 0); } } } bool CCharacter::ItemDump(char* pBuffer, int* nBufferSize_InOut) const { using namespace GAMELOG; sItemDump* lpItemDump = reinterpret_cast(pBuffer); char* lpItems = reinterpret_cast(&lpItemDump[1]); std::fill_n(lpItemDump->m_usDataSize, int(sItemDump::MAX_DUMP), 0); unsigned long dwSize = 0; unsigned short usTotalSize = sizeof(sItemDump); for (int nCount = 0; nCount < sItemDump::MAX_DUMP; ++nCount) { switch (nCount) { case sItemDump::EQUIP_DUMP: dwSize = *nBufferSize_InOut; m_Equipments.SerializeOut(lpItems, dwSize); lpItemDump->m_usDataSize[nCount] = static_cast(dwSize); break; case sItemDump::INVEN_DUMP: dwSize = *nBufferSize_InOut; m_Inventory.SerializeOut(lpItems, dwSize); lpItemDump->m_usDataSize[nCount] = static_cast(dwSize); break; case sItemDump::EXTRA_DUMP: dwSize = *nBufferSize_InOut; m_ExtraSpace.SerializeOut(lpItems, dwSize); lpItemDump->m_usDataSize[nCount] = static_cast(dwSize); break; case sItemDump::EXCHANGE_DUMP: dwSize = *nBufferSize_InOut; m_Exchange.SerializeOut(lpItems, dwSize); lpItemDump->m_usDataSize[nCount] = static_cast(dwSize); break; } lpItems += lpItemDump->m_usDataSize[nCount]; usTotalSize += lpItemDump->m_usDataSize[nCount]; *nBufferSize_InOut -= dwSize; } *nBufferSize_InOut = usTotalSize; return true; }