#include "stdafx.h" #include "Cell.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include __declspec(thread) static char g_BroadcastBuffer[PktMaxLen]; void CCell::ReleaseAllBuffer(CBuffer*& lpBuffer) { // ÀÏÀü¿¡ Àü¼ÛÇß´ø buffer¸¦ ÀüºÎ ReleaseÇÑ´Ù. CBuffer* lpPos = lpBuffer; CBuffer* lpDel = lpBuffer; while (0 != lpPos) { lpDel = lpPos; lpPos = lpPos->next(); SAFE_RELEASE_BUFFER(lpDel); } lpBuffer = 0; } void CCell::PrepareBroadCast() { // ÀÏÀü¿¡ Àü¼ÛÇß´ø buffer¸¦ ÀüºÎ ReleaseÇÑ´Ù. ReleaseAllBuffer(m_lpBroadcast2ndBuffer); if (m_lstCharacter.empty() && m_lstMonster.empty()) { // ÀÌ ¼¿¿¡´Â ¸ó½ºÅ͵µ, ij¸¯Å͵µ ¾ø´Ù. ó¸®ÇÏÁö ¾Ê´Â´Ù. return; } // ij¸¯ÅÍ µ¥ÀÌÅ͸¦ »ý¼ºÇÑ´Ù. const int MAX_BROADCAST_BUFFER_SIZE = 14 * 1024; CBufferFactory& bufferFactory = CCellManager::GetInstance().GetBufferFactory(); // ij¸¯ÅÍ µ¥ÀÌÅ͸¦ »ý¼ºÇÑ´Ù. CharacterList::iterator char_pos = m_lstCharacter.begin(); CharacterList::iterator char_end = m_lstCharacter.end(); CBuffer* lpBroadcastBuffer = CREATE_BUFFER(bufferFactory, MAX_BROADCAST_BUFFER_SIZE); for (; char_pos != char_end && 0 != lpBroadcastBuffer; ) { CCharacter* lpCharacter = *char_pos; //if (0 != lpCharacter && !lpCharacter->IsRideArms() && // ¿ì¼± º´±â¿¡ Ÿ°í À־ º¸³½´Ù. if (0 != lpCharacter && lpCharacter->IsOperationFlagSet(CCharacter::CHAR_INFO_LOADED)) { Broadcast2nd::CSerializeCharacterData& charData = lpCharacter->GetSerializeData(); if (lpBroadcastBuffer->push( charData.GetDeltaBroadcastData(), charData.GetDeltaBroadcastDataLen())) { // µ¥ÀÌÅÍ ÀúÀå ¼º°ø ++char_pos; } else { // ¹öÆÛ°¡ ²Ë Âù °æ¿ì, ¹öÆÛ¸¦ ºñ¿ö ÁÖ°í, °è¼Ó ÁøÇàÇÑ´Ù. lpBroadcastBuffer->next(m_lpBroadcast2ndBuffer); m_lpBroadcast2ndBuffer = lpBroadcastBuffer; lpBroadcastBuffer = CREATE_BUFFER(bufferFactory, MAX_BROADCAST_BUFFER_SIZE); } } else { // ij¸¯ÅͰ¡ º¹»ç ´ë»óÀÌ ¾Æ´Ñ °æ¿ìÀÌ´Ù. ++char_pos; } } // ¸ó½ºÅÍ µ¥ÀÌÅ͸¦ »ý¼ºÇÑ´Ù. MonsterList::iterator mon_pos = m_lstMonster.begin(); MonsterList::iterator mon_end = m_lstMonster.end(); for (; mon_pos != mon_end && 0 != lpBroadcastBuffer; ) { CMonster* lpMonster = *mon_pos; if (0 != lpMonster) { Broadcast2nd::CSerializeMonsterData& monsterData = lpMonster->GetSerializeData(); if (lpBroadcastBuffer->push( monsterData.GetDeltaBroadcastData(), monsterData.GetDeltaBroadcastDataLen())) { // µ¥ÀÌÅÍ ÀúÀå ¼º°ø ++mon_pos; } else { // ¹öÆÛ°¡ ²Ë Âù °æ¿ì, ¹öÆÛ¸¦ ºñ¿ö ÁÖ°í, °è¼Ó ÁøÇàÇÑ´Ù. lpBroadcastBuffer->next(m_lpBroadcast2ndBuffer); m_lpBroadcast2ndBuffer = lpBroadcastBuffer; lpBroadcastBuffer = CREATE_BUFFER(bufferFactory, MAX_BROADCAST_BUFFER_SIZE); } } else { ++mon_pos; } } if (0 != lpBroadcastBuffer) { if(0 < lpBroadcastBuffer->length()) { lpBroadcastBuffer->next(m_lpBroadcast2ndBuffer); m_lpBroadcast2ndBuffer = lpBroadcastBuffer; lpBroadcastBuffer = 0; } else { SAFE_RELEASE_BUFFER(lpBroadcastBuffer); } } } void SendBroadcastPacket(CCell& sendCell, char* szBroadcastBuffer, unsigned short usPacketLength, unsigned char cBroadcastType, unsigned char cDataType, unsigned long dwCurrentPulse) { // ÆÐŶ Çì´õ ÀÛ¼º Broadcast2nd::PktBroadcast* lpBroadcast = reinterpret_cast(szBroadcastBuffer); lpBroadcast->m_dwCurrentPulse = dwCurrentPulse; lpBroadcast->m_cBroadcastType = cBroadcastType; lpBroadcast->m_cDataType = cDataType; sendCell.SendAllCharacter(lpBroadcast, usPacketLength, CmdCellBroadCast2nd); } void CCell::BroadCast(unsigned long dwCurrentPulse) { if (!m_lstCharacter.empty()) { // º» ¼¿¿¡ º¸³¾ ij¸¯ÅͰ¡ ÀÖ´Â °æ¿ì¿¡¸¸ Àü¼Û // ÇöÀç ¼¿ÀÇ Ä³¸¯ÅÍ¿¡°Ô, ÁÖº¯ ¼¿ÀÇ Ä³¸¯ÅÍ Á¤º¸¸¦ ÀüºÎ º¸³½´Ù. // ¹öÆÛ µ¥ÀÌÅ͸¦ °¡´ÉÇÑ ¸¹ÀÌ ¸ð¾Æ¼­ ¾ÐÃàÇÑ ´ÙÀ½ Çѹø¿¡ ¸¹ÀÌ º¸³½´Ù. CCell** lppCellPos = m_lpConnectCell; CCell** lppCellEnd = m_lpConnectCell + CONNECT_NUM; char* szBufferPos = g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast); char* szBufferEnd = g_BroadcastBuffer + sizeof(g_BroadcastBuffer); CCell* lpCell = 0; CBuffer* lpBuffer = 0; unsigned long dwCompressed = PktMaxLen; unsigned short usPacketLength = 0; for (; lppCellPos != lppCellEnd; ++lppCellPos) { lpCell = *lppCellPos; if (0 != lpCell) { lpBuffer = lpCell->m_lpBroadcast2ndBuffer; while(0 != lpBuffer) { size_t nBufferLen = lpBuffer->length(); if (szBufferPos + nBufferLen < szBufferEnd) { // ¹öÆÛ°¡ ¾ÆÁ÷ ºñ¾î ÀÖ´Ù. memcpy(szBufferPos, lpBuffer->rd_ptr(), nBufferLen); szBufferPos += nBufferLen; lpBuffer = lpBuffer->next(); } else { SendBroadcastPacket(*this, g_BroadcastBuffer, static_cast(szBufferPos - g_BroadcastBuffer), Broadcast2nd::PktBroadcast::BROADCAST, Broadcast2nd::PktBroadcast::CHAR_DATA, dwCurrentPulse); // ¹öÆÛ°¡ °¡µæ á´Ù. ÀÏ´Ü Àü¼ÛÇϰí, ¹öÆÛ À§Ä¡¸¦ óÀ½À¸·Î µ¹¸°´Ù. szBufferPos = g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast); } } } } // ÃÖÁ¾À¸·Î º¸³½´Ù. (º¸³¾ µ¥ÀÌÅÍ ±æÀ̰¡ ¾ø´õ¶óµµ º¸³»¾ß ÇÑ´Ù) SendBroadcastPacket(*this, g_BroadcastBuffer, static_cast(szBufferPos - g_BroadcastBuffer), Broadcast2nd::PktBroadcast::BROADCAST_END, Broadcast2nd::PktBroadcast::CHAR_DATA, dwCurrentPulse); } } void SendCharInfoToOthers(CCharacter& character, CCell** lppSendCell, const int nMaxSendCell) { // ¿ì¼± º´±â¿¡ Ÿ°í À־ º¸³½´Ù. //if (!character.IsRideArms()) { const unsigned short MAX_PKT_DATA = sizeof(Broadcast2nd::PktBroadcast) + Broadcast2nd::CSerializeCharacterData::MAX_CHARACTER_DATA * 2; char szPacketBuffer[MAX_PKT_DATA]; Broadcast2nd::PktBroadcast* lpBroadcast = reinterpret_cast(szPacketBuffer); Broadcast2nd::CSerializeCharacterData& characterData = character.GetSerializeData(); unsigned short usCharacterDataLen = characterData.GetBroadcastDataLen(); // ÁÂÇ¥°¡ ¹Ù²î¾ú±â ¶§¹®¿¡, µ¥ÀÌÅ͸¦ °»½ÅÇØ¼­ º¸³½´Ù (Delta´Â °»½ÅÇÏÁö ¾Ê´Â´Ù) characterData.PrepareBroadcastData(character); lpBroadcast->m_dwCurrentPulse = 0; lpBroadcast->m_cBroadcastType = Broadcast2nd::PktBroadcast::LOGIN; lpBroadcast->m_cDataType = Broadcast2nd::PktBroadcast::CHAR_DATA; memcpy(lpBroadcast + 1, characterData.GetBroadcastData(), usCharacterDataLen); CCell** lppSendPos = lppSendCell; CCell** lppSendEnd = lppSendCell + nMaxSendCell; for (; lppSendPos != lppSendEnd; ++lppSendPos) { CCell* lpSendPos = *lppSendPos; if (0 != lpSendPos) { lpSendPos->SendAllCharacter(lpBroadcast, sizeof(Broadcast2nd::PktBroadcast) + usCharacterDataLen, CmdCellBroadCast2nd); } } } } //Interface///////////////////////////////////////////////////////////////////////////////////// // // ij¸¯ÅÍ ¼¿ ·Î±×ÀÎ // // Parameter : // 1st : Å©¸®ÃÄ ÁÖ¼Ò // 2st : ¸¶Áö¸·À¸·Î ·Î±×¾Æ¿ôÇÑ ¼¿ (·Î±×ÀÎ, ¸®Á¨, ¼ø°£À̵¿µîÀÇ °æ¿ì´Â 0) // // Do : // ¼¿¾ÈÀ¸·Î ij¸¯ÅͰ¡ ·Î±×ÀÎÇßÀ½À» ÁÖº¯ ¼¿¿¡ ¾Ë·Á ÁØ´Ù. // // Return : // /////////////////////////////////////////////////////////////////////////////////////////////// void CCell::SendCellLogin(CAggresiveCreature* lpAggresiveCreature, CCell* lpLastLogoutCell) { if (0 != lpAggresiveCreature) { unsigned long dwCID = lpAggresiveCreature->GetCID(); // ÇöÀç ¼¿°ú, ¸¶Áö¸·À¸·Î ·Î±×¾Æ¿ôÇÑ ¼¿°úÀÇ Â÷ÁýÇÕÀ» ±¸ÇÑ´Ù. // lpSendCell¿¡´Â ³»°¡ ³» ij¸¯ÅÍ µ¥ÀÌÅ͸¦ º¸³»°í, // ³ª¿¡°Ô ij¸¯ÅÍ µ¥ÀÌÅ͸¦ º¸³»¾ß ÇÒ ³à¼®µéÀÌ µé¾î ÀÖ´Ù. CCell* lpSendCell[CONNECT_NUM]; CCell** lppSendPos = 0; CCell** lppSendEnd = 0; CCell* lpSendPos = 0; if (0 != lpLastLogoutCell) { std::fill_n(lpSendCell, int(CONNECT_NUM), reinterpret_cast(0)); std::set_difference( m_lpSortedConnectedCell, m_lpSortedConnectedCell + CONNECT_NUM, lpLastLogoutCell->m_lpSortedConnectedCell, lpLastLogoutCell->m_lpSortedConnectedCell + CONNECT_NUM, lpSendCell); } else { std::copy(m_lpSortedConnectedCell, m_lpSortedConnectedCell + CONNECT_NUM, lpSendCell); } switch(Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: { CCharacter* lpCharacter = static_cast(lpAggresiveCreature); // ³» Á¤º¸¸¦ ´Ù¸¥ ij¸¯Å͵鿡°Ô º¸³»´Â ·çƾÀÌ´Ù. SendCharInfoToOthers(*lpCharacter, lpSendCell, CONNECT_NUM); CGameClientDispatch* lpDispatch = lpCharacter->GetDispatcher(); if (0 != lpDispatch) { // ÁÖº¯ÀÇ Ä³¸¯ÅÍ/¸ó½ºÅÍ Á¤º¸¸¦ ³ª¿¡°Ô º¸³½´Ù. char* szDataPos = g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast); char* szDataEnd = g_BroadcastBuffer + PktMaxLen - 1024; // Çì´õ ±â·Ï Broadcast2nd::PktBroadcast* lpBroadcast = reinterpret_cast(g_BroadcastBuffer); lpBroadcast->m_dwCurrentPulse = 0; lpBroadcast->m_cBroadcastType = Broadcast2nd::PktBroadcast::LOGIN; lpBroadcast->m_cDataType = Broadcast2nd::PktBroadcast::CHAR_DATA; // ·çÇÁ¸¦ µ·´Ù. lppSendPos = lpSendCell; lppSendEnd = lpSendCell + CONNECT_NUM; for (; lppSendPos != lppSendEnd; ++lppSendPos) { lpSendPos = *lppSendPos; if (0 != lpSendPos) { // µ¥ÀÌÅ͸¦ ¸ð¾Æ¼­ º¸³½´Ù. CCell::CharacterList::iterator char_pos = lpSendPos->m_lstCharacter.begin(); CCell::CharacterList::iterator char_end = lpSendPos->m_lstCharacter.end(); for (; char_pos != char_end; ) { CCharacter* lpOtherCharacter = *char_pos; Broadcast2nd::CSerializeCharacterData& characterData = lpOtherCharacter->GetSerializeData(); unsigned short usCharacterDataLen = characterData.GetBroadcastDataLen(); // º´±â¿¡ Ÿ°í À־ º¸³»Áö ¾ÊÀ¸¸é ¹®Á¦°¡ »ý±è(By Minbobo) /*if (lpOtherCharacter->IsRideArms()) { // º´±â¿¡ Ÿ°í ÀÖÀ¸¸é º¸³»Áö ¾ÊÀ½. ++char_pos; }*/ if (szDataPos + usCharacterDataLen < szDataEnd) { // ¹öÆÛ°¡ ¾ÆÁ÷ ³²¾Æ ÀÖÀ¸¸é, ¹öÆÛ¸µ. ¾Æ´Ï¸é Àü¼Û. memcpy(szDataPos, characterData.GetBroadcastData(), usCharacterDataLen); szDataPos += usCharacterDataLen; ++char_pos; } else { // ÆÐŶÀ» º¸³½´Ù. lpDispatch->GetSendStream().WrapCompress(g_BroadcastBuffer, static_cast(szDataPos - g_BroadcastBuffer), CmdCellBroadCast2nd, 0, 0); // ¹öÆÛ À§Ä¡ ÃʱâÈ­ szDataPos = g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast); } } // µ¥ÀÌÅ͸¦ ¸ð¾Æ¼­ º¸³½´Ù. CCell::MonsterList::iterator mon_pos = lpSendPos->m_lstMonster.begin(); CCell::MonsterList::iterator mon_end = lpSendPos->m_lstMonster.end(); for (; mon_pos != mon_end; ) { CMonster* lpMonster = *mon_pos; Broadcast2nd::CSerializeMonsterData& monsterData = lpMonster->GetSerializeData(); unsigned short usMonsterData = monsterData.GetBroadcastDataLen(); if (szDataPos + usMonsterData < szDataEnd) { // ¹öÆÛ°¡ ¾ÆÁ÷ ³²¾Æ ÀÖÀ¸¸é, ¹öÆÛ¸µ. ¾Æ´Ï¸é Àü¼Û. memcpy(szDataPos, monsterData.GetBroadcastData(), usMonsterData); szDataPos += usMonsterData; ++mon_pos; } else { // ÆÐŶÀ» º¸³½´Ù. lpDispatch->GetSendStream().WrapCompress(g_BroadcastBuffer, static_cast(szDataPos - g_BroadcastBuffer), CmdCellBroadCast2nd, 0, 0); // ¹öÆÛ À§Ä¡ ÃʱâÈ­ szDataPos = g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast); } } } } // µ¥ÀÌÅͰ¡ ÀÖÀ¸¸é if (g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast) < szDataPos) { // ÆÐŶÀ» º¸³½´Ù. lpDispatch->GetSendStream().WrapCompress(g_BroadcastBuffer, static_cast(szDataPos - g_BroadcastBuffer), CmdCellBroadCast2nd, 0, 0); } // ÁÖº¯ ¼¿ÀÇ ¾ÆÀÌÅÛ µ¥ÀÌÅ͸¦ ¸ð¾Æ¼­ ³» ij¸¯ÅÍ¿¡ º¸³½´Ù. // À̶§, ¹öÆÛ ±æÀ̸¦ ÃʰúÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. ¼¿´ç ÃÖ´ëÄ¡´Â 14kÁ¤µµ·Î ÇÑ´Ù. szDataPos = g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast); lpBroadcast->m_dwCurrentPulse = 0; lpBroadcast->m_cBroadcastType = Broadcast2nd::PktBroadcast::LOGIN; lpBroadcast->m_cDataType = Broadcast2nd::PktBroadcast::ITEM_DATA; // ·çÇÁ¸¦ µ·´Ù. lppSendPos = lpSendCell; lppSendEnd = lpSendCell + CONNECT_NUM; for (; lppSendPos != lppSendEnd; ++lppSendPos) { lpSendPos = *lppSendPos; if (0 != lpSendPos) { // µ¥ÀÌÅ͸¦ ¸ð¾Æ¼­ º¸³½´Ù. CCell::ItemList::iterator item_pos = lpSendPos->m_lstItem.begin(); CCell::ItemList::iterator item_end = lpSendPos->m_lstItem.end(); for (; item_pos != item_end; ) { ItemInfo& itemInfo = (*item_pos); // ¹öÆÛ°¡ ¾ÆÁ÷ ³²¾Æ ÀÖÀ¸¸é ¹öÆÛ¸µ, ¾Æ´Ï¸é Àü¼Û if (szDataPos + sizeof(FieldObject) < szDataEnd) { itemInfo.MakeFieldObject(*reinterpret_cast(szDataPos)); szDataPos += sizeof(FieldObject); ++item_pos; } else { // ÆÐŶÀ» º¸³½´Ù. lpDispatch->GetSendStream().WrapCompress(g_BroadcastBuffer, static_cast(szDataPos - g_BroadcastBuffer), CmdCellBroadCast2nd, 0, 0); // ¹öÆÛ À§Ä¡ ÃʱâÈ­ szDataPos = g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast); } } } } // µ¥ÀÌÅͰ¡ ÀÖÀ¸¸é if (szDataPos != g_BroadcastBuffer + sizeof(Broadcast2nd::PktBroadcast)) { // ÆÐŶÀ» º¸³½´Ù. lpDispatch->GetSendStream().WrapCompress(g_BroadcastBuffer, static_cast(szDataPos - g_BroadcastBuffer), CmdCellBroadCast2nd, 0, 0); } } } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: { CMonster* lpMonster = static_cast(lpAggresiveCreature); // ÀÚ½ÅÀÇ Á¤º¸¸¦ ÁÖº¯ ij¸¯Å͵鿡°Ô »Ñ¸°´Ù. const unsigned short MAX_PKT_DATA = sizeof(Broadcast2nd::PktBroadcast) + Broadcast2nd::CSerializeMonsterData::MAX_MONSTER_DATA * 2; char szPacketBuffer[MAX_PKT_DATA]; Broadcast2nd::PktBroadcast* lpBroadcast = reinterpret_cast(szPacketBuffer); Broadcast2nd::CSerializeMonsterData& monsterData = lpMonster->GetSerializeData(); unsigned short usMonsterDataLen = monsterData.GetBroadcastDataLen(); // ÁÂÇ¥°¡ ¹Ù²î¾ú±â ¶§¹®¿¡, µ¥ÀÌÅ͸¦ °»½ÅÇØ¼­ º¸³½´Ù (Delta´Â °»½ÅÇÏÁö ¾Ê´Â´Ù) monsterData.PrepareBroadcastData(*lpMonster); lpBroadcast->m_dwCurrentPulse = 0; lpBroadcast->m_cBroadcastType = Broadcast2nd::PktBroadcast::LOGIN; lpBroadcast->m_cDataType = Broadcast2nd::PktBroadcast::CHAR_DATA; memcpy(lpBroadcast + 1, monsterData.GetBroadcastData(), usMonsterDataLen); lppSendPos = lpSendCell; lppSendEnd = lpSendCell + CONNECT_NUM; for (; lppSendPos != lppSendEnd; ++lppSendPos) { CCell* lpSendPos = *lppSendPos; if (0 != lpSendPos) { lpSendPos->SendAllCharacter(lpBroadcast, sizeof(Broadcast2nd::PktBroadcast) + usMonsterDataLen, CmdCellBroadCast2nd); } } } break; } } } //Interface///////////////////////////////////////////////////////////////////////////////////// // // ij¸¯ÅÍ ¼¿ ·Î±× ¾Æ¿ô // // Parameter : // 1st : Å©¸®ÃÄ ÁÖ¼Ò // 2st : ·Î±×¾Æ¿ôÇÑ ÈÄ ·Î±×ÀÎÇÏ·Á´Â ¼¿ (·Î±×¾Æ¿ô µîÀ¸·Î ¾øÀ» °æ¿ì¿¡´Â 0À» ³Ö´Â´Ù.) // // Do : // ÁÖº¯ ¼¿¿¡ ³»°¡ ·Î±×¾Æ¿ôÇÑ´Ù°í ¾Ë¸°´Ù. // º¸ÀÌÁö ¾Ê¾Æ¾ß µÉ ij¸¯Å͵éÀ» ÀüºÎ Áö¿ì°Ô ÇÑ´Ù. // // Return : // /////////////////////////////////////////////////////////////////////////////////////////////// void CCell::SendCellLogout(CAggresiveCreature* lpAggresiveCreature, CCell* lpPrepareLoginCell) { }