void CGuildWarManager::SuggestEndDeny( void* pMsg )
{
	MSG_DWORD* pmsg = (MSG_DWORD*)pMsg;

	CPlayer* pPlayer = (CPlayer*)g_pUserTable->FindUser( pmsg->dwObjectID );
	if( pPlayer == NULL )	return;	
	DWORD dwGuildIdx1 = pPlayer->GetGuildIdx();
	DWORD dwGuildIdx2 = pmsg->dwData;
	if( dwGuildIdx1 == 0 || dwGuildIdx2 == 0 )	return;
	if( pPlayer->GetGuildMemberRank() != GUILD_MASTER )	return;

	CGuild* pGuild = GUILDMGR->GetGuild( dwGuildIdx2 );
	if( pGuild == NULL )	return;

	pPlayer = (CPlayer*)g_pUserTable->FindUser( pGuild->GetMasterIdx() );
	if( pPlayer )
	{
		MSG_DWORD Msg;
		Msg.Category = MP_GUILD_WAR;
		Msg.Protocol = MP_GUILD_WAR_SUGGESTEND_DENY;
		Msg.dwData = dwGuildIdx1;

		pPlayer->SendMsg( (MSGBASE*)&Msg, sizeof(Msg) );
	}
	else
	{
		MSG_DWORD2 Notify;
		Notify.Category = MP_GUILD_WAR;
		Notify.Protocol = MP_GUILD_WAR_SUGGESTEND_DENY_NOTIFY_TOMAP;
		Notify.dwData1 = pGuild->GetMasterIdx();
		Notify.dwData2 = dwGuildIdx1;

		g_Network.Send2AgentServer( (char*)&Notify, sizeof(Notify) );
	}
}
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::DeclareAccept( void* pMsg )
{
	/*
	071009 웅주
	요구사항:	연합<->길드, 길드<->길드, 연합<->연합 간의 전투가 가능해야한다.
	처리개요:	예를 들어 A길드와 B연합이 전쟁을 한다고 하자. 각각의 길드와 연합을 모두 다른 자료구조 A, B에 넣는다.
				길드는 B에 있는 길드 전체를 적으로 등록한다. 연합은 A에 있는 길드 전체를 적으로 등록한다.
				이런 식으로 기존 프로세스를 이용하여 연합전을 쉽게 처리할 수 있다.
	주의:		다양한 테스트 케이스를 고려하여 시험해봐야한다. 
	*/

	MSG_DWORD2* pmsg				= ( MSG_DWORD2* )pMsg;
	CPlayer*	friendlyGuildMaster	= ( CPlayer* )g_pUserTable->FindUser( pmsg->dwObjectID );

	if( ! friendlyGuildMaster )
	{
		return;	
	}

	const DWORD friendlyGuildIndex	= friendlyGuildMaster->GetGuildIdx();
	const DWORD enemyGuildIndex		= pmsg->dwData1;
	CGuild*		friendlyGuild		= GUILDMGR->GetGuildFromMasterIdx( pmsg->dwObjectID );
	CGuild*		enemyGuild			= GUILDMGR->GetGuild( enemyGuildIndex );

	if( ( ! friendlyGuild || ! enemyGuild )					||
			IsGuildWar( friendlyGuildIndex, enemyGuildIndex ) )
	{
		return;
	}

	Alliance		friendlyAlliance;
	Alliance		enemyAlliance;
	const DWORD		money = pmsg->dwData2;

	// 071008 웅주, 길드가 연합이라면 마스터인지 검사한 후 아군을 등록한다.
	{
		{
			CGuildUnion* alliance = GUILDUNIONMGR->GetUnion( friendlyGuild->GetUnionIndex() );

			if( alliance )
			{
				if( alliance->GetMasterGuild() != friendlyGuild )
				{
					// 처리 불필요. 이미 선전포고 요청할 때 검사했음
					return;
				}

				AddGuildToGroup( alliance, friendlyAlliance );
			}

			// 위의 루프에서 모든 동맹 내 길드의 선포금을 0으로 선포한다. 동맹 마스터 길드만 선포금이 지정되어야 하므로 마지막에 지정한다
			friendlyAlliance[ friendlyGuild ] = money;
		}

		{
			CGuildUnion* alliance = GUILDUNIONMGR->GetUnion( enemyGuild->GetUnionIndex() );

			if( alliance )
			{
				if( alliance->GetMasterGuild() != enemyGuild )
				{
					// 처리 불필요. 이미 선전포고 요청할 때 검사했음
					return;
				}

				AddGuildToGroup( alliance, enemyAlliance );
			}

			// 위의 루프에서 모든 동맹 내 길드의 선포금을 0으로 선포한다. 동맹 마스터 길드만 선포금이 지정되어야 하므로 마지막에 지정한다
			enemyAlliance[ enemyGuild ] = money;
		}
	}

	{
		CPlayer* enemyGuildMaster = ( CPlayer* )g_pUserTable->FindUser( enemyGuild->GetMasterIdx() );

		SendMoneyMsg( friendlyGuildMaster, enemyGuildMaster, money, MP_GUILD_WAR_REMOVEMONEY );
	}	

	AddEnemyToFriendly( friendlyAlliance, enemyAlliance );
	AddEnemyToFriendly( enemyAlliance, friendlyAlliance );
}
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() );
}