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()); } }
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; }
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; }
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; }
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; }
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); } } }
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; } } } }