#include "stdafx.h" #include "ClientCellMgr.h" #include "BroadcastCharacterData.h" #include #include #include #include #include "GMMemory.h" namespace Broadcast2nd { CClientCellMgr::CClientCellMgr() : m_dwCID(0) { } CClientCellMgr::~CClientCellMgr() { } void CClientCellMgr::Initialize(unsigned long dwCID) { Clear(); m_dwCID = dwCID; } void CClientCellMgr::Clear() { m_CharacterDataMap.clear(); } void CClientCellMgr::CellLogin(const char* szData, unsigned short usDataSize) { int nDataSize = usDataSize; const char* szDataPos = szData; unsigned long dwCID = 0; CCharacterData characterData; CMonsterData monsterData; CharacterDataMap::iterator char_pos; MonsterDataMap::iterator mon_pos; for(; sizeof(unsigned long) < nDataSize; ) { memcpy(&dwCID, szDataPos, sizeof(unsigned long)); szDataPos += sizeof(unsigned long); nDataSize -= sizeof(unsigned long); int nBufferSize = nDataSize; switch(Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: characterData.ClearData(); if(characterData.UpdateData(dwCID, 0, szDataPos, nBufferSize)) { char_pos = m_CharacterDataMap.lower_bound(dwCID); if(char_pos != m_CharacterDataMap.end() && char_pos->first == dwCID) { // ÀÌ¹Ì Ä³¸¯ÅͰ¡ ÀÖÀ» °æ¿ì, µ¥ÀÌÅ͸¦ °»½ÅÇÑ´Ù. char_pos->second = characterData; } else { // ij¸¯ÅͰ¡ ¾øÀ» °æ¿ì, ½Å±Ô·Î »ðÀÔÇÑ´Ù. m_CharacterDataMap.insert(char_pos, std::make_pair(dwCID, characterData)); } } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: monsterData.ClearData(); if (monsterData.UpdateData(dwCID, 0, szDataPos, nBufferSize)) { mon_pos = m_MonsterDataMap.lower_bound(dwCID); if (mon_pos != m_MonsterDataMap.end() && mon_pos->first == dwCID) { mon_pos->second = monsterData; } else { m_MonsterDataMap.insert(mon_pos, std::make_pair(dwCID, monsterData)); } } break; } // ÇѸ¶¸®¶óµµ ¾÷µ¥ÀÌÆ® ½ÇÆÐÇϸé, ¹öÆÛ°¡ ¿Õâ ±úÁ³À»¼öµµ ÀÖÀ¸¹Ç·Î // ±×³É PassÇÑ´Ù. szDataPos += nBufferSize; nDataSize -= nBufferSize; } } void CClientCellMgr::CellUpdateData(const char* szData, unsigned short usDataSize, unsigned long dwCurrentPulse) { int nDataSize = usDataSize; const char* szDataPos = szData; unsigned long dwCID = 0; unsigned long dwUpdateData = 0; CharacterDataMap::iterator char_pos; MonsterDataMap::iterator mon_pos; for(; sizeof(unsigned long) < nDataSize; ) { // CID¸¦ º¹»çÇϰí, CID±æÀ̸¦ ÀÏ´Ü Á¦°ÅÇÑ´Ù. memcpy(&dwCID, szDataPos, sizeof(unsigned long)); szDataPos += sizeof(unsigned long); nDataSize -= sizeof(unsigned long); int nBufferSize = nDataSize; switch(Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: char_pos = m_CharacterDataMap.find(dwCID); if(char_pos != m_CharacterDataMap.end()) { CCharacterData& charData = char_pos->second; if(!charData.UpdateData(dwCID, dwCurrentPulse, szDataPos, nBufferSize)) { break; } } else { // ij¸¯ÅͰ¡ ¾ø´Ù!. ¾ø´Â ij¸¯ÅÍÀÇ update°¡ ¿À¸é µ¥ÀÌÅ͸¦ ¹ö¸°´Ù. memcpy(&dwUpdateData, szDataPos, sizeof(unsigned long)); szDataPos += sizeof(unsigned long); nDataSize -= sizeof(unsigned long); nBufferSize = CCharacterData::EstimateBufferSize(dwUpdateData); } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: mon_pos = m_MonsterDataMap.find(dwCID); if(mon_pos != m_MonsterDataMap.end()) { CMonsterData& monData = mon_pos->second; if(!monData.UpdateData(dwCID, dwCurrentPulse, szDataPos, nBufferSize)) { break; } } else { // ¸ó½ºÅͰ¡ ¾ø´Ù!. ¾ø´Â ¸ó½ºÅÍÀÇ update°¡ ¿À¸é µ¥ÀÌÅ͸¦ ¹ö¸°´Ù. unsigned char cUpdateData = *reinterpret_cast(szDataPos); szDataPos += sizeof(unsigned char); nDataSize -= sizeof(unsigned char); nBufferSize = CMonsterData::EstimateBufferSize(cUpdateData); } break; } szDataPos += nBufferSize; nDataSize -= nBufferSize; } } void CClientCellMgr::CellLogout(unsigned long dwCID) { switch(Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: m_CharacterDataMap.erase(dwCID); break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: m_MonsterDataMap.erase(dwCID); break; } } void CClientCellMgr::RemoveCharDataByPulse(unsigned long dwCurrentPulse, unsigned long dwExceptCID) { CharacterDataMap::iterator char_pos = m_CharacterDataMap.begin(); CharacterDataMap::iterator char_end = m_CharacterDataMap.end(); for (; char_pos != char_end ; ) { CCharacterData& charData = char_pos->second; if (charData.GetLastUpdatedPulse() == dwCurrentPulse || charData.GetCID() == dwExceptCID) { ++char_pos; } else { char_pos = m_CharacterDataMap.erase(char_pos); } } MonsterDataMap::iterator mon_pos = m_MonsterDataMap.begin(); MonsterDataMap::iterator mon_end = m_MonsterDataMap.end(); for (; mon_pos != mon_end; ) { CMonsterData& monData = mon_pos->second; if (monData.GetLastUpdatedPulse() == dwCurrentPulse || monData.GetCID() == dwExceptCID) { ++mon_pos; } else { mon_pos = m_MonsterDataMap.erase(mon_pos); } } } CCharacterData* CClientCellMgr::GetCharacterData(unsigned long dwCID) { CharacterDataMap::iterator pos = m_CharacterDataMap.find(dwCID); return (pos != m_CharacterDataMap.end()) ? &pos->second : 0; } void CClientCellMgr::UpdatePos(unsigned long dwCID, const CNetworkPos& netPos) { switch(Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: { CharacterDataMap::iterator pos = m_CharacterDataMap.find(dwCID); if(pos != m_CharacterDataMap.end()) { pos->second.SetNetworkPos(netPos); } } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: { MonsterDataMap::iterator pos = m_MonsterDataMap.find(dwCID); if(pos != m_MonsterDataMap.end()) { pos->second.SetNetworkPos(netPos); } } break; } } void CClientCellMgr::UpdateStallName(unsigned long dwCID, const char* szStallName) { if(0 == szStallName) { szStallName = ""; } CharacterDataMap::iterator pos = m_CharacterDataMap.find(dwCID); if(pos != m_CharacterDataMap.end()) { pos->second.SetStallName(szStallName, strlen(szStallName) + 1); } } }