Example #1
0
void CLocalPlayer::SendOnFootFullSyncData()
{
	if(m_pPlayerPed)
	{
		RakNet::BitStream bsPlayerSync;
		PLAYER_SYNC_DATA playerSyncData;

		// write packet id
		bsPlayerSync.Write((MessageID)ID_PLAYER_SYNC);

		// get the player keys
		playerSyncData.wKeys = m_pPlayerPed->GetKeys();

		// get the player position
		m_pPlayerPed->GetPosition(&playerSyncData.vecPos);

		// get the player rotation
		playerSyncData.fRotation = m_pPlayerPed->GetRotation();
		
		// get player current weapon (casted to a byte to save space)
		playerSyncData.byteCurrentWeapon = m_pPlayerPed->GetCurrentWeapon();
		
		// get player shooting flags
		playerSyncData.byteShootingFlags = m_pPlayerPed->GetShootingFlags();
		
		// get player health (casted to a byte to save space)
		playerSyncData.byteHealth = (BYTE)m_pPlayerPed->GetHealth();

		// get player armour (casted to a byte to save space)
		playerSyncData.byteArmour = (BYTE)m_pPlayerPed->GetArmour();

		// write player sync data struct
		bsPlayerSync.Write((char *)&playerSyncData, sizeof(PLAYER_SYNC_DATA));

		// send aiming data if player has fire key held down and we have ammo
		if(m_pPlayerPed->IsFiring() && m_pPlayerPed->HasAmmoForCurrentWeapon())
		{
			// write a 1 bit to say the bit stream has aim sync data
			bsPlayerSync.Write1();

			// get the camera pointer
			CAMERA_TYPE * pCamera = pGame->GetCamera()->GetCamera();

			// write the aim sync data
			bsPlayerSync.Write((char *)&pCamera->aim, sizeof(CAMERA_AIM));
		}
		else
		{
			// write a 0 bit to say the bit stream has no aim sync data
			bsPlayerSync.Write0();
		}

		// send sync data
		pNetowkManager->GetRakPeer()->Send(&bsPlayerSync,HIGH_PRIORITY,UNRELIABLE_SEQUENCED,0,UNASSIGNED_SYSTEM_ADDRESS,TRUE);
	}
}
Example #2
0
void CPlayer::BroadcastSyncData()
{
	RakNet::BitStream bsSync;
		
	if(m_byteUpdateFromNetwork == UPDATE_TYPE_FULL_ONFOOT)
	{
		PLAYER_SYNC_DATA playerSyncData;
		bsSync.Write((MessageID)ID_PLAYER_SYNC);
		bsSync.Write(m_bytePlayerID);
		playerSyncData.wKeys = m_wKeys;
		memcpy(&playerSyncData.vecPos, &m_vecPos, sizeof(Vector3));
		playerSyncData.fRotation = m_fRotation;
		playerSyncData.byteCurrentWeapon = m_byteCurrentWeapon;
		playerSyncData.byteShootingFlags = m_byteShootingFlags;
		playerSyncData.byteHealth = m_byteHealth;
		playerSyncData.byteArmour = m_byteArmour;
		bsSync.Write((char *)&playerSyncData, sizeof(PLAYER_SYNC_DATA));

		if(m_bHasAim)
		{
			bsSync.Write1();
			bsSync.Write((char *)&m_Aiming, sizeof(S_CAMERA_AIM));
			m_bHasAim = false;
		}
		else
		{
			bsSync.Write0();
		}
		
		pNetowkManager->BroadcastData(&bsSync,HIGH_PRIORITY,UNRELIABLE_SEQUENCED,0,m_bytePlayerID);
	}
	else if(m_byteUpdateFromNetwork == UPDATE_TYPE_FULL_INCAR)
	{
		VEHICLE_SYNC_DATA vehicleSyncData;
		bsSync.Write((MessageID)ID_VEHICLE_SYNC);
		bsSync.Write(m_bytePlayerID);
		vehicleSyncData.vehicleID = m_vehicleID;
		vehicleSyncData.wKeys = m_wKeys;
		memcpy(&vehicleSyncData.vecRoll, &m_vecRoll, sizeof(Vector3));
		memcpy(&vehicleSyncData.vecDirection, &m_vecDirection, sizeof(Vector3));
		memcpy(&vehicleSyncData.vecPos, &m_vecPos, sizeof(Vector3));
		memcpy(&vehicleSyncData.vecMoveSpeed, &m_vecMoveSpeed, sizeof(Vector3));
		memcpy(&vehicleSyncData.vecTurnSpeed, &m_vecTurnSpeed, sizeof(Vector3));
		vehicleSyncData.byteVehicleHealth = PACK_VEHICLE_HEALTH(m_fVehicleHealth);
		vehicleSyncData.bytePlayerHealth = m_byteHealth;
		vehicleSyncData.bytePlayerArmour = m_byteArmour;
		bsSync.Write((char *)&vehicleSyncData, sizeof(VEHICLE_SYNC_DATA));

		pNetowkManager->BroadcastData(&bsSync,HIGH_PRIORITY,UNRELIABLE_SEQUENCED,0,m_bytePlayerID);
	}	
}
Example #3
0
void NetworkEngine::updatePingResponse()
{
	RakNet::BitStream data;

	if(isLobby())
	{
		data.Write1();
		unsigned char numPlayers = (unsigned char) peer->NumberOfConnections();
		data.Write(numPlayers);
		std::cout << "Total players: " << (unsigned int) numPlayers << std::endl;
		peer->SetOfflinePingResponse((char *)data.GetData(), data.GetNumberOfBytesUsed());
	} else
	{
		data.Write0();
	}

	peer->SetOfflinePingResponse((char *)data.GetData(), data.GetNumberOfBytesUsed());
}
Example #4
0
	void NetworkManager::sendMessage(const short id, const char *data, const short len, Client *destination)
	{
		RakNet::BitStream bs;
		bs.Write(id);
		if (data && len > 0) {
			bs.Write(len);
			bs.Write(data,len);
		} else
			bs.Write((short)0);
		SystemAddress recipient;
		if (destination) {
			recipient = destination->getSystemAddress();
			bs.Write1();
		} else {
			recipient = UNASSIGNED_SYSTEM_ADDRESS;
			bs.Write0();
		}
		rakPeer->RPC("NetworkManager::RPC_Message",&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, recipient, (destination ? false : true), 0, UNASSIGNED_NETWORK_ID,0);
	}
