Ejemplo n.º 1
0
void ReplicaManager::Destruct(Replica *replica, PlayerID playerId, bool broadcast)
{
	assert(replica);

	bool objectExists;
	unsigned replicatedObjectsIndex;
	replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists);
	if (objectExists==false)
		return;

	// For each existing participant, send a packet telling them of this object destruction
	RakNet::BitStream outBitstream;
	unsigned i,tempIndex;
	bool replicaReferenced;
	ParticipantStruct *participantStruct;
	replicaReferenced=false;
	for (i=0; i < participantList.Size(); i++)
	{
		participantStruct=participantList[i];

		if ((broadcast==true && playerId!=participantStruct->playerId) || 
			(broadcast==false && playerId==participantStruct->playerId))
		{
			// Send the destruction packet immediately
			if (replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID && (replicatedObjects[replicatedObjectsIndex].allowedInterfaces & REPLICA_SEND_DESTRUCTION))
			{
				outBitstream.Reset();
				outBitstream.Write((unsigned char)ID_REPLICA_MANAGER_DESTRUCTION);
				outBitstream.Write(replica->GetNetworkID());
				replica->SendDestruction(&outBitstream, participantStruct->playerId);
				if (outBitstream.GetNumberOfBitsUsed()>0)
				{
					rakPeer->Send(&outBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, sendChannel, participantStruct->playerId, false);
				}
			}

			// Remove any pending commands that reference this object, for this player
			tempIndex = participantStruct->commandList.GetIndexFromKey(replica, &objectExists);
			if (objectExists)
				participantStruct->commandList.RemoveAtIndex(tempIndex);

			// Remove any remote object state tracking for this object, for this player
			tempIndex = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
			if (objectExists)
				participantStruct->remoteObjectList.RemoveAtIndex(tempIndex);
		}
		else if (replicaReferenced==false)
		{
			// See if any commands or objects reference replica
			if (participantStruct->commandList.HasData(replica))
				replicaReferenced=true;
			else if (participantStruct->remoteObjectList.HasData(replica))
				replicaReferenced=true;
		}
	}

	// Remove replica from the list if no commands and no remote objects reference it
	if (replicaReferenced==false)
		replicatedObjects.RemoveAtIndex(replicatedObjectsIndex);
}
Ejemplo n.º 2
0
void SendPlayerPoolToPlayer(PLAYERID playerID)
{
	// let the player know about all the players in the server
	for(PLAYERID p = 0; p < MAX_PLAYERS; p++)
	{
		if(!playerPool[p].iIsConnected)
			continue;

		if(p == playerID)
			continue;

		BYTE byteNameLen = (BYTE)strlen(playerPool[p].szPlayerName);
		RakNet::BitStream bs;
		bs.Reset();
		bs.Write(p);
		bs.Write((int)1);
		bs.Write((BYTE)0);
		bs.Write(byteNameLen);
		bs.Write(playerPool[p].szPlayerName, byteNameLen);
		pRakServer->RPC(&RPC_ServerJoin, &bs, HIGH_PRIORITY, RELIABLE,
			0, pRakServer->GetPlayerIDFromIndex(playerID), FALSE, FALSE, UNASSIGNED_NETWORK_ID, NULL);

		Sleep(5); // well, shit.
	}
}
Ejemplo n.º 3
0
void FileListTransfer::PushReference(SystemAddress systemAddress)
{
	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int i=0;
	unsigned int bytesRead;	
	char *dataBlocks[2];
	int lengths[2];
	RakNet::BitStream outBitstream;
	while (i < filesToPush.Size())
	{
		if (filesToPush[i].systemAddress==systemAddress)
		{
			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			outBitstream.Write(filesToPush[i].fileListNode.context);
			outBitstream.Write(filesToPush[i].setID);
			stringCompressor->EncodeString(filesToPush[i].fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(filesToPush[i].setIndex);
			outBitstream.WriteCompressed(filesToPush[i].fileListNode.dataLengthBytes); // Original length in bytes

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(filesToPush[i].chunkSize, __FILE__, __LINE__);
			if (buff==0)
			{
				notifyOutOfMemory(__FILE__, __LINE__);
				continue;
			}
			bytesRead=filesToPush[i].incrementalReadInterface->GetFilePart(filesToPush[i].fileListNode.fullPathToFile, filesToPush[i].currentOffset, filesToPush[i].chunkSize, buff, filesToPush[i].fileListNode.context);
			outBitstream.WriteCompressed(filesToPush[i].currentOffset);
			filesToPush[i].currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			bool done = bytesRead!=filesToPush[i].chunkSize;
			outBitstream.Write(done);

			if (callback)
			{
				callback->OnFilePush(filesToPush[i].fileListNode.filename, filesToPush[i].fileListNode.fileLengthBytes, filesToPush[i].currentOffset-bytesRead, bytesRead, done, filesToPush[i].systemAddress);
			}

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false);
			SendListUnified(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false);
			if (done)
			{
				// Done
				RakNet::OP_DELETE_ARRAY(filesToPush[i].fileListNode.filename, __FILE__, __LINE__);
				filesToPush.RemoveAtIndex(i);
			}
			rakFree_Ex(buff, __FILE__, __LINE__ );
			return;
		}			
		else
			i++;
	}	
}
void NatPunchthroughServer::OnClosedConnection(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]);
		}
	}
}
Ejemplo n.º 5
0
void CRcon::Packet_NewIncomingConnection(Packet* pPacket)
{
	in_addr in;
	in.s_addr = pPacket->playerId.binaryAddress;
	logprintf("[RCON] Admin [%s] has connected.", inet_ntoa(in));

	RakNet::BitStream bsSend;

	char* szHostname = pConsole->GetStringVariable( "hostname" );
	BYTE byteHostnameLength = strlen(szHostname);

	CPlayerPool* pPlayerPool = pNetGame->GetPlayerPool();

	bsSend.Write( byteHostnameLength );
	bsSend.Write( szHostname, byteHostnameLength );

	m_pRakServer->RPC( RPC_RconConnect,&bsSend,HIGH_PRIORITY,RELIABLE,0,UNASSIGNED_PLAYER_ID,true,false);
	bsSend.Reset();

	for( int i = 0; i < MAX_PLAYERS; i++ )
	{
		if( pPlayerPool->GetSlotState(i) == TRUE ) 
		{
			bsSend.Write((BYTE)i);
			bsSend.Write(pPlayerPool->GetPlayerName(i),MAX_PLAYER_NAME);

			pRcon->GetRakServer()->RPC( RPC_ServerJoin, &bsSend, HIGH_PRIORITY, RELIABLE, 0,
				UNASSIGNED_PLAYER_ID, true, false );

			bsSend.Reset();	
			
			PLAYER_DATA playerData = GetPlayerInformation( i );
			bsSend.Write( (BYTE)i );
			bsSend.Write( (PCHAR)&playerData, sizeof(PLAYER_DATA) );
			pRcon->GetRakServer()->RPC( RPC_RconPlayerInfo, &bsSend, HIGH_PRIORITY, RELIABLE, 0,
				UNASSIGNED_PLAYER_ID, true, false );

			bsSend.Reset();	
		}
	}
}
Ejemplo n.º 6
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_);
	}
}
void Application::CreateMissile(float x, float y, float w, int id)
{
#ifdef NETWORKMISSLE
	// Lab 13 Task 9b : Implement networked version of createmissile
	RakNet::BitStream bs;
	unsigned char msgid;
	unsigned char deleted = 0;
	if (mymissile)
	{
		//sendupdatethroughnetworktodeletethismissile
		deleted = 1;
		msgid = ID_UPDATEMISSILE;
		bs.Write(msgid);
		bs.Write(id);
		bs.Write(deleted);
		bs.Write(x);
		bs.Write(y);
		bs.Write(w);
		rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0,
			UNASSIGNED_SYSTEM_ADDRESS, true);
		//deleteexistingmissile
		delete mymissile;
		mymissile = 0;
	}
	//addanewmissilebasedonthefollowingparametercoordinates
	mymissile = new Missile("missile.png", x, y, w, id);
	//sendnetworkcommandtoaddnewmissile
	bs.Reset();
	msgid = ID_NEWMISSILE;
	bs.Write(msgid);
	bs.Write(id);
	bs.Write(x);
	bs.Write(y);
	bs.Write(w);
	rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0,
		UNASSIGNED_SYSTEM_ADDRESS, true);

