void CGuildWarManager::SurrenderNotifyToMap( void* pMsg ) { const MSG_GUILD_WAR_RESULT* pmsg = ( MSG_GUILD_WAR_RESULT* )pMsg; const DWORD winnnerGuildIndex = pmsg->mWinner.mGuildIndex; const DWORD loserGuildIndex = pmsg->mLoser.mGuildIndex; MSG_DWORD4 message; { message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_SURRENDER; } // 승리 길드에게 메시지 전달 { CGuild* guild = GUILDMGR->GetGuild( winnnerGuildIndex ); if( guild ) { const MSG_GUILD_WAR_RESULT::Data& data = pmsg->mWinner; message.dwData1 = 1; // 1 = win message.dwData2 = loserGuildIndex; message.dwData3 = data.mScoreValue; message.dwData4 = DWORD( data.mScoreVariation ); guild->SendMsgToAll( &message, sizeof( message ) ); } } // 패배 길드에게 전달 { CGuild* guild = GUILDMGR->GetGuild( loserGuildIndex ); if( guild ) { const MSG_GUILD_WAR_RESULT::Data& data = pmsg->mLoser; message.dwData1 = 0; // 0 = surrender, message.dwData2 = winnnerGuildIndex; message.dwData3 = data.mScoreValue; message.dwData4 = DWORD( data.mScoreVariation ); guild->SendMsgToAll( &message, sizeof( message ) ); } } UnregistGuildWar( winnnerGuildIndex, loserGuildIndex ); // PenaltyForEndNotifyToMap( 1, loserGuildIndex ); UpdateGuildWarRecord( FALSE, 0, loserGuildIndex ); UpdateGuildWarRecord( FALSE, 1, winnnerGuildIndex ); }
void CGuildWarManager::NetworkMsgParse( BYTE Protocol, void* pMsg ) { switch( Protocol ) { case MP_GUILD_WAR_NACK: { MSG_BYTE* pmsg = (MSG_BYTE*)pMsg; CObject* object = g_pUserTable->FindUser( pmsg->dwObjectID ); if( object ) { object->SendMsg( pmsg, sizeof( MSG_BYTE ) ); } break; } case MP_GUILD_WAR_DECLARE: { Declare( pMsg ); break; } case MP_GUILD_WAR_DECLARE_NACK: { break; } case MP_GUILD_WAR_DECLARE_ACCEPT: { DeclareAccept( pMsg ); break; } case MP_GUILD_WAR_DECLARE_DENY: { DeclareDeny( pMsg ); break; } case MP_GUILD_WAR_DECLARE_DENY_NOTIFY_TOMAP: { DeclareDenyNotifyToMap( pMsg ); break; } case MP_GUILD_WAR_START: { break; } case MP_GUILD_WAR_START_NOTIFY_TOMAP: { StartNotifyToMap( pMsg ); break; } case MP_GUILD_WAR_PROC: { break; } case MP_GUILD_WAR_END: { break; } case MP_GUILD_WAR_END_NOTIFY_TOMAP: { MSG_DWORD2* pmsg = (MSG_DWORD2*)pMsg; DWORD dwGuildIdxWinner = pmsg->dwData1; DWORD dwGuildIdxLoser = pmsg->dwData2; if( dwGuildIdxWinner == 0 || dwGuildIdxLoser == 0 ) return; CGuild* pGuildWinner = GUILDMGR->GetGuild( dwGuildIdxWinner ); CGuild* pGuildLoser = GUILDMGR->GetGuild( dwGuildIdxLoser ); if( pGuildWinner == NULL || pGuildLoser == NULL ) return; MSG_DWORD2 Msg; Msg.Category = MP_GUILD_WAR; Msg.Protocol = MP_GUILD_WAR_END; // send guildwinner Msg.dwData1 = 1; // 0 = lose, 1 = win Msg.dwData2 = dwGuildIdxLoser; pGuildWinner->SendMsgToAll( &Msg, sizeof(Msg) ); // send guildloser Msg.dwData1 = 0; Msg.dwData2 = dwGuildIdxWinner; pGuildLoser->SendMsgToAll( &Msg, sizeof(Msg) ); // unregist UnregistGuildWar( dwGuildIdxWinner, dwGuildIdxLoser ); // PenaltyForEndNotifyToMap( 0, dwGuildIdxLoser ); // guildfieldwarrecord UpdateGuildWarRecord( FALSE, 0, dwGuildIdxLoser ); UpdateGuildWarRecord( FALSE, 1, dwGuildIdxWinner ); // registend //RegistEnd( dwGuildIdxWinner, dwGuildIdxLoser ); break; } case MP_GUILD_WAR_SUGGESTEND: { SuggestEnd( pMsg ); break; } case MP_GUILD_WAR_SUGGESTEND_NOTIFY_TOMAP: { const MSG_DWORD2* pmsg = (MSG_DWORD2*)pMsg; CObject* object = g_pUserTable->FindUser( pmsg->dwData1 ); if( object ) { MSG_DWORD message; message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_SUGGESTEND; message.dwData = pmsg->dwData2; object->SendMsg( &message, sizeof(message) ); } break; } case MP_GUILD_WAR_SUGGESTEND_NACK: { break; } case MP_GUILD_WAR_SUGGESTEND_ACCEPT: { SuggestEndAccept( pMsg ); break; } case MP_GUILD_WAR_SUGGESTEND_ACCEPT_NOTIFY_TOMAP: { SuggestEndAcceptNotifyToMap( pMsg ); break; } case MP_GUILD_WAR_SUGGESTEND_DENY: { SuggestEndDeny( pMsg ); break; } case MP_GUILD_WAR_SUGGESTEND_DENY_NOTIFY_TOMAP: { SuggestEndDenyNotifyToMap( pMsg ); break; } case MP_GUILD_WAR_SURRENDER: { Surrender( pMsg ); break; } case MP_GUILD_WAR_SURRENDER_NACK: { break; } case MP_GUILD_WAR_SURRENDER_NOTIFY_TOMAP: { SurrenderNotifyToMap( pMsg ); break; } case MP_GUILD_WAR_ADDMONEY_TOMAP: { AddMoneyToMap( pMsg ); break; } default: { ASSERT( 0 && "It is not defined" ); break; } } }
void CGuildWarManager::RemoveUnionEnemyFromGuild( CGuildUnion* friendlyUnion, CGuild* friendlyGuild ) { std::list< sGFWENEMY* > enemeyList; GetEnemy( friendlyUnion->GetMasterGuildIdx(), enemeyList ); const DWORD friendlyGuildIndex = friendlyGuild->GetIdx(); MSG_DWORD2 messageToFriendy; { messageToFriendy.Category = MP_GUILD_WAR; messageToFriendy.Protocol = MP_GUILD_WAR_END; messageToFriendy.dwData1 = 2; } MSG_DWORD2 messageToEnemy; { messageToEnemy.Category = MP_GUILD_WAR; messageToEnemy.Protocol = MP_GUILD_WAR_END; messageToEnemy.dwData1 = 2; // draw messageToEnemy.dwData2 = friendlyGuildIndex; } // 모든 적 목록에서 해당 길드를 적에서 제거하도록 한다. for( std::list< sGFWENEMY* >::const_iterator it = enemeyList.begin(); enemeyList.end() != it; ++it ) { const sGFWENEMY* enemyData = *it; const DWORD enemyGuildIndex = enemyData->dwEnemyGuildIdx; CGuild* enemyGuild = GUILDMGR->GetGuild( enemyGuildIndex ); if( ! enemyGuild ) { ASSERT( 0 ); continue; } // 적 길드에게 해당 길드와의 싸움을 끝낼 것을 알린다 { enemyGuild->SendMsgToAll( &messageToEnemy, sizeof( messageToEnemy ) ); } // 아군에게도 알리자 { messageToFriendy.dwData2 = enemyGuildIndex; friendlyGuild->SendMsgToAll( &messageToFriendy, sizeof( messageToFriendy ) ); } // 다른 맵에도 알린다(종전으로 표시될 것이다 { MSG_DWORD2 message; message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_SUGGESTEND_ACCEPT_NOTIFY_TOMAP; message.dwData1 = friendlyGuildIndex; message.dwData2 = enemyGuildIndex; g_Network.Send2AgentServer( (char*)&message, sizeof( message ) ); } // DB 및 메모리 갱신 { DeleteGuildWar( friendlyGuildIndex, enemyGuildIndex ); UnregistGuildWar( friendlyGuildIndex, enemyGuildIndex ); UpdateGuildWarRecord( TRUE, 2, enemyGuildIndex ); UpdateGuildWarRecord( TRUE, 2, friendlyGuildIndex ); } //SendToAllUser( 1, friendlyGuild->GetGuildName(), enemyGuild->GetGuildName() ); } }
void CGuildWarManager::AddUnionEnemyToGuild( CGuildUnion* friendlyUnion, CGuild* friendlyGuild ) { MSG_GUILD_LIST messageToFriendly; MSG_GUILD_LIST messageToEnemey; { messageToFriendly.Category = MP_GUILD_WAR; messageToFriendly.Protocol = MP_GUILD_WAR_START; messageToFriendly.mSize = 0; messageToEnemey.Category = MP_GUILD_WAR; messageToEnemey.Protocol = MP_GUILD_WAR_START; messageToEnemey.mSize = 1; MSG_GUILD_LIST::Data& dest = messageToEnemey.mData[ 0 ]; const GUILDINFO& source = friendlyGuild->GetInfo(); // 올바로 복사되는지 꼭 검사할 것 memcpy( &dest, &source, sizeof( source ) ); // 중간에 참전했으므로 선포금이 없다 dest.MarkName = 0; CGuildUnion* alliance = GUILDUNIONMGR->GetUnion( source.UnionIdx ); if( alliance ) { SafeStrCpy( dest.mUnionName, alliance->GetName(), sizeof( dest.mUnionName ) ); } else { dest.mUnionName[ 0 ] = 0; } } const DWORD friendlyGuildIndex = friendlyGuild->GetIdx(); std::list< sGFWENEMY* > enemeyList; GetEnemy( friendlyUnion->GetMasterGuildIdx(), enemeyList ); // 적대 길드 목록을 메시지에 담고, 신입 길드 또한 적 길드로 하여금 등록하게 한다. for( std::list< sGFWENEMY* >::const_iterator it = enemeyList.begin(); enemeyList.end() != it; ++it ) { const sGFWENEMY* enemyData = *it; const DWORD enemyGuildIndex = enemyData->dwEnemyGuildIdx; CGuild* enemyGuild = GUILDMGR->GetGuild( enemyGuildIndex ); if( ! enemyGuild ) { ASSERT( 0 ); continue; } // 적대 길드 정보를 담는다 // 신입 길드를 적으로 등록하도록 모든 적대 길드에게 보낸다. { MSG_GUILD_LIST::Data& dest = messageToFriendly.mData[ messageToFriendly.mSize++ ]; const GUILDINFO& source = enemyGuild->GetInfo(); // 제대로 복사되나 테스트할 것 memcpy( &dest, &source, sizeof( source ) ); // 중간에 참전하여 선포금이 없다 dest.MarkName = 0; CGuildUnion* alliance = GUILDUNIONMGR->GetUnion( source.UnionIdx ); if( alliance ) { SafeStrCpy( dest.mUnionName, alliance->GetName(), sizeof( dest.mUnionName ) ); } else { dest.mUnionName[ 0 ] = 0; } enemyGuild->SendMsgToAll( &messageToEnemey, messageToEnemey.GetSize() ); } // DB와 메모리에도 저장한다 { InsertGuildWar( friendlyGuildIndex, enemyGuildIndex, 0 ); RegistGuildWar( friendlyGuildIndex, enemyGuildIndex, 0 ); } // 다른 맵에도 등록하게 한다. { MSG_DWORD3 message; message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_START_NOTIFY_TOMAP; message.dwData1 = friendlyGuildIndex; message.dwData2 = enemyGuildIndex; message.dwData3 = 0; g_Network.Send2AgentServer( ( char* )&message, sizeof( message ) ); } } if( messageToFriendly.mSize ) { // 적대 길드 목록을 다 담은 후 신입 길드에게도 보낸다 friendlyGuild->SendMsgToAll( &messageToFriendly, messageToFriendly.GetSize() ); } }
void CGuildWarManager::AddEnemyToFriendly( Alliance& friendlyMap, Alliance& enemyMap ) { MSG_GUILD_LIST messageToClient; messageToClient.Category = MP_GUILD_WAR; messageToClient.Protocol = MP_GUILD_WAR_START; messageToClient.mSize = 0; // 길드 1의 적(길드2) 전체 정보를 넣는다 for( Alliance::iterator it = enemyMap.begin(); enemyMap.end() != it; ++it ) { CGuild* enemy = it->first; const MONEYTYPE money = it->second; if( ! enemy ) { ASSERT( 0 ); continue; } MSG_GUILD_LIST::Data& dest = messageToClient.mData[ messageToClient.mSize++ ]; const GUILDINFO& source = enemy->GetInfo(); // 제대로 복사되나 꼭 확인하자. 좀 위험한 코드 memcpy( &dest, &source, sizeof( source ) ); dest.MarkName = money; CGuildUnion* allianace = GUILDUNIONMGR->GetUnion( source.UnionIdx ); if( allianace ) { SafeStrCpy( dest.mUnionName, allianace->GetName(), sizeof( dest.mUnionName ) ); } else { dest.mUnionName[ 0 ] = 0; } } MSG_DWORD3 messageToAgent; messageToAgent.Category = MP_GUILD_WAR; messageToAgent.Protocol = MP_GUILD_WAR_START_NOTIFY_TOMAP; // 길드 2의 적, 즉 길드 1의 편 전부에게 보낸다. for( Alliance::iterator it = friendlyMap.begin(); friendlyMap.end() != it; ++it ) { CGuild* friendly = it->first; const MONEYTYPE friendlyMoney = it->second; if( ! friendly ) { ASSERT( 0 ); continue; } friendly->SendMsgToAll( &messageToClient, messageToClient.GetSize() ); // 아군 길드 각각이 상대 길드들을 적으로 등록하게 한다. for( Alliance::iterator inner = enemyMap.begin(); enemyMap.end() != inner; ++inner ) { CGuild* enemy = inner->first; const MONEYTYPE enemyMoney = inner->second; if( ! enemy ) { ASSERT( 0 ); continue; } // 두 길드 모두 선포금을 지니고 있을때만 돈을 업데이트해야한다. 그렇지 않은 길드는 선포금을 건 당사자가 아니다. const MONEYTYPE money = ( friendlyMoney && enemyMoney ? friendlyMoney : 0 ) ; InsertGuildWar( friendly->GetIdx(), enemy->GetIdx(), money ); RegistGuildWar( friendly->GetIdx(), enemy->GetIdx(), money ); // 다른 맵에도 등록하게 한다. { messageToAgent.dwData1 = friendly->GetIdx(); messageToAgent.dwData2 = enemy->GetIdx(); messageToAgent.dwData3 = money; g_Network.Send2AgentServer( (char*)&messageToAgent, sizeof( messageToAgent ) ); } } } }
void CGuildWarManager::SuggestEndAccept( void* pMsg ) { // 편의상 제안한 쪽은 아군, 받아들이는 쪽은 적군이라 하자 MSG_DWORD* pmsg = ( MSG_DWORD* )pMsg; CPlayer* friendlyGuildMaster = ( CPlayer* ) g_pUserTable->FindUser( pmsg->dwObjectID ); if( ! friendlyGuildMaster || friendlyGuildMaster->GetGuildMemberRank() != GUILD_MASTER ) { return; } const DWORD friendlyGuildIndex = friendlyGuildMaster->GetGuildIdx(); const DWORD enemyGuildIndex = pmsg->dwData; CGuild* friendlyGuild = GUILDMGR->GetGuild( friendlyGuildIndex ); CGuild* enemyGuild = GUILDMGR->GetGuild( enemyGuildIndex ); if( ! friendlyGuild || ! enemyGuild || ! IsGuildWar( friendlyGuildIndex, enemyGuildIndex ) ) { return; } // 동맹인데 마스터 길드가 아닐 경우 해킹 또는 클라이언트 검사 실패 { CGuildUnion* friendlyAlliance = GUILDUNIONMGR->GetUnion( friendlyGuild->GetUnionIndex() ); CGuildUnion* enemyAlliance = GUILDUNIONMGR->GetUnion( enemyGuild->GetUnionIndex() ); if( ( friendlyAlliance && friendlyAlliance->GetMasterGuild() != friendlyGuild ) || ( enemyAlliance && enemyAlliance->GetMasterGuild() != enemyGuild ) ) { return; } } // 편의상 종전을 요청한 측을 아군, 요청받은 측을 적군으로 하자 Alliance friendlyAlliance; Alliance enemyAlliance; // 연합인 경우 해당 길드를 모두 자료구조에 담는다. { // 아군 { CGuildUnion* alliance = GUILDUNIONMGR->GetUnion( friendlyGuild->GetUnionIndex() ); if( alliance ) { // 연합이 있는데도 마스터 길드가 아닌 경우 오류 if( alliance->GetMasterGuild() != friendlyGuild ) { return; } AddGuildToGroup( alliance, friendlyAlliance ); } friendlyAlliance[ friendlyGuild ] = GetWarMoney( friendlyGuildIndex, enemyGuildIndex ); } // 적군 { CGuildUnion* alliance = GUILDUNIONMGR->GetUnion( enemyGuild->GetUnionIndex() ); if( alliance ) { // 연합이 있는데도 마스터 길드가 아닌 경우 오류 if( alliance->GetMasterGuild() != enemyGuild ) { return; } AddGuildToGroup( alliance, enemyAlliance ); } enemyAlliance[ enemyGuild ] = GetWarMoney( friendlyGuildIndex, enemyGuildIndex ); } } // 선포금이 있다면 반환해주자 { const DWORD money = GetWarMoney( friendlyGuildIndex, enemyGuildIndex ); if( money ) { SendMoneyMsg( friendlyGuildMaster, NULL, money, MP_GUILD_WAR_ADDMONEY ); CPlayer* enemyGuildMaster = ( CPlayer* )g_pUserTable->FindUser( enemyGuild->GetMasterIdx() ); if( enemyGuildMaster ) { SendMoneyMsg( enemyGuildMaster, NULL, money, MP_GUILD_WAR_ADDMONEY ); } else { SendToAgentAddMoneyMsg( enemyGuild->GetMasterIdx(), money ); } } } // 자료구조를 순환하며, 각각의 전쟁을 종료시킨다. for( Alliance::const_iterator it = friendlyAlliance.begin(); friendlyAlliance.end() != it; ++it ) { // 전쟁 종료 CGuild* friendly = it->first; if( ! friendly ) { ASSERT( 0 ); continue; } const DWORD friendlyGuildIndex = friendly->GetIdx(); for( Alliance::const_iterator inner = enemyAlliance.begin(); enemyAlliance.end() != inner; ++inner ) { CGuild* enemy = inner->first; if( ! enemy ) { ASSERT( 0 ); continue; } const DWORD enemyGuildIndex = enemy->GetIdx(); // 길드전 중지를 해당 맵에 알린다 { MSG_DWORD2 message; message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_END; message.dwData1 = 2; // 2 = draw message.dwData2 = enemyGuildIndex; friendly->SendMsgToAll( &message, sizeof( message ) ); message.dwData2 = friendlyGuildIndex; enemy->SendMsgToAll( &message, sizeof( message ) ); } // 에이전트를 통해 다른 맵에게도 보낸다 { MSG_DWORD2 message; message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_SUGGESTEND_ACCEPT_NOTIFY_TOMAP; message.dwData1 = friendlyGuildIndex; message.dwData2 = enemyGuildIndex; g_Network.Send2AgentServer( (char*)&message, sizeof( message ) ); } DeleteGuildWar( friendlyGuildIndex, enemyGuildIndex ); UnregistGuildWar( friendlyGuildIndex, enemyGuildIndex ); UpdateGuildWarRecord( TRUE, 2, friendlyGuildIndex ); UpdateGuildWarRecord( TRUE, 2, enemyGuildIndex ); } } //SendToAllUser( 1, friendlyGuild->GetGuildName(), enemyGuild->GetGuildName() ); }