// Given a frequency table of 256 elements, all with a frequency of 1 or more, generate the tree
void HuffmanEncodingTree::GenerateFromFrequencyTable( unsigned int frequencyTable[ 256 ] )
{
	int counter;
	HuffmanEncodingTreeNode * node;
	HuffmanEncodingTreeNode *leafList[ 256 ]; // Keep a copy of the pointers to all the leaves so we can generate the encryption table bottom-up, which is easier
	// 1.  Make 256 trees each with a weight equal to the frequency of the corresponding character
	DataStructures::LinkedList<HuffmanEncodingTreeNode *> huffmanEncodingTreeNodeList;
	
	FreeMemory();
	
	for ( counter = 0; counter < 256; counter++ )
	{
		node = new HuffmanEncodingTreeNode;
		node->left = 0;
		node->right = 0;
		node->value = (unsigned char) counter;
		node->weight = frequencyTable[ counter ];
		
		if ( node->weight == 0 )
			node->weight = 1; // 0 weights are illegal
			
		leafList[ counter ] = node; // Used later to generate the encryption table
		
		InsertNodeIntoSortedList( node, &huffmanEncodingTreeNodeList ); // Insert and maintain sort order.
	}
	
	
	// 2.  While there is more than one tree, take the two smallest trees and merge them so that the two trees are the left and right
	// children of a new node, where the new node has the weight the sum of the weight of the left and right child nodes.
#ifdef _MSC_VER
#pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
#endif
	while ( 1 )
	{
		huffmanEncodingTreeNodeList.Beginning();
		HuffmanEncodingTreeNode *lesser, *greater;
		lesser = huffmanEncodingTreeNodeList.Pop();
		greater = huffmanEncodingTreeNodeList.Pop();
		node = new HuffmanEncodingTreeNode;
		node->left = lesser;
		node->right = greater;
		node->weight = lesser->weight + greater->weight;
		lesser->parent = node;  // This is done to make generating the encryption table easier
		greater->parent = node;  // This is done to make generating the encryption table easier
		
		if ( huffmanEncodingTreeNodeList.Size() == 0 )
		{
			// 3. Assign the one remaining node in the list to the root node.
			root = node;
			root->parent = 0;
			break;
		}
		
		// Put the new node back into the list at the correct spot to maintain the sort.  Linear search time
		InsertNodeIntoSortedList( node, &huffmanEncodingTreeNodeList );
	}
	
	bool tempPath[ 256 ]; // Maximum path length is 256
	unsigned short tempPathLength;
	HuffmanEncodingTreeNode *currentNode;
	RakNet::BitStream bitStream;
	
	// Generate the encryption table. From before, we have an array of pointers to all the leaves which contain pointers to their parents.
	// This can be done more efficiently but this isn't bad and it's way easier to program and debug
	
	for ( counter = 0; counter < 256; counter++ )
	{
		// Already done at the end of the loop and before it!
		tempPathLength = 0;
		
		// Set the current node at the leaf
		currentNode = leafList[ counter ];
		
		do
		{
			if ( currentNode->parent->left == currentNode )   // We're storing the paths in reverse order.since we are going from the leaf to the root
				tempPath[ tempPathLength++ ] = false;
			else
				tempPath[ tempPathLength++ ] = true;
				
			currentNode = currentNode->parent;
		}
		
		while ( currentNode != root );
		
		// Write to the bitstream in the reverse order that we stored the path, which gives us the correct order from the root to the leaf
		while ( tempPathLength-- > 0 )
		{
			if ( tempPath[ tempPathLength ] )   // Write 1's and 0's because writing a bool will write the BitStream TYPE_CHECKING validation bits if that is defined along with the actual data bit, which is not what we want
				bitStream.Write1();
			else
				bitStream.Write0();
		}
		
		// Read data from the bitstream, which is written to the encoding table in bits and bitlength. Note this function allocates the encodingTable[counter].encoding pointer
		encodingTable[ counter ].bitLength = ( unsigned char ) bitStream.CopyData( &encodingTable[ counter ].encoding );
		
		// Reset the bitstream for the next iteration
		bitStream.Reset();
	}
}
Example #6
0
void CChat::ProcessInput( void )
{
	// Are we not connected?
	if( !pCore->GetNetworkModule() || !pCore->GetNetworkModule()->IsConnected() )
		return;

	// Was anything entered?
	if( m_strInput.GetLength() > 0 )
	{
		// Is the input a command?
		bool bIsCommand = (m_strInput.GetChar( 0 ) == CHAT_CMD_CHAR);

		// Internal cmds
		bool bHasUsedCmd = false;

		// Process internal commands
		if( bIsCommand )
		{
			//
			std::string sInput = m_strInput.Get();

			// Get the end of the command
			size_t sCommandEnd = sInput.find( " " );

			// If we don't have a valid end use the end of the string
			if ( sCommandEnd == std::string::npos )
				sCommandEnd = sInput.length();

			// Get the command name
			std::string strCommand = sInput.substr( 1, (sCommandEnd - 1) );

			// Get the command parameters
			std::string strParams;

			// Do we have any parameters?
			if( sCommandEnd < sInput.length() )
				strParams = sInput.substr( (sCommandEnd + 1), sInput.length() );

			if( strCommand == "q" || strCommand == "quit" || strCommand == "exit" )
			{
				// Shutdown
				pCore->Shutdown();
				return;
			}
			else if( strCommand == "disconnect" )
			{
				// Are we connected?
				if( pCore->GetNetworkModule() && pCore->GetNetworkModule()->IsConnected() )
				{
					// Disconnect from the network
					pCore->GetNetworkModule()->Disconnect();

					// Stop multiplayer
					pCore->StopMultiplayer();

					// Go back to main menu
					pCore->GetGUI()->GetMainMenu()->SetVisible( true );
				}

				bHasUsedCmd = true;
			}
			else if( strCommand == "savepos" )
			{
				bHasUsedCmd = true;

				// Are we spawned?
				if( pCore->GetPlayerManager()->GetLocalPlayer()->IsSpawned() )
				{
					//
					CVector3 vecPosition;
					CVector3 vecRotation;
					bool bOnFoot = true;

					// Is the player on-foot?
					if( pCore->GetPlayerManager()->GetLocalPlayer()->GetState() == ePlayerState::PLAYERSTATE_ONFOOT )
					{
						// Get the localplayer position
						pCore->GetPlayerManager()->GetLocalPlayer()->GetPosition( &vecPosition );

						// Get the localplayer rotation
						pCore->GetPlayerManager()->GetLocalPlayer()->GetRotation( &vecRotation );
					}
					else if( pCore->GetPlayerManager()->GetLocalPlayer()->GetState() == ePlayerState::PLAYERSTATE_DRIVER || pCore->GetPlayerManager()->GetLocalPlayer()->GetState() == ePlayerState::PLAYERSTATE_PASSENGER )
					{
						// Get the vehicle position
						pCore->GetPlayerManager()->GetLocalPlayer()->GetVehicle()->GetPosition( &vecPosition );

						// Get the vehicle rotation
						pCore->GetPlayerManager()->GetLocalPlayer()->GetVehicle()->GetRotation( &vecRotation );

						//
						bOnFoot = false;
					}

					// Open the saved positions file
					FILE * pFile = fopen( SharedUtility::GetAbsolutePath( "data\\savedpositions.txt" ).Get(), "a" );

					// Did the file open?
					if( pFile )
					{
						// Get the localplayer pointer
						CLocalPlayer * pLocalPlayer = pCore->GetPlayerManager()->GetLocalPlayer();

						// Save the player position
						fprintf( pFile, "%d, %f, %f, %f, %f, %f, %f // %s\n", (bOnFoot ? pLocalPlayer->GetModel () : pLocalPlayer->GetVehicle()->GetModel ()), vecPosition.fX, vecPosition.fY, vecPosition.fZ, vecRotation.fX, vecRotation.fY, vecRotation.fZ, strParams.c_str() );

						// Close the saved positions file
						fclose( pFile );

						//
						AddInfoMessage( (bOnFoot ? " -> Onfoot position saved!" : " -> Invehicle position saved!") );
					}
					else
					{
						//
						AddInfoMessage( CColor( 255, 0, 0, 255 ), "Failed to open savedpositions.txt" );
					}
				}
			}
#ifdef DEBUG
			else if( strCommand == "lua" )
			{
				bHasUsedCmd = true;

				if( CLua::Execute( strParams.c_str() ) )
					AddInfoMessage( CColor( 50, 177, 94, 255 ), strParams.c_str() );
				else
					AddInfoMessage( CColor( 178, 40, 86, 255 ), strParams.c_str() );
			}
#endif
		}

		// Have we used a command?
		if( bHasUsedCmd )
		{
			// Add this command to the history
			AddToHistory();

			// This is an internal command, don't pass it to the server!
			return;
		}

		// Is the network module instance valid?
		if( pCore->GetNetworkModule() )
		{
			// Are we connected?
			if( pCore->GetNetworkModule()->IsConnected() )
			{
				RakNet::BitStream bitStream;
				RakNet::RakString strInput;

				// Is this a command?
				if( bIsCommand )
				{
					// Write 1
					bitStream.Write1();

					// Set the input minus the command character
					strInput = (GetInputText() + 1);
				}
				else
				{
					// Write 0
					bitStream.Write0();

					// Set the input
					strInput = GetInputText();
				}

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

				// Call the client event
				CSquirrelArguments pArguments;
				pArguments.push( strInput.C_String () );

				// Should we send this message?
				if ( pCore->GetClientScriptingManager()->GetEvents()->Call( "onClientChat", &pArguments ).GetInteger() == 1 )
				{
					// Send it to the server
					pCore->GetNetworkModule()->Call( RPC_PLAYER_CHAT, &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, true );

					// Add this message to the history
					AddToHistory();

					// Add the chat message for the localplayer if it's not a command
					if ( !bIsCommand )
						AddChatMessage( pCore->GetPlayerManager()->GetLocalPlayer(), GetInputText() );
				}
			}
		}
	}
}
Example #7
0
	void PlayerManager::HandlePacket(RakNet::Packet *packet)
	{
		RakNet::BitStream receivedData(packet->data, packet->length, false);

		RakNetwork *network = m_Network;
		RakNetGUID remotePeerGUID = packet->guid;

		unsigned char type;
		receivedData.Read(type);
		if (type == ID_NEW_INCOMING_CONNECTION)
		{
			// Notify new peers about the existing players
			if (NetworkManager::ArbitratorIsLocal())
			{
				for (auto it = PlayerRegistry::PlayersBegin(), end = PlayerRegistry::PlayersEnd(); it != end; ++it)
				{
					RakNet::BitStream newPlayerNotification;
					newPlayerNotification.Write0(); // Tell the peer that the player is on another system
					newPlayerNotification.Write(it->NetID);
					if (it->LocalIndex >= s_MaxLocalPlayers)
						newPlayerNotification.Write(it->GUID); // Remote player (relative to this arbitrator)
					else
						newPlayerNotification.Write(NetworkManager::GetNetwork()->GetLocalGUID()); // Local player
					network->Send(
						NetDestination(remotePeerGUID, false),
						!Timestamped,
						MTID_ADDPLAYER, &newPlayerNotification,
						MEDIUM_PRIORITY, RELIABLE_ORDERED, CID_SYSTEM);
				}
			}
		}
		else if (type == MTID_ADDPLAYER)
		{
			if (NetworkManager::ArbitratorIsLocal())
			{
				// So we can tell the remote peer what requested player we are adding:
				unsigned int remotePlayerIndex;
				receivedData.Read(remotePlayerIndex);

				PlayerID netId = m_NextNetId++;//m_UnusedNetIds.getFreeID();
				PlayerRegistry::AddRemotePlayer(netId, remotePeerGUID);

				{
					RakNet::BitStream response;
					response.Write1(); // Tell the peer that the player being added is on their system
					response.Write(netId);
					response.Write(remotePlayerIndex);
					network->Send(
						NetDestination(remotePeerGUID, false),
						!Timestamped,
						MTID_ADDPLAYER, &response,
						MEDIUM_PRIORITY, RELIABLE_ORDERED, CID_SYSTEM);
				}
				{
					RakNet::BitStream newPlayerNotification;
					newPlayerNotification.Write0(); // Tell the peer that the player being added is on another system
					newPlayerNotification.Write(netId);
					newPlayerNotification.Write(remotePeerGUID);
					network->Send(
						NetDestination(remotePeerGUID, true), // Broadcast
						!Timestamped,
						MTID_ADDPLAYER, &newPlayerNotification,
						MEDIUM_PRIORITY, RELIABLE_ORDERED, CID_SYSTEM);
				}
			}
			else
			{
				bool localPlayer = receivedData.ReadBit();
				// The net ID the arbiter has assigned to the new player:
				PlayerID netId;
				receivedData.Read(netId);

				if (localPlayer)
				{
					unsigned int localIndex;
					receivedData.Read(localIndex);
					PlayerRegistry::AddLocalPlayer(netId, localIndex);
				}
				else
				{
					RakNetGUID guid;
					receivedData.Read(guid);
					PlayerRegistry::AddRemotePlayer(netId, guid);
				}
			}
		}

		else if (type == MTID_REMOVEPLAYER)
		{
			PlayerID netId;
			receivedData.Read(netId);

			PlayerRegistry::RemovePlayer(netId);
		}
	}
