예제 #1
0
void sendPickUp(int iPickupID)
{
	RakNet::BitStream bsSend;
	bsSend.Write(iPickupID);
	pRakClient->RPC(&RPC_PickedUpPickup, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE, UNASSIGNED_NETWORK_ID, NULL);
}
예제 #2
0
파일: CChat.cpp 프로젝트: DarkKlo/maf2mp
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() );
				}
			}
		}
	}
}
예제 #3
0
void AutoRPC::OnAutoRPCCall(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes)
{
	RakNet::BitStream bs(data,lengthInBytes,false);

	bool hasParameterCount=false;
	char parameterCount;
	char inputStack[ARPC_MAX_STACK_SIZE];
	NetworkIDObject *networkIdObject;
	NetworkID networkId;
	bool hasNetworkId=false;
	bool hasFunctionIndex=false;
	unsigned int functionIndex;
	unsigned int bytesOnStack;
	char strIdentifier[512];
	int numberOfBitsUsed;
	incomingExtraData.Reset();
	bs.Read(hasParameterCount);
	if (hasParameterCount)
		bs.Read(parameterCount);
	else
		parameterCount=-1;
	bs.ReadCompressed(numberOfBitsUsed);
	if (numberOfBitsUsed > (int) incomingExtraData.GetNumberOfBitsAllocated())
		incomingExtraData.AddBitsAndReallocate(numberOfBitsUsed-(int) incomingExtraData.GetNumberOfBitsAllocated());
	bs.ReadBits(incomingExtraData.GetData(), numberOfBitsUsed, false);
	incomingExtraData.SetWriteOffset(numberOfBitsUsed);


//	const unsigned int outputStackSize = ARPC_MAX_STACK_SIZE+128*4; // Enough padding to round up to 4 for each parameter, max 128 parameters
//	char outputStack[outputStackSize];

	bs.Read(hasNetworkId);
	if (hasNetworkId)
	{
		bs.Read(networkId);
		if (networkIdManager==0 && (networkIdManager=rakPeerInterface->GetNetworkIDManager())==0)
		{
			// Failed - Tried to call object member, however, networkIDManager system was never registered
			SendError(systemAddress, RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE, "");
			return;
		}
		networkIdObject = networkIdManager->GET_OBJECT_FROM_ID<NetworkIDObject*>(networkId);
		if (networkIdObject==0)
		{
			// Failed - Tried to call object member, object does not exist (deleted?)
			SendError(systemAddress, RPC_ERROR_OBJECT_DOES_NOT_EXIST, "");
			return;
		}
	}
	else
	{
		networkIdObject=0;
	}
	bs.AlignReadToByteBoundary();
	bs.Read(hasFunctionIndex);
	if (hasFunctionIndex)
		bs.ReadCompressed(functionIndex);
	else
		stringCompressor->DecodeString(strIdentifier,512,&bs,0);
	bs.ReadCompressed(bytesOnStack);
	bs.ReadAlignedBytes((unsigned char *) inputStack,bytesOnStack);
	if (hasFunctionIndex)
	{
		if (functionIndex>localFunctions.Size())
		{
			// Failed - other system specified a totally invalid index
			// Possible causes: Bugs, attempts to crash the system, requested function not registered
			SendError(systemAddress, RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE, "");
			return;
		}
		// it was actually a mistake to implement ID_AUTO_RPC_UNKNOWN_REMOTE_INDEX. This hides the more relevant return code RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED and more importantly can result in the calls being out of order since it takes extra communication steps.
		/*
		if (localFunctions[functionIndex].functionPtr==0)
		{
			// Failed - Function index lookup failure. Try passing back what was sent to us, and requesting the string
			RakNet::BitStream out;
			if (incomingTimeStamp!=0)
			{
				out.Write((MessageID)ID_TIMESTAMP);
				out.Write(incomingTimeStamp);
			}
			out.Write((MessageID)ID_AUTO_RPC_UNKNOWN_REMOTE_INDEX);
			if (parameterCount>=0)
			{
				out.Write(true);
				out.Write(parameterCount);
			}
			else
			{
				out.Write(false);
			}
			out.WriteCompressed(functionIndex);
			out.WriteCompressed(numberOfBitsUsed);
			out.Write(&incomingExtraData);
			out.Write(hasNetworkId);
			if (hasNetworkId)
				out.Write(networkId);
			out.WriteCompressed(bytesOnStack);
			out.WriteAlignedBytes((const unsigned char*) inputStack, bytesOnStack);
			SendUnified(&out, HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false);
			
			return;
		}
		*/
	}
	else
	{
		// Find the registered function with this str
		for (functionIndex=0; functionIndex < localFunctions.Size(); functionIndex++)
		{
			if (localFunctions[functionIndex].identifier.isObjectMember == (networkIdObject!=0) &&
				strcmp(localFunctions[functionIndex].identifier.uniqueIdentifier, strIdentifier)==0)
			{
				// SEND RPC MAPPING
				RakNet::BitStream outgoingBitstream;
				outgoingBitstream.Write((MessageID)ID_AUTO_RPC_REMOTE_INDEX);
				outgoingBitstream.Write(hasNetworkId);
				outgoingBitstream.WriteCompressed(functionIndex);
				stringCompressor->EncodeString(strIdentifier,512,&outgoingBitstream,0);
				SendUnified(&outgoingBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false);
				break;
			}
		}

		if (functionIndex==localFunctions.Size())
		{
			for (functionIndex=0; functionIndex < localFunctions.Size(); functionIndex++)
			{
				if (strcmp(localFunctions[functionIndex].identifier.uniqueIdentifier, strIdentifier)==0)
				{
					if (localFunctions[functionIndex].identifier.isObjectMember==true && networkIdObject==0)
					{
						// Failed - Calling C++ function as C function
						SendError(systemAddress, RPC_ERROR_CALLING_CPP_AS_C, strIdentifier);
						return;
					}

					if (localFunctions[functionIndex].identifier.isObjectMember==false && networkIdObject!=0)
					{
						// Failed - Calling C++ function as C function
						SendError(systemAddress, RPC_ERROR_CALLING_C_AS_CPP, strIdentifier);
						return;
					}
				}
			}

			SendError(systemAddress, RPC_ERROR_FUNCTION_NOT_REGISTERED, strIdentifier);
			return;
		}
	}

	if (localFunctions[functionIndex].functionPtr==0)
	{
		// Failed - Function was previously registered, but isn't registered any longer
		SendError(systemAddress, RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED, localFunctions[functionIndex].identifier.uniqueIdentifier);
		return;
	}

	if (bytesOnStack > ARPC_MAX_STACK_SIZE)
	{
		// Failed - Not enough bytes on predetermined stack. Shouldn't hit this since the sender also uses this value
		SendError(systemAddress, RPC_ERROR_STACK_TOO_SMALL, localFunctions[functionIndex].identifier.uniqueIdentifier);
		return;
	}

	if (localFunctions[functionIndex].parameterCount>=0 && parameterCount>=0 && parameterCount!=localFunctions[functionIndex].parameterCount)
	{
		// Failed - The number of parameters that this function has was explicitly specified, and does not match up.
		SendError(systemAddress, RPC_ERROR_INCORRECT_NUMBER_OF_PARAMETERS, localFunctions[functionIndex].identifier.uniqueIdentifier);
		return;
	}

	
//	unsigned int bytesWritten;
//	unsigned char numParameters;
//	unsigned int parameterLengths[64]; // 64 is arbitrary, just needs to be more than whatever might be serialized


	GenRPC::CallParams call;

	if (DeserializeParametersAndBuildCall(call, inputStack, bytesOnStack, this, networkIdObject)==false)
	{
		// Failed - Couldn't deserialize
		SendError(systemAddress, RPC_ERROR_STACK_DESERIALIZATION_FAILED, localFunctions[functionIndex].identifier.uniqueIdentifier);
		return;
	}

	strncpy(currentExecution, localFunctions[functionIndex].identifier.uniqueIdentifier, sizeof(currentExecution)-1);

	if (!CallWithStack( call, localFunctions[functionIndex].functionPtr)){
		// Failed - Couldn't deserialize
		SendError(systemAddress, RPC_ERROR_STACK_DESERIALIZATION_FAILED, currentExecution);
		return;
	}


	currentExecution[0]=0;
}
예제 #4
0
void InitialData(RakNet::BitStream * pBitStream, RakNet::Packet * pPacket)
{
	// Get the playerid
	EntityId playerId = (EntityId) pPacket->guid.systemIndex;

	// Read the player version
	DWORD dwVersion;
	pBitStream->Read(dwVersion);

	// Read the player name
	RakNet::RakString _strName;
	pBitStream->Read(_strName);
	CString strName(_strName.C_String());

	// Read the player serial
	RakNet::RakString _strSerial;
	pBitStream->Read(_strSerial);
	CString strSerial(_strSerial.C_String());

	// Is the network version invalid?
	if (dwVersion != (DWORD)/*NETWORK_VERSION*/0x0)
	{
		// TODO
	}

	// Is the nickname already in use?
	// TODO: check is nick in use

	// Is the player banned?
	// TODO: check is banned

	// Add the player to the manager
	// TODO: add to player manager
	CPlayerEntity * pPlayer = new CPlayerEntity();

	pPlayer->SetName(strName);

	// Do we need the id; maybe internal for easier sync but definetly not public to the scripting engine
	pPlayer->SetId(CServer::GetInstance()->GetPlayerManager()->Add(pPlayer));
	playerId = pPlayer->GetId();
	srand(time(NULL));
	pPlayer->SetColor(CColor(rand() % 256, rand() % 256, rand() % 256).dwHexColor); //generate random color

	CLogFile::Printf("[join] %s (%i) has connected to the server. (%s)", strName.Get(), playerId, strSerial.Get());

	CScriptArguments args;
	CScriptPlayer * pScriptPlayer = new CScriptPlayer();
	pScriptPlayer->SetEntity(pPlayer);
	pPlayer->SetScriptPlayer(pScriptPlayer);
	args.push(pScriptPlayer);
	CEvents::GetInstance()->Call("playerJoin", &args, CEventHandler::eEventType::NATIVE_EVENT, 0);

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

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

	// Write the player colour
	bitStream.Write(pPlayer->GetColor());

	// Write the server name
	bitStream.Write(RakNet::RakString("IV:Network DEV Server"));

	// Write the max player count
	bitStream.Write(CVAR_GET_INTEGER("maxplayers"));

	// Write the port
	bitStream.Write(CVAR_GET_INTEGER("port"));

	// Send it back to the player
	CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_INITIAL_DATA), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false);

	for (EntityId i = 0; i < CServer::GetInstance()->GetPlayerManager()->GetMax(); ++i)
	{
		if (CServer::GetInstance()->GetPlayerManager()->DoesExists(i) && i != playerId)
		{
			bitStream.Reset();
			bitStream.Write(i);
			bitStream.Write(CServer::GetInstance()->GetPlayerManager()->GetAt(i)->GetName().Get());
			bitStream.Write(CServer::GetInstance()->GetPlayerManager()->GetAt(i)->GetColor());
			CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_NEW_PLAYER), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false);
		}
	}

	for (EntityId i = 0; i < CServer::GetInstance()->GetPlayerManager()->GetMax(); ++i)
	{
		if (CServer::GetInstance()->GetPlayerManager()->DoesExists(i) && i != playerId)
		{
			bitStream.Reset();
			bitStream.Write(playerId);
			bitStream.Write(pPlayer->GetName().Get());
			bitStream.Write(pPlayer->GetColor());
			CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_NEW_PLAYER), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, i, false);
		}
	}


	for (EntityId i = 0; i < CServer::GetInstance()->GetVehicleManager()->GetMax(); ++i)
	{
		if (CServer::GetInstance()->GetVehicleManager()->DoesExists(i))
		{
			bitStream.Reset();
			CVehicleEntity * pVehicle = CServer::GetInstance()->GetVehicleManager()->GetAt(i);
			bitStream.Write(pVehicle->GetId());
			bitStream.Write(pVehicle->GetModelId());

			CVector3 vecPosition;
			pVehicle->GetPosition(vecPosition);
			bitStream.Write(vecPosition);

			CVector3 vecRotation;
			pVehicle->GetRotation(vecRotation);
			bitStream.Write(vecRotation.fX);

			bitStream.Write(pVehicle->GetColor(1));
			bitStream.Write(pVehicle->GetColor(2));
			bitStream.Write(pVehicle->GetColor(3));
			bitStream.Write(pVehicle->GetColor(4));
			bitStream.Write(pVehicle->GetColor(5));

			CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_CREATE_VEHICLE), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false);
		}
	}

	bitStream.Reset();

	bitStream.Write(playerId);
	bitStream.Write(7);
	bitStream.Write(3);
	bitStream.Write(3);
	bitStream.Write(1);
}
예제 #5
0
void NatTypeDetectionServer::Update(void)
{
	int i=0;
	RakNet::TimeMS time = RakNet::GetTimeMS();
	RakNet::BitStream bs;
	SystemAddress boundAddress;

	RNS2RecvStruct *recvStruct;
	bufferedPacketsMutex.Lock();
	if (bufferedPackets.Size()>0)
		recvStruct=bufferedPackets.Pop();
	else
		recvStruct=0;
	bufferedPacketsMutex.Unlock();
	while (recvStruct)
	{
		SystemAddress senderAddr = recvStruct->systemAddress;
		char *data = recvStruct->data;
		if (data[0]==NAT_TYPE_PORT_RESTRICTED && recvStruct->socket==s3p4)
		{
			RakNet::BitStream bsIn((unsigned char*) data,recvStruct->bytesRead,false);
			RakNetGUID senderGuid;
			bsIn.IgnoreBytes(sizeof(MessageID));
			bool readSuccess = bsIn.Read(senderGuid);
			RakAssert(readSuccess);
			if (readSuccess)
			{
				unsigned int i = GetDetectionAttemptIndex(senderGuid);
				if (i!=(unsigned int)-1)
				{
					bs.Reset();
					bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT);
					// If different, then symmetric
					if (senderAddr!=natDetectionAttempts[i].systemAddress)
					{

#ifdef NTDS_VERBOSE
						printf("Determined client is symmetric\n");
#endif
						bs.Write((unsigned char) NAT_TYPE_SYMMETRIC);
					}
					else
					{
						// else port restricted
#ifdef NTDS_VERBOSE

						printf("Determined client is port restricted\n");
#endif
						bs.Write((unsigned char) NAT_TYPE_PORT_RESTRICTED);
					}

					rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false);

					// Done
					natDetectionAttempts.RemoveAtIndexFast(i);
				}
				else
				{
					//		RakAssert("i==0 in Update when looking up GUID in NatTypeDetectionServer.cpp. Either a bug or a late resend" && 0);
				}
			}
			else
			{
				//	RakAssert("Didn't read GUID in Update in NatTypeDetectionServer.cpp. Message format error" && 0);
			}
		}

		DeallocRNS2RecvStruct(recvStruct, _FILE_AND_LINE_);
		bufferedPacketsMutex.Lock();
		if (bufferedPackets.Size()>0)
			recvStruct=bufferedPackets.Pop();
		else
			recvStruct=0;
		bufferedPacketsMutex.Unlock();
	}

	/*

	// Only socket that receives messages is s3p4, to see if the external address is different than that of the connection to rakPeerInterface
	char data[ MAXIMUM_MTU_SIZE ];
	int len;
	SystemAddress senderAddr;
	len=NatTypeRecvFrom(data, s3p4, senderAddr);
	// Client is asking us if this is port restricted. Only client requests of this type come in on s3p4
	while (len>0 && data[0]==NAT_TYPE_PORT_RESTRICTED)
	{
		RakNet::BitStream bsIn((unsigned char*) data,len,false);
		RakNetGUID senderGuid;
		bsIn.IgnoreBytes(sizeof(MessageID));
		bool readSuccess = bsIn.Read(senderGuid);
		RakAssert(readSuccess);
		if (readSuccess)
		{
			unsigned int i = GetDetectionAttemptIndex(senderGuid);
			if (i!=(unsigned int)-1)
			{
				bs.Reset();
				bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT);
				// If different, then symmetric
				if (senderAddr!=natDetectionAttempts[i].systemAddress)
				{

				#ifdef NTDS_VERBOSE
					printf("Determined client is symmetric\n");
				#endif
					bs.Write((unsigned char) NAT_TYPE_SYMMETRIC);
				}
				else
				{
					// else port restricted

					#ifdef NTDS_VERBOSE
					printf("Determined client is port restricted\n");
					#endif
					bs.Write((unsigned char) NAT_TYPE_PORT_RESTRICTED);
				}

				rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false);

				// Done
				natDetectionAttempts.RemoveAtIndexFast(i);
			}
			else
			{
		//		RakAssert("i==0 in Update when looking up GUID in NatTypeDetectionServer.cpp. Either a bug or a late resend" && 0);
			}
		}
		else
		{
		//	RakAssert("Didn't read GUID in Update in NatTypeDetectionServer.cpp. Message format error" && 0);
		}

		len=NatTypeRecvFrom(data, s3p4, senderAddr);
	}
	*/


	while (i < (int) natDetectionAttempts.Size())
	{
		if (time > natDetectionAttempts[i].nextStateTime)
		{
			RNS2_SendParameters bsp;
			natDetectionAttempts[i].detectionState=(NATDetectionState)((int)natDetectionAttempts[i].detectionState+1);
			natDetectionAttempts[i].nextStateTime=time+natDetectionAttempts[i].timeBetweenAttempts;
			SystemAddress saOut;
			unsigned char c;
			bs.Reset();
			switch (natDetectionAttempts[i].detectionState)
			{
			case STATE_TESTING_NONE_1:
			case STATE_TESTING_NONE_2:
				c = NAT_TYPE_NONE;

#ifdef NTDS_VERBOSE
				printf("Testing NAT_TYPE_NONE\n");
#endif
				// S4P5 sends to C2. If arrived, no NAT. Done. (Else S4P5 potentially banned, do not use again).
				saOut=natDetectionAttempts[i].systemAddress;
				saOut.SetPortHostOrder(natDetectionAttempts[i].c2Port);
				// SocketLayer::SendTo_PC( s4p5, (const char*) &c, 1, saOut, __FILE__, __LINE__  );
				bsp.data = (char*) &c;
				bsp.length = 1;
				bsp.systemAddress = saOut;
				s4p5->Send(&bsp, _FILE_AND_LINE_);
				break;
			case STATE_TESTING_FULL_CONE_1:
			case STATE_TESTING_FULL_CONE_2:

#ifdef NTDS_VERBOSE
				printf("Testing NAT_TYPE_FULL_CONE\n");
#endif
				rakPeerInterface->WriteOutOfBandHeader(&bs);
				bs.Write((unsigned char) ID_NAT_TYPE_DETECT);
				bs.Write((unsigned char) NAT_TYPE_FULL_CONE);
				// S2P3 sends to C1 (Different address, different port, to previously used port on client). If received, Full-cone nat. Done.  (Else S2P3 potentially banned, do not use again).
				saOut=natDetectionAttempts[i].systemAddress;
				saOut.SetPortHostOrder(natDetectionAttempts[i].systemAddress.GetPort());
				// SocketLayer::SendTo_PC( s2p3, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __LINE__  );
				bsp.data = (char*) bs.GetData();
				bsp.length = bs.GetNumberOfBytesUsed();
				bsp.systemAddress = saOut;
				s2p3->Send(&bsp, _FILE_AND_LINE_);
				break;
			case STATE_TESTING_ADDRESS_RESTRICTED_1:
			case STATE_TESTING_ADDRESS_RESTRICTED_2:

#ifdef NTDS_VERBOSE
				printf("Testing NAT_TYPE_ADDRESS_RESTRICTED\n");
#endif
				rakPeerInterface->WriteOutOfBandHeader(&bs);
				bs.Write((unsigned char) ID_NAT_TYPE_DETECT);
				bs.Write((unsigned char) NAT_TYPE_ADDRESS_RESTRICTED);
				// S1P2 sends to C1 (Same address, different port, to previously used port on client). If received, address-restricted cone nat. Done.
				saOut=natDetectionAttempts[i].systemAddress;
				saOut.SetPortHostOrder(natDetectionAttempts[i].systemAddress.GetPort());
				//SocketLayer::SendTo_PC( s1p2, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __LINE__  );
				bsp.data = (char*) bs.GetData();
				bsp.length = bs.GetNumberOfBytesUsed();
				bsp.systemAddress = saOut;
				s1p2->Send(&bsp, _FILE_AND_LINE_);
				break;
			case STATE_TESTING_PORT_RESTRICTED_1:
			case STATE_TESTING_PORT_RESTRICTED_2:
				// C1 sends to S3P4. If address of C1 as seen by S3P4 is the same as the address of C1 as seen by S1P1, then port-restricted cone nat. Done

#ifdef NTDS_VERBOSE
				printf("Testing NAT_TYPE_PORT_RESTRICTED\n");
#endif
				bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_REQUEST);
				bs.Write(RakString::NonVariadic(s3p4Address));
				bs.Write(s3p4->GetBoundAddress().GetPort());
				rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false);
				break;
			default:

#ifdef NTDS_VERBOSE
				printf("Warning, exceeded final check STATE_TESTING_PORT_RESTRICTED_2.\nExpected that client would have sent NAT_TYPE_PORT_RESTRICTED on s3p4.\nDefaulting to Symmetric\n");
#endif
				bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT);
				bs.Write((unsigned char) NAT_TYPE_SYMMETRIC);
				rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false);
				natDetectionAttempts.RemoveAtIndexFast(i);
				i--;
				break;
			}

		}
		i++;
	}
}
예제 #6
0
void RPC4::CallLoopback( const char* uniqueID, RakNet::BitStream * bitStream )
{
	Packet *p=0;

	DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID);

	if (skhi.IsInvalid()==true)
	{
		if (rakPeerInterface) 
			p=AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1);
