void CServerRPCHandler::ChatInput(CBitStream * pBitStream, CPlayerSocket senderSocket)
{
	CLogFile::Printf("Got ChatInput RPC from player %d", senderSocket.playerId);

	// Ensure we have a valid bitstream
	if(!pBitStream)
	{
		CLogFile::Printf("Warning: Invalid bitstream for ChatInput RPC");
		return;
	}

	// Get the player pointer
	CPlayer * pPlayer = g_pServer->GetPlayerManager()->Get(senderSocket.playerId);

	// Is the player pointer valid?
	if(pPlayer)
	{
		// Read the data they sent us
		bool bIsCommand;
		String strInput;

		// Read if its a command or not
		bIsCommand = pBitStream->ReadBit();

		// Read the input
		if(!pBitStream->Read(strInput))
			return;

		// Prepare the event arguments
		CSquirrelArguments arguments;
		arguments.push(strInput);

		// Is it not a command?
		if(!bIsCommand)
		{
			// Trigger the event, if it is canceled, don't output the line to other players
			if(pPlayer->CallEvent("playerChat", &arguments))
			{
				// Construct the chat input bit stream
				CBitStream bitStream;

				// Write the player id
				bitStream.WriteCompressed(senderSocket.playerId);

				// Write the input
				bitStream.Write(strInput);

				// Send it to all other players
				g_pServer->GetNetworkManager()->RPC(RPC_CHAT_INPUT, &bitStream, PRIORITY_HIGH, RELIABILITY_RELIABLE_ORDERED, INVALID_ENTITY_ID, true);
			}
		}
		else
		{
			// Trigger the event
			pPlayer->CallEvent("playerCommand", &arguments);
		}

		CLogFile::Printf("Recieved chat input from player %d (Command?: %s, Input: %s)", senderSocket.playerId, bIsCommand ? "Yes" : "No", strInput.C_String());
	}
}
Beispiel #2
0
bool CAccountManager::LogOut ( CClient* pClient, CClient* pEchoClient )
{
    // Is he logged in?
    if ( !pClient->IsRegistered () )
    {
        if ( pEchoClient )
            pEchoClient->SendEcho ( "logout: You were not logged in" );
        return false;
    }

    if ( pClient->GetClientType () != CClient::CLIENT_PLAYER )
    {
        if ( pEchoClient )
            pEchoClient->SendEcho ( "logout: Only players can log out" );
        return false;
    }
    CPlayer* pPlayer = static_cast < CPlayer* > ( pClient );

    CAccount* pCurrentAccount = pClient->GetAccount ();
    pCurrentAccount->SetClient ( NULL );

    CAccount* pAccount = g_pGame->GetAccountManager ()->AddGuestAccount( GUEST_ACCOUNT_NAME );
    pClient->SetAccount ( pAccount );

    // Call our script event
    CLuaArguments Arguments;
    Arguments.PushAccount ( pCurrentAccount );
    Arguments.PushAccount ( pAccount );
    if ( !pPlayer->CallEvent ( "onPlayerLogout", Arguments ) )
    {
        // DENIED!
        pClient->SetAccount ( pCurrentAccount );
        pCurrentAccount->SetClient ( pClient );
        delete pAccount;
        return false;
    }

    // Tell the console
    CLogger::AuthPrintf ( "LOGOUT: %s logged out as '%s'\n", pClient->GetNick (), pCurrentAccount->GetName ().c_str () );

    // Tell the player
    if ( pEchoClient )
        pEchoClient->SendEcho ( "logout: You logged out" );

    return true;
}
Beispiel #3
0
bool CConsole::HandleInput ( const char* szCommand, CClient* pClient, CClient* pEchoClient )
{
    // Copy it
    char szCommandBuffer [256];
    szCommandBuffer [255] = 0;
    strncpy ( szCommandBuffer, szCommand, 255 );
    stripControlCodes ( szCommandBuffer );

    // Split it into two parts: Key and argument
    char* szKey = strtok ( szCommandBuffer, " " );
    char* szArguments = strtok ( NULL, "\0" );

    // Does the key exist?
    if ( szKey && szKey [0] != 0 )
    {
        CConsoleCommand* pCommand = GetCommand ( szKey );
        if ( pCommand )
        {
            // Can this user use this command?
            if ( m_pACLManager->CanObjectUseRight ( pClient->GetAccount ()->GetName ().c_str (),
                                                    CAccessControlListGroupObject::OBJECT_TYPE_USER,
                                                    szKey,
                                                    CAccessControlListRight::RIGHT_TYPE_COMMAND,
                                                    !pCommand->IsRestricted () ) )
            {
                return (*pCommand)( this, szArguments, pClient, pEchoClient );
            }

            // Not enough access, tell the console
            CLogger::LogPrintf ( "DENIED: Denied '%s' access to command '%s'\n", pClient->GetNick (), szKey );

            // Tell the client
            char szBuffer [128];
            _snprintf ( szBuffer, sizeof(szBuffer), "ACL: Access denied for '%s'", szKey );
            szBuffer[sizeof(szBuffer)-1] = '\0';

            pClient->SendEcho ( szBuffer );
            return false;
        }

        // Let the script handle it
        int iClientType = pClient->GetClientType ();

        switch ( iClientType )
        {
            case CClient::CLIENT_PLAYER:
            {
                // See if any registered command can process it
                CPlayer* pPlayer = static_cast < CPlayer* > ( pClient );
                m_pRegisteredCommands->ProcessCommand ( szKey, szArguments, pClient );

                // HACK: if the client gets destroyed before here, dont continue
                if ( m_pPlayerManager->Exists ( pPlayer ) )
                {
                    // Call the console event
                    CLuaArguments Arguments;
                    Arguments.PushString ( szCommand );
                    pPlayer->CallEvent ( "onConsole", Arguments );
                }
                break;
            }
            case CClient::CLIENT_CONSOLE:
            {
                // See if any registered command can process it
                CConsoleClient* pConsole = static_cast < CConsoleClient* > ( pClient );
                m_pRegisteredCommands->ProcessCommand ( szKey, szArguments, pClient );

                // Call the console event
                CLuaArguments Arguments;
                Arguments.PushString ( szCommand );
                pConsole->CallEvent ( "onConsole", Arguments );
                break;
            }
            default: break;
        }
    }

    // Doesn't exist
    return false;
}
bool CVehiclePuresyncPacket::Read ( NetBitStreamInterface& BitStream )
{
    // Got a player to read?
    if ( m_pSourceElement )
    {
        CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement );

        // Player is in a vehicle?
        CVehicle* pVehicle = pSourcePlayer->GetOccupiedVehicle ();
        if ( pVehicle )
        {
            // Read out the time context
            unsigned char ucTimeContext = 0;
            if ( !BitStream.Read ( ucTimeContext ) )
                return false;

            // Only read this packet if it matches the current time context that
            // player is in.
            if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) )
            {
                return false;
            }

            // Read out the keysync data
            CControllerState ControllerState;
            if ( !ReadFullKeysync ( ControllerState, BitStream ) )
                return false;

            // Read out its position
            SPositionSync position ( false );
            if ( !BitStream.Read ( &position ) )
                return false;
            pSourcePlayer->SetPosition ( position.data.vecPosition );

            // Jax: don't allow any outdated packets through
            unsigned char ucSeat;
            if ( !BitStream.Read ( ucSeat ) )
                return false;
            if ( ucSeat != pSourcePlayer->GetOccupiedVehicleSeat () )
            {
                // Mis-matching seats can happen when we warp into a different one,
                // which will screw up the whole packet
                return false;
            }

            // Read out the vehicle matrix only if he's the driver
            unsigned int uiSeat = pSourcePlayer->GetOccupiedVehicleSeat ();
            if ( uiSeat == 0 )
            {
                // Read out the vehicle rotation in degrees
                SRotationDegreesSync rotation;
                if( !BitStream.Read ( &rotation ) )
                    return false;

                // Set it
                pVehicle->SetPosition ( position.data.vecPosition );
                pVehicle->SetRotationDegrees ( rotation.data.vecRotation );

                // Move speed vector
                SVelocitySync velocity;
                if ( !BitStream.Read ( &velocity ) )
                    return false;

                pVehicle->SetVelocity ( velocity.data.vecVelocity );
                pSourcePlayer->SetVelocity ( velocity.data.vecVelocity );

                // Turn speed vector
                SVelocitySync turnSpeed;
                if ( !BitStream.Read ( &turnSpeed ) )
                    return false;

                pVehicle->SetTurnSpeed ( turnSpeed.data.vecVelocity );

                // Health
                SVehicleHealthSync health;
                if ( !BitStream.Read ( &health ) )
                    return false;
                float fPreviousHealth = pVehicle->GetHealth ();                
                float fHealth = health.data.fValue;

                // Less than last time?
                if ( fHealth < fPreviousHealth )
                {                 
                    // Grab the delta health
                    float fDeltaHealth = fPreviousHealth - fHealth;

					if ( fDeltaHealth > 0.0f )
					{
						// Call the onVehicleDamage event
						CLuaArguments Arguments;
						Arguments.PushNumber ( fDeltaHealth );
						pVehicle->CallEvent ( "onVehicleDamage", Arguments );
					}
                }
                pVehicle->SetHealth ( fHealth );

                // Trailer chain
                CVehicle* pTowedByVehicle = pVehicle;
                CVehicle* pTrailer = NULL;
                ElementID TrailerID;
                bool bHasTrailer;
                if ( !BitStream.ReadBit ( bHasTrailer ) )
                    return false;

                while ( bHasTrailer )
                {
                    BitStream.ReadCompressed ( TrailerID );
                    CElement* pElement = CElementIDs::GetElement ( TrailerID );
                    if ( pElement )
                        pTrailer = static_cast < CVehicle* > ( pElement );
                    
                    // Read out the trailer position and rotation
                    SPositionSync trailerPosition ( false );
                    if ( !BitStream.Read ( &trailerPosition ) )
                        return false;

                    SRotationDegreesSync trailerRotation;
                    if ( !BitStream.Read ( &trailerRotation ) )
                        return false;

                    // If we found the trailer
                    if ( pTrailer )
                    {
                        // Set its position and rotation
                        pTrailer->SetPosition ( trailerPosition.data.vecPosition );
                        pTrailer->SetRotationDegrees ( trailerRotation.data.vecRotation );
    
                        // Is this a new trailer, attached?
                        CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle ();
                        if ( pCurrentTrailer != pTrailer )
                        {
                            // If theres a trailer already attached
                            if ( pCurrentTrailer )
                            {
                                pTowedByVehicle->SetTowedVehicle ( NULL );
                                pCurrentTrailer->SetTowedByVehicle ( NULL );

                                // Tell everyone to detach them
                                CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false );
                                g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                                // Execute the attach trailer script function
                                CLuaArguments Arguments;
                                Arguments.PushElement ( pTowedByVehicle );
                                pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments );
                            }

                            // If something else is towing this trailer
                            CVehicle* pCurrentVehicle = pTrailer->GetTowedByVehicle ();
                            if ( pCurrentVehicle )
                            {
                                pCurrentVehicle->SetTowedVehicle ( NULL );
                                pTrailer->SetTowedByVehicle ( NULL );

                                // Tell everyone to detach them
                                CVehicleTrailerPacket AttachPacket ( pCurrentVehicle, pTrailer, false );
                                g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                                // Execute the attach trailer script function
                                CLuaArguments Arguments;
                                Arguments.PushElement ( pCurrentVehicle );
                                pTrailer->CallEvent ( "onTrailerDetach", Arguments );
                            }

                            pTowedByVehicle->SetTowedVehicle ( pTrailer );
                            pTrailer->SetTowedByVehicle ( pTowedByVehicle );

                            // Execute the attach trailer script function
                            CLuaArguments Arguments;
                            Arguments.PushElement ( pTowedByVehicle );
                            bool bContinue = pTrailer->CallEvent ( "onTrailerAttach", Arguments );

                            // Attach or detach trailers depending on the event outcome
                            CVehicleTrailerPacket TrailerPacket ( pTowedByVehicle, pTrailer, bContinue );
                            g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( TrailerPacket );
                        }
                    }
                    else
                        break;

                    pTowedByVehicle = pTrailer;

                    if ( BitStream.ReadBit ( bHasTrailer ) == false )
                        return false;
                }

                // If there was a trailer before
                CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle ();
                if ( pCurrentTrailer )
                {
                    pTowedByVehicle->SetTowedVehicle ( NULL );
                    pCurrentTrailer->SetTowedByVehicle ( NULL );

                    // Tell everyone else to detach them
                    CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false );
                    g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                    // Execute the detach trailer script function
                    CLuaArguments Arguments;
                    Arguments.PushElement ( pTowedByVehicle );
                    pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments );                    
                }
            }

            // Player health
            SPlayerHealthSync health;
            if ( !BitStream.Read ( &health ) )
                return false;
            float fHealth = health.data.fValue;

            float fOldHealth = pSourcePlayer->GetHealth ();
			float fHealthLoss = fOldHealth - fHealth;

            // Less than last packet's frame?
            if ( fHealth < fOldHealth && fHealthLoss > 0 )
            {
                // Call the onPlayerDamage event
                CLuaArguments Arguments;
                Arguments.PushNil ();
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( fHealthLoss );
                pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );
            }
            pSourcePlayer->SetHealth ( fHealth );

			// Armor
            SPlayerArmorSync armor;
            if ( !BitStream.Read ( &armor ) )
                return false;
            float fArmor = armor.data.fValue;

			float fOldArmor = pSourcePlayer->GetArmor ();
			float fArmorLoss = fOldArmor - fArmor;

			// Less than last packet's frame?
			if ( fArmor < fOldArmor && fArmorLoss > 0 )
			{
				// Call the onPlayerDamage event
				CLuaArguments Arguments;
                Arguments.PushNil ();
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( false );
				Arguments.PushNumber ( fArmorLoss );

				pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );					
			}
            pSourcePlayer->SetArmor ( fArmor );

            // Flags
            SVehiclePuresyncFlags flags;
            if ( !BitStream.Read ( &flags ) )
                return false;

            pSourcePlayer->SetWearingGoggles ( flags.data.bIsWearingGoggles );
            pSourcePlayer->SetDoingGangDriveby ( flags.data.bIsDoingGangDriveby );            

            // Weapon sync
            if ( flags.data.bHasAWeapon )
            {
                SWeaponSlotSync slot;
                if ( !BitStream.Read ( &slot ) )
                    return false;

                pSourcePlayer->SetWeaponSlot ( slot.data.uiSlot );

                if ( flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo ( slot.data.uiSlot ) )
                {
                    // Read the ammo states
                    SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), false, true );
                    if ( !BitStream.Read ( &ammo ) )
                        return false;
                    pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip );

                    // Read aim data
                    SWeaponAimSync aim ( pSourcePlayer->GetWeaponRange (), true );
                    if ( !BitStream.Read ( &aim ) )
                        return false;
                    pSourcePlayer->SetAimDirection ( aim.data.fArm );
                    pSourcePlayer->SetSniperSourceVector ( aim.data.vecOrigin );
                    pSourcePlayer->SetTargettingVector ( aim.data.vecTarget );

                    // Read the driveby direction
                    SDrivebyDirectionSync driveby;
                    if ( !BitStream.Read ( &driveby ) )
                        return false;
                    pSourcePlayer->SetDriveByDirection ( driveby.data.ucDirection );
                }
            }
            else
                pSourcePlayer->SetWeaponSlot ( 0 );


            // Vehicle specific data if he's the driver
            if ( uiSeat == 0 )
            {
                ReadVehicleSpecific ( pVehicle, BitStream );

                // Set vehicle specific stuff if he's the driver
                pVehicle->SetSirenActive ( flags.data.bIsSirenOrAlarmActive );
                pVehicle->SetSmokeTrailEnabled ( flags.data.bIsSmokeTrailEnabled );
                pVehicle->SetLandingGearDown ( flags.data.bIsLandingGearDown );
                pVehicle->SetOnGround ( flags.data.bIsOnGround );
                pVehicle->SetInWater ( flags.data.bIsInWater );
                pVehicle->SetDerailed ( flags.data.bIsDerailed );
                pVehicle->SetHeliSearchLightVisible ( flags.data.bIsHeliSearchLightVisible );
            }

            // Read the vehicle_look_left and vehicle_look_right control states
            // if it's an aircraft.
            if ( flags.data.bIsAircraft )
            {
                ControllerState.LeftShoulder2 = BitStream.ReadBit () * 255;
                ControllerState.RightShoulder2 = BitStream.ReadBit () * 255;
            }

            pSourcePlayer->GetPad ()->NewControllerState ( ControllerState );

            // Success
            return true;
        }
    }

    return false;
}
Beispiel #5
0
bool CAccountManager::LogIn ( CClient* pClient, CClient* pEchoClient, const char* szAccountName, const char* szPassword )
{
    // Is he already logged in?
    if ( pClient->IsRegistered () )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( "login: You are already logged in" );
        return false;
    }

    if ( pClient->GetClientType () != CClient::CLIENT_PLAYER )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( "login: Only players can log in" );
        return false;
    }

    // Get the players details
    CPlayer* pPlayer = static_cast < CPlayer* > ( pClient );
    SString strPlayerName = pPlayer->GetNick ();
    SString strPlayerIP = pPlayer->GetSourceIP ();
    SString strPlayerSerial = pPlayer->GetSerial ();

    if ( m_AccountProtect.IsFlooding ( strPlayerIP.c_str () ) )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account locked", szAccountName ).c_str() );
        CLogger::AuthPrintf ( "LOGIN: Ignoring %s trying to log in as '%s' (IP: %s  Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () );
        return false;
    }

    // Grab the account on his nick if any
    CAccount* pAccount = g_pGame->GetAccountManager ()->Get ( szAccountName );
    if ( !pAccount )
    {
        if ( pEchoClient ) pEchoClient->SendEcho( SString( "login: No known account for '%s'", szAccountName ).c_str() );
        CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' (Unknown account) (IP: %s  Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () );
        return false;
    }

    if ( pAccount->GetClient () )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account for '%s' is already in use", szAccountName ).c_str() );
        return false;
    }
    if ( !IsValidPassword( szPassword ) || !pAccount->IsPassword ( szPassword ) )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Invalid password for account '%s'", szAccountName ).c_str() );
        CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' with an invalid password (IP: %s  Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () );
        m_AccountProtect.AddConnect ( strPlayerIP.c_str () );
        return false;
    }

    // Check serial authorization
    if ( IsAuthorizedSerialRequired( pAccount ) )
    {
        pAccount->AddSerialForAuthorization( strPlayerSerial, strPlayerIP );
        if ( !pAccount->IsSerialAuthorized( strPlayerSerial ) )
        {
            if ( pEchoClient )
                pEchoClient->SendEcho( SString( "login: Serial pending authorization for account '%s' - See https:""//mtasa.com/authserial", szAccountName ) );
            CLogger::AuthPrintf( "LOGIN: %s tried to log in as '%s' with an unauthorized serial (IP: %s  Serial: %s)\n", *strPlayerName, szAccountName, *strPlayerIP, *strPlayerSerial );
            CLogger::AuthPrintf( "LOGIN: See https:""//mtasa.com/authserial\n" );
            return false;
        }
    }

    // Log him in
    CAccount* pCurrentAccount = pClient->GetAccount ();
    pClient->SetAccount ( pAccount );
    pAccount->SetClient ( pClient );

    // Call the onPlayerLogin script event
    CLuaArguments Arguments;
    Arguments.PushAccount ( pCurrentAccount );
    Arguments.PushAccount ( pAccount );
    Arguments.PushBoolean ( false );    // was bAutoLogin
    if ( !pPlayer->CallEvent ( "onPlayerLogin", Arguments ) )
    {
        // DENIED!
        pClient->SetAccount ( pCurrentAccount );
        pAccount->SetClient ( NULL );
        return false;
    }

    // Success is here
    pAccount->OnLoginSuccess ( strPlayerSerial, strPlayerIP );

    SString strGroupList = SString::Join ( ", ", g_pGame->GetACLManager ()->GetObjectGroupNames ( pAccount->GetName (), CAccessControlListGroupObject::OBJECT_TYPE_USER ) );
    CLogger::AuthPrintf ( "LOGIN: (%s) %s successfully logged in as '%s' (IP: %s  Serial: %s)\n", strGroupList.c_str (), pClient->GetNick (), pAccount->GetName ().c_str (), strPlayerIP.c_str (), strPlayerSerial.c_str () );

    // Tell the player
    if ( pEchoClient )
    {
        pEchoClient->SendEcho ( "login: You successfully logged in" );
    }

    // Update who was info
    if ( pClient->GetClientType () == CClient::CLIENT_PLAYER )
        g_pGame->GetConsole ()->GetWhoWas ()->OnPlayerLogin ( static_cast < CPlayer* > ( pClient ) );

    // Delete the old account if it was a guest account
    if ( !pCurrentAccount->IsRegistered () )
        delete pCurrentAccount;

    return true;
}
Beispiel #6
0
bool CPlayerPuresyncPacket::Read ( NetBitStreamInterface& BitStream )
{
    if ( m_pSourceElement )
    {
        CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement );

        // Read out the time context
        unsigned char ucTimeContext = 0;
        if ( !BitStream.Read ( ucTimeContext ) )
            return false;

        // Only read this packet if it matches the current time context that
        // player is in.
        if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) )
        {
            return false;
        }

        // Read out keys
        CControllerState ControllerState;
        ReadFullKeysync ( ControllerState, BitStream );
        pSourcePlayer->GetPad ()->NewControllerState ( ControllerState );

        // Read the flags
        SPlayerPuresyncFlags flags;
        if ( !BitStream.Read ( &flags ) )
            return false;

        pSourcePlayer->SetInWater ( flags.data.bIsInWater );
        pSourcePlayer->SetOnGround ( flags.data.bIsOnGround );
        pSourcePlayer->SetHasJetPack ( flags.data.bHasJetPack );
        pSourcePlayer->SetDucked ( flags.data.bIsDucked );
        pSourcePlayer->SetWearingGoggles ( flags.data.bWearsGoogles );
        pSourcePlayer->SetChoking ( flags.data.bIsChoking );
        pSourcePlayer->SetAkimboArmUp ( flags.data.bAkimboTargetUp );
        pSourcePlayer->SetOnFire ( flags.data.bIsOnFire );
        pSourcePlayer->SetStealthAiming ( flags.data.bStealthAiming );

        // Contact element
        CElement* pContactElement = NULL;
        if ( flags.data.bHasContact )
        {
            ElementID Temp;
            if ( !BitStream.ReadCompressed ( Temp ) )
                return false;
            pContactElement = CElementIDs::GetElement ( Temp );
        }
        CElement * pPreviousContactElement = pSourcePlayer->GetContactElement ();
        pSourcePlayer->SetContactElement ( pContactElement );

        if ( pPreviousContactElement != pContactElement )
        {
            // Call our onPlayerContact event
            CLuaArguments Arguments;
            if ( pPreviousContactElement )
                Arguments.PushElement ( pPreviousContactElement );
            else
                Arguments.PushNil ();
            if ( pContactElement )
                Arguments.PushElement ( pContactElement );
            else
                Arguments.PushNil ();

            pSourcePlayer->CallEvent ( "onPlayerContact", Arguments );
        }

        // Player position
        SPositionSync position ( false );
        if ( !BitStream.Read ( &position ) )
            return false;

        if ( pContactElement )
        {
            pSourcePlayer->SetContactPosition ( position.data.vecPosition );

            // Get the true position
            CVector vecTempPos = pContactElement->GetPosition ();
            position.data.vecPosition += vecTempPos;
        }
        pSourcePlayer->SetPosition ( position.data.vecPosition );

        // Player rotation
        SPedRotationSync rotation;
        if ( !BitStream.Read ( &rotation ) )
            return false;
        pSourcePlayer->SetRotation ( rotation.data.fRotation );

        // Move speed vector
        if ( flags.data.bSyncingVelocity )
        {
            SVelocitySync velocity;
            if ( !BitStream.Read ( &velocity ) )
                return false;
            pSourcePlayer->SetVelocity ( velocity.data.vecVelocity );
        }

        // Health ( stored with damage )
        SPlayerHealthSync health;
        if ( !BitStream.Read ( &health ) )
            return false;
        float fHealth = health.data.fValue;

        // Armor
        SPlayerArmorSync armor;
        if ( !BitStream.Read ( &armor ) )
            return false;

        float fArmor = armor.data.fValue;
        float fOldArmor = pSourcePlayer->GetArmor ();
        float fArmorLoss = fOldArmor - fArmor;

        pSourcePlayer->SetArmor ( fArmor );

        // Read out and set the camera rotation
        float fCameraRotation;
        if ( !BitStream.Read ( fCameraRotation ) )
            return false;
        pSourcePlayer->SetCameraRotation ( fCameraRotation );

        if ( flags.data.bHasAWeapon )
        {
            if ( BitStream.Version () >= 0x0d )
            {
                // Check client has the weapon we think he has
                unsigned char ucWeaponType;
                if ( !BitStream.Read ( ucWeaponType ) )
                    return false;

                if ( pSourcePlayer->GetWeaponType () != ucWeaponType )
                    return false;
            }

            // Current weapon slot
            SWeaponSlotSync slot;
            if ( !BitStream.Read ( &slot ) )
                return false;
            unsigned int uiSlot = slot.data.uiSlot;

            pSourcePlayer->SetWeaponSlot ( uiSlot );

            if ( CWeaponNames::DoesSlotHaveAmmo ( uiSlot ) )
            {
                // Read out the ammo states
                SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), true, true );
                if ( !BitStream.Read ( &ammo ) )
                    return false;
                pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip );
                pSourcePlayer->SetWeaponTotalAmmo ( ammo.data.usTotalAmmo );

                // Read out the aim data
                SWeaponAimSync sync ( pSourcePlayer->GetWeaponRange (), ( ControllerState.RightShoulder1 || ControllerState.ButtonCircle ) );
                if ( !BitStream.Read ( &sync ) )
                    return false;

                // Set the arm directions and whether or not arms are up
                pSourcePlayer->SetAimDirection ( sync.data.fArm );

                // Read the aim data only if he's shooting or aiming
                if ( sync.isFull() )
                {
                    pSourcePlayer->SetSniperSourceVector ( sync.data.vecOrigin );
                    pSourcePlayer->SetTargettingVector ( sync.data.vecTarget );
                }
            }
            else
            {
                pSourcePlayer->SetWeaponAmmoInClip ( 1 );
                pSourcePlayer->SetWeaponTotalAmmo ( 1 );
            }
        }
        else
        {
            pSourcePlayer->SetWeaponSlot ( 0 );
            pSourcePlayer->SetWeaponAmmoInClip ( 1 );
            pSourcePlayer->SetWeaponTotalAmmo ( 1 );
        }

        // Read out damage info if changed
        if ( BitStream.ReadBit () == true )
        {
            ElementID DamagerID;
            if ( !BitStream.ReadCompressed ( DamagerID ) )
                return false;

            SWeaponTypeSync weaponType;
            if ( !BitStream.Read ( &weaponType ) )
                return false;

            SBodypartSync bodyPart;
            if ( !BitStream.Read ( &bodyPart ) )
                return false;

            pSourcePlayer->SetDamageInfo ( DamagerID, weaponType.data.ucWeaponType, bodyPart.data.uiBodypart );
        }

        // If we know the player's dead, make sure the health we send on is 0
        if ( pSourcePlayer->IsDead () )
            fHealth = 0.0f;

        float fOldHealth = pSourcePlayer->GetHealth ();
        float fHealthLoss = fOldHealth - fHealth;
        pSourcePlayer->SetHealth ( fHealth );

        // Less than last packet's frame?
        if ( fHealthLoss > 0 || fArmorLoss > 0 )
        {
            float fDamage = 0.0f;
            if ( fHealthLoss > 0 ) fDamage += fHealthLoss;
            if ( fArmorLoss > 0 ) fDamage += fArmorLoss;

            // Call the onPlayerDamage event
            CLuaArguments Arguments;
            CElement* pKillerElement = CElementIDs::GetElement ( pSourcePlayer->GetPlayerAttacker () );
            if ( pKillerElement ) Arguments.PushElement ( pKillerElement );
            else Arguments.PushNil ();
            Arguments.PushNumber ( pSourcePlayer->GetAttackWeapon () );
            Arguments.PushNumber ( pSourcePlayer->GetAttackBodyPart () );
            Arguments.PushNumber ( fDamage );

            pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );
        }

        // Success
        return true;
    }

    return false;
}
Beispiel #7
0
void CMapManager::SpawnPlayer ( CPlayer& Player, const CVector& vecPosition, float fRotation, unsigned short usModel, unsigned char ucInterior, unsigned short usDimension, CTeam* pTeam )
{
    // Don't force them off their team if the spawnpoint doesn't have one
    if ( pTeam == NULL )
        pTeam = Player.GetTeam ();

    ElementID TeamID = ( pTeam ) ? pTeam->GetID () : INVALID_ELEMENT_ID;

    // Change the time context to avoid old sync packets arriving causing players
    // to slide from previous location to the new one.
    unsigned char ucTimeContext = Player.GenerateSyncTimeContext ();

    // Tell everyone where he spawns
    m_pPlayerManager->BroadcastOnlyJoined ( CPlayerSpawnPacket ( Player.GetID (), vecPosition, fRotation, usModel, ucInterior, usDimension, TeamID, ucTimeContext ) );

    // Remove him from any occupied vehicle
    CVehicle* pVehicle = Player.GetOccupiedVehicle ();
    if ( pVehicle )
    {
        pVehicle->SetOccupant ( NULL, Player.GetOccupiedVehicleSeat () );
        Player.SetOccupiedVehicle ( NULL, 0 );
    }

    // If this guy was jacking someone, make sure its aborted
    pVehicle = Player.GetJackingVehicle ();
    if ( pVehicle )
    {
        if ( Player.GetVehicleAction () == CPlayer::VEHICLEACTION_JACKING )
        {
            CPed * pOccupant = pVehicle->GetOccupant ( 0 );
            if ( pOccupant )
            {
                pOccupant->SetVehicleAction ( CPlayer::VEHICLEACTION_NONE );

                // Tell everyone
                CVehicleInOutPacket Reply ( pVehicle->GetID (), 0, CGame::VEHICLE_NOTIFY_JACK_RETURN, pOccupant->GetID (), Player.GetID () );
                Reply.SetSourceElement ( &Player );
                m_pPlayerManager->BroadcastOnlyJoined ( Reply );
            }
        }
        if ( pVehicle->GetJackingPlayer () == &Player )
            pVehicle->SetJackingPlayer ( NULL );
    }   

    // Update the player data
    Player.SetSpawned ( true );
    Player.SetHealth ( Player.GetMaxHealth () );
    Player.SetIsDead ( false );
    Player.SetWearingGoggles ( false );
    Player.SetHasJetPack ( false );
    Player.SetPosition ( vecPosition );
    Player.SetRotation ( fRotation );
    Player.SetModel ( usModel );
    Player.SetVehicleAction ( CPlayer::VEHICLEACTION_NONE );
    Player.SetTeam ( pTeam, true );
    Player.SetInterior ( ucInterior );
    Player.SetDimension ( usDimension );
    Player.AttachTo ( NULL );

    // Call onPlayerSpawn
    CLuaArguments OnPlayerSpawnArguments;
    OnPlayerSpawnArguments.PushNumber ( vecPosition.fX );
    OnPlayerSpawnArguments.PushNumber ( vecPosition.fY );
    OnPlayerSpawnArguments.PushNumber ( vecPosition.fZ );
    OnPlayerSpawnArguments.PushNumber ( fRotation );
    OnPlayerSpawnArguments.PushElement ( pTeam );
    OnPlayerSpawnArguments.PushNumber ( usModel );
    OnPlayerSpawnArguments.PushNumber ( ucInterior );
    OnPlayerSpawnArguments.PushNumber ( usDimension );
    Player.CallEvent ( "onPlayerSpawn", OnPlayerSpawnArguments );
}
void CServerRPCHandler::VehicleEnterExit(CBitStream * pBitStream, CPlayerSocket senderSocket)
{
	CLogFile::Printf("Got VehicleEnterExit RPC from player %d", senderSocket.playerId);

	// Ensure we have a valid bitstream
	if(!pBitStream)
	{
		CLogFile::Printf("Warning: Invalid bitstream for VehicleEnterExit RPC");
		return;
	}

	// Get the player pointer
	CPlayer * pPlayer = g_pServer->GetPlayerManager()->Get(senderSocket.playerId);

	// Is the player pointer valid?
	if(pPlayer)
	{
		// Read the vehicle entry/exit type
		BYTE byteVehicleEntryExitType;

		if(!pBitStream->Read(byteVehicleEntryExitType))
			return;

		// Read the vehicle id
		EntityId vehicleId;

		if(!pBitStream->ReadCompressed(vehicleId))
			return;

		// Get the vehicle
		CVehicle * pVehicle = g_pServer->GetVehicleManager()->Get(vehicleId);

		// Does the vehicle not exist?
		if(!pVehicle)
			return;

		// Is this an entry request?
		if(byteVehicleEntryExitType == VEHICLE_ENTRY_REQUEST)
		{
			// Read the seat id
			BYTE byteSeatId;

			if(!pBitStream->Read(byteSeatId))
				return;

			// Get the reply
			CSquirrelArguments arguments;
			arguments.push(vehicleId);
			arguments.push(byteSeatId);
			bool bReply = pPlayer->CallEvent("vehicleEntryRequest", &arguments);

			// Reply to the vehicle entry request
			CBitStream bitStream;
			bitStream.WriteCompressed(senderSocket.playerId);
			bitStream.WriteBit(bReply);

			// Was the reply ok?
			if(bReply)
			{
				bitStream.Write((BYTE)VEHICLE_ENTRY_RETURN);
				bitStream.Write(vehicleId);
				bitStream.Write(byteSeatId);
				g_pServer->GetNetworkManager()->RPC(RPC_VEHICLE_ENTER_EXIT, &bitStream, PRIORITY_HIGH, RELIABILITY_RELIABLE, INVALID_ENTITY_ID, true);
			}
		}
		// Is this an entry cancellation?
		if(byteVehicleEntryExitType == VEHICLE_ENTRY_CANCELLED)
		{
			// Read the seat id
			BYTE byteSeatId;

			if(!pBitStream->Read(byteSeatId))
				return;

			// Call the event
			CSquirrelArguments arguments;
			arguments.push(vehicleId);
			arguments.push(byteSeatId);
			pPlayer->CallEvent("vehicleEntryCancelled", &arguments);

			CBitStream bitStream;
			bitStream.WriteCompressed(senderSocket.playerId);
			bitStream.WriteBit(true);
			bitStream.Write((BYTE)VEHICLE_ENTRY_CANCELLED);
			bitStream.Write(vehicleId);
			g_pServer->GetNetworkManager()->RPC(RPC_VEHICLE_ENTER_EXIT, &bitStream, PRIORITY_HIGH, RELIABILITY_RELIABLE, senderSocket.playerId, true);
		}
		// Is this an entry completion?
		else if(byteVehicleEntryExitType == VEHICLE_ENTRY_COMPLETE)
		{
			// Read the seat id
			BYTE byteSeatId;

			if(!pBitStream->Read(byteSeatId))
				return;

			// Call the event
			CSquirrelArguments arguments;
			arguments.push(vehicleId);
			arguments.push(byteSeatId);
			pPlayer->CallEvent("vehicleEntryComplete", &arguments);

			// Set the player vehicle and seat id
			pPlayer->SetVehicle(pVehicle);
			pPlayer->SetVehicleSeatId(byteSeatId);

			// Set the vehicle occupant
			pVehicle->SetOccupant(byteSeatId, pPlayer);
		}
		// Is this an exit request?
		else if(byteVehicleEntryExitType == VEHICLE_EXIT_REQUEST)
		{
			// Get the reply
			CSquirrelArguments arguments;
			arguments.push(vehicleId);
			bool bReply = pPlayer->CallEvent("vehicleExitRequest", &arguments);

			// Reply to the vehicle exit request
			CBitStream bitStream;
			bitStream.WriteCompressed(senderSocket.playerId);
			bitStream.WriteBit(bReply);

			// Was the reply ok?
			if(bReply)
			{
				bitStream.Write((BYTE)VEHICLE_EXIT_RETURN);
				bitStream.Write(vehicleId);
				g_pServer->GetNetworkManager()->RPC(RPC_VEHICLE_ENTER_EXIT, &bitStream, PRIORITY_HIGH, RELIABILITY_RELIABLE, INVALID_ENTITY_ID, true);
			}
		}
		// Is this an exit completion?
		else if(byteVehicleEntryExitType == VEHICLE_EXIT_COMPLETE)
		{
			// Call the event
			CSquirrelArguments arguments;
			arguments.push(vehicleId);
			arguments.push(pPlayer->GetVehicleSeatId());
			pPlayer->CallEvent("vehicleExitComplete", &arguments);

			// Reset the vehicle occupant
			pVehicle->SetOccupant(pPlayer->GetVehicleSeatId(), NULL);

			// Reset the player vehicle and seat id
			pPlayer->SetVehicle(NULL);
			pPlayer->SetVehicleSeatId(0);
		}
		// Is this a forceful exit?
		else if(byteVehicleEntryExitType == VEHICLE_EXIT_FORCEFUL)
		{
			// Call the event
			CSquirrelArguments arguments;
			arguments.push(vehicleId);
			arguments.push(pPlayer->GetVehicleSeatId());
			pPlayer->CallEvent("vehicleForcefulExit", &arguments);

			// Reset the vehicle occupant
			pVehicle->SetOccupant(pPlayer->GetVehicleSeatId(), NULL);

			// Reset the player vehicle and seat id
			pPlayer->SetVehicle(NULL);
			pPlayer->SetVehicleSeatId(0);
		}
	}
}
Beispiel #9
0
void CPickup::Use ( CPlayer& Player )
{
    // Call the onPickupUse event
    CLuaArguments Arguments;
    Arguments.PushElement ( &Player );
    if ( !CallEvent ( "onPickupUse", Arguments ) )
    {
        CLuaArguments Arguments2;
        Arguments2.PushElement ( this );      // pickup
        Player.CallEvent ( "onPlayerPickupUse", Arguments2 );
    }
    else
    {
        CLuaArguments Arguments2;
        Arguments2.PushElement ( this );      // pickup
        if ( Player.CallEvent ( "onPlayerPickupUse", Arguments2 ) )
        {
            // Tell all the other players to hide it if the respawn intervals are bigger than 0
            if ( m_ulRespawnIntervals > 0 )
            {
                // Save our last used time
                m_ulLastUsedTime = GetTime ();
                // Mark us as not spawned
                m_bSpawned = false;
        
                // Mark us as hidden
                SetVisible ( false );
            }
        
            // Tell him to play the sound and hide/show it
            Player.Send ( CPickupHitConfirmPacket ( this, true ) );
        
            // Tell everyone else to hide/show it as neccessary
            g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( CPickupHitConfirmPacket ( this, false ), &Player );
        
            // Handle it depending on the type
            switch ( m_ucType )
            {
                // Health pickup?
                case CPickup::HEALTH:
                {
                    float fHealth = Player.GetHealth ();
                    float fNewHealth = fHealth + m_fAmount;
                    if ( fNewHealth > 200.0f )
                        fNewHealth = 200.0f;

                    CStaticFunctionDefinitions::SetElementHealth ( &Player, fNewHealth );

                    break;
                }

                // Armor pickup?
                case CPickup::ARMOR:
                {
                    float fArmor = Player.GetArmor ();
                    float fNewArmor = fArmor + m_fAmount;
                    if ( fNewArmor > 100.0f )
                        fNewArmor = 100.0f;

                    CStaticFunctionDefinitions::SetPedArmor ( &Player, fNewArmor );

                    break;
                }

                // Weapon pickup?
                case CPickup::WEAPON:
                {
                    // Give him the weapon
                    CStaticFunctionDefinitions::GiveWeapon ( &Player, m_ucWeaponType, m_usAmmo );
                    break;
                }
                default: break;
            }
        }
    }
}