Example #8
0
void CLocalPlayer::OnLeaveVehicle( void )
{
	// Set the player state
	SetState( PLAYERSTATE_ONFOOT );

	// Is the vehicle instance valid?
	if( m_pVehicle )
	{
		// Get the seat of this player
		EntityId seat = m_seat;

		// Construct a new bitstream
		RakNet::BitStream pBitStream;

		// Write the vehicle id
		pBitStream.WriteCompressed( m_pVehicle->GetId() );

		// Write the seat
		pBitStream.WriteCompressed( seat );

		// Write if we're exiting quickly!
		m_bFastExitVehicle ? pBitStream.Write1() : pBitStream.Write0();

		// Send to the server
		pCore->GetNetworkModule()->Call( RPC_EXIT_VEHICLE, &pBitStream, HIGH_PRIORITY, RELIABLE_ORDERED, true );

#ifdef DEBUG
		pCore->GetChat()->AddDebugMessage( "CLocalPlayer::OnExitVehicle( %d, %d ) - Forcefully: %s", m_pVehicle->GetId(), seat, (IsBeingRemovedForcefully () ? "Yes" : "No") );
#endif

		// Are we not being removed forcefully?
		if ( !IsBeingRemovedForcefully () )
		{
			// Handle this enter with the network vehicle
			m_pVehicle->HandlePlayerExit( this, seat, false );

			// Do we need to respawn this vehicle? (Set to true when vehicle enters water)
			if( bRespawnVehicle && m_seat == 0 )
			{
				// Respawn the vehicle
				m_pVehicle->Respawn();

				// 
				bRespawnVehicle = false;
			}

			// Are we a passenger?
			if( m_seat > 0 )
			{
				// Restore the player controls
				LockControls( bOldControlState );

				// Restore the camera lock state
				pCore->GetCamera()->LockControl( bOldCameraState );

				//
				*(DWORD *)(m_pPlayerPed->GetPed() + 0x310) = 6;
			}
		}

		// Reset the vehicle
		SetVehicle( NULL );

		// Reset the seat
		SetSeat( INVALID_ENTITY_ID );

		// Reset the target data
		SetEnteringVehicle( NULL, INVALID_ENTITY_ID );

		// Reset the fast vehicle exit flag
		FlagForFastExitVehicle ( false );

		// Reset the forceful exit flag
		SetRemoveForcefully ( false );
	}
}