#if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
		else
			p=tcpInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1);
#endif

		if (rakPeerInterface)
			p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
#if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
		else
			p->guid=UNASSIGNED_RAKNET_GUID;
#endif

		p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
		p->systemAddress.systemIndex=(SystemIndex)-1;
		p->data[0]=ID_RPC_REMOTE_ERROR;
		p->data[1]=RPC_ERROR_FUNCTION_NOT_REGISTERED;
		strcpy((char*) p->data+2, uniqueID);
		
		PushBackPacketUnified(p,false);

		return;
	}

	RakNet::BitStream out;
	out.Write((MessageID) ID_RPC_PLUGIN);
	out.Write((MessageID) ID_RPC4_CALL);
	out.WriteCompressed(uniqueID);
	out.Write(false); // nonblocking
	if (bitStream)
	{
		bitStream->ResetReadPointer();
		out.AlignWriteToByteBoundary();
		out.Write(bitStream);
	}
	if (rakPeerInterface) 
		p=AllocatePacketUnified(out.GetNumberOfBytesUsed());
#if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
	else
		p=tcpInterface->AllocatePacket(out.GetNumberOfBytesUsed());
#endif

	if (rakPeerInterface)
		p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
#if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
	else
		p->guid=UNASSIGNED_RAKNET_GUID;
