#include "StdAfx.h" #include ".\channelmanager.h" #include "Channel.h" #include "UserManager.h" #include "User.h" #include // µ¿Á¢ º¸°í À§ÇØ #include #include "ServerSession.h" #include "ServerSessionManager.h" // ¸¶½ºÅÍ ¼­¹ö °ü¸® À§ÇØ #include "WorldServerInfoParser.h" // ¼­¹ö ¿¬°á #include // ¸¶À»/ÇÊµå ¼½ÅÍ ¼¼ÆÃ #include #include #ifdef _JP_0_20101123_PMS #include "WorldServer.h" #endif ChannelManager::ChannelManager(void) { m_pChannelPool = NULL; } ChannelManager::~ChannelManager(void) { assert( m_pChannelPool == NULL ); } VOID ChannelManager::Init() { m_pChannelPool = new util::CMemoryPoolFactory; m_pChannelPool->Initialize( 5, 1 ); m_StatisticsTimer.SetTimer( WorldServerInfoParser::Instance()->GetStatisticsInterval() ); #ifndef __WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ if( !LoadFieldInfo() ) MessageOut( eCRITICAL_LOG, "FieldInfo Load Failed"); #endif //__WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ // MessageOut( eFULL_LOG, "Set Timer %u", m_StatisticsTimer.GetIntervalTime() ); } VOID ChannelManager::Release() { CHANNEL_MAP_ITER it; Channel *pChannel; CHANNEL_MAP& mapClone = m_mapChannels; for( it = mapClone.begin(); it != mapClone.end(); ++it ) { pChannel = it->second; RemoveChannel( pChannel->GetChannelID() ); } mapClone.clear(); FIELDINFO_MAP_ITER iter; for( iter = m_mapFieldInfo.begin(); iter != m_mapFieldInfo.end(); iter++ ) { FieldInfo*& pFieldInfo = (*iter).second; if(pFieldInfo) { pFieldInfo->Destroy(); SAFE_DELETE(pFieldInfo); //delete pFieldInfo; <- ÀÌ°Í ¿Ö ÁÖ¼®Ã³¸® Çß´ÂÁö È®ÀÎÇØ º¸ÀÚ } } m_mapFieldInfo.clear(); m_pChannelPool->Release(); SAFE_DELETE(m_pChannelPool); } VOID ChannelManager::Update() { // ÀÏÁ¤ ½Ã°£¸¶´Ù µ¿Á¢ Á¤º¸ Àü¼Û DWORD dwTotalCount=0, dwVillageCount=0, dwBattleZoneCount=0; // 10Ãʸ¶´Ù üũ...´õ·´°Ô »¡¸® Çϳ×...-0- if( m_StatisticsTimer.IsExpired() ) { CHANNEL_MAP_ITER it; Channel *pChannel; MSG_MW_USERCOUNT_SYN sendMsg; BYTE byChannel; DWORD dwTotalTemp = 0; // Àüü µ¿Á¢ sendMsg.byChannelCount = 0; for( it = m_mapChannels.begin(); it != m_mapChannels.end(); ++it ) { pChannel = it->second; byChannel = sendMsg.byChannelCount; sendMsg.ChannelInfo[byChannel].dwChannelID = pChannel->GetChannelID(); pChannel->RefreshUserNum(); // ÀÏ´Ü ¸Å¹ø À¯Àú ¼ýÀÚ °»½Å - Inc/Dec ¾µ °æ¿ì ¿¹¿Ü »óȲ¿¡ ´ëÇÑ ´ëó°¡ Á¦´ë·Î ¾È µÈ´Ù // Àӽ÷Π·ÎµùÁßÀ̰ųª Çʵå Áö¿ªµé¿¡ Æ÷ÇÔµÇÁö ¾Ê´Â °÷¿¡ ÀÖ´Â ³ðµéÀ» ¹èƲÁ¸ µ¿Á¢¿¡ ÇÕ»êÇÑ´Ù // ÇÕ»ê ¹æ¹ý: ¼öÁ¤µÈ ¹èƲÁ¸ µ¿Á¢ = ¹èƲÁ¸ µ¿Á¢ + (³²´Â µ¿Á¢) // = ¹èƲÁ¸ µ¿Á¢ + (Àüü µ¿Á¢ - ¸¶À» µ¿Á¢ - ¹èƲÁ¸ µ¿Á¢) // = Àüü µ¿Á¢ - ¸¶À» µ¿Á¢ sendMsg.ChannelInfo[byChannel].dwVillageCount = pChannel->GetZoneUserNum( eZONETYPE_CHARSELECT ) + pChannel->GetZoneUserNum( eZONETYPE_VILLAGE ) + pChannel->GetZoneUserNum( eZONETYPE_DOMINATION_FIELD ) + pChannel->GetZoneUserNum( eZONETYPE_FIELD ) + pChannel->GetZoneUserNum( eZONETYPE_SPA_FIELD); if( pChannel->GetNumerOfNormalUsers() < sendMsg.ChannelInfo[byChannel].dwVillageCount ) { MessageCount( eCRITICAL_LOG, "Channel[%u] User Statistics Error! Not Correct Field UserNum!![%u/%u]", pChannel->GetNumerOfNormalUsers(), sendMsg.ChannelInfo[byChannel].dwVillageCount ); sendMsg.ChannelInfo[byChannel].dwBattleZoneCount = 0; } else { sendMsg.ChannelInfo[byChannel].dwBattleZoneCount = pChannel->GetNumerOfNormalUsers() - sendMsg.ChannelInfo[byChannel].dwVillageCount; } sendMsg.ChannelInfo[byChannel].dwVillagePCRoomCount = pChannel->GetZonePCRoomUserNum( eZONETYPE_CHARSELECT ) + pChannel->GetZonePCRoomUserNum( eZONETYPE_VILLAGE ) + pChannel->GetZonePCRoomUserNum( eZONETYPE_DOMINATION_FIELD ) + pChannel->GetZonePCRoomUserNum( eZONETYPE_FIELD ) + pChannel->GetZonePCRoomUserNum( eZONETYPE_SPA_FIELD); if( pChannel->GetNumerOfPCRoomUsers() < sendMsg.ChannelInfo[byChannel].dwVillagePCRoomCount ) { MessageCount( eCRITICAL_LOG, "Channel[%u] User Statistics Error! Not Correct Field UserNum!![%u/%u]", pChannel->GetNumerOfNormalUsers(), sendMsg.ChannelInfo[byChannel].dwVillagePCRoomCount ); sendMsg.ChannelInfo[byChannel].dwBattleZonePCRoomCount = 0; } else { sendMsg.ChannelInfo[byChannel].dwBattleZonePCRoomCount = pChannel->GetNumerOfPCRoomUsers() - sendMsg.ChannelInfo[byChannel].dwVillagePCRoomCount; } MessageCount( eFULL_LOG, "Connected Users[Channel%d]:Total(%u)Field(%u/%u)Battle(%u/%u)", sendMsg.ChannelInfo[byChannel].dwChannelID, pChannel->GetTotalUserNum(), sendMsg.ChannelInfo[byChannel].dwVillageCount, sendMsg.ChannelInfo[byChannel].dwVillagePCRoomCount, sendMsg.ChannelInfo[byChannel].dwBattleZoneCount, sendMsg.ChannelInfo[byChannel].dwBattleZonePCRoomCount ); dwTotalCount += pChannel->GetTotalUserNum(); dwVillageCount += sendMsg.ChannelInfo[byChannel].dwVillageCount + sendMsg.ChannelInfo[byChannel].dwVillagePCRoomCount; dwBattleZoneCount += sendMsg.ChannelInfo[byChannel].dwBattleZoneCount + sendMsg.ChannelInfo[byChannel].dwBattleZonePCRoomCount; sendMsg.byChannelCount++; } MessageCount( eCRITICAL_LOG, "Total Users:Total(%u)Field(%u)Battle(%u)", dwTotalCount, dwVillageCount, dwBattleZoneCount ); // ServerInfo¸¦ ÆÄÀÏ¿¡¼­ ¹ÞÁö ¾Ê¾Ò´Âµ¥ if( !WorldServerInfoParser::Instance()->IsServerInfoFromFile() ) { // ¸¶½ºÅÍ ¼­¹ö¿¡ Á¢¼Óµµ ¾È µÅ ÀÖÀ¸¸é µ¿Á¢ º¸°í¿¡ ½ÇÆÐÇÑ °Å´Ù! ServerSession *pMasterServer = ServerSessionManager::Instance()->GetMasterServer(); if( !pMasterServer ) { MessageOut( eCRITICAL_LOG, "Connect Statistics Send Failed - No Master Server"); return; } pMasterServer->Send( (BYTE*)&sendMsg, sendMsg.GetSize() ); MessageOut( eFULL_LOG, "Send Connect Statistics to Master Server"); } } } Channel* ChannelManager::AllocChannel() { Channel *pChannel = (Channel *)m_pChannelPool->Alloc(); pChannel->Init(); return pChannel; } VOID ChannelManager::FreeChannel( Channel *pChannel ) { pChannel->Release(); m_pChannelPool->Free( pChannel ); } VOID ChannelManager::AddChannel( DWORD dwChannelID ) { CHANNEL_MAP_ITER it = m_mapChannels.find( dwChannelID ); if( it != m_mapChannels.end() ) return; Channel *pChannel = AllocChannel(); pChannel->SetChannelID( dwChannelID ); m_mapChannels.insert( CHANNEL_MAP_PAIR( dwChannelID, pChannel ) ); MessageOut( eCRITICAL_LOG, "Add Channel(%d)", dwChannelID ); #ifdef _JP_0_20101123_PMS WorldServer::Instance()->SetPMSChannelCount(m_mapChannels.size()); #endif } void ChannelManager::RemoveChannel(DWORD channel_id) { // CHANGES: f110521.2L, prevent recursively remove processing CHANNEL_MAP::iterator it = m_mapChannels.find(channel_id); if (it == m_mapChannels.end()) { return; }; Channel* const channel = it->second; m_mapChannels.erase(it); FreeChannel(channel); MessageOut(eCRITICAL_LOG, "Remove Channel(%d)", channel_id); #ifdef _JP_0_20101123_PMS WorldServer::Instance()->SetPMSChannelCount(m_mapChannels.size()); #endif } Channel* ChannelManager::GetChannel( DWORD dwChannelID ) { CHANNEL_MAP_ITER it = m_mapChannels.find( dwChannelID ); if( it == m_mapChannels.end() ) { return NULL; } else { return it->second; } } /* VOID ChannelManager::SendToAllChannel( BYTE *pMsg, WORD wSize ) { CHANNEL_MAP_ITER it; Channel *pChannel; for( it = m_mapChannels.begin(); it != m_mapChannels.end(); ++it ) { pChannel = it->second; pChannel->SendToAll( pMsg, wSize ); } } */ VOID ChannelManager::SendToVillages( BYTE *pMsg, WORD wSize ) { CHANNEL_MAP_ITER it; Channel *pChannel; for( it = m_mapChannels.begin(); it != m_mapChannels.end(); ++it ) { pChannel = it->second; pChannel->SendToVillages( pMsg, wSize ); } } VOID ChannelManager::SendToBattleZones( BYTE *pMsg, WORD wSize ) { CHANNEL_MAP_ITER it; Channel *pChannel; for( it = m_mapChannels.begin(); it != m_mapChannels.end(); ++it ) { pChannel = it->second; pChannel->SendToBattleZones( pMsg, wSize ); } } VOID ChannelManager::DisplayChannelInfo() { CHANNEL_MAP_ITER it; Channel *pChannel; if( m_mapChannels.empty() ) { MessageOut(eCRITICAL_LOG, "No Channel." ); return; } for( it = m_mapChannels.begin(); it != m_mapChannels.end(); ++it ) { pChannel = it->second; pChannel->DisplayInfo(); } } FieldInfo* ChannelManager::GetFieldInfo( DWORD dwFieldCode ) { FIELDINFO_MAP_ITER iter = m_mapFieldInfo.find( dwFieldCode ); if( iter == m_mapFieldInfo.end() ) { return NULL; } FieldInfo* pFieldInfo = (*iter).second; return pFieldInfo; } BOOL ChannelManager::LoadFieldInfo() { // (WAVERIX)(080605)(reduce error rates) MapInfoParser* const pParser = MapInfoParser::Instance(); sMAPINFO_HASH& HashMap = pParser->GetMapInfoHash(); if( HashMap.empty() ) { MessageOut( eCRITICAL_LOG, "MapInfoParser Error - No Data" ); return FALSE; } // ¸¶À» ¸ÊÀÎ °æ¿ì¸¸ ½ÇÁ¦·Î Àд´٠// (WAVERIX)(080718)(memory leak buf-fix) : [ÇØ¿Ü] solarauth¿ÍÀÇ Àç Á¢¼Ó½Ã ¹®Á¦°¡ ¾ß±âµÈ´Ù. // - m_mapFieldInfo´Â LoadFieldInfo°¡ È£ÃâµÇ´Â ½ÃÁ¡¿¡¸¸ Ãß°¡µÈ´Ù. // - µû¶ó¼­ m_mapFieldInfo¿¡ °ªÀÌ Á¸Àç½Ã ±×³É true¹ÝȯÇϱâ·Î ÇÑ´Ù. if( !m_mapFieldInfo.empty() ) { MessageOut( eCRITICAL_LOG, "Already Loaded Fields" ); return TRUE; } FOREACH_CONTAINER( sMAPINFO_HASH::value_type& rNode, HashMap, sMAPINFO_HASH ) { sMAPINFO* const pMapInfo = rNode.second; const eZONETYPE ztZONE = pMapInfo->GetZoneType4SharedCode(); switch( ztZONE ) { case eZONETYPE_DOMINATION_FIELD: case eZONETYPE_VILLAGE: case eZONETYPE_FIELD: case eZONETYPE_SPA_FIELD: { // ¸Ê Àо Village Ãß°¡ for( int i=0 ; iFCode[i]; if( !map_code ) continue; if( GetFieldInfo( map_code ) ) continue; FieldInfo* const pFieldInfo = new FieldInfo; pFieldInfo->Create( pParser->GetFieldInfo( map_code ) ); pFieldInfo->Load(); pFieldInfo->EstablishSectorInfo( VILLAGE_SECTOR_SIZE, TRUE ); // ÀÌ°Í ÀÌ·¸°Ô ÇÏ´Â ÀÌÀ¯ ºÒ¸í.... FCode ·çÇÁµ¹¸é¼­ ¹¹ÇÏ´Â ÁþÀÎÁö... ¹º°¡ ÀÌÇØ°¡ ¾È°£´Ù. const FIELDCODE field_code = pFieldInfo->GetFieldCode(); const std::pair< FIELDINFO_MAP_ITER, bool > ret = m_mapFieldInfo.insert( FIELDINFO_MAP_PAIR( field_code, pFieldInfo ) ); if( ret.second ) SUNLOG( eFULL_LOG, "FieldInfo[%u] Template Add Completed", field_code ); else { SUNLOG( eCRITICAL_LOG, "FieldInfo[%u] Duplicated Info %u\n", field_code ); delete pFieldInfo; } } } break; } } return TRUE; } BOOL ChannelManager::LoadScript( eSCRIPT_CODE ScriptCode, BOOL bReload ) { switch( ScriptCode ) { case SCRIPT_SHOUTRANGE: return _LoadLinkedZoneFile( bReload ); } return FALSE; } BOOL ChannelManager::_LoadLinkedZoneFile( BOOL bReload ) { m_mapLinkedZoneInfo.clear(); SERVER_LINKEDZONE_INFO LinkedZoneInfo; char szTemp[MAX_FIELD_NAME_SIZE]; const INT nRowSize = GetRowSize(); for( INT nRow=0; nRow