void CGuildWarManager::SuggestEnd( void* pMsg ) { // 편의상 종전을 요청한 측을 아군, 요청받은 측을 적군이라 칭하자 const MSG_DWORD3* pmsg = (MSG_DWORD3*)pMsg; CGuild* friendlyGuild = GUILDMGR->GetGuildFromMasterIdx( pmsg->dwData1 ); CGuild* enemyGuild = GUILDMGR->GetGuildFromMasterIdx( pmsg->dwData2 ); if( ! friendlyGuild || ! enemyGuild || ! IsGuildWar( friendlyGuild->GetIdx(), enemyGuild->GetIdx() ) ) { return; } // 동맹인데 마스터 길드가 아닐 경우 해킹 또는 클라이언트 검사 실패 { CGuildUnion* friendlyAlliance = GUILDUNIONMGR->GetUnion( friendlyGuild->GetUnionIndex() ); CGuildUnion* enemyAlliance = GUILDUNIONMGR->GetUnion( enemyGuild->GetUnionIndex() ); if( ( friendlyAlliance && friendlyAlliance->GetMasterGuild() != friendlyGuild ) || ( enemyAlliance && enemyAlliance->GetMasterGuild() != enemyGuild ) ) { return; } } // 요청 측에 대기하라고 알린다 { CObject* friendlyPlayer = g_pUserTable->FindUser( pmsg->dwData1 ); if( friendlyPlayer ) { MSG_BYTE message; message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_WAIT; message.bData = MP_GUILD_WAR_SUGGESTEND; friendlyPlayer->SendMsg( &message, sizeof( message ) ); } } // 제안 받은 측에 메시지 보내자 { CObject* enemyPlayer = g_pUserTable->FindUser( pmsg->dwData2 ); if( enemyPlayer ) { MSG_DWORD message; message.Category = MP_GUILD_WAR; message.Protocol = MP_GUILD_WAR_SUGGESTEND; message.dwData = friendlyGuild->GetIdx(); enemyPlayer->SendMsg( &message, sizeof( message ) ); } } }
void CGuildWarManager::Surrender( void* pMsg ) { const MSG_DWORD* pmsg = (MSG_DWORD*)pMsg; CGuild* winnerGuild = GUILDMGR->GetGuild( pmsg->dwData ); CGuild* loserGuild = GUILDMGR->GetGuildFromMasterIdx( pmsg->dwObjectID ); if( ! winnerGuild || ! loserGuild || ! IsGuildWar( winnerGuild->GetIdx(), loserGuild->GetIdx() ) ) { return; } // 동맹인데 마스터 길드가 아닐 경우 해킹 또는 클라이언트 검사 실패 { CGuildUnion* winnerAlliance = GUILDUNIONMGR->GetUnion( winnerGuild->GetUnionIndex() ); CGuildUnion* loseAlliance = GUILDUNIONMGR->GetUnion( loserGuild->GetUnionIndex() ); if( ( winnerAlliance && winnerAlliance->GetMasterGuild() != winnerGuild ) || ( loseAlliance && loseAlliance->GetMasterGuild() != loserGuild ) ) { return; } } // 선포금 지급 { const CGuildManager::ScoreSetting& setting = GUILDMGR->GetScoreSetting(); const DWORD money = DWORD( setting.mWinMoneyRate * 2.0f * GetWarMoney( winnerGuild->GetIdx(), loserGuild->GetIdx() ) ); if( money ) { CPlayer* player = ( CPlayer* )g_pUserTable->FindUser( winnerGuild->GetMasterIdx() ); if( player ) { SendMoneyMsg( player, 0, money, MP_GUILD_WAR_ADDMONEY ); } else { SendToAgentAddMoneyMsg( winnerGuild->GetMasterIdx(), money ); } } } // 항복할때 다른 길드의 포인트를 일괄적으로 조정해주어야 한다. 일단 정확한 값을 얻기 위해 // DB 쿼리를 요구한 후 결과가 오면 처리해야한다. 처리 후 늦게 업데이트되므로 먼저 보내자 GuildSelectForRewardByWar( winnerGuild->GetIdx(), winnerGuild->GetUnionIndex(), loserGuild->GetIdx(), loserGuild->GetUnionIndex() ); }
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() ); }