Esempio n. 1
0
string CGamePlayer :: GetCountry()
{
	if (m_Country.empty())
	{
		if ((GetExternalIPString()=="127.0.0.1" || GetExternalIPString() == m_Game->m_Config->m_ExternalIP) && !m_Game->m_GHost->IsRootAdmin(m_Name))
			m_Country = "Ga";
		else
			m_Country = m_Game->m_GHost->m_DBLocal->FromCheck( UTIL_ByteArrayToUInt32( GetExternalIP( ), true ) );
	}
	return m_Country;
}
Esempio n. 2
0
bool CPotentialPlayer :: Update( void *fd )
{
	if( m_DeleteMe )
		return true;

	if( !m_Socket )
		return false;

	m_Socket->DoRecv( (fd_set *)fd );
	ExtractPackets( );
	ProcessPackets( );
	
	// make sure we don't keep this socket open forever (disconnect after five seconds)
	if( m_ConnectionState == 0 && GetTicks( ) - m_ConnectionTime > m_Game->m_GHost->m_DenyMaxReqjoinTime && !m_Banned )
	{
		CONSOLE_Print( "[DENY] Kicking player: REQJOIN not received within a few seconds" );
		m_DeleteMe = true;
		m_Game->m_GHost->DenyIP( GetExternalIPString( ), m_Game->m_GHost->m_DenyReqjoinDuration, "REQJOIN not received within a few seconds" );
		
	}

	// don't call DoSend here because some other players may not have updated yet and may generate a packet for this player
	// also m_Socket may have been set to NULL during ProcessPackets but we're banking on the fact that m_DeleteMe has been set to true as well so it'll short circuit before dereferencing

	return m_DeleteMe || m_Error || m_Socket->HasError( ) || !m_Socket->GetConnected( );
}
Esempio n. 3
0
string CGamePlayer :: GetProvider()
{
	if (m_Provider=="")
	{
		if (GetCountry()!="??" && GetCountry()!="Ga")
			m_Provider=m_Game->m_GHost->UDPChatWhoIs(GetCountry(), GetExternalIPString( ));
	}
	return m_Provider;
}
Esempio n. 4
0
string CGamePlayer :: GetCountry()
{
	if (m_Country=="")
	{
		if (GetExternalIPString()=="127.0.0.1")
			m_Country = "Ga";
		else
			m_Country = m_Game->m_GHost->m_DBLocal->FromCheck( UTIL_ByteArrayToUInt32( GetExternalIP( ), true ) );
	}
	return m_Country;
}
Esempio n. 5
0
void CGamePlayer :: ProcessPackets( )
{
    if( !m_Socket )
        return;

    CIncomingAction *Action = NULL;
    CIncomingChatPlayer *ChatPlayer = NULL;
    CIncomingMapSize *MapSize = NULL;
    bool HasMap = false;
    uint32_t CheckSum = 0;
    uint32_t Pong = 0;

    // process all the received packets in the m_Packets queue

    while( !m_Packets.empty( ) )
    {
        CCommandPacket *Packet = m_Packets.front( );
        m_Packets.pop( );

        if( Packet->GetPacketType( ) == W3GS_HEADER_CONSTANT )
        {
            switch( Packet->GetID( ) )
            {
            case CGameProtocol :: W3GS_LEAVEGAME:
                m_Game->EventPlayerLeft( this, m_Protocol->RECEIVE_W3GS_LEAVEGAME( Packet->GetData( ) ) );
                break;

            case CGameProtocol :: W3GS_GAMELOADED_SELF:
                if( m_Protocol->RECEIVE_W3GS_GAMELOADED_SELF( Packet->GetData( ) ) )
                {
                    if( !m_FinishedLoading && m_Game->GetGameLoading( ) )
                    {
                        m_FinishedLoading = true;
                        m_FinishedLoadingTicks = GetTicks( );
                        m_Game->EventPlayerLoaded( this );
                    }
                    else
                    {
                        // we received two W3GS_GAMELOADED_SELF packets from this player!
                    }
                }

                break;

            case CGameProtocol :: W3GS_OUTGOING_ACTION:
                Action = m_Protocol->RECEIVE_W3GS_OUTGOING_ACTION( Packet->GetData( ), m_PID );

                if( Action )
                {
                    // don't delete Action here because the game is going to store it in a queue and delete it later
                    m_Game->EventPlayerAction( this, Action );
                }

                break;

            case CGameProtocol :: W3GS_OUTGOING_KEEPALIVE:
                CheckSum = m_Protocol->RECEIVE_W3GS_OUTGOING_KEEPALIVE( Packet->GetData( ) );
                m_CheckSums.push( CheckSum );
                ++m_SyncCounter;
                m_Game->EventPlayerKeepAlive( this, CheckSum );
                break;

            case CGameProtocol :: W3GS_CHAT_TO_HOST:
                ChatPlayer = m_Protocol->RECEIVE_W3GS_CHAT_TO_HOST( Packet->GetData( ) );

                if( ChatPlayer )
                {
                    // determine if we should auto-mute this player
                    if( ChatPlayer->GetType( ) == CIncomingChatPlayer :: CTH_MESSAGE || ChatPlayer->GetType( ) == CIncomingChatPlayer :: CTH_MESSAGEEXTRA )
                    {
                        if( m_Level <= 1 &&! GetMuted( ) )
                        {
                            m_MuteMessages.push_back( GetTicks( ) );

                            if( m_MuteMessages.size( ) > 7 )
                                m_MuteMessages.erase( m_MuteMessages.begin( ) );

                            uint32_t RecentCount = 0;
                            for( unsigned int i = 0; i < m_MuteMessages.size( ); ++i )
                            {
                                if( GetTicks( ) - m_MuteMessages[i] < 5000 )
                                {
                                    RecentCount++;
                                }
                            }

                            if( m_Game->m_OHBot->m_AutoMuteSpammer && RecentCount >= 7 )
                            {
                                m_Count++;
                                if(  m_Count == 1 )
                                {
                                    SetMuted( true );
                                    m_MutedAuto = true;
                                    m_Game->SendChat( m_PID, "["+m_Game->m_OHBot->m_BotManagerName+"] "+m_Game->m_OHBot->m_Language->SpamWarning( ) );
                                    m_MuteMessages.clear( );
                                    m_Game->SendAllChat( "["+m_Game->m_OHBot->m_BotManagerName+"] " + m_Game->m_OHBot->m_Language->UserWasMutedForReason( m_Name, "spamming" ) );
                                }
                                if( m_Count == 2 )
                                {
                                    m_Game->SendAllChat( m_Game->m_OHBot->m_Language->UserIgnoerNotify( m_Name ) );
                                    m_Game->SendChat( m_PID, "["+m_Game->m_OHBot->m_BotManagerName+"] "+m_Game->m_OHBot->m_Language->SpamWarning2( ) );
                                    SetMuted( true );
                                    m_Game->m_Pairedpenps.push_back( Pairedpenp( string(), m_Game->m_OHBot->m_DB->Threadedpenp( m_Name, "Spam" , m_Game->m_OHBot->m_BotManagerName, 1, "add" ) ) );
                                    m_MutedAuto = true;
                                    m_Game->SendAllChat( "["+m_Game->m_OHBot->m_BotManagerName+"] " + m_Game->m_OHBot->m_Language->UserWasMutedForReason( m_Name, "spamming" ) );
                                }
                                if( m_Count == 3 )
                                {
				    m_Game->BanPlayerByPenality( m_Name, GetExternalIPString( ), m_Game->m_OHBot->m_BotManagerName, m_PenalityLevel, "Spam" );
                                    SetMuted( true );
                                    m_Game->SendAllChat( "["+m_Game->m_OHBot->m_BotManagerName+"] " + m_Game->m_OHBot->m_Language->UserWasMutedForReason( m_Name, "spamming" ) );

                                }
                            }

                            //we adding this condition not in the next condition to avoid a jump into ohbot.cpp to check if the message was a flame message or not
                            if(m_Game->m_OHBot->m_FlameCheck && ( m_Name != "dolan" || m_Name != "Dolan" ) )
                            {
                                //now check for flamers
                                if( m_Game->m_OHBot->FlameCheck( ChatPlayer->GetMessage( ) ) )
                                {
                                    m_FlameMessages.push_back( GetTicks( ) );

                                    if( m_FlameMessages.size( ) > 10 )
                                        m_FlameMessages.erase( m_FlameMessages.begin( ) );

                                    RecentCount = 0;

                                    for( unsigned int i = 0; i < m_FlameMessages.size( ); ++i )
                                    {
                                        if( GetTicks( ) - m_FlameMessages[i] < 60000 )
                                            RecentCount++;
                                    }

                                    if( RecentCount == 1 )
                                    {
                                        m_Game->SendChat( m_PID, "["+m_Game->m_OHBot->m_BotManagerName+"] "+m_Game->m_OHBot->m_Language->FlameWarn ());
                                    }

                                    if( RecentCount == 2 )
                                    {
                                        m_Game->SendChat( m_PID, "["+m_Game->m_OHBot->m_BotManagerName+"] "+m_Game->m_OHBot->m_Language->FlameWarn2 () );
                                        SetMuted( true );
                                        m_MutedAuto = true;
                                        m_Game->SendAllChat( "["+m_Game->m_OHBot->m_BotManagerName+"] " + m_Game->m_OHBot->m_Language->UserWasMutedForReason( m_Name, "flaming" ) );
                                    }

                                    if( RecentCount == 3 )
                                    {
                                        m_Game->SendChat( m_PID, m_Game->m_OHBot->m_Language->FlameWarn3 () );
                                        SetMuted( true );
                                        m_Game->m_Pairedpenps.push_back( Pairedpenp( string(), m_Game->m_OHBot->m_DB->Threadedpenp( m_Name, "Flame/Insult" , m_Game->m_OHBot->m_BotManagerName, 1, "add" ) ) );
                                        m_MutedAuto = true;
                                        m_Game->SendAllChat( "["+m_Game->m_OHBot->m_BotManagerName+"] " + m_Game->m_OHBot->m_Language->UserWasMutedForReason( m_Name, "flaming" ) );
                                    }

                                    if( RecentCount == 4 )
                                    {
					m_Game->BanPlayerByPenality( m_Name, GetExternalIPString( ), m_Game->m_OHBot->m_BotManagerName, m_PenalityLevel, "Flame/Insult" );
                                        SetMuted( true );
                                        m_Game->SendAllChat( "["+m_Game->m_OHBot->m_BotManagerName+"] " + m_Game->m_OHBot->m_Language->UserWasMutedForReason( m_Name, "flaming" ) );

                                    }
                                    if( RecentCount == 5 )
                                    {
                                        //some people simple dont understand the ban policy.
                                        m_Game->BanPlayerByPenality( m_Name, GetExternalIPString( ), m_Game->m_OHBot->m_BotManagerName, m_PenalityLevel, "Flame/Insult" );
					SetMuted( true );
                                        m_Game->SendAllChat( "["+m_Game->m_OHBot->m_BotManagerName+"] " + m_Game->m_OHBot->m_Language->UserWasMutedForReason( m_Name, "flaming" ) );

                                    }
                                }
                            }
                        }
                    }
                    m_Game->EventPlayerChatToHost( this, ChatPlayer );
                }
                delete ChatPlayer;
                ChatPlayer = NULL;
                break;

            case CGameProtocol :: W3GS_DROPREQ:
                // todotodo: no idea what's in this packet

                if( !m_DropVote )
                {
                    m_DropVote = true;
                    m_Game->EventPlayerDropRequest( this );
                }

                break;

            case CGameProtocol :: W3GS_MAPSIZE:
                MapSize = m_Protocol->RECEIVE_W3GS_MAPSIZE( Packet->GetData( ), m_Game->m_OHBot->m_Map->GetMapSize( ) );

                if( MapSize )
                    m_Game->EventPlayerMapSize( this, MapSize );

                delete MapSize;
                MapSize = NULL;
                break;

            case CGameProtocol :: W3GS_PONG_TO_HOST:
                Pong = m_Protocol->RECEIVE_W3GS_PONG_TO_HOST( Packet->GetData( ) );

                // we discard pong values of 1
                // the client sends one of these when connecting plus we return 1 on error to kill two birds with one stone

                if( Pong != 1 )
                {
                    // we also discard pong values when we're downloading because they're almost certainly inaccurate
                    // this statement also gives the player a 5 second grace period after downloading the map to allow queued (i.e. delayed) ping packets to be ignored

                    if( !m_DownloadStarted || ( m_DownloadFinished && GetTime( ) - m_FinishedDownloadingTime >= 5 ) )
                    {
                        // we also discard pong values when anyone else is downloading if we're configured to

                        if( m_Game->m_OHBot->m_PingDuringDownloads || !m_Game->IsDownloading( ) )
                        {
                            m_Pings.push_back( GetTicks( ) - Pong );

                            if( m_Pings.size( ) > 20 )
                                m_Pings.erase( m_Pings.begin( ) );
                        }
                    }
                }

                m_Game->EventPlayerPongToHost( this, Pong );
                break;
            }
        }
        else if( Packet->GetPacketType( ) == GPS_HEADER_CONSTANT )
        {
            BYTEARRAY Data = Packet->GetData( );

            if( Packet->GetID( ) == CGPSProtocol :: GPS_INIT )
            {
                if( m_Game->m_OHBot->IsMode( BOT_MODE_GPROXY ) )
                {
                    m_GProxy = true;
                    m_Socket->PutBytes( m_Game->m_OHBot->m_GPSProtocol->SEND_GPSS_INIT( m_Game->m_OHBot->m_ReconnectPort, m_PID, m_GProxyReconnectKey, m_Game->GetGProxyEmptyActions( ) ) );
                    //Log->Info( "[GAME: " + m_Game->GetGameName( ) + "] player [" + m_Name + "] is using GProxy++" );
                }
                else
                {
                    // todotodo: send notice that we're not permitting reconnects
                    // note: GProxy++ should never send a GPS_INIT message if bot_reconnect = 0 because we don't advertise the game with invalid map dimensions
                    // but it would be nice to cover this case anyway
                }
            }
            else if( Packet->GetID( ) == CGPSProtocol :: GPS_RECONNECT )
            {
                // this is handled in ohbot.cpp
            }
            else if( Packet->GetID( ) == CGPSProtocol :: GPS_ACK && Data.size( ) == 8 )
            {
                uint32_t LastPacket = UTIL_ByteArrayToUInt32( Data, false, 4 );
                uint32_t PacketsAlreadyUnqueued = m_TotalPacketsSent - m_GProxyBuffer.size( );

                if( LastPacket > PacketsAlreadyUnqueued )
                {
                    uint32_t PacketsToUnqueue = LastPacket - PacketsAlreadyUnqueued;

                    if( PacketsToUnqueue > m_GProxyBuffer.size( ) )
                        PacketsToUnqueue = m_GProxyBuffer.size( );

                    while( PacketsToUnqueue > 0 )
                    {
                        m_GProxyBuffer.pop( );
                        --PacketsToUnqueue;
                    }
                }
            }
        }

        delete Packet;
    }
}
Esempio n. 6
0
bool CGamePlayer :: Update( void *fd )
{
	// wait 4 seconds after joining before sending the /whois or /w
	// if we send the /whois too early battle.net may not have caught up with where the player is and return erroneous results

	if( m_WhoisShouldBeSent && !m_Spoofed && !m_WhoisSent && !m_JoinedRealm.empty( ) && GetTime( ) - m_JoinTime >= 4 )
	{
		// todotodo: we could get kicked from battle.net for sending a command with invalid characters, do some basic checking

		// check if we have this ip in our spoofed cached ip list
		bool isspoofed = m_Game->m_GHost->IsSpoofedIP(GetName(), GetExternalIPString());

		if (isspoofed)
		{
			CONSOLE_Print("[OPT] Player "+GetName()+" is in the cached spoof checked list");
			m_Game->AddToSpoofed(m_Game->m_Server, GetName(), false);
		}

		if (!isspoofed && GetExternalIPString()!="127.0.0.1")
		for( vector<CBNET *> :: iterator i = m_Game->m_GHost->m_BNETs.begin( ); i != m_Game->m_GHost->m_BNETs.end( ); i++ )
		{
			if( (*i)->GetServer( ) == m_JoinedRealm )
			{
				if( m_Game->GetGameState( ) == GAME_PUBLIC )
				{
					if ((*i)->GetWhereis() || (*i)->GetPasswordHashType( ) == "pvpgn" )
						(*i)->QueueChatCommand( "/whereis " + m_Name );
					else
						(*i)->QueueChatCommand( "/whois " + m_Name );
				}
				else if( m_Game->GetGameState( ) == GAME_PRIVATE )
					(*i)->QueueChatCommand( m_Game->m_GHost->m_Language->SpoofCheckByReplying( ), m_Name, true );
			}
		}

		m_WhoisSent = true;
	}

	// check for socket timeouts
	// if we don't receive anything from a player for 30 seconds we can assume they've dropped
	// this works because in the lobby we send pings every 5 seconds and expect a response to each one
	// and in the game the Warcraft 3 client sends keepalives frequently (at least once per second it looks like)

	if( m_Socket && GetTime( ) - m_Socket->GetLastRecv( ) >= 30 )
		m_Game->EventPlayerDisconnectTimedOut( this );
	// make sure we're not waiting too long for the first MAPSIZE packet
	
	if( m_ConnectionState == 1 && GetTicks( ) - m_ConnectionTime > m_Game->m_GHost->m_DenyMaxMapsizeTime && !m_Game->GetGameLoaded() && !m_Game->GetGameLoading() )
	{
		CONSOLE_Print( "[DENY] Kicking player: MAPSIZE not received within a few seconds" );
		m_DeleteMe = true;
		SetLeftReason( "MAPSIZE not received within a few seconds" );
		SetLeftCode( PLAYERLEAVE_LOBBY );
		m_Game->OpenSlot( m_Game->GetSIDFromPID( GetPID( ) ), false );
		m_Game->m_GHost->DenyIP( GetExternalIPString( ), m_Game->m_GHost->m_DenyMapsizeDuration, "MAPSIZE not received within a few seconds" );
	}
	
	// disconnect if the player is downloading too slowly
	
	if( m_DownloadStarted && !m_DownloadFinished && !m_Game->GetGameLoaded() && !m_Game->GetGameLoading() && GetLastMapPartSent( ) != 0 )
	{
		uint32_t downloadingTime = GetTicks( ) - m_StartedDownloadingTicks;
		uint32_t Seconds = downloadingTime / 1000;
		uint32_t Rate = GetLastMapPartSent( ) / 1024; // Rate in miliseconds
		if (Seconds>0)
			Rate /= Seconds;
		
		if(!(m_Game->IsSafe(GetName()) || m_Game->IsAdmin(GetName()) || m_Game->IsRootAdmin(GetName()) || m_Game->IsOwner(GetName()) )){			
		//	uint32_t iRate = (uint32_t)Rate;
			if ( m_Game->m_GHost->m_DLRateLimit != 0 )
			if ( GetLastMapPartSent( ) <= 102400 )
			if ( 0 < Rate && Rate < m_Game->m_GHost->m_DLRateLimit ){
				m_Game->DelTempOwner( GetName() );
				m_Game->SendAllChat( m_Game->m_GHost->m_Language->KickMsgForSlowDL( GetName( ) , UTIL_ToString( Rate ), UTIL_ToString(m_Game->m_GHost->m_DLRateLimit) ) );							
				m_Game->m_GHost->m_Callables.push_back( m_Game->m_GHost->m_DB->ThreadedBanAdd( GetJoinedRealm( ), GetName( ), GetExternalIPString(), m_Game->GetGameName( ), "AUTOBAN", "Slow internet", 1, 0 ));
				if ( m_Game->m_GHost->m_BlacklistSlowDLder && !m_Game->IsBlacklisted(m_Game->GetBannedNames( ),GetName( )) )
					m_Game->AddBannedNames(GetName( ));
				m_DeleteMe = true;				
				SetLeftReason( "kicked for downloading too slowly " + UTIL_ToString( Rate ) + " KB/s" );				
				SetLeftCode( PLAYERLEAVE_LOBBY );
				m_Game->OpenSlot( m_Game->GetSIDFromPID( GetPID( ) ), false );
			}
			
			if( downloadingTime > m_Game->m_GHost->m_DenyMaxDownloadTime )
			{
				m_Game->DelTempOwner( GetName() );
				m_Game->SendAllChat( m_Game->m_GHost->m_Language->KickMsgForSlowDL( GetName( ),"","" ) );
				m_DeleteMe = true;
				SetLeftReason( "download time is too long" );
				SetLeftCode( PLAYERLEAVE_LOBBY );
				m_Game->OpenSlot( m_Game->GetSIDFromPID( GetPID( ) ), false );
				m_Game->m_GHost->DenyIP( GetExternalIPString( ), m_Game->m_GHost->m_DenyDownloadDuration, "("+ GetName( ) +") rejected because download time is too long" );
			}
		}
	}
	
	// unmute player
	if( GetMuted( ) && ( GetTicks( ) - m_MutedTicks > 60000 || ( m_MutedAuto && GetTicks( ) - m_MutedTicks > 15000 ) ) )
	{
		SetMuted( false );
		m_Game->SendAllChat( "[" + m_Name + "] has been automatically unmuted. (Don't spam or you'll be muted again!)" );
		m_MuteMessages.clear( );
	}

	// GProxy++ acks

	if( m_GProxy && GetTime( ) - m_LastGProxyAckTime >= 10 )
	{
		if( m_Socket )
			m_Socket->PutBytes( m_Game->m_GHost->m_GPSProtocol->SEND_GPSS_ACK( m_TotalPacketsReceived ) );

		m_LastGProxyAckTime = GetTime( );
	}

	// base class update

	CPotentialPlayer :: Update( fd );
	bool Deleting;

	if( m_GProxy && m_Game->GetGameLoaded( ) )
		Deleting = m_DeleteMe || m_Error;
	else
		Deleting = m_DeleteMe || m_Error || m_Socket->HasError( ) || !m_Socket->GetConnected( );

	// try to find out why we're requesting deletion
	// in cases other than the ones covered here m_LeftReason should have been set when m_DeleteMe was set

	if( m_Error ){
		m_Game->m_GHost->DenyIP( GetExternalIPString( ), 180000, "player error" );
		m_Game->EventPlayerDisconnectPlayerError( this );
		m_Socket->Reset( );
		return Deleting;
	}
	if( m_Socket )
	{
		if( m_Socket->HasError( ) ){
			m_Game->EventPlayerDisconnectSocketError( this );
			if( !m_GProxy )
				m_Game->m_GHost->DenyIP( GetExternalIPString( ), 20000, "socket error" );
		}
		else if( !m_Socket->GetConnected( ) ){
			m_Game->EventPlayerDisconnectConnectionClosed( this );
			if( !m_GProxy )
				m_Game->m_GHost->DenyIP( GetExternalIPString( ), 30000, "connection closed" );
		}
	}

	return Deleting;
}