#endif
	p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
	p->systemAddress.systemIndex=(SystemIndex)-1;
	memcpy(p->data,out.GetData(),out.GetNumberOfBytesUsed());
	PushBackPacketUnified(p,false);
	return;
}
예제 #7
0
PluginReceiveResult RPC4::OnReceive(Packet *packet)
{
	if (packet->data[0]==ID_RPC_PLUGIN)
	{
		RakNet::BitStream bsIn(packet->data,packet->length,false);
		bsIn.IgnoreBytes(2);

		if (packet->data[1]==ID_RPC4_CALL)
		{
			RakNet::RakString functionName;
			bsIn.ReadCompressed(functionName);
			bool isBlocking=false;
			bsIn.Read(isBlocking);
			if (isBlocking==false)
			{
				DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(functionName.C_String());
				if (skhi.IsInvalid())
				{
					RakNet::BitStream bsOut;
					bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR);
					bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED);
					bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1);
					SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
					return RR_STOP_PROCESSING_AND_DEALLOCATE;
				}

				void ( *fp ) ( RakNet::BitStream *, Packet * );
				fp = registeredNonblockingFunctions.ItemAtIndex(skhi);
				bsIn.AlignReadToByteBoundary();
				fp(&bsIn,packet);
			}
			else
			{
				DataStructures::HashIndex skhi = registeredBlockingFunctions.GetIndexOf(functionName.C_String());
				if (skhi.IsInvalid())
				{
					RakNet::BitStream bsOut;
					bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR);
					bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED);
					bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1);
					SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
					return RR_STOP_PROCESSING_AND_DEALLOCATE;
				}

				void ( *fp ) ( RakNet::BitStream *, RakNet::BitStream *, Packet * );
				fp = registeredBlockingFunctions.ItemAtIndex(skhi);
				RakNet::BitStream returnData;
				bsIn.AlignReadToByteBoundary();
				fp(&bsIn, &returnData, packet);

				RakNet::BitStream out;
				out.Write((MessageID) ID_RPC_PLUGIN);
				out.Write((MessageID) ID_RPC4_RETURN);
				returnData.ResetReadPointer();
				out.AlignWriteToByteBoundary();
				out.Write(returnData);
				SendUnified(&out,IMMEDIATE_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
			}
		}
		else if (packet->data[1]==ID_RPC4_SIGNAL)
		{
			RakNet::RakString sharedIdentifier;
			bsIn.ReadCompressed(sharedIdentifier);
			DataStructures::HashIndex functionIndex;
			functionIndex = localSlots.GetIndexOf(sharedIdentifier);
			RakNet::BitStream serializedParameters;
            bsIn.AlignReadToByteBoundary();
			bsIn.Read(&serializedParameters);
			InvokeSignal(functionIndex, &serializedParameters, packet);
		}
		else
		{
			RakAssert(packet->data[1]==ID_RPC4_RETURN);
			blockingReturnValue.Reset();
			blockingReturnValue.Write(bsIn);
			gotBlockingReturnValue=true;
		}
		
		return RR_STOP_PROCESSING_AND_DEALLOCATE;
	}

	bool objectExists;
	unsigned int index, index2;
	index = localCallbacks.GetIndexFromKey(packet->data[0],&objectExists);
	if (objectExists)
	{
		LocalCallback *lc;
		lc = localCallbacks[index];
		for (index2=0; index2 < lc->functions.Size(); index2++)
		{
			RakNet::BitStream bsIn(packet->data, packet->length, false);

			DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(lc->functions[index2].C_String());
			if (skhi.IsInvalid()==false)
			{
				void ( *fp ) ( RakNet::BitStream *, Packet * );
				fp = registeredNonblockingFunctions.ItemAtIndex(skhi);
				bsIn.AlignReadToByteBoundary();
				fp(&bsIn,packet);
			}		
		}
	}

	return RR_CONTINUE_PROCESSING;
}
예제 #8
0
PluginReceiveResult SQLite3ServerPlugin::OnReceive(Packet *packet)
{
	switch (packet->data[0])
	{
	case ID_SQLite3_EXEC:
		{
			unsigned int queryId;
			RakNet::RakString dbIdentifier;
			RakNet::RakString inputStatement;
			RakNet::BitStream bsIn(packet->data, packet->length, false);
			bsIn.IgnoreBytes(sizeof(MessageID));
			bsIn.Read(queryId);
			bsIn.Read(dbIdentifier);
			bsIn.Read(inputStatement);
			bool isRequest;
			bsIn.Read(isRequest);
			if (isRequest)
			{
				// Server code

				unsigned int idx = dbHandles.GetIndexOf(dbIdentifier);
				if (idx==-1)
				{
					RakNet::BitStream bsOut;
					bsOut.Write((MessageID)ID_SQLite3_UNKNOWN_DB);
					bsOut.Write(queryId);
					bsOut.Write(dbIdentifier);
					bsOut.Write(inputStatement);
					SendUnified(&bsOut, MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
				}
				else
				{
#ifdef SQLite3_STATEMENT_EXECUTE_THREADED
					// Push to the thread
					SQLExecThreadInput input;
					input.data=(char*) rakMalloc_Ex(packet->length, _FILE_AND_LINE_);
					memcpy(input.data,packet->data,packet->length);
					input.dbHandle=dbHandles[idx].dbHandle;
					input.length=packet->length;
					input.sender=packet->systemAddress;
					sqlThreadPool.AddInput(ExecStatementThread, input);
#else
					char *errorMsg;
					RakNet::RakString errorMsgStr;
					SQLite3Table outputTable;					
					sqlite3_exec(dbHandles[idx].dbHandle, inputStatement.C_String(), PerRowCallback, &outputTable, &errorMsg);
					if (errorMsg)
					{
						errorMsgStr=errorMsg;
						sqlite3_free(errorMsg);
					}
					RakNet::BitStream bsOut;
					bsOut.Write((MessageID)ID_SQLite3_EXEC);
					bsOut.Write(queryId);
					bsOut.Write(dbIdentifier);
					bsOut.Write(inputStatement);
					bsOut.Write(false);
					bsOut.Write(errorMsgStr);
					outputTable.Serialize(&bsOut);
					SendUnified(&bsOut, MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
#endif
				}
			}
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
		}
		break;
	}

	return RR_CONTINUE_PROCESSING;
}
예제 #9
0
파일: Scripting.cpp 프로젝트: carmoIn/SKY
// native SendLastSyncData(playerid, toplayerid, animation = 0)
static cell AMX_NATIVE_CALL Natives::SendLastSyncData( AMX* amx, cell* params )
{
	if (!serverVersion)
		return 0;

	CHECK_PARAMS(3, "SendLastSyncData");

	int playerid = (int)params[1];
	int toplayerid = (int)params[2];
	int animation = (int)params[3];
	BYTE ps = ID_PLAYER_SYNC;
	CSyncData* d = &lastSyncData[playerid];

	RakNet::BitStream bs;
	bs.Write((BYTE)ID_PLAYER_SYNC);
	bs.Write((WORD)playerid);

	if (d->wUDAnalog) {
		bs.Write(true);
		bs.Write((WORD)d->wUDAnalog);
	} else {
		bs.Write(false);
	}

	if (d->wLRAnalog) {
		bs.Write(true);
		bs.Write((WORD)d->wLRAnalog);
	} else {
		bs.Write(false);
	}

	bs.Write((WORD)d->wKeys);

	bs.Write(d->vecPosition.fX);
	bs.Write(d->vecPosition.fY);
	bs.Write(d->vecPosition.fZ);

	if (fakeQuat[playerid] != NULL) {
		bs.Write((bool)(fakeQuat[playerid]->w<0.0f));
		bs.Write((bool)(fakeQuat[playerid]->x<0.0f));
		bs.Write((bool)(fakeQuat[playerid]->y<0.0f));
		bs.Write((bool)(fakeQuat[playerid]->z<0.0f));
		bs.Write((unsigned short)(fabs(fakeQuat[playerid]->x)*65535.0));
		bs.Write((unsigned short)(fabs(fakeQuat[playerid]->y)*65535.0));
		bs.Write((unsigned short)(fabs(fakeQuat[playerid]->z)*65535.0));
	} else {
		bs.Write((bool)(d->fQuaternionAngle<0.0f));
		bs.Write((bool)(d->vecQuaternion.fX<0.0f));
		bs.Write((bool)(d->vecQuaternion.fY<0.0f));
		bs.Write((bool)(d->vecQuaternion.fZ<0.0f));
		bs.Write((unsigned short)(fabs(d->vecQuaternion.fX)*65535.0));
		bs.Write((unsigned short)(fabs(d->vecQuaternion.fY)*65535.0));
		bs.Write((unsigned short)(fabs(d->vecQuaternion.fZ)*65535.0));
	}

	BYTE health, armour;

	if (fakeHealth[playerid] != 255) {
		health = fakeHealth[playerid];
	} else {
		health = d->byteHealth;
	}

	if (fakeArmour[playerid] != 255) {
		armour = fakeArmour[playerid];
	} else {
		armour = d->byteArmour;
	}

	if (health >= 100) {
		health = 0xF;
	} else {
		health /= 7;
	}

	if (armour >= 100) {
		armour = 0xF;
	} else {
		armour /= 7;
	}

	bs.Write((BYTE)((health << 4) | (armour)));

	bs.Write(d->byteWeapon);
	bs.Write(d->byteSpecialAction);

	// Make them appear standing still if paused
	if (GetTickCount() - lastUpdateTick[playerid] > 2000) {
		bs.WriteVector(0.0f, 0.0f, 0.0f);
	} else {
		bs.WriteVector(d->vecVelocity.fX, d->vecVelocity.fY, d->vecVelocity.fZ);
	}

	if (d->wSurfingInfo) {
		bs.Write(true);

		bs.Write(d->wSurfingInfo);
		bs.Write(d->vecSurfing.fX);
		bs.Write(d->vecSurfing.fY);
		bs.Write(d->vecSurfing.fZ);
	} else {
		bs.Write(false);
	}

	// Animations are only sent when they are changed
	if (animation) {
		bs.Write(true);
		bs.Write(animation);
	} else {
		bs.Write(false);
	}

	pRakServer->Send(&bs, HIGH_PRIORITY, RELIABLE_SEQUENCED, 0, pRakServer->GetPlayerIDFromIndex(toplayerid), false);

	return 1;
}
예제 #10
0
PluginReceiveResult FullyConnectedMesh2::OnVerifiedJoinStart(Packet *packet)
{
	RakNet::BitStream bsIn(packet->data,packet->length,false);
	bsIn.IgnoreBytes(sizeof(MessageID));

	unsigned short listSize;
	bsIn.Read(listSize);

	unsigned int curIndex = GetJoinsInProgressIndex(packet->guid);
	if (curIndex!=(unsigned int) -1)
	{
		// Got update to existing list

		VerifiedJoinInProgress *vjip = joinsInProgress[curIndex];
// 		if (vjip->sentResults==false)
// 		{
// 			// Got ID_FCM2_VERIFIED_JOIN_START twice before sending ID_FCM2_VERIFIED_JOIN_CAPABLE
// 			RakAssert(vjip->sentResults!=false);
// 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
// 		}

		for (unsigned int i=0; i < vjip->members.Size(); i++)
		{
			vjip->members[i].workingFlag=false;
		}

		// Server has updated list of participants
		for (unsigned short i=0; i < listSize; i++)
		{
			VerifiedJoinInProgressMember vjipm;
			ReadVerifiedJoinInProgressMember(&bsIn, &vjipm);

			unsigned int j;
			if (vjipm.guid!=UNASSIGNED_RAKNET_GUID)
				j = GetVerifiedJoinInProgressMemberIndex(vjipm.guid, vjip);
			else
				j = GetVerifiedJoinInProgressMemberIndex(vjipm.systemAddress, vjip);
			if (j==(unsigned int)-1)
			{
				// New
				vjipm.workingFlag=true;
				vjipm.joinInProgressState=JIPS_PROCESSING;
				vjip->members.Push(vjipm, _FILE_AND_LINE_);

				// Allow resend of ID_FCM2_VERIFIED_JOIN_CAPABLE
				//vjip->sentResults=false;
			}
			else
			{
				vjip->members[j].workingFlag=true;
			}
		}

		for (unsigned int i=0; i < vjip->members.Size(); i++)
		{
			if (vjip->members[i].workingFlag==false)
				vjip->members[i].joinInProgressState=JIPS_UNNECESSARY;
		}

		if (ProcessVerifiedJoinInProgressIfCompleted(vjip))
		{
			// Completed
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
		}

		// Else tell user about new list
		return RR_CONTINUE_PROCESSING;
	}

	VerifiedJoinInProgress *vjip = RakNet::OP_NEW<VerifiedJoinInProgress>(_FILE_AND_LINE_);
	vjip->requester=packet->guid;
	if (listSize==0)
	{
		//vjip->sentResults=true;

		// Send back result
		RakNet::BitStream bsOut;
		bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_CAPABLE);
		bsOut.WriteCasted<unsigned short>(0);
		SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
		//vjip->sentResults=true;
		joinsInProgress.Push(vjip, _FILE_AND_LINE_);
		return RR_STOP_PROCESSING_AND_DEALLOCATE;
	}

	//vjip->sentResults=false;

	for (unsigned short i=0; i < listSize; i++)
	{
		VerifiedJoinInProgressMember vjipm;
		ReadVerifiedJoinInProgressMember(&bsIn, &vjipm);
		vjip->members.Push(vjipm, _FILE_AND_LINE_);
	}
	joinsInProgress.Push(vjip, _FILE_AND_LINE_);
	return RR_CONTINUE_PROCESSING;
}
예제 #11
0
SQLite3ServerPlugin::SQLExecThreadOutput ExecStatementThread(SQLite3ServerPlugin::SQLExecThreadInput threadInput, bool *returnOutput, void* perThreadData)
{
	unsigned int queryId;
	RakNet::RakString dbIdentifier;
	RakNet::RakString inputStatement;
	RakNet::BitStream bsIn((unsigned char*) threadInput.data, threadInput.length, false);
	bsIn.IgnoreBytes(sizeof(MessageID));
	bsIn.Read(queryId);
	bsIn.Read(dbIdentifier);
	bsIn.Read(inputStatement);
	// bool isRequest;
	// bsIn.Read(isRequest);
	bsIn.IgnoreBits(1);

	char *errorMsg;
	RakNet::RakString errorMsgStr;
	SQLite3Table outputTable;					
	sqlite3_exec(threadInput.dbHandle, inputStatement.C_String(), PerRowCallback, &outputTable, &errorMsg);
	if (errorMsg)
	{
		errorMsgStr=errorMsg;
		sqlite3_free(errorMsg);
	}

	RakNet::BitStream bsOut;
	bsOut.Write((MessageID)ID_SQLite3_EXEC);
	bsOut.Write(queryId);
	bsOut.Write(dbIdentifier);
	bsOut.Write(inputStatement);
	bsOut.Write(false);
	bsOut.Write(errorMsgStr);
	outputTable.Serialize(&bsOut);

	// Free input data
	rakFree_Ex(threadInput.data,_FILE_AND_LINE_);

	// Copy to output data
	SQLite3ServerPlugin::SQLExecThreadOutput threadOutput;
	threadOutput.data=(char*) rakMalloc_Ex(bsOut.GetNumberOfBytesUsed(),_FILE_AND_LINE_);
	memcpy(threadOutput.data,bsOut.GetData(),bsOut.GetNumberOfBytesUsed());
	threadOutput.length=bsOut.GetNumberOfBytesUsed();
	threadOutput.sender=threadInput.sender;	
	// SendUnified(&bsOut, MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);

	*returnOutput=true;
	return threadOutput;
}
예제 #12
0
void FullyConnectedMesh2::RespondOnVerifiedJoinCapable(Packet *packet, bool accept, BitStream *additionalData)
{
	VerifiedJoinInProgress vjip;
	DecomposeJoinCapable(packet, &vjip);

	DataStructures::List<RakNetGUID> participatingMembersOnClientSucceeded;
	DataStructures::List<RakNetGUID> participatingMembersOnClientFailed;
	DataStructures::List<RakNetGUID> participatingMembersNotOnClient;
	DataStructures::List<RakNetGUID> clientMembersNotParticipatingSucceeded;
	DataStructures::List<RakNetGUID> clientMembersNotParticipatingFailed;
	CategorizeVJIP(&vjip,
		participatingMembersOnClientSucceeded,
		participatingMembersOnClientFailed,
		participatingMembersNotOnClient,
		clientMembersNotParticipatingSucceeded,
		clientMembersNotParticipatingFailed);

	if (participatingMembersNotOnClient.Size()>0)
	{
		BitStream bsOut;
		bsOut.Write((MessageID) ID_FCM2_VERIFIED_JOIN_START);
		bsOut.WriteCasted<unsigned short>(participatingMembersNotOnClient.Size());
		unsigned int i;
		for (i=0; i < participatingMembersNotOnClient.Size(); i++)
		{
			bsOut.Write(participatingMembersNotOnClient[i]);
			bsOut.Write(rakPeerInterface->GetSystemAddressFromGuid(participatingMembersNotOnClient[i]));
		}
		SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
		return;
	}

	RakAssert(participatingMembersOnClientFailed.Size()==0);
	RakAssert(participatingMembersNotOnClient.Size()==0);
	
	RakNet::BitStream bsOut;
	if (accept)
	{
		bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_ACCEPTED);
		bsOut.Write(packet->guid);
		
		// Tell client to disconnect from clientMembersNotParticipatingSucceeded 
		bsOut.WriteCasted<unsigned short>(clientMembersNotParticipatingSucceeded.Size());
		for (unsigned int i=0; i < clientMembersNotParticipatingSucceeded.Size(); i++)
			bsOut.Write(clientMembersNotParticipatingSucceeded[i]);
		
		// Tell client to call AddParticipant() for participatingMembersOnClientSucceeded
		bsOut.WriteCasted<unsigned short>(participatingMembersOnClientSucceeded.Size());
		for (unsigned int i=0; i < participatingMembersOnClientSucceeded.Size(); i++)
			bsOut.Write(participatingMembersOnClientSucceeded[i]);

		if (additionalData)
			bsOut.Write(additionalData);

		for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
			SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, fcm2ParticipantList[i].rakNetGuid, false);

		// Process immediately
		// This is so if another ID_FCM2_VERIFIED_JOIN_CAPABLE is buffered, it responds with ID_FCM2_VERIFIED_JOIN_START
		AddParticipant(packet->guid);

		Packet *p = AllocatePacketUnified(bsOut.GetNumberOfBytesUsed());
		memcpy(p->data, bsOut.GetData(), bsOut.GetNumberOfBytesUsed());
		p->systemAddress=packet->systemAddress;
		p->systemAddress.systemIndex=(SystemIndex)-1;
		p->guid=packet->guid;
		p->wasGeneratedLocally=true;
		rakPeerInterface->PushBackPacket(p, true);
	}
	else
	{
		// Tell client rejected, otherwise process the same as ID_FCM2_VERIFIED_JOIN_FAILED
		bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_REJECTED);
		bsOut.Write(additionalData);
	}

	SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
}
예제 #13
0
파일: netrpc.cpp 프로젝트: LBRGeorge/jmnvc
void RequestClass(PCHAR Data, int iBitLength, PlayerID sender)
{
	RakNet::BitStream bsData(Data,iBitLength/8,FALSE);
	
	BYTE byteRequestedClass;
	BYTE byteRequestOutcome = 0;
	BYTE bytePlayerID = pRak->GetIndexFromPlayerID(sender);
	bsData.Read(byteRequestedClass);

	if(!pNetGame->GetPlayerPool()->GetSlotState(bytePlayerID)) return;
	
	if(pNetGame->GetGameLogic()->HandleSpawnClassRequest(bytePlayerID,byteRequestedClass)) 
	{
		byteRequestOutcome = 1;
	}

	RakNet::BitStream bsSpawnRequestReply;
	CPlayer *pPlayer=pNetGame->GetPlayerPool()->GetAt(bytePlayerID);
	PLAYER_SPAWN_INFO *SpawnInfo = pPlayer->GetSpawnInfo();

	bsSpawnRequestReply.Write(byteRequestOutcome);
	bsSpawnRequestReply.Write(SpawnInfo->byteTeam);
	bsSpawnRequestReply.Write(SpawnInfo->byteSkin);
	bsSpawnRequestReply.Write((float)SpawnInfo->vecPos.X);
	bsSpawnRequestReply.Write((float)SpawnInfo->vecPos.Y);
	bsSpawnRequestReply.Write((float)SpawnInfo->vecPos.Z);
	bsSpawnRequestReply.Write((float)SpawnInfo->fRotation);
	bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeapons[0]);
	bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeaponsAmmo[0]);
	bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeapons[1]);
	bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeaponsAmmo[1]);
	bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeapons[2]);
	bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeaponsAmmo[2]);

	pRak->RPC("RequestClass",&bsSpawnRequestReply,HIGH_PRIORITY,RELIABLE,0,sender,FALSE,FALSE);
}
예제 #14
0
void selectTextDraw(int iTextDrawID)
{
	RakNet::BitStream bsSend;
	bsSend.Write(iTextDrawID);
	pRakClient->RPC(&RPC_ClickTextDraw, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE, UNASSIGNED_NETWORK_ID, NULL);
}
예제 #15
0
void NatPunchthroughServer::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
    (void) lostConnectionReason;
    (void) systemAddress;

    unsigned int i=0;
    bool objectExists;
    i = users.GetIndexFromKey(rakNetGUID, &objectExists);
    if (objectExists)
    {
        RakNet::BitStream outgoingBs;
        DataStructures::List<User *> freedUpInProgressUsers;
        User *user = users[i];
        User *otherUser;
        unsigned int connectionAttemptIndex;
        ConnectionAttempt *connectionAttempt;
        for (connectionAttemptIndex=0; connectionAttemptIndex < user->connectionAttempts.Size(); connectionAttemptIndex++)
        {
            connectionAttempt=user->connectionAttempts[connectionAttemptIndex];
            outgoingBs.Reset();
            if (connectionAttempt->recipient==user)
            {
                otherUser=connectionAttempt->sender;
            }
            else
            {
                otherUser=connectionAttempt->recipient;
            }

            // 05/28/09 Previously only told sender about ID_NAT_CONNECTION_TO_TARGET_LOST
            // However, recipient may be expecting it due to external code
            // In that case, recipient would never get any response if the sender dropped
            outgoingBs.Write((MessageID)ID_NAT_CONNECTION_TO_TARGET_LOST);
            outgoingBs.Write(rakNetGUID);
            outgoingBs.Write(connectionAttempt->sessionId);
            rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,otherUser->systemAddress,false);

            // 4/22/09 - Bug: was checking inProgress, legacy variable not used elsewhere
            if (connectionAttempt->attemptPhase==ConnectionAttempt::NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS)
            {
                otherUser->isReady=true;
                freedUpInProgressUsers.Insert(otherUser, _FILE_AND_LINE_ );
            }

            otherUser->DeleteConnectionAttempt(connectionAttempt);
        }

        RakNet::OP_DELETE(users[i], _FILE_AND_LINE_);
        users.RemoveAtIndex(i);

        for (i=0; i < freedUpInProgressUsers.Size(); i++)
        {
            StartPunchthroughForUser(freedUpInProgressUsers[i]);
        }
    }

    // Also remove from groupPunchthroughRequests
    for (i=0; i < users.Size(); i++)
    {
        bool objectExists;
        unsigned int gprIndex;
        gprIndex = users[i]->groupPunchthroughRequests.GetIndexFromKey(rakNetGUID, &objectExists);
        if (objectExists)
        {
//			printf("DEBUG %i\n", __LINE__);

            RakNet::BitStream outgoingBs;
            outgoingBs.Write((MessageID)ID_NAT_TARGET_NOT_CONNECTED);
            outgoingBs.Write(rakNetGUID);
            rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,users[i]->systemAddress,false);

            users[i]->groupPunchthroughRequests.RemoveAtIndex(gprIndex);
        }
    }
}
예제 #16
0
void CGangZonePool::HideForAll(WORD wZone)
{
	RakNet::BitStream bsParams;
	bsParams.Write(wZone);
	pNetGame->GetRakServer()->RPC(RPC_ScrRemoveGangZone, &bsParams, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_PLAYER_ID, true, false);
}
예제 #17
0
void NatPunchthroughServer::OnGetMostRecentPort(Packet *packet)
{
    RakNet::BitStream bsIn(packet->data, packet->length, false);
    bsIn.IgnoreBytes(sizeof(MessageID));
    uint16_t sessionId;
    unsigned short mostRecentPort;
    bsIn.Read(sessionId);
    bsIn.Read(mostRecentPort);

    unsigned int i,j;
    User *user;
    ConnectionAttempt *connectionAttempt;
    bool objectExists;
    i = users.GetIndexFromKey(packet->guid, &objectExists);

    if (natPunchthroughServerDebugInterface)
    {
        RakNet::RakString log;
        char addr1[128], addr2[128];
        packet->systemAddress.ToString(true,addr1);
        packet->guid.ToString(addr2);
        log=RakNet::RakString("Got ID_NAT_GET_MOST_RECENT_PORT from systemAddress %s guid %s. port=%i. sessionId=%i. userFound=%i.", addr1, addr2, mostRecentPort, sessionId, objectExists);
        natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
    }

    if (objectExists)
    {
        user=users[i];
        user->mostRecentPort=mostRecentPort;
        RakNet::Time time = RakNet::GetTime();

        for (j=0; j < user->connectionAttempts.Size(); j++)
        {
            connectionAttempt=user->connectionAttempts[j];
            if (connectionAttempt->attemptPhase==ConnectionAttempt::NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS &&
                    connectionAttempt->sender->mostRecentPort!=0 &&
                    connectionAttempt->recipient->mostRecentPort!=0 &&
                    // 04/29/08 add sessionId to prevent processing for other systems
                    connectionAttempt->sessionId==sessionId)
            {
                SystemAddress senderSystemAddress = connectionAttempt->sender->systemAddress;
                SystemAddress recipientSystemAddress = connectionAttempt->recipient->systemAddress;
                SystemAddress recipientTargetAddress = recipientSystemAddress;
                SystemAddress senderTargetAddress = senderSystemAddress;
                recipientTargetAddress.SetPort(connectionAttempt->recipient->mostRecentPort);
                senderTargetAddress.SetPort(connectionAttempt->sender->mostRecentPort);

                // Pick a time far enough in the future that both systems will have gotten the message
                int targetPing = rakPeerInterface->GetAveragePing(recipientTargetAddress);
                int senderPing = rakPeerInterface->GetAveragePing(senderSystemAddress);
                RakNet::Time simultaneousAttemptTime;
                if (targetPing==-1 || senderPing==-1)
                    simultaneousAttemptTime = time + 1500;
                else
                {
                    int largerPing = targetPing > senderPing ? targetPing : senderPing;
                    if (largerPing * 4 < 100)
                        simultaneousAttemptTime = time + 100;
                    else
                        simultaneousAttemptTime = time + (largerPing * 4);
                }

                if (natPunchthroughServerDebugInterface)
                {
                    RakNet::RakString log;
                    char addr1[128], addr2[128];
                    recipientSystemAddress.ToString(true,addr1);
                    connectionAttempt->recipient->guid.ToString(addr2);
                    log=RakNet::RakString("Sending ID_NAT_CONNECT_AT_TIME to recipient systemAddress %s guid %s", addr1, addr2);
                    natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
                }

                // Send to recipient timestamped message to connect at time
                RakNet::BitStream bsOut;
                bsOut.Write((MessageID)ID_TIMESTAMP);
                bsOut.Write(simultaneousAttemptTime);
                bsOut.Write((MessageID)ID_NAT_CONNECT_AT_TIME);
                bsOut.Write(connectionAttempt->sessionId);
                bsOut.Write(senderTargetAddress); // Public IP, using most recent port
                for (j=0; j < MAXIMUM_NUMBER_OF_INTERNAL_IDS; j++) // Internal IP
                    bsOut.Write(rakPeerInterface->GetInternalID(senderSystemAddress,j));
                bsOut.Write(connectionAttempt->sender->guid);
                bsOut.Write(false);
                rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,recipientSystemAddress,false);


                if (natPunchthroughServerDebugInterface)
                {
                    RakNet::RakString log;
                    char addr1[128], addr2[128];
                    senderSystemAddress.ToString(true,addr1);
                    connectionAttempt->sender->guid.ToString(addr2);
                    log=RakNet::RakString("Sending ID_NAT_CONNECT_AT_TIME to sender systemAddress %s guid %s", addr1, addr2);
                    natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
                }


                // Same for sender
                bsOut.Reset();
                bsOut.Write((MessageID)ID_TIMESTAMP);
                bsOut.Write(simultaneousAttemptTime);
                bsOut.Write((MessageID)ID_NAT_CONNECT_AT_TIME);
                bsOut.Write(connectionAttempt->sessionId);
                bsOut.Write(recipientTargetAddress); // Public IP, using most recent port
                for (j=0; j < MAXIMUM_NUMBER_OF_INTERNAL_IDS; j++) // Internal IP
                    bsOut.Write(rakPeerInterface->GetInternalID(recipientSystemAddress,j));
                bsOut.Write(connectionAttempt->recipient->guid);
                bsOut.Write(true);
                rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,senderSystemAddress,false);

                connectionAttempt->recipient->DerefConnectionAttempt(connectionAttempt);
                connectionAttempt->sender->DeleteConnectionAttempt(connectionAttempt);

                // 04/29/08 missing return
                return;
            }
        }
    }
    else
    {

        if (natPunchthroughServerDebugInterface)
        {
            RakNet::RakString log;
            char addr1[128], addr2[128];
            packet->systemAddress.ToString(true,addr1);
            packet->guid.ToString(addr2);
            log=RakNet::RakString("Ignoring ID_NAT_GET_MOST_RECENT_PORT from systemAddress %s guid %s", addr1, addr2);
            natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
        }

    }
}
예제 #18
0
void CLocalPlayer::SendInVehicleSync( void )
{
	// Are we not connected to the network?
	if( !pCore->GetNetworkModule()->IsConnected() )
		return;

	// Are we dead?
	if( IsDead() )
		return;

	// Get the vehicle instance
	CNetworkVehicle * pVehicle = pCore->GetVehicleManager()->GetFromGameGUID( GetPlayerPed()->GetCurrentVehicle()->m_dwGUID );

	// Did we fail to find the vehicle?
	if( !pVehicle )
		return;

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

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

	// Construct a new in vehicle sync data structure
	InVehicleSync inVehicleSync;

	// Get the vehicle position
	pVehicle->GetPosition( &inVehicleSync.m_vecPosition );

	// Get the vehicle rotation
	pVehicle->GetRotation( &inVehicleSync.m_vecRotation );

	// Get the vehicle dirt level
	inVehicleSync.m_fDirtLevel = pVehicle->GetVehicle()->GetDirtLevel();

	// Get the vehicle tuning table
	inVehicleSync.m_iTuningTable = pVehicle->GetVehicle()->GetTuningTable();

	// Get the vehicle horn state
	inVehicleSync.m_bHornState = pVehicle->GetVehicle()->IsHornOn();

	// Get the vehicle siren state
	inVehicleSync.m_bSirenState = pVehicle->GetVehicle()->IsSirenOn();

	// Get the vehicle fuel
	inVehicleSync.m_fFuel = pVehicle->GetVehicle()->GetFuel();

	// Get the vehicle speed
	pVehicle->GetSpeedVec( &inVehicleSync.m_vecVelocity );

	// Get the turn speed
	inVehicleSync.m_fTurnSpeed = pVehicle->GetSteer();

	// Get the engine damage
	inVehicleSync.m_fEngineDamage = pVehicle->GetVehicle()->GetEngineDamage();

	// Get the vehicle plate text
	strcpy( inVehicleSync.m_szPlateText, pVehicle->GetPlateText() );
	inVehicleSync.m_szPlateText[ 6 ] = '\0';

	// Get the vehicle colour
	pVehicle->GetColour( &inVehicleSync.m_primaryColour, &inVehicleSync.m_secondaryColour );

	// Get the power state
	inVehicleSync.m_bPower = pVehicle->GetVehicle()->GetPower();

	// Get the brake state
	inVehicleSync.m_bBrake = pVehicle->GetVehicle()->GetBrake();

	// Get the vehicle wheel models (DISABLED FOR TESTING)
	for ( int i = 0; i < 3; i++ )
		inVehicleSync.m_bWheelModels[ i ] = 0xFF; //Game::GetIdFromVehicleWheelModel ( pVehicle->GetVehicle()->GetWheelTexture ( i ) );

	// Get the handbrake state
	inVehicleSync.m_bHandbrake = pVehicle->GetVehicle()->IsHandbrakeOn ();

	// Get the light state
	inVehicleSync.m_bLightState = pVehicle->GetVehicle()->GetLightState ();

	// Write the sync structure into the bitstream
	pBitStream.Write( (char *)&inVehicleSync, sizeof(InVehicleSync) );

	// Send the bitstream to the server
	pCore->GetNetworkModule()->Call( RPC_VEHICLE_SYNC, &pBitStream, LOW_PRIORITY, UNRELIABLE_SEQUENCED, true );
}
예제 #19
0
bool RPC4::CallBlocking( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, RakNet::BitStream *returnData )
{
	RakNet::BitStream out;
	out.Write((MessageID) ID_RPC_PLUGIN);
	out.Write((MessageID) ID_RPC4_CALL);
	out.WriteCompressed(uniqueID);
	out.Write(true); // Blocking
	if (bitStream)
	{
		bitStream->ResetReadPointer();
		out.AlignWriteToByteBoundary();
		out.Write(bitStream);
	}
	RakAssert(returnData);
	RakAssert(rakPeerInterface);
	ConnectionState cs;
	cs = rakPeerInterface->GetConnectionState(systemIdentifier);
	if (cs!=IS_CONNECTED)
		return false;

	SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,false);

	returnData->Reset();
	blockingReturnValue.Reset();
	gotBlockingReturnValue=false;
	Packet *packet;
	DataStructures::Queue<Packet*> packetQueue;
	while (gotBlockingReturnValue==false)
	{
		// TODO - block, filter until gotBlockingReturnValue==true or ID_CONNECTION_LOST or ID_DISCONNECTION_NOTIFICXATION or ID_RPC_REMOTE_ERROR/RPC_ERROR_FUNCTION_NOT_REGISTERED
		RakSleep(30);

		packet=rakPeerInterface->Receive();

		if (packet)
		{
			if (
				(packet->data[0]==ID_CONNECTION_LOST || packet->data[0]==ID_DISCONNECTION_NOTIFICATION) &&
				((systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID && packet->guid==systemIdentifier.rakNetGuid) ||
				(systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS && packet->systemAddress==systemIdentifier.systemAddress))
				)
			{
				// Push back to head in reverse order
				rakPeerInterface->PushBackPacket(packet,true);
				while (packetQueue.Size())
					rakPeerInterface->PushBackPacket(packetQueue.Pop(),true);
				return false;
			}
			else if (packet->data[0]==ID_RPC_REMOTE_ERROR && packet->data[1]==RPC_ERROR_FUNCTION_NOT_REGISTERED)
			{
				RakNet::RakString functionName;
				RakNet::BitStream bsIn(packet->data,packet->length,false);
				bsIn.IgnoreBytes(2);
				bsIn.Read(functionName);
				if (functionName==uniqueID)
				{
					// Push back to head in reverse order
					rakPeerInterface->PushBackPacket(packet,true);
					while (packetQueue.Size())
						rakPeerInterface->PushBackPacket(packetQueue.Pop(),true);
					return false;
				}
				else
				{
					packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_);
				}
			}
			else
			{
				packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_);
			}
		}
	}

	returnData->Write(blockingReturnValue);
	returnData->ResetReadPointer();
	return true;
}
예제 #20
0
void CLocalPlayer::OnEnterVehicle( void )
{
	// Get the vehicle instance from the vehicle guid
	CNetworkVehicle * pNetworkVehicle = pCore->GetVehicleManager()->GetFromGameGUID( GetPlayerPed()->GetCurrentVehicle()->m_dwGUID );

	// Is the vehicle instance valid?
	if( pNetworkVehicle )
	{
#ifdef _DEBUG
		M2Vehicle * pVehicle = pNetworkVehicle->GetVehicle()->GetVehicle();
		DWORD dwVehicleData = (DWORD)(pVehicle) + 0xA8;

		pCore->GetChat()->AddDebugMessage ( "Vehicle: 0x%p, VehicleData: 0x%p", pVehicle, dwVehicleData );
#endif

		// Set the initial seat as the driver
		EntityId seat = 0;

		// Is the player in the passenger seat?
		//if( GetState() == PLAYERSTATE_PASSENGER )
		//	seat = pNetworkVehicle->GetVehicle()->GetPedOccupiedSeat( GetPlayerPed()->GetPed() );

		// Does the vehicle already have a driver?
		if ( pNetworkVehicle->GetDriver () )
			seat = pNetworkVehicle->GetVehicle()->GetPedOccupiedSeat( GetPlayerPed()->GetPed() );

		// Are we getting in as the driver?
		if( seat == 0 )
			SetState( PLAYERSTATE_DRIVER );
		else
			SetState( PLAYERSTATE_PASSENGER );

#ifdef _DEBUG
		pCore->GetChat()->AddDebugMessage( "Seat: %d, Driver: 0x%p, State: %d", seat, pNetworkVehicle->GetDriver (), GetState () );
#endif

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

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

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

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

#ifdef _DEBUG
		pCore->GetChat()->AddDebugMessage( "CLocalPlayer::OnEnterVehicle( %d, %d )", pNetworkVehicle->GetId(), seat );
#endif

		// Handle this enter with the network vehicle
		pNetworkVehicle->HandlePlayerEnter( this, seat );

		// Set the vehicle
		SetVehicle( pNetworkVehicle );

		// Set the seat
		SetSeat( seat );

		// Set the target data
		SetEnteringVehicle( pNetworkVehicle, seat );
	}
}
예제 #21
0
PluginReceiveResult Router::OnReceive(Packet *packet)
{
	if (packet->data[0]==ID_ROUTE_AND_MULTICAST ||
		(packet->length>5 && packet->data[0]==ID_TIMESTAMP && packet->data[5]==ID_ROUTE_AND_MULTICAST))
	{
#ifdef _DO_PRINTF
		RAKNET_DEBUG_PRINTF("%i got routed message from %i\n", peer->GetExternalID(packet->systemAddress).port, packet->systemAddress.port);
#endif
		RakNetTime timestamp;
		PacketPriority priority;
		PacketReliability reliability;
		unsigned char orderingChannel;
		SystemAddress originalSender;
		RakNet::BitStream out;
		BitSize_t outStartingOffset;
		unsigned int payloadBitLength;
		unsigned payloadWriteByteOffset;
		RakNet::BitStream incomingBitstream(packet->data, packet->length, false);
		incomingBitstream.IgnoreBits(8);
		
		if (packet->data[0]==ID_TIMESTAMP)
		{
			incomingBitstream.Read(timestamp);
			out.Write((MessageID)ID_TIMESTAMP);
			out.Write(timestamp);
			incomingBitstream.IgnoreBits(8);
		}

		// Read the send parameters
		unsigned char c;
		incomingBitstream.ReadCompressed(c);
		priority=(PacketPriority)c;
		incomingBitstream.ReadCompressed(c);
		reliability=(PacketReliability)c;
		incomingBitstream.ReadCompressed(orderingChannel);
		incomingBitstream.Read(payloadBitLength);
		
		out.Write((MessageID)ID_ROUTE_AND_MULTICAST);
		out.WriteCompressed((unsigned char)priority);
		out.WriteCompressed((unsigned char)reliability);
		out.WriteCompressed((unsigned char)orderingChannel);
		out.Write(payloadBitLength);
		out.AlignWriteToByteBoundary();
		incomingBitstream.AlignReadToByteBoundary();
		payloadWriteByteOffset=(unsigned int) BITS_TO_BYTES(out.GetWriteOffset());
		out.Write(&incomingBitstream, payloadBitLength); // This write also does a read on incomingBitStream

		if (restrictByType)
		{
			RakNet::BitStream t(out.GetData()+payloadWriteByteOffset, sizeof(unsigned char), false);
			MessageID messageID;
			t.Read(messageID);
			if (allowedTypes.HasData(messageID)==false)
				return RR_STOP_PROCESSING_AND_DEALLOCATE; // Don't route restricted types
		}

		incomingBitstream.Read(originalSender);
		out.Write(originalSender);
		outStartingOffset=out.GetWriteOffset();

		// Deserialize the root
		bool hasData=false;
		SystemAddress recipient;
		unsigned short numberOfChildren;
		incomingBitstream.Read(hasData);
		incomingBitstream.Read(recipient); // This should be our own address
		if (incomingBitstream.ReadCompressed(numberOfChildren)==false)
		{
#ifdef _DEBUG
			RakAssert(0);
#endif
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
		}

		unsigned childIndex;
		bool childHasData=false;
		SystemAddress childRecipient;
		unsigned short childNumberOfChildren;
		SystemAddress immediateRecipient;
		immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS;
		int pendingNodeCount=0;

		for (childIndex=0; childIndex < numberOfChildren; childIndex++)
		{
			while (pendingNodeCount!=-1)
			{
				// Copy out the serialized subtree for this child
				incomingBitstream.Read(childHasData);
				incomingBitstream.Read(childRecipient);
				if (!incomingBitstream.ReadCompressed(childNumberOfChildren))
					return RR_STOP_PROCESSING_AND_DEALLOCATE;
				if (immediateRecipient==UNASSIGNED_SYSTEM_ADDRESS)
				{
					immediateRecipient=childRecipient;
				}

				pendingNodeCount+=childNumberOfChildren-1;

				out.Write(childHasData);
				out.Write(childRecipient);
				out.WriteCompressed(childNumberOfChildren);
			}

#ifdef _DO_PRINTF
			RAKNET_DEBUG_PRINTF("%i routing to %i\n", peer->GetExternalID(packet->systemAddress).port, immediateRecipient.port);
#endif

			// Send what we got so far
			SendUnified(&out, priority, reliability, orderingChannel, immediateRecipient, false);

			// Restart writing the per recipient data
			out.SetWriteOffset(outStartingOffset);

			// Reread the top level node
			immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS;

			pendingNodeCount=0;

		}

		// Write the user payload to the packet struct if this is a destination and change the sender and return true
		if (hasData)
		{
#ifdef _DO_PRINTF
			RAKNET_DEBUG_PRINTF("%i returning payload to user\n", peer->GetExternalID(packet->systemAddress).port);
#endif

			if (packet->data[0]==ID_TIMESTAMP )
			{
				memcpy( packet->data + sizeof(RakNetTime)+sizeof(unsigned char), out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) );
				packet->bitSize=BYTES_TO_BITS(sizeof(RakNetTime)+sizeof(unsigned char))+payloadBitLength;
			}
			else
			{
				memcpy( packet->data, out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) );
				packet->bitSize=payloadBitLength;
			}
			packet->length=(unsigned int) BITS_TO_BYTES(packet->bitSize);
			packet->systemAddress.systemIndex=(SystemIndex)-1;
			packet->systemAddress=originalSender;

			return RR_CONTINUE_PROCESSING;
		}

		// Absorb
		return RR_STOP_PROCESSING_AND_DEALLOCATE;
	}

	return RR_CONTINUE_PROCESSING;
}
예제 #22
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 );
	}
}
void NatTypeDetectionServer::Update(void)
{
	int i=0;
	RakNetTimeMS time = RakNet::GetTime();
	RakNet::BitStream bs;
	SystemAddress boundAddress;

	// Only socket that receives messages is s3p4, to see if the external address is different than that of the connection to rakPeerInterface
	char data[ MAXIMUM_MTU_SIZE ];
	int len;
	SystemAddress senderAddr;
	len=NatTypeRecvFrom(data, s3p4, senderAddr);
	// Client is asking us if this is port restricted. Only client requests of this type come in on s3p4
	while (len>0 && data[0]==NAT_TYPE_PORT_RESTRICTED)
	{
		RakNet::BitStream bsIn((unsigned char*) data,len,false);
		RakNetGUID senderGuid;
		bsIn.IgnoreBytes(sizeof(MessageID));
		bool readSuccess = bsIn.Read(senderGuid);
		RakAssert(readSuccess);
		if (readSuccess)
		{
			unsigned int i = GetDetectionAttemptIndex(senderGuid);
			if (i!=(unsigned int)-1)
			{
				bs.Reset();
				bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT);
				// If different, then symmetric
				if (senderAddr!=natDetectionAttempts[i].systemAddress)
				{
					printf("Determined client is symmetric\n");
					bs.Write((unsigned char) NAT_TYPE_SYMMETRIC);
				}
				else
				{
					// else port restricted
					printf("Determined client is port restricted\n");
					bs.Write((unsigned char) NAT_TYPE_PORT_RESTRICTED);
				}

				rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false);

				// Done
				natDetectionAttempts.RemoveAtIndexFast(i);
			}
			else
			{
				RakAssert("i==0 in Update when looking up GUID in NatTypeDetectionServer.cpp. Either a bug or a late resend" && 0);
			}
		}
		else
		{
			RakAssert("Didn't read GUID in Update in NatTypeDetectionServer.cpp. Message format error" && 0);
		}

		len=NatTypeRecvFrom(data, s3p4, senderAddr);
	}


	while (i < (int) natDetectionAttempts.Size())
	{
		if (time > natDetectionAttempts[i].nextStateTime)
		{
			natDetectionAttempts[i].detectionState=(NATDetectionState)((int)natDetectionAttempts[i].detectionState+1);
			natDetectionAttempts[i].nextStateTime=time+natDetectionAttempts[i].timeBetweenAttempts;
			unsigned char c;
			bs.Reset();
			switch (natDetectionAttempts[i].detectionState)
			{
			case STATE_TESTING_NONE_1:
			case STATE_TESTING_NONE_2:
				c = NAT_TYPE_NONE;
				printf("Testing NAT_TYPE_NONE\n");
				// S4P5 sends to C2. If arrived, no NAT. Done. (Else S4P5 potentially banned, do not use again).
				SocketLayer::Instance()->SendTo_PC( s4p5, (const char*) &c, 1, natDetectionAttempts[i].systemAddress.binaryAddress, natDetectionAttempts[i].c2Port );
				break;
			case STATE_TESTING_FULL_CONE_1:
			case STATE_TESTING_FULL_CONE_2:
				printf("Testing NAT_TYPE_FULL_CONE\n");
				rakPeerInterface->WriteOutOfBandHeader(&bs, ID_OUT_OF_BAND_INTERNAL);
				bs.Write((unsigned char) ID_NAT_TYPE_DETECT);
				bs.Write((unsigned char) NAT_TYPE_FULL_CONE);
				// S2P3 sends to C1 (Different address, different port, to previously used port on client). If received, Full-cone nat. Done.  (Else S2P3 potentially banned, do not use again).
				SocketLayer::Instance()->SendTo_PC( s2p3, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), natDetectionAttempts[i].systemAddress.binaryAddress, natDetectionAttempts[i].systemAddress.port );
				break;
			case STATE_TESTING_ADDRESS_RESTRICTED_1:
			case STATE_TESTING_ADDRESS_RESTRICTED_2:
				printf("Testing NAT_TYPE_ADDRESS_RESTRICTED\n");
				rakPeerInterface->WriteOutOfBandHeader(&bs, ID_OUT_OF_BAND_INTERNAL);
				bs.Write((unsigned char) ID_NAT_TYPE_DETECT);
				bs.Write((unsigned char) NAT_TYPE_ADDRESS_RESTRICTED);
				// S1P2 sends to C1 (Same address, different port, to previously used port on client). If received, address-restricted cone nat. Done.
				SocketLayer::Instance()->SendTo_PC( s1p2, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), natDetectionAttempts[i].systemAddress.binaryAddress, natDetectionAttempts[i].systemAddress.port );
				break;
			case STATE_TESTING_PORT_RESTRICTED_1:
			case STATE_TESTING_PORT_RESTRICTED_2:
				// C1 sends to S3P4. If address of C1 as seen by S3P4 is the same as the address of C1 as seen by S1P1, then port-restricted cone nat. Done
				printf("Testing NAT_TYPE_PORT_RESTRICTED\n");
				bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_REQUEST);
				bs.Write(RakString::NonVariadic(s3p4Address));
				bs.Write(s3p4Port);
				rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false);
				break;
			default:
				printf("Warning, exceeded final check STATE_TESTING_PORT_RESTRICTED_2.\nExpected that client would have sent NAT_TYPE_PORT_RESTRICTED on s3p4.\nDefaulting to Symmetric\n");
				bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT);
				bs.Write((unsigned char) NAT_TYPE_SYMMETRIC);
				rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false);
				natDetectionAttempts.RemoveAtIndexFast(i);
				i--;
				break;
			}

		}
		i++;
	}
}
예제 #24
0
void ConnectionGraph2::AddParticipant(const SystemAddress &systemAddress, RakNetGUID rakNetGUID)
{
	// Relay the new connection to other systems.
	RakNet::BitStream bs;
	bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
	bs.Write((uint32_t)1);
	bs.Write(systemAddress);
	bs.Write(rakNetGUID);
	bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(rakNetGUID));
	SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true);

	// Send everyone to the new guy
	DataStructures::List<SystemAddress> addresses;
	DataStructures::List<RakNetGUID> guids;
	rakPeerInterface->GetSystemList(addresses, guids);
	bs.Reset();
	bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
	BitSize_t writeOffset = bs.GetWriteOffset();
	bs.Write((uint32_t) addresses.Size());

	unsigned int i;
	uint32_t count=0;
	for (i=0; i < addresses.Size(); i++)
	{
		if (addresses[i]==systemAddress)
			continue;

		bs.Write(addresses[i]);
		bs.Write(guids[i]);
		bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(guids[i]));
		count++;
	}

	if (count>0)
	{
		BitSize_t writeOffset2 = bs.GetWriteOffset();
		bs.SetWriteOffset(writeOffset);
		bs.Write(count);
		bs.SetWriteOffset(writeOffset2);
		SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false);
	}

	bool objectExists;
	unsigned int ii = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists);
	if (objectExists==false)
	{
		RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(_FILE_AND_LINE_);
		remoteSystem->guid=rakNetGUID;
		remoteSystems.InsertAtIndex(remoteSystem,ii,_FILE_AND_LINE_);
	}
}
예제 #25
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);
		}
	}