#else
	// Lab 13 Task 3 : Implement local version missile creation
	if (mymissile) // Delete existing missle
	{
		delete mymissile;
		mymissile = NULL;
	}

	// Add missle
	mymissile = new Missile("missile.png", x, y, w, id);
#endif
}
void ServerApp::SendWelcomePackage(SystemAddress& addr)
{
	++newID;
	unsigned int shipcount = static_cast<unsigned int>(clients_.size());
	unsigned char msgid = ID_WELCOME;
	
	RakNet::BitStream bs;
	bs.Write(msgid);
	bs.Write(newID);
	bs.Write(shipcount);

	// Send all existing ships
	for (ClientMap::iterator itr = clients_.begin(); itr != clients_.end(); ++itr)
	{
		std::cout << "Ship " << itr->second.id << " pos" << itr->second.x_ << " " << itr->second.y_ << std::endl;
		bs.Write( itr->second.id );
		bs.Write( itr->second.x_ );
		bs.Write( itr->second.y_ );
		bs.Write( itr->second.type_ );
	}

	for (vector<ServerEnemy*>::iterator it = enemyList.begin(); it != enemyList.end(); ++it)
	{
		ServerEnemy* e = *it;
		bs.Write(e->id);
		bs.Write(e->active);
		bs.Write(e->type_);
		bs.Write(e->x_);
		bs.Write(e->y_);
		bs.Write(e->vel_x);
		bs.Write(e->vel_y);
		bs.Write(e->speed);
		bs.Write(e->hp);
	}

	bs.Write(base_hp);

	rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED,0, addr, false);

	bs.Reset();

	ServerGameObject newobject(newID);
	newobject.active = true;

	clients_.insert(std::make_pair(addr, newobject));
	clientList.push_back(addr); // Add client to list

	std::cout << "New guy, assigned id " << newID << std::endl;
}
Ejemplo n.º 9
0
void ConnectionGraph2::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
{
	(void) isIncoming;

	// Send all existing systems to new connection
	RakNet::BitStream bs;
	bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
	bs.Write((unsigned int)1);
	bs.Write(systemAddress);
	bs.Write(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((unsigned int) addresses.Size());

	unsigned int i;
	unsigned int count=0;
	for (i=0; i < addresses.Size(); i++)
	{
		if (addresses[i]==systemAddress)
			continue;
		
		bs.Write(addresses[i]);
		bs.Write(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);
	}

	RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(__FILE__,__LINE__);
	remoteSystem->guid=rakNetGUID;
	remoteSystems.Insert(rakNetGUID,remoteSystem,true,__FILE__,__LINE__);
}
bool CNetwork::update()
{
    Packet *packet = m_peer->Receive();
    while(packet)
    {
        handlePacket(packet);
        m_peer->DeallocatePacket(packet);
        packet = m_peer->Receive();
    }

    if (m_readTimer->elapsed() > m_tick_rate)
    {
        RakNet::BitStream bs;
        typedef std::map<int, CompLocation*> LocationMap;
        BOOST_FOREACH(LocationMap::value_type value, CKernel::data()->getAllLocation())
        {
            //TODO(#2#) BE SURE ABOUT NETWORK PERFORMANCE
            if(value.second->getTick() == m_tick)
            {
                bs.Reset();
                bs.Write((MessageID)ID_ENTITY_POS);
                bs.Write(value.first);
                bs.Write(value.second->position());
                bs.Write(value.second->direction());
                bs.Write(value.second->velocity());
                CompInfo* info = CKernel::data()->getGameObjectInfo(value.first);
                if (info)
                {
                    sendToAllInMap(info->map(), bs);
                }
            }
        }

        m_readTimer->restart();
        if(m_tick >= m_tick_max) m_tick = 0;
        else ++m_tick;
    }
Ejemplo n.º 11
0
void Router2::SendOOBMessages(Router2::MiniPunchRequest *mpr)
{
	// Mini NAT punch
	// Send from srcToDestPort to packet->systemAddress (source). If the message arrives, the remote system should reply.
	SendOOBFromSpecifiedSocket(ID_ROUTER_2_REPLY_TO_SENDER_PORT, mpr->sourceAddress, mpr->forwardingSocket);

	// Send from destToSourcePort to endpointSystemAddress (destination). If the message arrives, the remote system should reply.
	SendOOBFromSpecifiedSocket(ID_ROUTER_2_REPLY_TO_SENDER_PORT, mpr->endpointAddress, mpr->forwardingSocket);


    if (debugInterface) {
        char buff [512];

        char buff2[128];

        mpr->sourceAddress   .ToString(true,buff2);

        debugInterface->ShowDiagnostic(FormatStringTS(buff,"call SendOOBFromSpecifiedSocket(...,%s,...)", buff2));

        mpr->endpointAddress .ToString(true,buff2);

        debugInterface->ShowDiagnostic(FormatStringTS(buff,"call SendOOBFromSpecifiedSocket(...,%s,...)", buff2));
    }                                              

	// Tell source to send to forwardingPort
	RakNet::BitStream extraData;
	extraData.Write(mpr->forwardingPort);
	RakAssert(mpr->forwardingPort!=0);
	SendOOBFromRakNetPort(ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT, &extraData, mpr->sourceAddress);

	// Tell destination to send to forwardingPort
	extraData.Reset();
	extraData.Write(mpr->forwardingPort);
	RakAssert(mpr->forwardingPort);
	SendOOBFromRakNetPort(ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT, &extraData, mpr->endpointAddress);
}
Ejemplo n.º 12
0
/*
What is being done here is having 8 peers all connect to eachother and be
connected. Then it check if they all connect. If so send data in ordered reliable mode for 100
loops.

Possible ideas for changes:
Possibly use rakpeerinterfaces GetSystemList() for number of 
connected peers instead of manually tracking. Would be slower though,
shouldn't be significant at this number but the recieve speed it part of the test.

Success conditions:
Peers connect and receive all packets in order.
No disconnections allowed in this version of the test.



Failure conditions:

If cannot connect to all peers for 20 seconds.
All packets are not recieved.
All packets are not in order.
Disconnection.
*/
int EightPeerTest::RunTest(DataStructures::List<RakNet::RakString> params,bool isVerbose,bool noPauses)
{

	const int peerNum= 8;
	RakPeerInterface *peerList[peerNum];//A list of 8 peers
	int connectionAmount[peerNum];//Counter for me to keep track of connection requests and accepts
	int recievedFromList[peerNum][peerNum];//Counter for me to keep track of packets received
	int lastNumberReceivedFromList[peerNum][peerNum];//Counter for me to keep track of last recieved sequence number



	Packet *packet;
	RakNet::BitStream bitStream;
	destroyList.Clear(false,__FILE__,__LINE__);

	//Initializations of the arrays
	for (int i=0;i<peerNum;i++)
	{
		peerList[i]=RakNetworkFactory::GetRakPeerInterface();
		destroyList.Push(peerList[i],__FILE__,__LINE__);
		connectionAmount[i]=0;


		for (int j=0;j<peerNum;j++)
		{
			recievedFromList[i][j]=0;
			lastNumberReceivedFromList[i][j]=0;
		}

		peerList[i]->Startup(peerNum*2, 30, &SocketDescriptor(60000+i,0), 1);
		peerList[i]->SetMaximumIncomingConnections(peerNum);

	}




	//Connect all the peers together



	for (int i=0;i<peerNum;i++)
	{

		for (int j=i+1;j<peerNum;j++)//Start at i+1 so don't connect two of the same together.
		{

			if (!peerList[i]->Connect("127.0.0.1", 60000+j, 0,0))
			{

				if (isVerbose)
				{
					DebugTools::ShowError("Problem while calling connect. \n",!noPauses && isVerbose,__LINE__,__FILE__);

				}


				return 1;//This fails the test, don't bother going on.

			}

		}

	}







	RakNetTime entryTime=RakNet::GetTime();//Loop entry time
	bool initialConnectOver=false;//Our initial connect all has been done.


	for (int k=0;k<100;)//Quit after we send 100 messages while connected, if not all connected and not failure, otherwise fail after 20 seconds and exit
	{



		bool allConnected=true;//Start true, only one failed case makes it all fail
		for (int i=0;i<peerNum;i++)//Make sure all peers are connected to eachother
		{
			if (connectionAmount[i]<peerNum-1)
			{

				allConnected=false;
			}
		}


		if (RakNet::GetTime()-entryTime>20000 &&!initialConnectOver &&!allConnected)//failed for 20 seconds
		{

			if (isVerbose)
				DebugTools::ShowError("Failed to connect to all peers after 20 seconds",!noPauses && isVerbose,__LINE__,__FILE__);


			return 2;
			break;
		}

		if (allConnected)
		{
			if(!initialConnectOver)
				initialConnectOver=true;

			for (int i=0;i<peerNum;i++)//Have all peers send a message to all peers
			{

				bitStream.Reset();


				bitStream.Write((unsigned char) (ID_USER_PACKET_ENUM+1));

				bitStream.Write(k);
				bitStream.Write(i);

				peerList[i]->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);

			}
			k++;
		}

		if (k>=97)//This is our last 3 loops, give it time to send packet and arrive on interface, 2 seconds is more than enough 
		{
			RakSleep(2000);
		}

		for (int i=0;i<peerNum;i++)//Receive for all peers
		{

			if (allConnected)//If all connected try to make the data more visually appealing by bunching it in one receive
			{
				int waittime=0;
				do
				{
					packet=peerList[i]->Receive();
					waittime++;

					if (!packet)
					{
						RakSleep(1);

					}

					if (waittime>1000)//Check for packet every millisec and if one second has passed move on, don't block execution
					{
						break;
					}
				}
				while(!packet);//For testing purposes wait for packet a little while, go if not recieved
			}
			else//Otherwise just keep recieving quickly until connected
			{
				packet=peerList[i]->Receive();


			}
			if (isVerbose)
				printf("For peer %i with %i connected peers.\n",i,connectionAmount[i]);
			while(packet)
			{
				switch (packet->data[0])
				{
				case ID_REMOTE_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
					{
						printf("Another client has disconnected.\n");
						DebugTools::ShowError("Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					}
					return 3;
					break;
				case ID_REMOTE_CONNECTION_LOST:
					if (isVerbose)
					{
						printf("Another client has lost the connection.\n");
						DebugTools::ShowError("Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);           
					}
					return 3;
					break;
				case ID_REMOTE_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("Another client has connected.\n");
					break;
				case ID_CONNECTION_REQUEST_ACCEPTED:
					if (isVerbose)              
						printf("Our connection request has been accepted.\n");
					connectionAmount[i]++;

					break;
				case ID_CONNECTION_ATTEMPT_FAILED:

					if (isVerbose)
						DebugTools::ShowError("A connection has failed.\n Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					return 2;
					break;

				case ID_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("A connection is incoming.\n");
					connectionAmount[i]++;//For this test assume connection. Test will fail if connection fails.
					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS://Should not happend
					if (isVerbose)    
					{
						printf("The server is full. This shouldn't happen in this test ever.\n");

						DebugTools::ShowError("Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					}
					return 2;
					break;

				case ID_ALREADY_CONNECTED:
					if (isVerbose)              
						printf("Already connected\n");//Shouldn't happen

					break;


				case ID_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
					{
						printf("We have been disconnected.\n");

						DebugTools::ShowError("Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					}
					return 3;
					break;
				case ID_CONNECTION_LOST:
					allConnected=false;
					connectionAmount[i]--;
					if (isVerbose)
					{
						printf("Connection lost.\n");

						DebugTools::ShowError("Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					}

					return 3;

					break;
				default:


					if (packet->data[0]==ID_USER_PACKET_ENUM+1)
					{


						int thePeerNum;
						int sequenceNum;
						bitStream.Reset();
						bitStream.Write((char*)packet->data, packet->length);
						bitStream.IgnoreBits(8);
						bitStream.Read(sequenceNum);
						bitStream.Read(thePeerNum);


						if (isVerbose)
							printf("Message %i from %i\n",sequenceNum,thePeerNum );

						if (thePeerNum>=0&&thePeerNum<peerNum)
						{
							if (lastNumberReceivedFromList[i][thePeerNum]==sequenceNum)
							{
								lastNumberReceivedFromList[i][thePeerNum]++;
							}
							else
							{
								if (isVerbose)
								{
									printf("Packets out of order");
									DebugTools::ShowError("Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);

								}
								return 4;
							}
							recievedFromList[i][thePeerNum]++;}
					}
					break;
				}

				peerList[i]->DeallocatePacket(packet);

				// Stay in the loop as long as there are more packets.
				packet = peerList[i]->Receive();
			}
		}
		RakSleep(0);//If needed for testing
	}





	for (int i=0;i<peerNum;i++)
	{

		for (int j=0;j<peerNum;j++)
		{
			if (i!=j)
			{
				if (isVerbose)
					printf("%i recieved %i packets from %i\n",i,recievedFromList[i][j],j);
				if  (recievedFromList[i][j]!=100)
				{
					if (isVerbose)
					{
						printf("Not all packets recieved. it was in reliable ordered mode so that means test failed or wait time needs increasing\n");

						DebugTools::ShowError("Test failed.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					}
					return 5;


				}

			}
		}
	}


	printf("All packets recieved in order,pass\n");
	return 0;

}
Ejemplo n.º 13
0
int main(int argc, char **argv)
{
	RakPeerInterface *rakPeer;
	char str[256];
	char ip[32];
	unsigned short remotePort, localPort;
	RakNet::Packet *packet;

	printf("This project tests sending a burst of messages to a remote system.\n");
	printf("Difficulty: Beginner\n\n");
	
	rakPeer = RakNet::RakPeerInterface::GetInstance();
	
	printf("Enter remote IP (enter to not connect): ");
	Gets(ip, sizeof(ip));
	if (ip[0])
	{
		printf("Enter remote port: ");
		Gets(str, sizeof(str));
		if (str[0]==0)
			strcpy(str, "60000");
		remotePort=atoi(str);
		
		printf("Enter local port: ");
		Gets(str, sizeof(str));
		if (str[0]==0)
			strcpy(str, "0");
		localPort=atoi(str);
		
		RakNet::SocketDescriptor socketDescriptor(localPort,0);
		rakPeer->Startup(32, &socketDescriptor, 1);
		
		printf("Connecting...\n");
		rakPeer->Connect(ip, remotePort, 0, 0);
	}
	else
	{
		printf("Enter local port: ");
		Gets(str, sizeof(str));
		if (str[0]==0)
			strcpy(str, "60000");
		localPort=atoi(str);
		
		RakNet::SocketDescriptor socketDescriptor(localPort,0);
		rakPeer->Startup(32, &socketDescriptor, 1);
	}
	rakPeer->SetMaximumIncomingConnections(32);
	
	printf("'s' to send. ' ' for statistics. 'q' to quit.\n");

	while (1)
	{
		if (kbhit())
		{
			char ch=getch();
			if (ch=='q')
				return 1;
			else if (ch==' ')
			{
				RakNetStatistics *rss;
				char message[2048];
					rss=rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0));
				StatisticsToString(rss, message, 2);
				printf("%s", message);
			}
			else if (ch=='s')
			{
				char msgSizeStr[128], msgCountStr[128];
				uint32_t msgSize, msgCount,index;
				printf("Enter message size in bytes: ");
				Gets(msgSizeStr, sizeof(msgSizeStr));
				if (msgSizeStr[0]==0)
					msgSize=4096;
				else
					msgSize=atoi(msgSizeStr);
				printf("Enter times to repeatedly send message: ");
				Gets(msgCountStr, sizeof(msgCountStr));
				if (msgCountStr[0]==0)
					msgCount=128;
				else
					msgCount=atoi(msgCountStr);
				RakNet::BitStream bitStream;
				for (index=0; index < msgCount; index++)
				{
					bitStream.Reset();
					bitStream.Write((MessageID)ID_USER_PACKET_ENUM);
					bitStream.Write(msgSize);
					bitStream.Write(index);
					bitStream.Write(msgCount);
					bitStream.PadWithZeroToByteLength(msgSize);
					rakPeer->Send(&bitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
				}
				printf("Sent\n");
					
			}
		}
		
		for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive())
		{
			switch(packet->data[0])
			{
			case ID_CONNECTION_REQUEST_ACCEPTED:
				printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
				break;
			case ID_NEW_INCOMING_CONNECTION:
				printf("ID_NEW_INCOMING_CONNECTION\n");
				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				printf("ID_NO_FREE_INCOMING_CONNECTIONS\n");
				break;
			case ID_DISCONNECTION_NOTIFICATION:
				printf("ID_DISCONNECTION_NOTIFICATION\n");
				break;
			case ID_CONNECTION_LOST:
				printf("ID_CONNECTION_LOST\n");
				break;
			case ID_CONNECTION_ATTEMPT_FAILED:
				printf("Connection attempt failed\n");
				break;
			case ID_USER_PACKET_ENUM:
				{
					uint32_t msgSize, msgCount, index;
					RakNet::BitStream bitStream(packet->data, packet->length, false);
					bitStream.IgnoreBytes(sizeof(MessageID));
					bitStream.Read(msgSize);
					bitStream.Read(index);
					bitStream.Read(msgCount);
					printf("%i/%i len=%i", index+1, msgCount, packet->length);
					if (msgSize > BITS_TO_BYTES(bitStream.GetReadOffset()) && packet->length!=msgSize)
						printf("UNDERLENGTH!\n");
					else
						printf("\n");
					break;
				}
			default:
				printf("Unknown message type %i\n", packet->data[0]);
			}
		}
	
		RakSleep(30);
	}

	rakPeer->Shutdown(100);
	RakNet::RakPeerInterface::DestroyInstance(rakPeer);

	return 1;
}
void NatTypeDetectionServer::Update(void)
{
	int i=0;
	RakNet::TimeMS time = RakNet::GetTimeMS();
	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;
			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;
				printf("Testing NAT_TYPE_NONE\n");
				// S4P5 sends to C2. If arrived, no NAT. Done. (Else S4P5 potentially banned, do not use again).
				saOut=natDetectionAttempts[i].systemAddress;
				saOut.SetPort(natDetectionAttempts[i].c2Port);
				SocketLayer::SendTo_PC( s4p5, (const char*) &c, 1, saOut, __FILE__, __LINE__  );
				break;
			case STATE_TESTING_FULL_CONE_1:
			case STATE_TESTING_FULL_CONE_2:
				printf("Testing NAT_TYPE_FULL_CONE\n");
				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.SetPort(natDetectionAttempts[i].systemAddress.GetPort());
				SocketLayer::SendTo_PC( s2p3, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __LINE__  );
				break;
			case STATE_TESTING_ADDRESS_RESTRICTED_1:
			case STATE_TESTING_ADDRESS_RESTRICTED_2:
				printf("Testing NAT_TYPE_ADDRESS_RESTRICTED\n");
				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.SetPort(natDetectionAttempts[i].systemAddress.GetPort());
				SocketLayer::SendTo_PC( s1p2, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __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
				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++;
	}
}
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;
}
void UDPProxyCoordinator::OnForwardingReplyFromServerToCoordinator(Packet *packet)
{
	RakNet::BitStream incomingBs(packet->data, packet->length, false);
	incomingBs.IgnoreBytes(2);
	SenderAndTargetAddress sata;
	incomingBs.Read(sata.senderClientAddress);
	incomingBs.Read(sata.targetClientAddress);
	DataStructures::DefaultIndexType index = forwardingRequestList.GetIndexOf(sata);
	if (index==(DataStructures::DefaultIndexType)-1)
	{
		// The guy disconnected before the request finished
		return;
	}
	ForwardingRequest *fw = forwardingRequestList[index];

	UDPForwarderResult success;
	unsigned char c;
	incomingBs.Read(c);
	success=(UDPForwarderResult)c;

	RakNet::BitStream outgoingBs;
	if (success==UDPFORWARDER_SUCCESS)
	{
		char serverIP[64];
		packet->systemAddress.ToString(false,serverIP);
		unsigned short srcToDestPort;
		unsigned short destToSourcePort;
		incomingBs.Read(srcToDestPort);
		incomingBs.Read(destToSourcePort);

		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
		outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_SUCCEEDED);
		outgoingBs.Write(sata.senderClientAddress);
		outgoingBs.Write(sata.targetClientAddress);
		outgoingBs.Write(RakNet::RakString(serverIP));
		outgoingBs.Write(srcToDestPort);
		outgoingBs.Write(destToSourcePort);
		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);

		outgoingBs.Reset();
		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
		outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_NOTIFICATION);
		outgoingBs.Write(sata.senderClientAddress);
		outgoingBs.Write(sata.targetClientAddress);
		outgoingBs.Write(RakNet::RakString(serverIP));
		outgoingBs.Write(srcToDestPort);
		outgoingBs.Write(destToSourcePort);
		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sata.targetClientAddress, false);

		// 05/18/09 Keep the entry around for some time after success, so duplicates are reported if attempting forwarding from the target system before notification of success
		fw->timeoutAfterSuccess=RakNet::GetTimeMS()+fw->timeoutOnNoDataMS;
		// forwardingRequestList.RemoveAtIndex(index);
		// RakNet::OP_DELETE(fw,_FILE_AND_LINE_);

		return;
	}
	else if (success==UDPFORWARDER_NO_SOCKETS)
	{
		// Try next server
		TryNextServer(sata, fw);
	}
	else
	{
		RakAssert(success==UDPFORWARDER_FORWARDING_ALREADY_EXISTS);

		// Return in progress
		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
		outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS);
		outgoingBs.Write(sata.senderClientAddress);
		outgoingBs.Write(sata.targetClientAddress);
		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);
		forwardingRequestList.RemoveAtIndex(index,_FILE_AND_LINE_);
		RakNet::OP_DELETE(fw,_FILE_AND_LINE_);
	}
}
Ejemplo n.º 17
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();

	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::GLOBAL_EVENT, 0);

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

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

	// Write the player colour
	bitStream.Write(0xFFFFFF/*CServer::GetInstance()->GetPlayerManager()->GetAt(playerId)->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, playerId, false);

	CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_START_GAME), &bitStream, HIGH_PRIORITY, RELIABLE, playerId, false);

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

		}
	}

	for (EntityId i = 0; i < CServer::GetInstance()->GetPlayerManager()->GetMax(); ++i)
	{
		if (CServer::GetInstance()->GetPlayerManager()->DoesExists(i) && i != playerId)
		{
			bitStream.Reset();
			bitStream.WriteCompressed(playerId);
			bitStream.Write(strName.Get());
			CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_NEW_PLAYER), &bitStream, HIGH_PRIORITY, RELIABLE, 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()*/90);

			CVector3 vecPosition;
			pVehicle->GetPosition(vecPosition);
			bitStream.Write(vecPosition);
			CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_CREATE_VEHICLE), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, -1, true);
		}
	}

	bitStream.Reset();

	bitStream.WriteCompressed(playerId);
	bitStream.Write(7);
	bitStream.Write(3);
	bitStream.Write(3);
	bitStream.Write(1);
}
Ejemplo n.º 18
0
void DownloadFinished(RakNet::BitStream * pBitStream, RakNet::Packet * pPacket)
{

	// 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 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));
	EntityId 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);
		}
	}

	for (EntityId i = 0; i < CServer::GetInstance()->GetCheckpointManager()->GetMax(); ++i)
	{
		if (CServer::GetInstance()->GetCheckpointManager()->DoesExists(i))
		{
			bitStream.Reset();
			CCheckpointEntity * pCheckpoint = CServer::GetInstance()->GetCheckpointManager()->GetAt(i);
			bitStream.Write(pCheckpoint->GetId());
			bitStream.Write(pCheckpoint->GetType());

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

			CVector3 vecTargetPosition;
			pCheckpoint->GetTargetPosition(vecTargetPosition);
			bitStream.Write(vecTargetPosition);

			bitStream.Write(pCheckpoint->GetRadius());

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


			// Checkpoint visibility
			if (!pCheckpoint->GetVisible())
			{
				bitStream.Reset();

				bitStream.Write(pCheckpoint->GetId());
				CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_CHECKPOINT_HIDE), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false);

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

	if (callback)
		fileList->SetCallback(callback);

	unsigned int i, totalLength;
	RakNet::BitStream outBitstream;
	bool sendReference;
	char *dataBlocks[2];
	int lengths[2];
	totalLength=0;
	for (i=0; i < fileList->fileList.Size(); i++)
	{
		const FileListNode &fileListNode = fileList->fileList[i];
		totalLength+=fileListNode.fileLengthBytes;
	}

	// Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes
	bool anythingToWrite;
	outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER);
	outBitstream.Write(setID);
	anythingToWrite=fileList->fileList.Size()>0;
	outBitstream.Write(anythingToWrite);
	if (anythingToWrite)
	{
		outBitstream.WriteCompressed(fileList->fileList.Size());
		outBitstream.WriteCompressed(totalLength);

		if (rakPeer)
			rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		else
			SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
	
		for (i=0; i < fileList->fileList.Size(); i++)
		{
			outBitstream.Reset();
			sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0;
			if (sendReference)
			{
				StoreForPush(fileList->fileList[i].context, setID, fileList->fileList[i].filename, fileList->fileList[i].fullPathToFile, i, fileList->fileList[i].fileLengthBytes, fileList->fileList[i].dataLengthBytes, recipient, priority, orderingChannel, _incrementalReadInterface, _chunkSize);
				continue;
			}

			outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
			
			outBitstream.Write(fileList->fileList[i].context);
			outBitstream.Write(setID);
			stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream);
			
			outBitstream.WriteCompressed(i);
			outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes

			outBitstream.AlignWriteToByteBoundary();

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=fileList->fileList[i].data;
			lengths[1]=fileList->fileList[i].dataLengthBytes;
			if (rakPeer)
				rakPeer->SendList(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
			else
				SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		}
	}
	else
	{
		if (rakPeer)
			rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		else
			SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
	}
}
Ejemplo n.º 21
0
void FileListTransfer::Send(FileList *fileList, RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, bool compressData, IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize)
{
	(void) compressData;

	if (callback)
		fileList->SetCallback(callback);

	unsigned int i, totalLength;
	RakNet::BitStream outBitstream;
	bool sendReference;
	const char *dataBlocks[2];
	int lengths[2];
	totalLength=0;
	for (i=0; i < fileList->fileList.Size(); i++)
	{
		const FileListNode &fileListNode = fileList->fileList[i];
		totalLength+=fileListNode.fileLengthBytes;
	}

	// Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes
	bool anythingToWrite;
	outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER);
	outBitstream.Write(setID);
	anythingToWrite=fileList->fileList.Size()>0;
	outBitstream.Write(anythingToWrite);
	if (anythingToWrite)
	{
		outBitstream.WriteCompressed(fileList->fileList.Size());
		outBitstream.WriteCompressed(totalLength);

		if (rakPeer)
			rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		else
			SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);

		DataStructures::Queue<FileToPush*> filesToPush;
	
		for (i=0; i < fileList->fileList.Size(); i++)
		{
			sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0;
			if (sendReference)
			{
				FileToPush *fileToPush = RakNet::OP_NEW<FileToPush>(__FILE__,__LINE__);
				fileToPush->fileListNode.context=fileList->fileList[i].context;
				fileToPush->setIndex=i;
				fileToPush->fileListNode.filename=fileList->fileList[i].filename;
				fileToPush->fileListNode.fullPathToFile=fileList->fileList[i].fullPathToFile;
				fileToPush->fileListNode.fileLengthBytes=fileList->fileList[i].fileLengthBytes;
				fileToPush->fileListNode.dataLengthBytes=fileList->fileList[i].dataLengthBytes;
				//	fileToPush->systemAddress=recipient;
				fileToPush->setID=setID;
				fileToPush->packetPriority=priority;
				fileToPush->orderingChannel=orderingChannel;
				fileToPush->currentOffset=0;
				fileToPush->incrementalReadInterface=_incrementalReadInterface;
				fileToPush->chunkSize=_chunkSize;
				filesToPush.Push(fileToPush,__FILE__,__LINE__);
			}
			else
			{
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);

				outBitstream.Write(fileList->fileList[i].context);
				outBitstream.Write(setID);
				stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream);

				outBitstream.WriteCompressed(i);
				outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes

				outBitstream.AlignWriteToByteBoundary();

				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=fileList->fileList[i].data;
				lengths[1]=fileList->fileList[i].dataLengthBytes;
				SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
			}
		}

		if (filesToPush.IsEmpty()==false)
		{
			FileToPushRecipient *ftpr=0;
			filesToPushAllSameAddressMutex.Lock();
			for (unsigned int i=0; i < filesToPushAllSameAddress.Size(); i++)
			{
				if (filesToPushAllSameAddress[i]->systemAddress==recipient)
				{
					ftpr=filesToPushAllSameAddress[i];
					break;
				}
			}
			if (ftpr==0)
			{
				ftpr = RakNet::OP_NEW<FileToPushRecipient>(__FILE__,__LINE__);
				ftpr->systemAddress=recipient;
				filesToPushAllSameAddress.Push(ftpr, __FILE__,__LINE__);
			}
			while (filesToPush.IsEmpty()==false)
			{
				ftpr->filesToPush.Push(filesToPush.Pop(), __FILE__,__LINE__);
			}
			filesToPushAllSameAddressMutex.Unlock();
			SendIRIToAddress(recipient);
			return;
		}
	}
	else
	{
		if (rakPeer)
			rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		else
			SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
	}
}
Ejemplo n.º 22
0
void FileListTransfer::Send(FileList *fileList, RakNet::RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize)
{
	for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++)
		fileList->AddCallback(fileListProgressCallbacks[flpcIndex]);

	unsigned int i, totalLength;
	RakNet::BitStream outBitstream;
	bool sendReference;
	const char *dataBlocks[2];
	int lengths[2];
	totalLength=0;
	for (i=0; i < fileList->fileList.Size(); i++)
	{
		const FileListNode &fileListNode = fileList->fileList[i];
		totalLength+=fileListNode.dataLengthBytes;
	}

	// Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes
	bool anythingToWrite;
	outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER);
	outBitstream.Write(setID);
	anythingToWrite=fileList->fileList.Size()>0;
	outBitstream.Write(anythingToWrite);
	if (anythingToWrite)
	{
		outBitstream.WriteCompressed(fileList->fileList.Size());
		outBitstream.WriteCompressed(totalLength);

		if (rakPeer)
			rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		else
			SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);

		DataStructures::Queue<FileToPush*> filesToPush;
	
		for (i=0; i < fileList->fileList.Size(); i++)
		{
			sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0;
			if (sendReference)
			{
				FileToPush *fileToPush = RakNet::OP_NEW<FileToPush>(_FILE_AND_LINE_);
				fileToPush->fileListNode.context=fileList->fileList[i].context;
				fileToPush->setIndex=i;
				fileToPush->fileListNode.filename=fileList->fileList[i].filename;
				fileToPush->fileListNode.fullPathToFile=fileList->fileList[i].fullPathToFile;
				fileToPush->fileListNode.fileLengthBytes=fileList->fileList[i].fileLengthBytes;
				fileToPush->fileListNode.dataLengthBytes=fileList->fileList[i].dataLengthBytes;
				//	fileToPush->systemAddress=recipient;
				//fileToPush->setID=setID;
				fileToPush->packetPriority=priority;
				fileToPush->orderingChannel=orderingChannel;
				fileToPush->currentOffset=0;
				fileToPush->incrementalReadInterface=_incrementalReadInterface;
				fileToPush->chunkSize=_chunkSize;
				filesToPush.Push(fileToPush,_FILE_AND_LINE_);
			}
			else
			{
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
				outBitstream << fileList->fileList[i].context;
				// outBitstream.Write(fileList->fileList[i].context);
				outBitstream.Write(setID);
				StringCompressor::Instance()->EncodeString(fileList->fileList[i].filename, 512, &outBitstream);

				outBitstream.WriteCompressed(i);
				outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes

				outBitstream.AlignWriteToByteBoundary();

				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=fileList->fileList[i].data;
				lengths[1]=fileList->fileList[i].dataLengthBytes;
				SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
			}
		}

		if (filesToPush.IsEmpty()==false)
		{
			FileToPushRecipient *ftpr;

			fileToPushRecipientListMutex.Lock();
			for (unsigned int i=0; i < fileToPushRecipientList.Size(); i++)
			{
				if (fileToPushRecipientList[i]->systemAddress==recipient && fileToPushRecipientList[i]->setId==setId)
				{
// 					ftpr=fileToPushRecipientList[i];
// 					ftpr->AddRef();
// 					break;
					RakAssert("setId already in use for this recipient" && 0);
				}
			}
			fileToPushRecipientListMutex.Unlock();

			//if (ftpr==0)
			//{
				ftpr = RakNet::OP_NEW<FileToPushRecipient>(_FILE_AND_LINE_);
				ftpr->systemAddress=recipient;
				ftpr->setId=setID;
				ftpr->refCount=2; // Allocated and in the list
				fileToPushRecipientList.Push(ftpr, _FILE_AND_LINE_);
			//}
			while (filesToPush.IsEmpty()==false)
			{
				////ftpr->filesToPushMutex.Lock();
				ftpr->filesToPush.Push(filesToPush.Pop(), _FILE_AND_LINE_);
				////ftpr->filesToPushMutex.Unlock();
			}
			// ftpr out of scope
			ftpr->Deref();
			SendIRIToAddress(recipient, setID);
			return;
		}
		else
		{
			for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++)
				fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(recipient, setID);
		}
	}
	else
	{
		for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++)
			fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(recipient, setID);

		if (rakPeer)
			rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		else
			SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
	}
}
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;
					}
				}
			}
		}
	}
}
Ejemplo n.º 24
0
void NatPunchthrough::Update(RakPeerInterface *peer)
{
	(void) peer;
	if (connectionRequestList.Size())
	{
		RakNetTime time = RakNet::GetTime();
		RakNet::BitStream outBitstream;
		unsigned i;
		i=0;
		while (i < connectionRequestList.Size())
		{
			// Remove old connection requests that get no answer
			if (connectionRequestList[i]->timeoutTime < time)
			{
				rakFree(connectionRequestList[i]->passwordData);
				delete connectionRequestList[i];
				connectionRequestList.RemoveAtIndex(i);
				continue;
			}
			
			// If we are a facilitator, do pings
			if (connectionRequestList[i]->facilitatingConnection)
			{
				if (time >= connectionRequestList[i]->nextActionTime )
				{
					if (connectionRequestList[i]->pingCount < PING_COUNT)
					{
						// Ping
						connectionRequestList[i]->pingCount++;
						rakPeer->Ping(connectionRequestList[i]->receiverPublic);
						rakPeer->Ping(connectionRequestList[i]->senderPublic);
						connectionRequestList[i]->nextActionTime=time+PING_INTERVAL;
					}
					else if (connectionRequestList[i]->pingCount == PING_COUNT)
					{
						// Done pinging.  Wait till the next stage
						int receiverPing, senderPing;
						receiverPing=rakPeer->GetAveragePing(connectionRequestList[i]->receiverPublic);
						senderPing=rakPeer->GetAveragePing(connectionRequestList[i]->senderPublic);
						if (receiverPing > senderPing)
							connectionRequestList[i]->nextActionTime=(RakNetTime)(receiverPing*SEND_TIMESTAMP_DELAY_PING_MULTIPLE);
						else
							connectionRequestList[i]->nextActionTime=(RakNetTime)(senderPing*SEND_TIMESTAMP_DELAY_PING_MULTIPLE);
						connectionRequestList[i]->pingCount++;
					}
					else
					{
						// Send the timestamped message to both systems so they send datagrams to each other simultaneously
						int receiverPing, senderPing;
						RakNetTime delayTime;
						receiverPing=rakPeer->GetAveragePing(connectionRequestList[i]->receiverPublic);
						senderPing=rakPeer->GetAveragePing(connectionRequestList[i]->senderPublic);
						if (receiverPing > senderPing)
							delayTime=(RakNetTime)(receiverPing*SEND_PUNCHTHROUGH_DELAY_PING_MULTIPLE);
						else
							delayTime=(RakNetTime)(senderPing*SEND_PUNCHTHROUGH_DELAY_PING_MULTIPLE);

						if (delayTime < 500)
							delayTime=500;

						outBitstream.Reset();
						outBitstream.Write((MessageID)ID_TIMESTAMP);
						outBitstream.Write(time+delayTime);
						outBitstream.Write((MessageID)ID_NAT_CONNECT_AT_TIME);
						// A few poorly behaved NATs are known to scan the body of UDP datagrams for 4-byte fields that look like IP addresses, and translate them as they would the IP address fields in the IP header.
						outBitstream.Write(true);
						outBitstream.Write(rakPeer->GetInternalID(connectionRequestList[i]->receiverPublic));
						rakPeer->Send(&outBitstream, SYSTEM_PRIORITY, RELIABLE, 0, connectionRequestList[i]->senderPublic, false);

						outBitstream.Reset();
						outBitstream.Write((MessageID)ID_TIMESTAMP);
						outBitstream.Write(time+delayTime);
						outBitstream.Write((MessageID)ID_NAT_SEND_OFFLINE_MESSAGE_AT_TIME);
						// A few poorly behaved NATs are known to scan the body of UDP datagrams for 4-byte fields that look like IP addresses, and translate them as they would the IP address fields in the IP header.
						outBitstream.Write(true);
						outBitstream.Write(connectionRequestList[i]->senderPublic);
						outBitstream.Write(rakPeer->GetInternalID(connectionRequestList[i]->senderPublic));
						rakPeer->Send(&outBitstream, SYSTEM_PRIORITY, RELIABLE, 0, connectionRequestList[i]->receiverPublic, false);

						delete [] connectionRequestList[i]->passwordData;
						delete connectionRequestList[i];
						connectionRequestList.RemoveAtIndex(i);
						continue;
					}
				}	
			}
			// Else not a facilitator.  If nextActionTime is non-zero, connect or send the offline message
			else if (connectionRequestList[i]->nextActionTime && time >= connectionRequestList[i]->nextActionTime && connectionRequestList[i]->attemptedConnection==false)
			{
				ConnectionRequest *connectionRequest = connectionRequestList[i];
				DataStructures::List<SystemAddress> fallbackAddresses;
//				unsigned fallbackIndex;
				RakNet::BitStream oob;
				if (connectionRequest->receiverPublic!=UNASSIGNED_SYSTEM_ADDRESS)
				{
			//		fallbackAddresses.Clear();
			//		connectionRequest->GetAddressList(peer, fallbackAddresses, connectionRequest->senderPublic, connectionRequest->senderPrivate, true);
			//		for (unsigned fallbackIndex=0; fallbackIndex < fallbackAddresses.Size(); fallbackIndex++)
			//			peer->Ping(fallbackAddresses[fallbackIndex].ToString(false),fallbackAddresses[fallbackIndex].port,false);

					// Connect to this system.
					LogOut(FormatString("Connecting to public address %s\n", connectionRequest->receiverPublic.ToString(true)));
					rakPeer->Connect(connectionRequest->receiverPublic.ToString(false), connectionRequest->receiverPublic.port, connectionRequest->passwordData, connectionRequest->passwordDataLength);
					connectionRequest->attemptedConnection=true;

					/*
					if (connectionRequestList[i]->receiverPrivate==connectionRequestList[i]->receiverPublic)
					{
						// Otherwise done with this connection, as it's a normal connection attempt
						rakFree(connectionRequestList[i]->passwordData);
						delete connectionRequestList[i];
						connectionRequestList.RemoveAtIndex(i);
						continue;
					}
					*/
				}
				else
				{
					RakAssert(connectionRequestList[i]->senderPublic!=UNASSIGNED_SYSTEM_ADDRESS);

					// Send ID_NAT_ADVERTISE_RECIPIENT_PORT to all possible remote ports
					fallbackAddresses.Clear();
					connectionRequest->GetAddressList(peer, fallbackAddresses, connectionRequest->senderPublic, connectionRequest->senderPrivate, true);
					
					/// 04/13/08 I think if I send to all possible fallbacks in order it starts reusing external ports or else assigns them in a random way
					/// Sending 4X to each port in order did work however.
					/// Timing matches that of RakPeer's failure notices and retries
					if ((unsigned int) connectionRequestList[i]->recipientOfflineCount < fallbackAddresses.Size())
					{
						unsigned k;
						//for (k=0; k < 4; k++)
						for (k=0; k < (unsigned) connectionRequestList[i]->recipientOfflineCount && k < fallbackAddresses.Size(); k++)
						{
							oob.Write(ID_NAT_ADVERTISE_RECIPIENT_PORT);
							oob.Write(rakPeer->GetExternalID(connectionRequest->facilitator));
							// This is duplicated intentionally, since the first packet is often dropped
							peer->SendOutOfBand(fallbackAddresses[k].ToString(false),fallbackAddresses[k].port,ID_OUT_OF_BAND_INTERNAL,(const char*) oob.GetData(),oob.GetNumberOfBytesUsed(),0);
							peer->SendOutOfBand(fallbackAddresses[k].ToString(false),fallbackAddresses[k].port,ID_OUT_OF_BAND_INTERNAL,(const char*) oob.GetData(),oob.GetNumberOfBytesUsed(),0);
						}

						LogOut(FormatString("Recipient sending ID_OUT_OF_BAND_INTERNAL to %s\n", fallbackAddresses[connectionRequestList[i]->recipientOfflineCount].ToString(true)));
					}

					/*
					for (fallbackIndex=0; fallbackIndex < fallbackAddresses.Size(); fallbackIndex++)
					{
						// This follows a similar path to the sender connecting to us.
						// If this message arrives, it lets the sender know our external port.
						// The sender can then use this port instead of just going down the fallbackAddresses guessing.
						// This saves us if the recipient is impossible to connect to, but the sender is not.
						oob.Reset();
						oob.Write(ID_NAT_ADVERTISE_RECIPIENT_PORT);
						oob.Write(rakPeer->GetExternalID(connectionRequest->facilitator));
						peer->SendOutOfBand(fallbackAddresses[fallbackIndex].ToString(false),fallbackAddresses[fallbackIndex].port,ID_OUT_OF_BAND_INTERNAL,(const char*) oob.GetData(),oob.GetNumberOfBytesUsed(),0);

						// bool SendOutOfBand(const char *host, unsigned short remotePort, MessageID header, const char *data, BitSize_t dataLength, unsigned connectionSocketIndex=0 );
					}
					*/


//					LogOut(FormatString("Pinging %s\n", connectionRequest->senderPublic.ToString(true)));

				//	rakPeer->Connect(connectionRequestList[i]->senderPublic.ToString(false),connectionRequestList[i]->senderPublic.port,0,0,0);

					/*
					SystemAddress senderAddrWithFPort;
					SystemAddress senderAddrWithRPort;
					SystemAddress senderAddrWithIPort;
					senderAddrWithFPort=connectionRequestList[i]->senderPublic;
					senderAddrWithFPort.port=connectionRequestList[i]->facilitator.port;
					senderAddrWithRPort=connectionRequestList[i]->senderPublic;
					senderAddrWithRPort.port=rakPeer->GetExternalID(connectionRequestList[i]->facilitator).port;
					senderAddrWithIPort=connectionRequestList[i]->senderPublic;
					senderAddrWithIPort.port=rakPeer->GetInternalID().port;
					*/

				//	LogOut(FormatString("Recipient sending TTL %i hops to %s\n", TTL_HOPS, connectionRequestList[i]->senderPublic.ToString()));
				//	rakPeer->SendTTL(connectionRequestList[i]->senderPublic.ToString(false), connectionRequestList[i]->senderPublic.port, false);


					// Send offline message to this system, hopefully at the exact same time that system tries to connect to us.
//					rakPeer->Ping(connectionRequestList[i]->senderPublic.ToString(false), connectionRequestList[i]->senderPublic.port, false);
					/*
					rakPeer->Ping(senderAddrWithFPort.ToString(false), senderAddrWithFPort.port, false);
					rakPeer->Ping(senderAddrWithRPort.ToString(false), senderAddrWithRPort.port, false);
					rakPeer->Ping(senderAddrWithIPort.ToString(false), senderAddrWithIPort.port, false);
					*/

			//		if (connectionRequestList[i]->senderPrivate!=connectionRequestList[i]->senderPublic)
			//			rakPeer->Ping(connectionRequestList[i]->senderPrivate.ToString(false), connectionRequestList[i]->senderPrivate.port, false);

			//		LogOut(FormatString("Recipient sending TTL %i hops to %s\n", TTL_HOPS, connectionRequestList[i]->senderPublic.ToString(false)));
				//	peer->SendTTL(connectionRequestList[i]->senderPublic.ToString(false),connectionRequestList[i]->senderPublic.port, TTL_HOPS+connectionRequestList[i]->recipientOfflineCount, 0);
				//	peer->SendTTL(connectionRequestList[i]->senderPublic.ToString(false),connectionRequestList[i]->senderPublic.port+1, TTL_HOPS+connectionRequestList[i]->recipientOfflineCount, 0);
				//	peer->SendTTL(connectionRequestList[i]->senderPrivate.ToString(false),connectionRequestList[i]->senderPrivate.port, TTL_HOPS+connectionRequestList[i]->recipientOfflineCount, 0);

					connectionRequestList[i]->recipientOfflineCount++;
					if (connectionRequestList[i]->recipientOfflineCount==RECIPIENT_OFFLINE_MAX_COUNT)
					{
						rakFree(connectionRequestList[i]->passwordData);
						delete connectionRequestList[i];
						connectionRequestList.RemoveAtIndex(i);
					}
					else
					{
						connectionRequestList[i]->nextActionTime=time+RECIPIENT_OFFLINE_MESSAGE_INTERVAL;
					}

					continue;
				}
			}
			
			i++;
		}
	}
}
Ejemplo n.º 25
0
void CVehiclePool::showVehicleForPlayer( _VehicleID vehicleid, _PlayerID playerid )
{
	RakNet::BitStream bStream;
	CVehicle* vehicle = GetVehicle( vehicleid );
	if( vehicle == 0 ) return;

	float angle = 0.0f;
	if( vehicle->vehMatrix.up.X == 0.0f && vehicle->vehMatrix.up.Y == 0.0f || vehicle->GetSpawnInfo()->vehType == 0x219 || vehicle->GetSpawnInfo()->vehType == 0x21A )
	{
		angle = vehicle->GetSpawnInfo()->vehRot;
	}
	else
	{
		angle = atan2( -vehicle->vehMatrix.up.X, vehicle->vehMatrix.up.Y ) * 57.2957763671875f;
		if( angle >= 360.0 ) angle -= 360.0f;
		else if( angle < 0.0f ) angle += 360.0f;
	}

	bStream.Write( ( _VehicleID ) vehicleid );
	bStream.Write( ( uint32_t ) vehicle->GetSpawnInfo( )->vehType );
#ifdef _BIG_ENDIAN_SYSTEM
	bStream.Write(vehicle->vehMatrix.pos.X);
	bStream.Write(vehicle->vehMatrix.pos.Y);
	bStream.Write(vehicle->vehMatrix.pos.Z);
#else
	bStream.Write( (char*)&vehicle->vehMatrix.pos, sizeof( tVector ) );
#endif
	bStream.Write( ( float ) angle );
	bStream.Write( ( uint8_t )vehicle->GetSpawnInfo()->vehColor1 );
	bStream.Write( ( uint8_t )vehicle->GetSpawnInfo()->vehColor2 );
	bStream.Write( ( float ) vehicle->vehHealth );
	bStream.Write( ( uint8_t ) vehicle->GetSpawnInfo()->vehInterior );
	bStream.Write( ( uint32_t ) vehicle->vehDoorStatus );
	bStream.Write( ( uint32_t ) vehicle->vehPanelStatus );
	bStream.Write( ( uint8_t ) vehicle->vehLightStatus );
	bStream.Write( ( uint8_t ) vehicle->vehTireStatus );
#ifdef _BIG_ENDIAN_SYSTEM
	bStream.Write( (char*)&vehicle->vehModInfo.vehModSlots, sizeof(vehicle->vehModInfo.vehModSlots));
	bStream.Write(vehicle->vehModInfo.vehPaintJob);
	bStream.Write(vehicle->vehModInfo.vehColor1);
	bStream.Write(vehicle->vehModInfo.vehColor2);
#else
	bStream.Write( (char*)&vehicle->vehModInfo, sizeof( VEHMOD_INFO ) );
#endif
	__NetGame->PlayerRPC( RPC_ShowVehicleToPlayer, &bStream, playerid, 2 );

	if( strlen( vehicle->vehNumberPlate ) > 0 )
	{
		bStream.Reset( );
		bStream.Write( ( _VehicleID ) vehicleid );
		bStream.Write( ( uint8_t )strlen( vehicle->vehNumberPlate ) );
		bStream.Write( (char*)vehicle->vehNumberPlate, strlen( vehicle->vehNumberPlate ) );
		char* RPC_SetVehicleNumberPlate = 0;
		__NetGame->PlayerRPC( RPC_SetVehicleNumberPlate, &bStream, playerid, 2);
	}

	if ( vehicle->hasParamExModified() )
	{
		bStream.Reset( );
		VEHPARAM_EX* params = vehicle->GetParamsEx();
		bStream.Write( vehicleid );
		bStream.Write( (char*)params, sizeof( VEHPARAM_EX ) );
		__NetGame->PlayerRPC( RPC_SetVehicleParamsEx, &bStream, playerid, 2 );
	}

	uint8_t paramsFlags = vehicle->GetParamsForPlayer( playerid );
	vehicle->SetParamsForPlayer( playerid, paramsFlags & 1, ( paramsFlags & 2 ) ? 1 : 0 ); // Prevent lock/unlocking bug

	vehicle->UpdateVehicleColorForPlayer( playerid ); // prevent unsynced color


}
Ejemplo n.º 26
0
int SendIRIToAddressCB(FileListTransfer::ThreadData threadData, bool *returnOutput, void* perThreadData)
{
	(void) perThreadData;

	FileListTransfer *fileListTransfer = threadData.fileListTransfer;
	SystemAddress systemAddress = threadData.systemAddress;
	*returnOutput=false;

	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int bytesRead;	
	const char *dataBlocks[2];
	int lengths[2];
	unsigned int smallFileTotalSize=0;
	RakNet::BitStream outBitstream;
	unsigned int ftpIndex;

	fileListTransfer->fileToPushRecipientListMutex.Lock();
	for (ftpIndex=0; ftpIndex < fileListTransfer->fileToPushRecipientList.Size(); ftpIndex++)
	{
		FileListTransfer::FileToPushRecipient *ftpr = fileListTransfer->fileToPushRecipientList[ftpIndex];
		// Referenced by both ftpr and list
		ftpr->AddRef();

		fileListTransfer->fileToPushRecipientListMutex.Unlock();

		if (ftpr->systemAddress==systemAddress)
		{
			FileListTransfer::FileToPush *ftp = ftpr->filesToPush.Peek();

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(ftp->chunkSize, _FILE_AND_LINE_);
			if (buff==0)
			{
				ftpr->Deref();
				notifyOutOfMemory(_FILE_AND_LINE_);
				return 0;
			}

			// Read the next file chunk
			bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);

			bool done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead;
			while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize)
			{
				// Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
				// outBitstream.Write(ftp->fileListNode.context);
				outBitstream << ftp->fileListNode.context;
				outBitstream.Write(ftp->setID);
				StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
				outBitstream.WriteCompressed(ftp->setIndex);
				outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
				outBitstream.AlignWriteToByteBoundary();
				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=(const char*) buff;
				lengths[1]=bytesRead;

				fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

				// LWS : fixed freed pointer reference
//				unsigned int chunkSize = ftp->chunkSize;
				RakNet::OP_DELETE(ftp,_FILE_AND_LINE_);
				ftpr->filesToPush.Pop();
				smallFileTotalSize+=bytesRead;
				//done = bytesRead!=ftp->chunkSize;
				ftp = ftpr->filesToPush.Peek();

				bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
				done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead;
			}


			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			// outBitstream.Write(ftp->fileListNode.context);
			outBitstream << ftp->fileListNode.context;
			outBitstream.Write(ftp->setID);
			StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(ftp->setIndex);
			outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
			outBitstream.WriteCompressed(ftp->currentOffset);
			ftp->currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			outBitstream.Write(done);

			for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++)
				fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress, ftp->setID);

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false);
			fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

			// Mutex state: FileToPushRecipient (ftpr) has AddRef. fileToPushRecipientListMutex not locked.
			if (done)
			{
				// Done
				unsigned short setId = ftp->setID;
				RakNet::OP_DELETE(ftp,_FILE_AND_LINE_);
				ftpr->filesToPush.Pop();

				if (ftpr->filesToPush.Size()==0)
				{
					for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++)
						fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(systemAddress, setId);

					// Remove ftpr from fileToPushRecipientList
					fileListTransfer->RemoveFromList(ftpr);
				}
			}

			// ftpr out of scope
			ftpr->Deref();

			rakFree_Ex(buff, _FILE_AND_LINE_ );
			return 0;
		}
		else
		{
			ftpr->Deref();
			fileListTransfer->fileToPushRecipientListMutex.Lock();
		}
	}

	fileListTransfer->fileToPushRecipientListMutex.Unlock();

	return 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.SetPortHostOrder(connectionAttempt->recipient->mostRecentPort);
				senderTargetAddress.SetPortHostOrder(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());
		}

	}
}
Ejemplo n.º 28
0
void FileListTransfer::SendIRIToAddress(SystemAddress systemAddress)
{
	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int bytesRead;	
	const char *dataBlocks[2];
	int lengths[2];
	unsigned int smallFileTotalSize=0;
	RakNet::BitStream outBitstream;

	filesToPushAllSameAddressMutex.Lock();
	for (unsigned int ftpIndex=0; ftpIndex < filesToPushAllSameAddress.Size(); ftpIndex++)
	{
		FileToPushRecipient *ftpr = filesToPushAllSameAddress[ftpIndex];
		if (ftpr->systemAddress==systemAddress)
		{
			FileToPush *ftp = ftpr->filesToPush.Peek();

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(ftp->chunkSize, __FILE__, __LINE__);
			if (buff==0)
			{
				filesToPushAllSameAddressMutex.Unlock();
				notifyOutOfMemory(__FILE__, __LINE__);
				return;
			}

			bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
			bool done = bytesRead!=ftp->chunkSize;
			while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize)
			{
				// Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
				outBitstream.Write(ftp->fileListNode.context);
				outBitstream.Write(ftp->setID);
				stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
				outBitstream.WriteCompressed(ftp->setIndex);
				outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
				outBitstream.AlignWriteToByteBoundary();
				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=(const char*) buff;
				lengths[1]=bytesRead;
				SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

				RakNet::OP_DELETE(ftp,__FILE__,__LINE__);
				ftpr->filesToPush.Pop();
				smallFileTotalSize+=bytesRead;
				done = bytesRead!=ftp->chunkSize;
				ftp = ftpr->filesToPush.Peek();
				bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
			}


			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			outBitstream.Write(ftp->fileListNode.context);
			outBitstream.Write(ftp->setID);
			stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(ftp->setIndex);
			outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
			outBitstream.WriteCompressed(ftp->currentOffset);
			ftp->currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			outBitstream.Write(done);

			if (callback)
			{
				callback->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress);
			}

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false);
			SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);
			if (done)
			{
				// Done
				RakNet::OP_DELETE(ftp,__FILE__,__LINE__);
				ftpr->filesToPush.Pop();
				if (ftpr->filesToPush.Size()==0)
				{
					RakNet::OP_DELETE(ftpr,__FILE__,__LINE__);
					filesToPushAllSameAddress.RemoveAtIndexFast(ftpIndex);
				}
			}
			rakFree_Ex(buff, __FILE__, __LINE__ );
			break;
		}
	}
	filesToPushAllSameAddressMutex.Unlock();
}