예제 #26
0
void Equip::Render() {
	if (mDragSprite.GetVisible()) {
		SVector2 position = mDragSprite.GetPosition();
		float x = Input_GetMouseScreenX() - position.x;
		float y = Input_GetMouseScreenY() - position.y - 32;

		int slot = -1;
		if (Input_IsMousePressed(Mouse::LBUTTON)) {
			// Ring Left
			if (x > 226 && x < 269 && y > 93 && y < 138) {
				slot = ring2;
			}

			// Ring Right
			if (x > 226 && x < 269 && y > 144 && y < 187) {
				slot = ring;
			}

			// Right arm
			if (x > 177 && x < 219 && y > 119 && y < 162) {
				slot = shield;
			}

			// Left arm
			if (x > 78 && x < 118 && y > 120 && y < 163) {
				slot = weapon;
			}

			// Helmet
			if (x > 28 && x < 70 && y > -4 && y < 40) {
				slot = helmet;
			}

			// Armor
			if (x > 28 && x < 70 && y > 94 && y < 137) {
				slot = armor;
			}

			// Boots
			if (x > 28 && x < 70 && y > 143 && y < 189) {
				slot = boots;
			}

			// Necklace
			if (x > 28 && x < 70 && y > 45 && y < 88) {
				slot = necklace;
			}

			if (slot >= 0 && mInventory.GetSpaceLeft() > 0
					&& mPlayerInfo.GetEqiupItemImage(slot) > 0) {
				mSprite[slot].Unload();
				mPlayerInfo.SetEqiupItem(slot, 0, 0);

				RakNet::BitStream bsOut;
				bsOut.Write((RakNet::MessageID) ID_UNEQIUP_ITEM);
				bsOut.Write(slot);
				mRaknet.mPeer->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0,
						mRaknet.mServerAddress, false);
			}
		}

		mDragSprite.Render();
		mStats.Render();

		mSprite[weapon].SetPosition(position.x + 83, position.y + 155);
		mSprite[shield].SetPosition(position.x + 182, position.y + 155);
		mSprite[helmet].SetPosition(position.x + 32, position.y + 32);
		mSprite[armor].SetPosition(position.x + 32, position.y + 130);
		mSprite[boots].SetPosition(position.x + 32, position.y + 182);
		mSprite[necklace].SetPosition(position.x + 32, position.y + 81);
		mSprite[ring].SetPosition(position.x + 230, position.y + 132);
		mSprite[ring2].SetPosition(position.x + 230, position.y + 182);

		for (int a = 0; a < 8; ++a) {
			if (mPlayerInfo.GetEqiupItemImage(a) > 0) {
				mSprite[a].Render();
			}
		}

		char temp[CHAR_MAX];
		sprintf(temp, "MouseX: %f", x);
		Graphics_DebugText(temp, 5, 225, 0XFF0000);

		sprintf(temp, "MouseY: %f", y);
		Graphics_DebugText(temp, 5, 250, 0XFF0000);

		sprintf(temp, "%s", mPlayerInfo.GetUsername());
		mFont.Print(temp, (int) (position.x + 112.0f),
				(int) (position.y + 23.0f));

		if (mStats.GetVisible()) {
			sprintf(temp, "%d", mPlayerInfo.GetStr());
			mFont.Print(temp, (int) (position.x + 210.0f),
					(int) (position.y + 288.0f));

			sprintf(temp, "%d", mPlayerInfo.GetDex());
			mFont.Print(temp, (int) (position.x + 210.0f),
					(int) (position.y + 305.0f));

			sprintf(temp, "%d", mPlayerInfo.GetInt());
			mFont.Print(temp, (int) (position.x + 210.0f),
					(int) (position.y + 322.0f));

			sprintf(temp, "%d", mPlayerInfo.GetAttack());
			mFont.Print(temp, (int) (position.x + 210.0f),
					(int) (position.y + 339.0f));

			sprintf(temp, "%d", mPlayerInfo.GetDefence());
			mFont.Print(temp, (int) (position.x + 210.0f),
					(int) (position.y + 356.0f));

			sprintf(temp, "%d", mPlayerInfo.GetCrit());
			mFont.Print(temp, (int) (position.x + 210.0f),
					(int) (position.y + 373.0f));
		}
	}
}
예제 #27
0
bool AutoRPC::SendCall(const char *uniqueIdentifier, const char *stack, unsigned int bytesOnStack, char parameterCount)
{
	SystemAddress systemAddr;
	RPCIdentifier identifier;
	unsigned int outerIndex;
	unsigned int innerIndex;

	if (uniqueIdentifier==0)
		return false;

	identifier.uniqueIdentifier=(char*) uniqueIdentifier;
	identifier.isObjectMember=(outgoingNetworkID!=UNASSIGNED_NETWORK_ID);

	RakNet::BitStream bs;
	if (outgoingTimestamp!=0)
	{
		bs.Write((MessageID)ID_TIMESTAMP);
		bs.Write(outgoingTimestamp);
	}
	bs.Write((MessageID)ID_AUTO_RPC_CALL);
	if (parameterCount>=0)
	{
		bs.Write(true);
		bs.Write(parameterCount);
	}
	else
	{
		bs.Write(false);
	}
	bs.WriteCompressed(outgoingExtraData.GetNumberOfBitsUsed());
	bs.Write(&outgoingExtraData);
	if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID)
	{
		bs.Write(true);
		bs.Write(outgoingNetworkID);
	}
	else
	{
		bs.Write(false);
	}
	// This is so the call SetWriteOffset works
	bs.AlignWriteToByteBoundary();
	BitSize_t writeOffset = bs.GetWriteOffset();
	SystemAddress outgoingSystemAddress;
	if (outgoingSystemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID)
		outgoingSystemAddress = rakPeerInterface->GetSystemAddressFromGuid(outgoingSystemIdentifier.rakNetGuid);
	else
		outgoingSystemAddress = outgoingSystemIdentifier.systemAddress;
	if (outgoingBroadcast)
	{
		unsigned systemIndex;
		for (systemIndex=0; systemIndex < rakPeerInterface->GetMaximumNumberOfPeers(); systemIndex++)
		{
			systemAddr=rakPeerInterface->GetSystemAddressFromIndex(systemIndex);
			if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS && systemAddr!=outgoingSystemAddress)
			{
				if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex))
				{
					// Write a number to identify the function if possible, for faster lookup and less bandwidth
					bs.Write(true);
					bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex);
				}
				else
				{
					bs.Write(false);
					stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0);
				}

				bs.WriteCompressed(bytesOnStack);
				bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack);
				SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false);

				// Start writing again after ID_AUTO_RPC_CALL
				bs.SetWriteOffset(writeOffset);
			}
		}
	}
	else
	{
		systemAddr = outgoingSystemAddress;
		if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS)
		{
			if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex))
			{
				// Write a number to identify the function if possible, for faster lookup and less bandwidth
				bs.Write(true);
				bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex);
			}
			else
			{
				bs.Write(false);
				stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0);
			}

			bs.WriteCompressed(bytesOnStack);
			bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack);
			SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false);
		}
		else
			return false;
	}
	return true;
}
예제 #28
0
void NatPunchthroughServer::Update(void)
{
    ConnectionAttempt *connectionAttempt;
    User *user, *recipient;
    unsigned int i,j;
    RakNet::Time time = RakNet::GetTime();
    if (time > lastUpdate+250)
    {
        lastUpdate=time;

        for (i=0; i < users.Size(); i++)
        {
            user=users[i];
            for (j=0; j < user->connectionAttempts.Size(); j++)
            {
                connectionAttempt=user->connectionAttempts[j];
                if (connectionAttempt->sender==user)
                {
                    if (connectionAttempt->attemptPhase!=ConnectionAttempt::NAT_ATTEMPT_PHASE_NOT_STARTED &&
                            time > connectionAttempt->startTime &&
                            time > 10000 + connectionAttempt->startTime ) // Formerly 5000, but sometimes false positives
                    {
                        RakNet::BitStream outgoingBs;

                        // that other system might not be running the plugin
                        outgoingBs.Write((MessageID)ID_NAT_TARGET_UNRESPONSIVE);
                        outgoingBs.Write(connectionAttempt->recipient->guid);
                        outgoingBs.Write(connectionAttempt->sessionId);
                        rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,connectionAttempt->sender->systemAddress,false);

                        // 05/28/09 Previously only told sender about ID_NAT_CONNECTION_TO_TARGET_LOST
                        // However, recipient may be expecting it due to external code
                        // In that case, recipient would never get any response if the sender dropped
                        outgoingBs.Reset();
                        outgoingBs.Write((MessageID)ID_NAT_TARGET_UNRESPONSIVE);
                        outgoingBs.Write(connectionAttempt->sender->guid);
                        outgoingBs.Write(connectionAttempt->sessionId);
                        rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,connectionAttempt->recipient->systemAddress,false);

                        connectionAttempt->sender->isReady=true;
                        connectionAttempt->recipient->isReady=true;
                        recipient=connectionAttempt->recipient;


                        if (natPunchthroughServerDebugInterface)
                        {
                            char str[1024];
                            char addr1[128], addr2[128];
                            // 8/01/09 Fixed bug where this was after DeleteConnectionAttempt()
                            connectionAttempt->sender->systemAddress.ToString(true,addr1);
                            connectionAttempt->recipient->systemAddress.ToString(true,addr2);
                            sprintf(str, "Sending ID_NAT_TARGET_UNRESPONSIVE to sender %s and recipient %s.", addr1, addr2);
                            natPunchthroughServerDebugInterface->OnServerMessage(str);
                            RakNet::RakString log;
                            connectionAttempt->sender->LogConnectionAttempts(log);
                            connectionAttempt->recipient->LogConnectionAttempts(log);
                        }


                        connectionAttempt->sender->DerefConnectionAttempt(connectionAttempt);
                        connectionAttempt->recipient->DeleteConnectionAttempt(connectionAttempt);

                        StartPunchthroughForUser(user);
                        StartPunchthroughForUser(recipient);

                        break;
                    }
                }
            }
        }
    }
}
예제 #29
0
void AutoRPC::OnRPCUnknownRemoteIndex(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes, RakNetTime timestamp)
{
	char inputStack[ARPC_MAX_STACK_SIZE];
	NetworkID networkId;
	bool hasNetworkId=false;
	unsigned int functionIndex;
	unsigned int bytesOnStack;
	int numberOfBitsUsed;
	char parameterCount;
	bool hasParameterCount=false;

	RakNet::BitStream extraData;
	RakNet::BitStream bs(data,lengthInBytes,false);
	bs.Read(hasParameterCount);
	if (hasParameterCount)
		bs.Read(parameterCount);
	bs.ReadCompressed(functionIndex);
	bs.ReadCompressed(numberOfBitsUsed);
	extraData.AddBitsAndReallocate(numberOfBitsUsed);
	bs.ReadBits(extraData.GetData(), numberOfBitsUsed, false);
	extraData.SetWriteOffset(numberOfBitsUsed);
	bs.Read(hasNetworkId);
	if (hasNetworkId)
		bs.Read(networkId);
	bs.ReadCompressed(bytesOnStack);
	bs.ReadAlignedBytes((unsigned char*) inputStack, bytesOnStack);

	unsigned outerIndex;
	if (remoteFunctions.Has(systemAddress))
	{
		outerIndex = remoteFunctions.GetIndexAtKey(systemAddress);
		DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions[outerIndex];
		unsigned i;
		for (i=0; i < theList->Size(); i++)
		{
			if (theList->operator [](i).functionIndex==functionIndex)
			{
				RakNet::BitStream out;
				// Recover by resending the RPC with the function identifier string this time
				if (timestamp!=0)
				{
					out.Write((MessageID)ID_TIMESTAMP);
					out.Write(timestamp);
				}
				out.Write((MessageID)ID_AUTO_RPC_CALL);
				if (parameterCount>=0)
				{
					out.Write(true);
					out.Write(parameterCount);
				}
				else
				{
					out.Write(false);
				}				
				out.WriteCompressed(numberOfBitsUsed);
				out.Write(&extraData);
				out.Write(hasNetworkId);
				if (hasNetworkId)
					out.Write(networkId);
				out.AlignWriteToByteBoundary();
				out.Write(false);
				stringCompressor->EncodeString(theList->operator [](i).identifier.uniqueIdentifier, 512, &out, 0);
				out.WriteCompressed(bytesOnStack);
				out.WriteAlignedBytes((const unsigned char*) inputStack, bytesOnStack);
				SendUnified(&out, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddress, false);
				return;
			}
		}
	}

	// Failed to recover, inform the user
	Packet *p = rakPeerInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char));
	RakNet::BitStream bs2(p->data, sizeof(MessageID)+sizeof(unsigned char), false);
	bs2.SetWriteOffset(0);
	bs2.Write((MessageID)ID_RPC_REMOTE_ERROR);
	bs2.Write((unsigned char)RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED);
	stringCompressor->EncodeString("",256,&bs,0);
	p->systemAddress=systemAddress;
	rakPeerInterface->PushBackPacket(p, false);

}
int ReliableOrderedConvertedTest::RunTest(DataStructures::List<RakNet::RakString> params,bool isVerbose,bool noPauses)
{

	RakPeerInterface *sender, *receiver;
	unsigned int packetNumberSender[32],packetNumberReceiver[32], receivedPacketNumberReceiver, receivedTimeReceiver;
	char str[256];
	char ip[32];
	RakNetTime sendInterval, nextSend, currentTime, quitTime;
	unsigned short remotePort, localPort;
	unsigned char streamNumberSender,streamNumberReceiver;
	RakNet::BitStream bitStream;
	Packet *packet;
	bool doSend=false;

	for (int i=0; i < 32; i++)
	{
		packetNumberSender[i]=0;
		packetNumberReceiver[i]=0;

	}

	/*
	if (argc==2)
	{
	fp = fopen(argv[1],"wt");
	SetMalloc_Ex(LoggedMalloc);
	SetRealloc_Ex(LoggedRealloc);
	SetFree_Ex(LoggedFree);
	}
	else
	*/
	fp=0;
	destroyList.Clear(false,__FILE__,__LINE__);

	sender =RakNetworkFactory::GetRakPeerInterface();
	destroyList.Push(	sender ,__FILE__,__LINE__);
	//sender->ApplyNetworkSimulator(.02, 100, 50);

	/*
	if (str[0]==0)
	sendInterval=30;
	else
	sendInterval=atoi(str);*///possible future params

	sendInterval=30;

	/*
	printf("Enter remote IP: ");
	gets(ip);
	if (ip[0]==0)*/
	strcpy(ip, "127.0.0.1");

	/*
	printf("Enter remote port: ");
	gets(str);
	if (str[0]==0)*/
	strcpy(str, "60000");
	remotePort=atoi(str);
	/*
	printf("Enter local port: ");
	gets(str);
	if (str[0]==0)*/
	strcpy(str, "0");
	localPort=atoi(str);

	if (isVerbose)
		printf("Connecting...\n");

	SocketDescriptor tmp(localPort,0);
	sender->Startup(1, 30, &tmp, 1);
	sender->Connect(ip, remotePort, 0, 0);

	receiver =RakNetworkFactory::GetRakPeerInterface();
	destroyList.Push(	receiver ,__FILE__,__LINE__);

	/*
	printf("Enter local port: ");
	gets(str);
	if (str[0]==0)*/
	strcpy(str, "60000");
	localPort=atoi(str);

	if (isVerbose)
		printf("Waiting for connections...\n");

	SocketDescriptor tmp2(localPort,0);
	receiver->Startup(32, 30, &tmp2, 1);
	receiver->SetMaximumIncomingConnections(32);

	//	if (sender)
	//		sender->ApplyNetworkSimulator(128000, 50, 100);
	//	if (receiver)
	//		receiver->ApplyNetworkSimulator(128000, 50, 100);

	/*printf("How long to run this test for, in seconds?\n");
	gets(str);
	if (str[0]==0)*/
	strcpy(str, "12");

	currentTime = RakNet::GetTime();
	quitTime = atoi(str) * 1000 + currentTime;

	nextSend=currentTime;

	while (currentTime < quitTime)
		//while (1)
	{

		packet = sender->Receive();
		while (packet)
		{
			// PARSE TYPES
			switch(packet->data[0])
			{
			case ID_CONNECTION_REQUEST_ACCEPTED:
				if (isVerbose)
					printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
				doSend=true;
				nextSend=currentTime;
				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				if (isVerbose)
					printf("ID_NO_FREE_INCOMING_CONNECTIONS\n");
				break;
			case ID_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("ID_DISCONNECTION_NOTIFICATION\n");
				break;
			case ID_CONNECTION_LOST:
				if (isVerbose)
					printf("ID_CONNECTION_LOST\n");
				break;
			case ID_CONNECTION_ATTEMPT_FAILED:
				if (isVerbose)
					printf("Connection attempt failed\n");
				break;
			}

			sender->DeallocatePacket(packet);
			packet = sender->Receive();
		}

		while (doSend && currentTime > nextSend)
		{
			streamNumberSender=0;
			//	streamNumber = randomMT() % 32;
			// Do the send
			bitStream.Reset();
			bitStream.Write((unsigned char) (ID_USER_PACKET_ENUM+1));
			bitStream.Write(packetNumberSender[streamNumberSender]++);
			bitStream.Write(streamNumberSender);
			bitStream.Write(currentTime);
			char *pad;
			int padLength = (randomMT() % 5000) + 1;
			pad = new char [padLength];
			bitStream.Write(pad, padLength);
			delete [] pad;
			// Send on a random priority with a random stream
			// if (sender->Send(&bitStream, HIGH_PRIORITY, (PacketReliability) (RELIABLE + (randomMT() %2)) ,streamNumber, UNASSIGNED_SYSTEM_ADDRESS, true)==false)
			if (sender->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED ,streamNumberSender, UNASSIGNED_SYSTEM_ADDRESS, true)==false)
				packetNumberSender[streamNumberSender]--; // Didn't finish connecting yet?

			RakNetStatistics *rssSender;
			rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0));
			if (isVerbose)
				printf("Snd: %i.\n", packetNumberSender[streamNumberSender]);

			nextSend+=sendInterval;

			// Test halting
			//	if (rand()%20==0)
			//		nextSend+=1000;
		}

		packet = receiver->Receive();
		while (packet)
		{
			switch(packet->data[0])
			{
			case ID_NEW_INCOMING_CONNECTION:
				if (isVerbose)
					printf("ID_NEW_INCOMING_CONNECTION\n");
				break;
			case ID_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("ID_DISCONNECTION_NOTIFICATION\n");
				break;
			case ID_CONNECTION_LOST:
				if (isVerbose)
					printf("ID_CONNECTION_LOST\n");
				break;
			case ID_USER_PACKET_ENUM+1:
				bitStream.Reset();
				bitStream.Write((char*)packet->data, packet->length);
				bitStream.IgnoreBits(8); // Ignore ID_USER_PACKET_ENUM+1
				bitStream.Read(receivedPacketNumberReceiver);
				bitStream.Read(streamNumberReceiver);
				bitStream.Read(receivedTimeReceiver);

				if (receivedPacketNumberReceiver!=packetNumberReceiver[streamNumberReceiver])
				{

					//WARNING: If you modify the below code make sure the whole string remains in bounds, sprintf will NOT do it for you. 
					//The error string is 512 in length

					//Note: Removed buffer checking because chance is insignificant, left code if wanted in future. Needs limits.h ISO C standard.

					/*
					int maxIntWorkingCopy= INT_MAX;

					int maxIntCharLen =0; 

					while (maxIntWorkingCopy>0)
					{maxIntCharLen++;
					maxIntWorkingCopy/=10;
					}

					if (strlen(lastError)>maxIntCharLen* 3 +27)//512 should be a good len for now
					{*/

					sprintf(lastError,"Expecting %i got %i (channel %i).",packetNumberReceiver[streamNumberReceiver], receivedPacketNumberReceiver, streamNumberReceiver);

					/*
					}
					else
					{
					sprintf(lastError,"Did not get what was expected. More details can be given if the error string buffer size is increased.");

					}*/

					if (isVerbose)
					{

						RakNetStatistics *rssSender,*rssReceiver;
						char message[2048];

						rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0));

						rssReceiver=receiver->GetStatistics(receiver->GetSystemAddressFromIndex(0));
						StatisticsToString(rssSender, message, 2);
						printf("Server stats %s\n", message);
						StatisticsToString(rssReceiver, message, 2);
						printf("Client stats%s", message);

						DebugTools::ShowError(lastError,!noPauses && isVerbose,__LINE__,__FILE__);
					}

					return 1;
				}
				else
					if (isVerbose)
					{
						printf("Got %i.Channel %i.Len %i.", packetNumberReceiver[streamNumberReceiver], streamNumberReceiver, packet->length);

						printf("Sent=%u Received=%u Diff=%i.\n", receivedTimeReceiver, currentTime, (int)currentTime - (int) receivedTimeReceiver);
					}

					packetNumberReceiver[streamNumberReceiver]++;
					break;
			}

			receiver->DeallocatePacket(packet);
			packet = receiver->Receive();
		}

		RakSleep(0);

		currentTime=RakNet::GetTime();
	}

	if (isVerbose)
	{

		RakNetStatistics *rssSender,*rssReceiver;
		char message[2048];

		rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0));

		rssReceiver=receiver->GetStatistics(receiver->GetSystemAddressFromIndex(0));
		StatisticsToString(rssSender, message, 2);
		printf("Server stats %s\n", message);
		StatisticsToString(rssReceiver, message, 2);
		printf("Client stats%s", message);
	}

	if (fp)
		fclose(fp);

	return 0;
}