Exemplo n.º 1
0
bool NatPunchthrough::Connect(const char* destination, unsigned short remotePort, const char *passwordData, int passwordDataLength, SystemAddress facilitator)
{
	SystemAddress systemAddress;
	systemAddress.SetBinaryAddress(destination);
	systemAddress.port=remotePort;
	return Connect(systemAddress, passwordData, passwordDataLength, facilitator);
}
Exemplo n.º 2
0
bool CommonFunctions::WaitAndConnect(RakPeerInterface *peer,char* ip,unsigned short int port,int millisecondsToWait)
{

	SystemAddress connectToAddress;

	connectToAddress.SetBinaryAddress(ip);
	connectToAddress.port=port;
	TimeMS entryTime=GetTimeMS();

	while(!CommonFunctions::ConnectionStateMatchesOptions (peer,connectToAddress,true)&&GetTimeMS()-entryTime<millisecondsToWait)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (peer,connectToAddress,true,true,true,true))
		{
			peer->Connect(ip,port,0,0);
		}

		RakSleep(100);

	}

	if (ConnectionStateMatchesOptions (peer,connectToAddress,true))
	{
		return 1;
	}

	return 0;
}
Exemplo n.º 3
0
void CommonFunctions::DisconnectAndWait(RakPeerInterface *peer,char* ip,unsigned short int port)
{
	SystemAddress targetAddress;

	targetAddress.SetBinaryAddress(ip);
	targetAddress.port=port;

	while(CommonFunctions::ConnectionStateMatchesOptions (peer,targetAddress,true,true,true,true))//disconnect client
	{

		peer->CloseConnection (targetAddress,true,0,LOW_PRIORITY); 
	}

}
void ManyClientsOneServerDeallocateBlockingTest::WaitForConnectionRequestsToComplete(RakPeerInterface **clientList, int clientNum, bool isVerbose)
{
	SystemAddress currentSystem;
	bool msgWasPrinted=false;

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

		currentSystem.SetBinaryAddress("127.0.0.1");
		currentSystem.port=60000;

		while (clientList[i]->IsConnectionAttemptPending (currentSystem) )
		{
			if (msgWasPrinted==false)
			{
				printf("Waiting for connection requests to complete.\n");
				msgWasPrinted=true;
			}

			RakSleep(30);
		}

	}
}
void ManyClientsOneServerBlockingTest::WaitForConnectionRequestsToComplete(RakPeerInterface **clientList, int clientNum, bool isVerbose)
{
	SystemAddress currentSystem;
	bool msgWasPrinted=false;

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

		currentSystem.SetBinaryAddress("127.0.0.1");
		currentSystem.port=60000;

		while (CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,false,true,true) )
		{
			if (msgWasPrinted==false)
			{
				printf("Waiting for connection requests to complete.\n");
				msgWasPrinted=true;
			}

			RakSleep(30);
		}

	}
}
/*
Description:

Tests:
virtual void RakPeerInterface::AddToSecurityExceptionList  	(  	const char *   	 ip  	 )   	
virtual void RakPeerInterface::AddToBanList  	(  	const char *   	 IP, 		TimeMS  	milliseconds = 0	  	) 	
virtual void RakPeerInterface::GetIncomingPassword  	(  	char *   	 passwordData, 		int *  	passwordDataLength	  	) 
virtual void RakPeerInterface::InitializeSecurity  	(  	const char *   	 pubKeyE, 		const char *  	pubKeyN, 		const char *  	privKeyP, 		const char *  	privKeyQ	  	) 			
virtual bool RakPeerInterface::IsBanned  	(  	const char *   	 IP  	 )   	 
virtual bool RakPeerInterface::IsInSecurityExceptionList  	(  	const char *   	 ip  	 )  
virtual void RakPeerInterface::RemoveFromSecurityExceptionList  	(  	const char *   	 ip  	 )  
virtual void RakPeerInterface::RemoveFromBanList  	(  	const char *   	 IP  	 )   
virtual void RakPeerInterface::SetIncomingPassword  	(  	const char *   	 passwordData, 		int  	passwordDataLength	  	) 	
virtual void 	ClearBanList (void)=0

Success conditions:
All functions pass tests.

Failure conditions:
Any function fails test.

Client connects with no password
Client connects with wrong password
Client failed to connect with correct password
Client was banned but connected anyways
GetIncomingPassword returned wrong password
IsBanned does not show localhost as banned
Localhost was not unbanned
Client failed to connect after banlist removal
Client failed to connect after banlist removal with clear function
Client did not connect encrypted
Client connected encrypted but shouldn't have
IsInSecurityExceptionList does not register localhost addition

RakPeerInterface Functions used, tested indirectly by its use:
Startup
SetMaximumIncomingConnections
Receive
DeallocatePacket
Send
IsConnected
GetStatistics

RakPeerInterface Functions Explicitly Tested:
SetIncomingPassword  
GetIncomingPassword  
AddToBanList
IsBanned
RemoveFromBanList  
ClearBanList 
InitializeSecurity  //Disabled because of RakNetStatistics changes 		 		
AddToSecurityExceptionList  //Disabled because of RakNetStatistics changes 		   	 
IsInSecurityExceptionList //Disabled because of RakNetStatistics changes 	  	  
RemoveFromSecurityExceptionList //Disabled because of RakNetStatistics changes 	  

*/
int SecurityFunctionsTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
{

	char thePassword[]="password";
	server=RakPeerInterface::GetInstance();

	client=RakPeerInterface::GetInstance();

	client->Startup(1,&SocketDescriptor(),1);
	server->Startup(1,&SocketDescriptor(60000,0),1);
	server->SetMaximumIncomingConnections(1);
	server->SetIncomingPassword(thePassword,(int)strlen(thePassword));

	char returnedPass[22];
	int returnedLen=22;
	server->GetIncomingPassword(returnedPass,&returnedLen);
	returnedPass[returnedLen]=0;//Password is a data block convert to null terminated string to make the test easier

	if (strcmp(returnedPass,thePassword)!=0)
	{
		if (isVerbose)
		{

			printf("%s was returned but %s is the password\n",returnedPass,thePassword);
			DebugTools::ShowError("GetIncomingPassword returned wrong password\n",!noPauses && isVerbose,__LINE__,__FILE__);
		}
		return 5;
	}

	SystemAddress serverAddress;

	serverAddress.SetBinaryAddress("127.0.0.1");
	serverAddress.port=60000;
	TimeMS entryTime=GetTimeMS();

	if (isVerbose)
		printf("Testing if  no password is rejected\n");

	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,0,0);
		}

		RakSleep(100);

	}

	if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
	{
		if (isVerbose)
			DebugTools::ShowError("Client connected with no password\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 1;
	}

	if (isVerbose)
		printf("Testing if incorrect password is rejected\n");

	char badPass[]="badpass";
	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,badPass,(int)strlen(badPass));
		}

		RakSleep(100);

	}

	if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
	{
		if (isVerbose)
			DebugTools::ShowError("Client connected with wrong password\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 2;
	}

	if (isVerbose)
		printf("Testing if correct password is accepted\n");

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
		}

		RakSleep(100);

	}

	if (!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
	{
		if (isVerbose)
			DebugTools::ShowError("Client failed to connect with correct password\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 3;
	}

	while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
	{

		client->CloseConnection (serverAddress,true,0,LOW_PRIORITY); 
	}

	if (isVerbose)
		printf("Testing if connection is rejected after adding to ban list\n");

	server->AddToBanList("127.0.0.1",0);

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
		}

		RakSleep(100);

	}

	if(!server->IsBanned("127.0.0.1"))
	{

		if (isVerbose)
			DebugTools::ShowError("IsBanned does not show localhost as banned\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 6;

	}

	if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
	{
		if (isVerbose)
			DebugTools::ShowError("Client was banned but connected anyways\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 4;
	}

	if (isVerbose)
		printf("Testing if connection is accepted after ban removal by RemoveFromBanList\n");

	server->RemoveFromBanList("127.0.0.1");
	if(server->IsBanned("127.0.0.1"))
	{

		if (isVerbose)
			DebugTools::ShowError("Localhost was not unbanned\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 7;

	}

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
		}

		RakSleep(100);

	}

	if (!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
	{
		if (isVerbose)
			DebugTools::ShowError("Client failed to connect after banlist removal\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 8;
	}

	while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
	{

		client->CloseConnection (serverAddress,true,0,LOW_PRIORITY); 
	}

	if (isVerbose)
		printf("Testing if connection is rejected after adding to ban list\n");

	server->AddToBanList("127.0.0.1",0);

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
		}

		RakSleep(100);

	}

	if(!server->IsBanned("127.0.0.1"))
	{

		if (isVerbose)
			DebugTools::ShowError("IsBanned does not show localhost as banned\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 6;

	}

	if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
	{
		if (isVerbose)
			DebugTools::ShowError("Client was banned but connected anyways\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 4;
	}

	if (isVerbose)
		printf("Testing if connection is accepted after ban removal by ClearBanList\n");

	server->ClearBanList();
	if(server->IsBanned("127.0.0.1"))
	{

		if (isVerbose)
			DebugTools::ShowError("Localhost was not unbanned\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 7;

	}

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
		}

		RakSleep(100);

	}

	if (!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
	{
		if (isVerbose)
			DebugTools::ShowError("Client failed to connect after banlist removal with clear function\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 9;
	}

	while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
	{

		client->CloseConnection (serverAddress,true,0,LOW_PRIORITY); 
	}

/*//Disabled because of statistics changes

	if (isVerbose)
		printf("Testing InitializeSecurity on server\n");

	//-----------------------------

	// RSACrypt is a using namespace RakNet;
class that handles RSA encryption/decryption internally

	RSACrypt rsacrypt;

	uint32_t e;
	uint32_t modulus[RAKNET_RSA_FACTOR_LIMBS];

	uint32_t p[RAKNET_RSA_FACTOR_LIMBS/2],q[RAKNET_RSA_FACTOR_LIMBS/2];

	printf("Generating %i bit key. This will take a while...\n", RAKNET_RSA_FACTOR_LIMBS*32);
	rsacrypt.generatePrivateKey(RAKNET_RSA_FACTOR_LIMBS);
	e=rsacrypt.getPublicExponent();
	rsacrypt.getPublicModulus(modulus);
	rsacrypt.getPrivateP(p);
	rsacrypt.getPrivateQ(q);

	RakPeerInterface::DestroyInstance(server);
	server=RakPeerInterface::GetInstance();

	server->InitializeSecurity(0,0,(char*)p, (char*)q);
	server->Startup(1,30,&SocketDescriptor(60000,0),1);
	server->SetMaximumIncomingConnections(1);
	server->SetIncomingPassword(thePassword,strlen(thePassword));

	if (isVerbose)
		printf("Testing if client connects encrypted\n");

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,strlen(thePassword));
		}

		RakSleep(100);

	}

	char str2[]="AAAAAAAAAA";
	str2[0]=(char)(ID_USER_PACKET_ENUM+1);
	client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
	client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);

	Packet *packet;
	entryTime=GetTimeMS();
	while(GetTimeMS()-entryTime<1000)
	{
		for (packet=server->Receive(); packet;server->DeallocatePacket(packet), packet=server->Receive())
		{

		}
	}

	RakNetStatistics *rss;

	rss=client->GetStatistics(serverAddress);

	if (rss->encryptionBitsSent<=0)//If we did connect encrypted we should see encryptionBitsSent
	{
		if (isVerbose)
			DebugTools::ShowError("Client did not connect encrypted\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 10;
	}

	while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
	{

		client->CloseConnection (serverAddress,true,0,LOW_PRIORITY); 
	}

	//Destroy to clear statistics
	RakPeerInterface::DestroyInstance(client);

	client=RakPeerInterface::GetInstance();

	client->Startup(1,30,&SocketDescriptor(),1);

	if (isVerbose)
		printf("Testing AddToSecurityExceptionList client should connect without encryption\n");

	server->AddToSecurityExceptionList("127.0.0.1");

	if (!server->IsInSecurityExceptionList("127.0.0.1"))
	{
		if (isVerbose)
			DebugTools::ShowError("IsInSecurityExceptionList does not register localhost addition\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 12;
	}

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,strlen(thePassword));
		}

		RakSleep(100);

	}

	str2[0]=(char)(ID_USER_PACKET_ENUM+1);
	client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
	client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);

	//	Packet *packet;

	entryTime=GetTimeMS();
	while(GetTimeMS()-entryTime<1000)
	{
		for (packet=server->Receive(); packet;server->DeallocatePacket(packet), packet=server->Receive())
		{

		}
	}

	rss=client->GetStatistics(serverAddress);

	if (rss->encryptionBitsSent>0)//If we did connect encrypted we should see encryptionBitsSent
	{
		if (isVerbose)
			DebugTools::ShowError("Client connected encrypted but shouldn't have\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 11;
	}

	if (isVerbose)
		printf("Testing RemoveFromSecurityExceptionList\n");

	while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
	{

		client->CloseConnection (serverAddress,true,0,LOW_PRIORITY); 
	}

	server->RemoveFromSecurityExceptionList("127.0.0.1");

	if (isVerbose)
		printf("Testing if client connects encrypted\n");

	entryTime=GetTimeMS();
	while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
	{

		if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
		{
			client->Connect("127.0.0.1",serverAddress.port,thePassword,strlen(thePassword));
		}

		RakSleep(100);

	}

	str2[0]=(char)(ID_USER_PACKET_ENUM+1);
	client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
	client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);

	entryTime=GetTimeMS();
	while(GetTimeMS()-entryTime<1000)
	{
		for (packet=server->Receive(); packet;server->DeallocatePacket(packet), packet=server->Receive())
		{

		}
	}

	rss=client->GetStatistics(serverAddress);

	if (rss->encryptionBitsSent<=0)//If we did connect encrypted we should see encryptionBitsSent
	{
		if (isVerbose)
			DebugTools::ShowError("Client did not connect encrypted\n",!noPauses && isVerbose,__LINE__,__FILE__);
		return 10;
	}

*/

	return 0;

}
/*
	Update 24.08.2015 Xiphoseer
	This function now contains all logic to
		- Read the 53-01-00-00 LOGIN_REQUEST packet
		- Verify the login credentials using the database
		- Sending the response to the client
		- Register the client in SessionsTable and UsersPool
*/
void HandleUserLogin(RakPeerInterface* rakServer, Packet* packet, CONNECT_INFO* cfg) {
	//Make the packet data accessible via a bit stream
	RakNet::BitStream *data = new RakNet::BitStream(packet->data, packet->length, false);
	unsigned char packetID;
	data->Read(packetID);
	unsigned short networkType;
	data->Read(networkType);
	unsigned long packetType;
	data->Read(packetType);
	unsigned char pad;
	data->Read(pad);
	
	//Check if the correct packet is passed to this function
	if (networkType == RemoteConnection::AUTH && packetType == AuthPacketID::LOGIN_REQUEST) {
		// Read all available data from the login packet
		// and log it, TODO: transform that into debug log messages
		std::wstring username = PacketTools::ReadFromPacket(data, 33);
		std::wstring password = PacketTools::ReadFromPacket(data, 41);
		Logger::log("AUTH", "LOGIN", "Username: "******"AUTH", "LOGIN", "Password: "******"AUTH", "LOGIN", "Language: " + std::to_string(language_id), LOG_ALL);
		unsigned char uk1;
		data->Read(uk1);
		Logger::log("AUTH", "LOGIN", "Unknown?: " + std::to_string(uk1), LOG_ALL);
		std::wstring process_info = PacketTools::ReadFromPacket(data, 256);
		std::wstring graphics_info = PacketTools::ReadFromPacket(data, 128);
		Logger::log("AUTH", "LOGIN", UtfConverter::ToUtf8(process_info), LOG_ALL);
		Logger::log("AUTH", "LOGIN", UtfConverter::ToUtf8(graphics_info), LOG_ALL);
		unsigned long num_processors, type_processor;
		data->Read(num_processors);
		data->Read(type_processor);
		unsigned short level_processor, revision_processor;
		data->Read(level_processor);
		data->Read(revision_processor);
		Logger::log("AUTH", "LOGIN", "Processor: " + 
			std::to_string(num_processors) + ", " + 
			std::to_string(type_processor) + ", " + 
			std::to_string(level_processor) + ", " + 
			std::to_string(revision_processor),
			LOG_ALL
			);
		unsigned long uk2;
		data->Read(uk2);
		Logger::log("AUTH", "LOGIN", "Unknown?: " + std::to_string(uk2), LOG_ALL);
		if (data->GetNumberOfUnreadBits() > 0){
			unsigned long os_major_version, os_minor_version, os_build_number, os_platform_id;
			data->Read(os_major_version);
			data->Read(os_minor_version);
			data->Read(os_build_number);
			data->Read(os_platform_id);
			Logger::log("AUTH", "LOGIN", "OS: " +
				std::to_string(os_major_version) + '.' +
				std::to_string(os_minor_version) + '.' +
				std::to_string(os_build_number), LOG_ALL);
			Logger::log("AUTH", "LOGIN", "OSP: " + std::to_string(os_platform_id), LOG_ALL);
		}
		
		std::string usernameA, passwordA;
		usernameA = UtfConverter::ToUtf8(username);
		passwordA = UtfConverter::ToUtf8(password);

		//Validating the input
		//Set default values
		UserSuccess currentLoginStatus = UserSuccess::SUCCESS;
		//Ref<User> user = NULL;
		
		//query the account id of the associated with the username from the database
		unsigned int accountid = AccountsTable::getAccountID(usernameA);
		if (accountid == 0){
			//If the query return 0, no user was found
			currentLoginStatus = UserSuccess::INVALID_USER;
		}else{
			//check if the password is correct
			bool passwordCorrect = AccountsTable::checkPassword(passwordA, accountid);
			AccountAccessInfo info = AccountsTable::getAccessInfo(accountid);

			if (info.locked || info.banned){
				if (info.banned){
					Logger::log("USER", "LOGIN", "User is BANNED");
					currentLoginStatus = UserSuccess::BANNED;
				}
				else{
					Logger::log("USER", "LOGIN", "User is LOCKED");
					currentLoginStatus = UserSuccess::LOCKED;
				}
			}
			else{
				if (passwordCorrect){
					//password correct
					if (info.loginTries > 0){
						info.loginTries = 0;
					}
				}
				else{
					//password incorrect
					info.loginTries++;
					if (info.loginTries > 2){
						info.locked = true;
						info.loginTries = 3;
						Logger::log("USER", "LOGIN", "User is LOCKED");
						currentLoginStatus = UserSuccess::LOCKED;
					}else{
						Logger::log("USER", "LOGIN", "User has INCORRECT_PASSWORD");
						currentLoginStatus = UserSuccess::INVALID_PASS;
					}					
				}
				AccountsTable::setAccessInfo(accountid, info);
			}
		}

		//respond to the client

		LoginStatusPacket loginStatusPacket;

		// Set the loginStatus
		loginStatusPacket.loginStatus = currentLoginStatus;

		// Set Talk_Like_A_Pirate_String
		loginStatusPacket.talkLikeAPirate = "Talk_Like_A_Pirate";
		loginStatusPacket.unknownString = "";

		// Set client version
		loginStatusPacket.clientVersion1 = 1;
		loginStatusPacket.clientVersion2 = 10;
		loginStatusPacket.clientVersion3 = 64;

		// This is unknown data...
		loginStatusPacket.unknown = "_";

		time_t t = time(NULL);
		unsigned int addr = packet->systemAddress.binaryAddress;
		long long a = (long long)t * (long long)addr;
		std::string keyhash = md5(std::to_string(a));
		std::wstring key = StringToWString(keyhash, 33);

		// Get the user key
		loginStatusPacket.userKey = key;
		//loginStatusPacket.userKey = "0 9 4 e 7 0 1 a c 3 b 5 5 2 0 b 4 7 8 9 5 b 3 1 8 5 7 b f 1 c 3   ";

		// Set chat IPs/Port and the other IP
		loginStatusPacket.chatIp = "192.168.0.20"; //TODO: make dynamic
		loginStatusPacket.chatPort = 2003;
		loginStatusPacket.anotherIp = "192.168.0.20";

		loginStatusPacket.possibleGuid = "00000000-0000-0000-0000-000000000000";

		loginStatusPacket.zeroLong = 0;

		// Set localization
		loginStatusPacket.localizationChar[0] = 0x55;
		loginStatusPacket.localizationChar[1] = 0x53;
		loginStatusPacket.localizationChar[2] = 0x00;

		// Subscribed?
		loginStatusPacket.firstLoginSubscription = 1;
		loginStatusPacket.subscribed = 0;

		loginStatusPacket.zeroLongLong = 0;

		loginStatusPacket.redirectIp = cfg->redirectIp;
		loginStatusPacket.redirectPort = cfg->redirectPort;

		// Set the error msg and the error msg length
		// This message only shows
		loginStatusPacket.errorMsg = "";
		loginStatusPacket.errorMsgLength = loginStatusPacket.errorMsg.length();

		std::string world_server_address;
		
		SystemAddress serverAddr;
		serverAddr.SetBinaryAddress(cfg->redirectIp);
		serverAddr.port = cfg->redirectPort;

		int instanceid = InstancesTable::getInstanceId(serverAddr);
		if (instanceid == -1){
			loginStatusPacket.loginStatus = UserSuccess::UNKNOWN2;
			loginStatusPacket.errorMsg = "Universe not available";
			currentLoginStatus = UserSuccess::UNKNOWN2;
			Logger::log("AUTH", "LOGIN", "INSTANCE UNAVAILABLE", LOG_ERROR);
		}
		
		if (currentLoginStatus == UserSuccess::SUCCESS){
			// Login the user to the server
			Session::login(packet->systemAddress, accountid, keyhash, instanceid);
			Logger::log("AUTH", "LOGIN", usernameA + " Logged-in");
			SendStatusPacket(rakServer, packet->systemAddress, loginStatusPacket);
			return;
		}
		SendStatusPacket(rakServer, packet->systemAddress, loginStatusPacket);
	}
	Logger::log("AUTH", "LOGIN", "Login failed", LOG_WARNING);
}
/*
Description: Tests what happens if two instances of RakNet connect to each other at the same time. This has caused handshaking problems in the past.

Success conditions:
Everything connects and sends normally.

Failure conditions:
Expected values from ping/pong do not occur within expected time.
*/
int CrossConnectionConvertTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
{

	static const unsigned short SERVER_PORT=1234;
	//	char serverMode[32];
	char serverIP[64];

	strcpy(serverIP,"127.0.0.1");	

	char clientIP[64];
	RakPeerInterface *server,*client;
	unsigned short clientPort;
	bool gotNotification;
	server=RakPeerInterface::GetInstance();
	destroyList.Clear(false,_FILE_AND_LINE_);
	destroyList.Push(server,_FILE_AND_LINE_);
	client=RakPeerInterface::GetInstance();
	destroyList.Push(client,_FILE_AND_LINE_);

	

	server->Startup(1,&SocketDescriptor(SERVER_PORT,0), 1);
	server->SetMaximumIncomingConnections(1);

	client->Startup(1,&SocketDescriptor(0,0), 1);

	client->Ping(serverIP,SERVER_PORT,false);

	//	PacketLogger pl;
	//	pl.LogHeader();
	//	rakPeer->AttachPlugin(&pl);

	TimeMS connectionAttemptTime=0,connectionResultDeterminationTime=0,nextTestStartTime=0;

	TimeMS entryTime=GetTimeMS();//Loop entry time

	bool printedYet=false;
	while(GetTimeMS()-entryTime<10000)//Run for 10 Secoonds
	{

		Packet *p;

		printedYet=false;

		for (p=server->Receive(); p; server->DeallocatePacket(p), p=server->Receive())
		{

			if (isVerbose&&!printedYet)
			{
				printf("Server:\n");
				printedYet=true;
			}
			if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
			{

				if (isVerbose)
					printf("ID_NEW_INCOMING_CONNECTION\n");
				gotNotification=true;
			}
			else if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
			{

				if (isVerbose)
					printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
				gotNotification=true;
			}
			else if (p->data[0]==ID_UNCONNECTED_PING)
			{

				if (isVerbose)
					printf("ID_PING\n");
				connectionAttemptTime=GetTimeMS()+1000;
				p->systemAddress.ToString(false,clientIP);
				clientPort=p->systemAddress.port;
				gotNotification=false;
			}
			else if (p->data[0]==ID_UNCONNECTED_PONG)
			{

				if (isVerbose)
					printf("ID_UNCONNECTED_PONG\n");
				TimeMS sendPingTime;
				BitStream bs(p->data,p->length,false);
				bs.IgnoreBytes(1);
				bs.Read(sendPingTime);
				TimeMS rtt = GetTimeMS() - sendPingTime;
				if (rtt/2<=500)
					connectionAttemptTime=GetTimeMS()+1000-rtt/2;
				else
					connectionAttemptTime=GetTimeMS();
				gotNotification=false;
			}
		}

		printedYet=false;
		for (p=client->Receive(); p; client->DeallocatePacket(p), p=client->Receive())
		{

			if (isVerbose&&!printedYet)
			{
				printf("Client:\n");
				printedYet=true;
			}
			if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
			{

				if (isVerbose)
					printf("ID_NEW_INCOMING_CONNECTION\n");
				gotNotification=true;
			}
			else if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
			{

				if (isVerbose)
					printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
				gotNotification=true;
			}
			else if (p->data[0]==ID_UNCONNECTED_PING)
			{

				if (isVerbose)
					printf("ID_PING\n");
				connectionAttemptTime=GetTimeMS()+1000;
				p->systemAddress.ToString(false,clientIP);
				clientPort=p->systemAddress.port;
				gotNotification=false;
			}
			else if (p->data[0]==ID_UNCONNECTED_PONG)
			{

				if (isVerbose)
					printf("ID_UNCONNECTED_PONG\n");
				TimeMS sendPingTime;
				BitStream bs(p->data,p->length,false);
				bs.IgnoreBytes(1);
				bs.Read(sendPingTime);
				TimeMS rtt = GetTimeMS() - sendPingTime;
				if (rtt/2<=500)
					connectionAttemptTime=GetTimeMS()+1000-rtt/2;
				else
					connectionAttemptTime=GetTimeMS();
				gotNotification=false;
			}
		}

		if (connectionAttemptTime!=0 && GetTimeMS()>=connectionAttemptTime)
		{

			if (isVerbose)
				printf("Attemping connection\n");
			connectionAttemptTime=0;

			server->Connect(clientIP,clientPort,0,0);
			client->Connect(serverIP,SERVER_PORT,0,0);

			connectionResultDeterminationTime=GetTimeMS()+2000;
		}
		if (connectionResultDeterminationTime!=0 && GetTimeMS()>=connectionResultDeterminationTime)
		{
			connectionResultDeterminationTime=0;
			if (gotNotification==false)
			{
				DebugTools::ShowError("Did not recieve expected response. \n",!noPauses && isVerbose,__LINE__,__FILE__);
				return 1;
			}

			SystemAddress sa;
			sa.SetBinaryAddress(serverIP);
			sa.port=SERVER_PORT;
			client->CancelConnectionAttempt(sa);

			sa.SetBinaryAddress(clientIP);
			sa.port=clientPort;
			server->CancelConnectionAttempt(sa);

			server->CloseConnection(server->GetSystemAddressFromIndex(0),true,0);
			client->CloseConnection(client->GetSystemAddressFromIndex(0),true,0);

			//if (isServer==false)
			nextTestStartTime=GetTimeMS()+1000;

		}
		if (nextTestStartTime!=0 && GetTimeMS()>=nextTestStartTime)
		{
			client->Ping(serverIP,SERVER_PORT,false);
			nextTestStartTime=0;
		}
		RakSleep(0);

	}
	if (isVerbose)
		printf("Test succeeded.\n");

	return 0;

}
/*
What is being done here is having 8 peers all connect to eachother, disconnect, connect again.

Do this for about 10 seconds. Then allow them all to connect for one last time.

This test also tests the cancelpendingconnections.

Also tests nonblocking connects, the simpler one PeerConnectDisconnect tests without it

Good ideas for changes:
After the last check run a eightpeers like test an add the conditions
of that test as well.

Make sure that if we initiate the connection we get a proper message
and if not we get a proper message. Add proper conditions.

Randomize sending the disconnect notes

Success conditions:
All connected normally and pending requests get canceled normally.

Failure conditions:
Doesn't reconnect normally.

During the very first connect loop any connect returns false.

Connect function returns false and peer is not connected to anything.

Pending request is not canceled.

*/
int PeerConnectDisconnectWithCancelPendingTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
{

	const int peerNum= 8;
	const int maxConnections=peerNum*3;//Max allowed connections for test set to times 3 to eliminate problem variables
	RakPeerInterface *peerList[peerNum];//A list of 8 peers

	SystemAddress currentSystem;

	Packet *packet;
	destroyList.Clear(false,_FILE_AND_LINE_);

	//Initializations of the arrays
	for (int i=0;i<peerNum;i++)
	{
		peerList[i]=RakPeerInterface::GetInstance();
		destroyList.Push(peerList[i],_FILE_AND_LINE_);

		peerList[i]->Startup(maxConnections, &SocketDescriptor(60000+i,0), 1);
		peerList[i]->SetMaximumIncomingConnections(maxConnections);

	}

	//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)!=CONNECTION_ATTEMPT_STARTED)
			{

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

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

			}

		}	

	}

	TimeMS entryTime=GetTimeMS();//Loop entry time

	DataStructures::List< SystemAddress  > systemList;
	DataStructures::List< RakNetGUID > guidList;

	printf("Entering disconnect loop \n");
	bool printedYet;

	while(GetTimeMS()-entryTime<10000)//Run for 10 Secoonds
	{

		//Disconnect all peers IF connected to any
		for (int i=0;i<peerNum;i++)
		{

			peerList[i]->GetSystemList(systemList,guidList);//Get connectionlist
			int len=systemList.Size();

			for (int j=0;j<len;j++)//Disconnect them all
			{

				peerList[i]->CloseConnection (systemList[j],true,0,LOW_PRIORITY); 	
			}

		}

		RakSleep(100);
		//Clear pending if not finished

		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.
			{

				currentSystem.SetBinaryAddress("127.0.0.1");
				currentSystem.port=60000+j;

				peerList[i]->CancelConnectionAttempt(currentSystem);  	//Make sure a connection is not pending before trying to connect.

			}

		}

		RakSleep(100);
		//Connect

		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)!=CONNECTION_ATTEMPT_STARTED)
				{

					currentSystem.SetBinaryAddress("127.0.0.1");
					currentSystem.port=60000+j;

					peerList[i]->GetSystemList(systemList,guidList);//Get connectionlist

					int len=systemList.Size();

					if(CommonFunctions::ConnectionStateMatchesOptions (peerList[i],currentSystem,false,true,true))//Did we drop the pending connection? 
					{
						if (isVerbose)
							DebugTools::ShowError("Did not cancel the pending request \n",!noPauses && isVerbose,__LINE__,__FILE__);

						return 3;

					}

					if (!CommonFunctions::ConnectionStateMatchesOptions (peerList[i],currentSystem,true,true,true,true))
					{
						if (isVerbose)
							DebugTools::ShowError("Problem while calling connect. \n",!noPauses && isVerbose,__LINE__,__FILE__);

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

				}

			}	

		}

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

			printedYet=false;

			packet=peerList[i]->Receive();

			while(packet)
			{

				if (isVerbose&&!printedYet)
				{
					printf("For peer %i\n",i);
					printedYet=true;
				}
				switch (packet->data[0])
				{
				case ID_REMOTE_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("Another client has disconnected.\n");

					break;
				case ID_REMOTE_CONNECTION_LOST:
					if (isVerbose)
						printf("Another client has lost the connection.\n");

					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");

					break;
				case ID_CONNECTION_ATTEMPT_FAILED:
					if (isVerbose)
						printf("A connection has failed.\n");

					break;

				case ID_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("A connection is incoming.\n");

					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS:
					if (isVerbose)              
						printf("The server is full.\n");

					break;

				case ID_ALREADY_CONNECTED:
					if (isVerbose)              
						printf("Already connected\n");

					break;

				case ID_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("We have been disconnected.\n");
					break;
				case ID_CONNECTION_LOST:
					if (isVerbose)
						printf("Connection lost.\n");

					break;
				default:

					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
	}

	while(GetTimeMS()-entryTime<2000)//Run for 2 Secoonds to process incoming disconnects
	{

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

			packet=peerList[i]->Receive();

			while(packet)
			{

				if (isVerbose&&!printedYet)
				{
					printf("For peer %i\n",i);
					printedYet=true;
				}
				switch (packet->data[0])
				{
				case ID_REMOTE_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("Another client has disconnected.\n");

					break;
				case ID_REMOTE_CONNECTION_LOST:
					if (isVerbose)
						printf("Another client has lost the connection.\n");

					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");

					break;
				case ID_CONNECTION_ATTEMPT_FAILED:
					if (isVerbose)
						printf("A connection has failed.\n");

					break;

				case ID_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("A connection is incoming.\n");

					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS:
					if (isVerbose)              
						printf("The server is full.\n");

					break;

				case ID_ALREADY_CONNECTED:
					if (isVerbose)              
						printf("Already connected\n");

					break;

				case ID_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("We have been disconnected.\n");
					break;
				case ID_CONNECTION_LOST:
					if (isVerbose)
						printf("Connection lost.\n");

					break;
				default:

					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
	}

	//Connect

	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.
		{

			currentSystem.SetBinaryAddress("127.0.0.1");
			currentSystem.port=60000+j;

			peerList[i]->CancelConnectionAttempt(currentSystem);  	//Make sure a connection is not pending before trying to connect.

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

				peerList[i]->GetSystemList(systemList,guidList);//Get connectionlist
				int len=systemList.Size();

				if (len==0)//No connections, should not fail.
				{

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

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

			}

		}	

	}

	entryTime=GetTimeMS();

	while(GetTimeMS()-entryTime<5000)//Run for 5 Secoonds
	{

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

			printedYet=false;
			packet=peerList[i]->Receive();

			while(packet)
			{
				if (isVerbose&&!printedYet)
				{
					printf("For peer %i\n",i);
					printedYet=true;
				}
				switch (packet->data[0])
				{
				case ID_REMOTE_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("Another client has disconnected.\n");

					break;
				case ID_REMOTE_CONNECTION_LOST:
					if (isVerbose)
						printf("Another client has lost the connection.\n");

					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");

					break;
				case ID_CONNECTION_ATTEMPT_FAILED:
					if (isVerbose)
						printf("A connection has failed.\n");

					break;

				case ID_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("A connection is incoming.\n");

					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS:
					if (isVerbose)              
						printf("The server is full.\n");

					break;

				case ID_ALREADY_CONNECTED:
					if (isVerbose)              
						printf("Already connected\n");

					break;

				case ID_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("We have been disconnected.\n");
					break;
				case ID_CONNECTION_LOST:
					if (isVerbose)
						printf("Connection lost.\n");

					break;
				default:

					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++)
	{

		peerList[i]->GetSystemList(systemList,guidList);
		int connNum=guidList.Size();//Get the number of connections for the current peer
		if (connNum!=peerNum-1)//Did we connect to all?
		{

			if (isVerbose)
				DebugTools::ShowError("Not all peers reconnected normally.\n ",!noPauses && isVerbose,__LINE__,__FILE__);

			return 2;

		}

	}

	if (isVerbose)
		printf("Pass\n");
	return 0;

}
/*
What is being done here is having 256 clients connect to one server, disconnect, connect again.

Do this for about 10 seconds. Then allow them all to connect for one last time.

This one has a nonblocking recieve so doesn't wait for connects or anything.
Just rapid connecting disconnecting.

Good ideas for changes:
After the last check run a eightpeers like test an add the conditions
of that test as well.

Make sure that if we initiate the connection we get a proper message
and if not we get a proper message. Add proper conditions.

Randomize sending the disconnect notes

Success conditions:
All connected normally.

Failure conditions:
Doesn't reconnect normally.

During the very first connect loop any connect returns false.

Connect function returns false and peer is not connected to anything.

*/
int ManyClientsOneServerNonBlockingTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
{

	const int clientNum= 256;

	RakPeerInterface *clientList[clientNum];//A list of clients
	RakPeerInterface *server;//The server
	SystemAddress currentSystem;

	//SystemAddress currentSystem;

	Packet *packet;
	destroyList.Clear(false,_FILE_AND_LINE_);

	//Initializations of the arrays
	for (int i=0;i<clientNum;i++)
	{
		clientList[i]=RakPeerInterface::GetInstance();
		destroyList.Push(clientList[i],_FILE_AND_LINE_);

		clientList[i]->Startup(1,&SocketDescriptor(), 1);

	}

	server=RakPeerInterface::GetInstance();
	destroyList.Push(server,_FILE_AND_LINE_);
	server->Startup(clientNum, &SocketDescriptor(60000,0), 1);
	server->SetMaximumIncomingConnections(clientNum);

	//Connect all the clients to the server

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

		if (clientList[i]->Connect("127.0.0.1", 60000, 0,0)!=CONNECTION_ATTEMPT_STARTED)
		{

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

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

		}

	}

	TimeMS entryTime=GetTimeMS();//Loop entry time

	DataStructures::List< SystemAddress  > systemList;
	DataStructures::List< RakNetGUID > guidList;

	if (isVerbose)
		printf("Entering disconnect loop \n");

	while(GetTimeMS()-entryTime<10000)//Run for 10 Secoonds
	{

		//Disconnect all clients IF connected to any from client side
		for (int i=0;i<clientNum;i++)
		{

			clientList[i]->GetSystemList(systemList,guidList);//Get connectionlist
			int len=systemList.Size();

			for (int j=0;j<len;j++)//Disconnect them all
			{

				clientList[i]->CloseConnection (systemList[j],true,0,LOW_PRIORITY); 	
			}

		}

		//RakSleep(100);

		//Connect

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

			currentSystem.SetBinaryAddress("127.0.0.1");
			currentSystem.port=60000;
			if(!CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,true,true,true,true) )//Are we connected or is there a pending operation ?
			{

				if (clientList[i]->Connect("127.0.0.1", 60000, 0,0)!=CONNECTION_ATTEMPT_STARTED)
				{

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

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

				}
			}

		}

		//Server receive

		packet=server->Receive();

		if (isVerbose&&packet)
			printf("For server\n");

		while(packet)
		{

			switch (packet->data[0])
			{
			case ID_REMOTE_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("Another client has disconnected.\n");

				break;
			case ID_REMOTE_CONNECTION_LOST:
				if (isVerbose)
					printf("Another client has lost the connection.\n");

				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");

				break;
			case ID_CONNECTION_ATTEMPT_FAILED:
				if (isVerbose)
					printf("A connection has failed.\n");

				break;

			case ID_NEW_INCOMING_CONNECTION:
				if (isVerbose)              
					printf("A connection is incoming.\n");

				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				if (isVerbose)              
					printf("The server is full.\n");

				break;

			case ID_ALREADY_CONNECTED:
				if (isVerbose)              
					printf("Already connected\n");

				break;

			case ID_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("We have been disconnected.\n");
				break;
			case ID_CONNECTION_LOST:
				if (isVerbose)
					printf("Connection lost.\n");

				break;
			default:

				break;
			}

			server->DeallocatePacket(packet);

			// Stay in the loop as long as there are more packets.
			packet = server->Receive();
		}

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

			packet=clientList[i]->Receive();

			if (isVerbose&&packet)
				printf("For peer %i\n",i);

			while(packet)
			{

				switch (packet->data[0])
				{
				case ID_REMOTE_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("Another client has disconnected.\n");

					break;
				case ID_REMOTE_CONNECTION_LOST:
					if (isVerbose)
						printf("Another client has lost the connection.\n");

					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");

					break;
				case ID_CONNECTION_ATTEMPT_FAILED:
					if (isVerbose)
						printf("A connection has failed.\n");

					break;

				case ID_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("A connection is incoming.\n");

					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS:
					if (isVerbose)              
						printf("The server is full.\n");

					break;

				case ID_ALREADY_CONNECTED:
					if (isVerbose)              
						printf("Already connected\n");

					break;

				case ID_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("We have been disconnected.\n");
					break;
				case ID_CONNECTION_LOST:
					if (isVerbose)
						printf("Connection lost.\n");

					break;
				default:

					break;
				}

				clientList[i]->DeallocatePacket(packet);

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

	entryTime=GetTimeMS();

	while(GetTimeMS()-entryTime<2000)//Run for 2 Secoonds to process incoming disconnects
	{

		//Server receive

		packet=server->Receive();

		if (isVerbose&&packet)
			printf("For server\n");

		while(packet)
		{

			switch (packet->data[0])
			{
			case ID_REMOTE_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("Another client has disconnected.\n");

				break;
			case ID_REMOTE_CONNECTION_LOST:
				if (isVerbose)
					printf("Another client has lost the connection.\n");

				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");

				break;
			case ID_CONNECTION_ATTEMPT_FAILED:
				if (isVerbose)
					printf("A connection has failed.\n");

				break;

			case ID_NEW_INCOMING_CONNECTION:
				if (isVerbose)              
					printf("A connection is incoming.\n");

				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				if (isVerbose)              
					printf("The server is full.\n");

				break;

			case ID_ALREADY_CONNECTED:
				if (isVerbose)              
					printf("Already connected\n");

				break;

			case ID_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("We have been disconnected.\n");
				break;
			case ID_CONNECTION_LOST:
				if (isVerbose)
					printf("Connection lost.\n");

				break;
			default:

				break;
			}

			server->DeallocatePacket(packet);

			// Stay in the loop as long as there are more packets.
			packet = server->Receive();
		}

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

			packet=clientList[i]->Receive();
			if (isVerbose&&packet)
				printf("For peer %i\n",i);

			while(packet)
			{

				switch (packet->data[0])
				{
				case ID_REMOTE_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("Another client has disconnected.\n");

					break;
				case ID_REMOTE_CONNECTION_LOST:
					if (isVerbose)
						printf("Another client has lost the connection.\n");

					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");

					break;
				case ID_CONNECTION_ATTEMPT_FAILED:
					if (isVerbose)
						printf("A connection has failed.\n");

					break;

				case ID_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("A connection is incoming.\n");

					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS:
					if (isVerbose)              
						printf("The server is full.\n");

					break;

				case ID_ALREADY_CONNECTED:
					if (isVerbose)              
						printf("Already connected\n");

					break;

				case ID_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("We have been disconnected.\n");
					break;
				case ID_CONNECTION_LOST:
					if (isVerbose)
						printf("Connection lost.\n");

					break;
				default:

					break;
				}

				clientList[i]->DeallocatePacket(packet);

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

	//Connect

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

		currentSystem.SetBinaryAddress("127.0.0.1");
		currentSystem.port=60000;

		if(!CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,true,true,true,true) )//Are we connected or is there a pending operation ?
		{

			if (clientList[i]->Connect("127.0.0.1", 60000, 0,0)!=CONNECTION_ATTEMPT_STARTED)
			{

				clientList[i]->GetSystemList(systemList,guidList);//Get connectionlist
				int len=systemList.Size();

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

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

			}
		}

	}

	entryTime=GetTimeMS();

	while(GetTimeMS()-entryTime<5000)//Run for 5 Secoonds
	{

		//Server receive

		packet=server->Receive();
		if (isVerbose&&packet)
			printf("For server\n");

		while(packet)
		{

			switch (packet->data[0])
			{
			case ID_REMOTE_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("Another client has disconnected.\n");

				break;
			case ID_REMOTE_CONNECTION_LOST:
				if (isVerbose)
					printf("Another client has lost the connection.\n");

				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");

				break;
			case ID_CONNECTION_ATTEMPT_FAILED:
				if (isVerbose)
					printf("A connection has failed.\n");

				break;

			case ID_NEW_INCOMING_CONNECTION:
				if (isVerbose)              
					printf("A connection is incoming.\n");

				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				if (isVerbose)              
					printf("The server is full.\n");

				break;

			case ID_ALREADY_CONNECTED:
				if (isVerbose)              
					printf("Already connected\n");

				break;

			case ID_DISCONNECTION_NOTIFICATION:
				if (isVerbose)
					printf("We have been disconnected.\n");
				break;
			case ID_CONNECTION_LOST:
				if (isVerbose)
					printf("Connection lost.\n");

				break;
			default:

				break;
			}

			server->DeallocatePacket(packet);

			// Stay in the loop as long as there are more packets.
			packet = server->Receive();
		}

		for (int i=0;i<clientNum;i++)//Receive for all clients
		{

			packet=clientList[i]->Receive();
			if (isVerbose&&packet)
				printf("For peer %i\n",i);

			while(packet)
			{

				switch (packet->data[0])
				{
				case ID_REMOTE_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("Another client has disconnected.\n");

					break;
				case ID_REMOTE_CONNECTION_LOST:
					if (isVerbose)
						printf("Another client has lost the connection.\n");

					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");

					break;
				case ID_CONNECTION_ATTEMPT_FAILED:
					if (isVerbose)
						printf("A connection has failed.\n");

					break;

				case ID_NEW_INCOMING_CONNECTION:
					if (isVerbose)              
						printf("A connection is incoming.\n");

					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS:
					if (isVerbose)              
						printf("The server is full.\n");

					break;

				case ID_ALREADY_CONNECTED:
					if (isVerbose)              
						printf("Already connected\n");

					break;

				case ID_DISCONNECTION_NOTIFICATION:
					if (isVerbose)
						printf("We have been disconnected.\n");
					break;
				case ID_CONNECTION_LOST:
					if (isVerbose)
						printf("Connection lost.\n");

					break;
				default:

					break;
				}

				clientList[i]->DeallocatePacket(packet);

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

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

		clientList[i]->GetSystemList(systemList,guidList);
		int connNum=guidList.Size();//Get the number of connections for the current peer
		if (connNum!=1)//Did we connect to all?
		{

			if (isVerbose)
				printf("Not all clients reconnected normally.\nFailed on clients number %i\n",i);

			if (isVerbose)
				DebugTools::ShowError("",!noPauses && isVerbose,__LINE__,__FILE__);

		
			

			return 2;

		}

	}

	

	if (isVerbose)
		printf("Pass\n");
	return 0;

}
Exemplo n.º 11
0
int ComprehensiveConvertTest::RunTest(DataStructures::List<RakNet::RakString> params,bool isVerbose,bool noPauses)
{

	static const int CONNECTIONS_PER_SYSTEM =4;

	SystemAddress currentSystem;

	//	DebugTools::ShowError("Note: The conversion of this is on hold until the original sample's problem is known.",!noPauses && isVerbose,__LINE__,__FILE__);

	//	return 55;


	//	AutoRPC autoRpcs[NUM_PEERS];




	//AutoRPC autoRpcs[NUM_PEERS];

	
	int peerIndex;
	float nextAction;
	int i;
	int portAdd;


	char data[8096];

	int seed = 12345;
	if (isVerbose)
		printf("Using seed %i\n", seed);
	seedMT(seed);

	for (i=0; i < NUM_PEERS; i++)
	{

		//autoRpcs[i].RegisterFunction("RPC1", RPC1, false);
		//autoRpcs[i].RegisterFunction("RPC2", RPC2, false);
		//autoRpcs[i].RegisterFunction("RPC3", RPC3, false);
		//autoRpcs[i].RegisterFunction("RPC4", RPC4, false);
		peers[i]=RakNetworkFactory::GetRakPeerInterface();
		peers[i]->SetMaximumIncomingConnections(CONNECTIONS_PER_SYSTEM);
		SocketDescriptor socketDescriptor(60000+i, 0);
		peers[i]->Startup(NUM_PEERS, 0, &socketDescriptor, 1);
		peers[i]->SetOfflinePingResponse("Offline Ping Data", (int)strlen("Offline Ping Data")+1);
		peers[i]->ApplyNetworkSimulator(500,50,50);



		//		peers[i]->AttachPlugin(&autoRpc[i]);



	}

	for (i=0; i < NUM_PEERS; i++)
	{

		portAdd=randomMT()%NUM_PEERS;

		currentSystem.SetBinaryAddress("127.0.0.1");
		currentSystem.port=60000+portAdd;
		if(!peers[i]->IsConnected (currentSystem,true,true) )//Are we connected or is there a pending operation ?
		{
			if (!peers[i]->Connect("127.0.0.1", 60000+portAdd, 0, 0))
			{
				DebugTools::ShowError("Problem while calling connect.\n",!noPauses && isVerbose,__LINE__,__FILE__);
				return 1;

			}

		}

	}

	RakNetTime endTime = RakNet::GetTime()+10000;
	while (RakNet::GetTime()<endTime)
	{
		nextAction = frandomMT();

		if (nextAction < .04f)
		{
			// Initialize
			peerIndex=randomMT()%NUM_PEERS;
			SocketDescriptor socketDescriptor(60000+peerIndex, 0);
			peers[peerIndex]->Startup(NUM_PEERS, randomMT()%30, &socketDescriptor, 1);
			portAdd=randomMT()%NUM_PEERS;

			currentSystem.SetBinaryAddress("127.0.0.1");
			currentSystem.port=60000+portAdd;
			if(!peers[peerIndex]->IsConnected (currentSystem,true,true) )//Are we connected or is there a pending operation ?
			{
				if(!peers[peerIndex]->Connect("127.0.0.1", 60000+portAdd, 0, 0))
				{
					DebugTools::ShowError("Problem while calling connect.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					return 1;

				}

			}
		}
		else if (nextAction < .09f)
		{
			// Connect
			peerIndex=randomMT()%NUM_PEERS;
			portAdd=randomMT()%NUM_PEERS;

			currentSystem.SetBinaryAddress("127.0.0.1");
			currentSystem.port=60000+portAdd;
			if(!peers[peerIndex]->IsConnected (currentSystem,true,true) )//Are we connected or is there a pending operation ?
			{
				if (!peers[peerIndex]->Connect("127.0.0.1", 60000+portAdd, 0, 0))
				{
					DebugTools::ShowError("Problem while calling connect.\n",!noPauses && isVerbose,__LINE__,__FILE__);
					return 1;

				}
			}
		}
		else if (nextAction < .10f)
		{
			// Disconnect
			peerIndex=randomMT()%NUM_PEERS;
			//	peers[peerIndex]->Shutdown(randomMT() % 100);
		}
		else if (nextAction < .12f)
		{
			// GetConnectionList
			peerIndex=randomMT()%NUM_PEERS;
			SystemAddress remoteSystems[NUM_PEERS];
			unsigned short numSystems=NUM_PEERS;
			peers[peerIndex]->GetConnectionList(remoteSystems, &numSystems);
			if (numSystems>0)
			{
				if (isVerbose){
					printf("%i: ", 60000+numSystems);
					for (i=0; i < numSystems; i++)
					{
						printf("%i: ", remoteSystems[i].port);
					}
					printf("\n");
				}
			}			
		}
		else if (nextAction < .14f)
		{
			// Send
			int dataLength;
			PacketPriority priority;
			PacketReliability reliability;
			unsigned char orderingChannel;
			SystemAddress target;
			bool broadcast;

			//	data[0]=ID_RESERVED1+(randomMT()%10);
			data[0]=ID_USER_PACKET_ENUM;
			dataLength=3+(randomMT()%8000);
			//			dataLength=600+(randomMT()%7000);
			priority=(PacketPriority)(randomMT()%(int)NUMBER_OF_PRIORITIES);
			reliability=(PacketReliability)(randomMT()%((int)RELIABLE_SEQUENCED+1));
			orderingChannel=randomMT()%32;
			if ((randomMT()%NUM_PEERS)==0)
				target=UNASSIGNED_SYSTEM_ADDRESS;
			else
				target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS);

			broadcast=(bool)(randomMT()%2);
#ifdef _VERIFY_RECIPIENTS
			broadcast=false; // Temporarily in so I can check recipients
#endif

			peerIndex=randomMT()%NUM_PEERS;
			sprintf(data+3, "dataLength=%i priority=%i reliability=%i orderingChannel=%i target=%i broadcast=%i\n", dataLength, priority, reliability, orderingChannel, target.port, broadcast);
			//unsigned short localPort=60000+i;
#ifdef _VERIFY_RECIPIENTS
			memcpy((char*)data+1, (char*)&target.port, sizeof(unsigned short));
#endif
			data[dataLength-1]=0;
			peers[peerIndex]->Send(data, dataLength, priority, reliability, orderingChannel, target, broadcast);
		}
		else if (nextAction < .18f)
		{
			// RPC
			int dataLength;
			PacketPriority priority;
			PacketReliability reliability;
			unsigned char orderingChannel;
			SystemAddress target;
			bool broadcast;
			char RPCName[10];

			data[0]=ID_USER_PACKET_ENUM+(randomMT()%10);
			dataLength=3+(randomMT()%8000);
			//			dataLength=600+(randomMT()%7000);
			priority=(PacketPriority)(randomMT()%(int)NUMBER_OF_PRIORITIES);
			reliability=(PacketReliability)(randomMT()%((int)RELIABLE_SEQUENCED+1));
			orderingChannel=randomMT()%32;
			peerIndex=randomMT()%NUM_PEERS;
			if ((randomMT()%NUM_PEERS)==0)
				target=UNASSIGNED_SYSTEM_ADDRESS;
			else
				target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS);
			broadcast=(bool)(randomMT()%2);
#ifdef _VERIFY_RECIPIENTS
			broadcast=false; // Temporarily in so I can check recipients
#endif

			sprintf(data+3, "dataLength=%i priority=%i reliability=%i orderingChannel=%i target=%i broadcast=%i\n", dataLength, priority, reliability, orderingChannel, target.port, broadcast);
#ifdef _VERIFY_RECIPIENTS
			memcpy((char*)data, (char*)&target.port, sizeof(unsigned short));
#endif
			data[dataLength-1]=0;
			sprintf(RPCName, "RPC%i", (randomMT()%4)+1);
			//				autoRpc[i]->Call(RPCName);
			//peers[peerIndex]->RPC(RPCName, data, dataLength*8, priority, reliability, orderingChannel, target, broadcast, 0, UNASSIGNED_NETWORK_ID,0);
		}
		else if (nextAction < .181f)
		{
			// CloseConnection
			SystemAddress target;
			peerIndex=randomMT()%NUM_PEERS;
			target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS);
			peers[peerIndex]->CloseConnection(target, (bool)(randomMT()%2), 0);
		}
		else if (nextAction < .20f)
		{
			// Offline Ping
			peerIndex=randomMT()%NUM_PEERS;
			peers[peerIndex]->Ping("127.0.0.1", 60000+(randomMT()%NUM_PEERS), (bool)(randomMT()%2));
		}
		else if (nextAction < .21f)
		{
			// Online Ping
			SystemAddress target;
			target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS);
			peerIndex=randomMT()%NUM_PEERS;
			peers[peerIndex]->Ping(target);
		}
		else if (nextAction < .24f)
		{
			// SetCompileFrequencyTable
			peerIndex=randomMT()%NUM_PEERS;
			peers[peerIndex]->SetCompileFrequencyTable(randomMT()%2);
		}
		else if (nextAction < .25f)
		{
			// GetStatistics
			SystemAddress target, mySystemAddress;
			RakNetStatistics *rss;
			mySystemAddress=peers[peerIndex]->GetInternalID();
			target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS);
			peerIndex=randomMT()%NUM_PEERS;
			rss=peers[peerIndex]->GetStatistics(mySystemAddress);
			if (rss)
			{
				StatisticsToString(rss, data, 0);
				if (isVerbose)
					printf("Statistics for local system %i:\n%s", mySystemAddress.port, data);

			}

			rss=peers[peerIndex]->GetStatistics(target);
			if (rss)
			{
				StatisticsToString(rss, data, 0);
				if (isVerbose)
					printf("Statistics for target system %i:\n%s", target.port, data);

			}			
		}

		for (i=0; i < NUM_PEERS; i++)
			peers[i]->DeallocatePacket(peers[i]->Receive());


		RakSleep(0);

	}


	

	return 0;

}
/*

The server timeout for this test is set to one second.

What is being done here is having 256 clients connect to a server.

Then the client is deallocated.

It is put to sleep for double the timeout amount.

After that the timeout should trigger and the clients register as disconnected.

Then the connection is started again.

Do this for about 30 seconds. 

It is put to sleep for double the timeout amount.

Then allow them all to connect for one last time.

This version waits for connect and such in a loop, blocking execution so it is a blocking test.

Good ideas for changes:
After the last check run a eightpeers like test an add the conditions
of that test as well.

Success conditions:
All connected normally.

Failure conditions:
Doesn't reconnect normally.

During the very first connect loop any connect returns false.

Connect function returns false and peer is not connected to anything,pending a connection, or disconnecting.

GetTimeoutTime does not match the set timeout.

RakPeerInterface Functions used, tested indirectly by its use:
Startup
Connect
SetMaximumIncomingConnections
Receive
Send
DeallocatePacket
GetSystemList
SetMaximumIncomingConnections

RakPeerInterface Functions Explicitly Tested:
GetTimeoutTime
SetTimeoutTime
Connect
IsConnected

*/
int ManyClientsOneServerDeallocateBlockingTest::RunTest(DataStructures::List<RakNet::RakString> params,bool isVerbose,bool noPauses)
{

	SystemAddress currentSystem;

	//Initializations of the arrays
	for (int i=0;i<clientNum;i++)
	{

		clientList[i]=RakNetworkFactory::GetRakPeerInterface();

		SocketDescriptor tmp;
		clientList[i]->Startup(1,30,&tmp, 1);

	}

	server=RakNetworkFactory::GetRakPeerInterface();
	SocketDescriptor tmp(60000,0);
	server->Startup(clientNum, 30, &tmp, 1);
	server->SetMaximumIncomingConnections(clientNum);

	const int timeoutTime=1000;
	server->SetTimeoutTime(timeoutTime,UNASSIGNED_SYSTEM_ADDRESS);

	int retTimeout=(int)server->GetTimeoutTime(UNASSIGNED_SYSTEM_ADDRESS);
	if (retTimeout!=timeoutTime)
	{

		if (isVerbose)
			DebugTools::ShowError("GetTimeoutTime did not match the timeout that was set. \n",!noPauses && isVerbose,__LINE__,__FILE__);

		return 3;

	}

	//Connect all the clients to the server

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

		if (!clientList[i]->Connect("127.0.0.1", 60000, 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

	DataStructures::List< SystemAddress  > systemList;
	DataStructures::List< RakNetGUID > guidList;

	if (isVerbose)
		printf("Entering disconnect loop \n");

	while(RakNet::GetTime()-entryTime<30000)//Run for 30 Secoonds
	{

		//Deallocate client IF connected
		for (int i=0;i<clientNum;i++)
		{

			clientList[i]->GetSystemList(systemList,guidList);//Get connectionlist
			int len=systemList.Size();

			if(len>=1)
			{

				RakNetworkFactory::DestroyRakPeerInterface(clientList[i]);
				clientList[i]=RakNetworkFactory::GetRakPeerInterface();
	

				SocketDescriptor tmp;
				clientList[i]->Startup(1,30,&tmp, 1);
			}

		}

		RakSleep(2000);//Allow connections to timeout.

		//Connect

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

			currentSystem.SetBinaryAddress("127.0.0.1");
			currentSystem.port=60000;
			if(!clientList[i]->IsConnected (currentSystem,true,true) )//Are we connected or is there a pending operation ?
			{

				if (!clientList[i]->Connect("127.0.0.1", 60000, 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.

				}
			}

		}

		WaitAndPrintResults(clientList,clientNum,isVerbose,server);

	}

	WaitAndPrintResults(clientList,clientNum,isVerbose,server);

	printf("Connecting clients\n");

	RakSleep(2000);//Allow connections to timeout.

	//Connect

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

		currentSystem.SetBinaryAddress("127.0.0.1");
		currentSystem.port=60000;

		if(!clientList[i]->IsConnected (currentSystem,true,true) )//Are we connected or is there a pending operation ?
		{
			printf("Calling Connect() for client %i.\n",i);

			if (!clientList[i]->Connect("127.0.0.1", 60000, 0,0))
			{
				clientList[i]->GetSystemList(systemList,guidList);//Get connectionlist
				int len=systemList.Size();

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

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

			}
		}
		else
		{
			if (clientList[i]->IsConnected (currentSystem,true,false)==false)
				printf("Not calling Connect() for client %i because IsConnected() returned true (isDisconnecting).\n",i);
			else if (clientList[i]->IsConnected (currentSystem,false,true)==false)
				printf("Not calling Connect() for client %i  because IsConnected() returned true (isConnecting).\n",i);
			else if (clientList[i]->IsConnected (currentSystem,false,false)==false)
				printf("Not calling Connect() for client %i because IsConnected() returned true (isConnected).\n",i);
		}

	}

	WaitAndPrintResults(clientList,clientNum,isVerbose,server);

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

		clientList[i]->GetSystemList(systemList,guidList);
		int connNum=guidList.Size();//Get the number of connections for the current peer
		if (connNum!=1)//Did we connect all?
		{

			if (isVerbose)
			{
				printf("Not all clients reconnected normally.\nFailed on client number %i\n",i);

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

			return 2;

		}

	}

	if (isVerbose)
		printf("Pass\n");
	return 0;

}
Exemplo n.º 13
0
int main(void)
{
	PortAudioStream *stream;
	PaError    err;
	mute=false;

	bool quit;
	char ch;

	printf("A sample on how to use RakVoice. You need a microphone for this sample.\n");
	printf("RakVoice relies on Speex for voice encoding and decoding.\n");
	printf("See DependentExtensions/RakVoice/speex-1.1.12 for speex projects.\n");
	printf("For windows, I had to define HAVE_CONFIG_H, include win32/config.h,\n");
	printf("and include the files under libspeex, except those that start with test.\n");
	printf("PortAudio is also included and is used to read and write audio data.  You\n");
	printf("can substitute whatever you want if you do not want to use portaudio.\n");
	printf("Difficulty: Advanced\n\n");

	// Since voice is peer to peer, we give the option to use the nat punchthrough client if desired.
	NatPunchthroughClient natPunchthroughClient;
	char port[256];
	rakPeer = RakNetworkFactory::GetRakPeerInterface();
	printf("Enter local port (enter for default): ");
	gets(port);
	if (port[0]==0)
		strcpy(port, "60000");
	SocketDescriptor socketDescriptor(atoi(port),0);
	rakPeer->Startup(4, 30, &socketDescriptor, 1);
	rakPeer->SetMaximumIncomingConnections(4);
	rakPeer->AttachPlugin(&rakVoice);
	rakPeer->AttachPlugin(&natPunchthroughClient);
	rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER*sizeof(SAMPLE));

	err = Pa_Initialize();
	if( err != paNoError ) goto error;
	
	err = Pa_OpenStream(
		&stream,
		Pa_GetDefaultInputDeviceID(),
		1, // Num channels, whatever that means
		PA_SAMPLE_TYPE,
		NULL,
		Pa_GetDefaultOutputDeviceID(),
		1, // Num channels
		PA_SAMPLE_TYPE,
		NULL,
		SAMPLE_RATE,
		FRAMES_PER_BUFFER,            /* frames per buffer */
		0,               /* number of buffers, if zero then use default minimum */
		0, /* paDitherOff, // flags */
		PACallback,
		0 );

	if( err != paNoError ) goto error;

	err = Pa_StartStream( stream );
	if( err != paNoError ) goto error;

	printf("Support NAT punchthrough? (y/n)? ");
	bool useNatPunchthrough;
	useNatPunchthrough=(getche()=='y');
	printf("\n");
	char facilitatorIP[256];
	{//Linux fix. Won't compile without it. Because of the goto error above, the scope is ambigious. Make it a block to define that it will not be used after the jump.
	//Doesn't change current logic
	SystemAddress facilitator;
	if (useNatPunchthrough)
	{
		printf("My GUID is %s\n", rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS).ToString());

		printf("Enter IP of facilitator (enter for default): ");
		gets(facilitatorIP);
		if (facilitatorIP[0]==0)
			strcpy(facilitatorIP, "94.198.81.195");
		facilitator.SetBinaryAddress(facilitatorIP);
		facilitator.port=NAT_PUNCHTHROUGH_FACILITATOR_PORT;
		rakPeer->Connect(facilitatorIP, NAT_PUNCHTHROUGH_FACILITATOR_PORT, 0, 0);
		printf("Connecting to facilitator...\n");
	}
	else
	{
		printf("Not supporting NAT punchthrough.\n");
	}


    
	Packet *p;
	quit=false;
	if (useNatPunchthrough==false)
		printf("(Q)uit. (C)onnect. (D)isconnect. C(l)ose voice channels. (M)ute. ' ' for stats.\n");

	while (!quit)
	{
		if (kbhit())
		{
			ch=getch();
			if (ch=='y')
			{
				quit=true;
			}
			else if (ch=='c')
			{
				if (useNatPunchthrough)
				{
					RakNetGUID destination;
					printf("Enter GUID of destination: ");
					char guidStr[256];
					while (1)
					{
						gets(guidStr);
						if (!destination.FromString(guidStr))
							printf("Invalid GUID format. Try again.\nEnter GUID of destination: ");
						else
							break;
					}
					printf("Starting NAT punch. Please wait...\n");
					natPunchthroughClient.OpenNAT(destination,facilitator);
				}
				else
				{
					char ip[256];
					printf("Enter IP of remote system: ");
					gets(ip);
					if (ip[0]==0)
						strcpy(ip, "127.0.0.1");
					printf("Enter port of remote system: ");
					gets(port);
					if (port[0]==0)
						strcpy(port, "60000");
					rakPeer->Connect(ip, atoi(port), 0,0);

				}
			}
			else if (ch=='m')
			{
				mute=!mute;
				if (mute)
					printf("Now muted.\n");
				else
					printf("No longer muted.\n");
			}
			else if (ch=='d')
			{
				rakPeer->Shutdown(100,0);
			}
			else if (ch=='l')
			{
				rakVoice.CloseAllChannels();
			}
			else if (ch==' ')
			{
				char message[2048];
				RakNetStatistics *rss=rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0));
				StatisticsToString(rss, message, 2);
				printf("%s", message);
			}
			else if (ch=='q')
				quit=true;
			ch=0;
		}

		p=rakPeer->Receive();
		while (p)
		{
			if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
			{
				if (p->systemAddress==facilitator)
				{
					printf("Connection to facilitator completed\n");
					printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n");
				}
				else
				{
					printf("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString());
					rakVoice.RequestVoiceChannel(p->guid);
				}
			}
			else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED)
			{
				if (p->systemAddress==facilitator)
				{
					printf("Connection to facilitator failed. Using direct connections\n");
					useNatPunchthrough=false;
					printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n");
				}
				else
				{
					printf("ID_CONNECTION_ATTEMPT_FAILED\n");
				}
			}
			else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST || p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY)
			{
				printf("Got new channel from %s\n", p->systemAddress.ToString());
			}
			else if (p->data[0]==ID_NAT_TARGET_NOT_CONNECTED)
			{
				RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_TARGET_NOT_CONNECTED for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_TARGET_UNRESPONSIVE)
			{
				RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_TARGET_UNRESPONSIVE for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST)
			{
				RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_CONNECTION_TO_TARGET_LOST for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_ALREADY_IN_PROGRESS)
			{
				RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_ALREADY_IN_PROGRESS for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_PUNCHTHROUGH_FAILED)
			{
				printf("ID_NAT_PUNCHTHROUGH_FAILED for %s\n", p->guid.ToString());
			}
			else if (p->data[0]==ID_NAT_PUNCHTHROUGH_SUCCEEDED)
			{
				printf("ID_NAT_PUNCHTHROUGH_SUCCEEDED for %s. Connecting...\n", p->guid.ToString());
				rakPeer->Connect(p->systemAddress.ToString(false),p->systemAddress.port,0,0);
			}
			else if (p->data[0]==ID_ALREADY_CONNECTED)
			{
				printf("ID_ALREADY_CONNECTED\n");
			}
			else if (p->data[0]==ID_RAKVOICE_CLOSE_CHANNEL)
			{
				printf("ID_RAKVOICE_CLOSE_CHANNEL\n");
			}
			else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION)
			{
				printf("ID_DISCONNECTION_NOTIFICATION\n");
			}
			else if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
			{
				printf("ID_NEW_INCOMING_CONNECTION\n");
			}
			else
			{
				printf("Unknown packet ID %i\n", p->data[0]);
			}


			rakPeer->DeallocatePacket(p);
			p=rakPeer->Receive();
		}


		Pa_Sleep( 30 );
	}
	}

	err = Pa_CloseStream( stream );
	if( err != paNoError ) goto error;

	Pa_Terminate();

	rakPeer->Shutdown(300);
	RakNetworkFactory::DestroyRakPeerInterface(rakPeer);

	return 0;

error:
	Pa_Terminate();
	fprintf( stderr, "An error occured while using the portaudio stream\n" );
	fprintf( stderr, "Error number: %d\n", err );
	fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
	return -1;
}
Exemplo n.º 14
0
int main(void)
{
	int i;

	for (i=0; i < NUM_PEERS; i++)
		rakPeer[i]=RakNetworkFactory::GetRakPeerInterface();

	printf("This project tests and demonstrates the ready event plugin.\n");
	printf("It is used in a peer to peer environment to have a group of\nsystems signal an event.\n");
	printf("It is useful for changing turns in a turn based game,\nor for lobby systems where everyone has to set ready before the game starts\n");
	printf("Difficulty: Beginner\n\n");

	int peerIndex;

	// Initialize the message handlers
	for (peerIndex=0; peerIndex < NUM_PEERS; peerIndex++)
	{
		fullyConnectedMeshPlugin[peerIndex].Startup(0,0);
		rakPeer[peerIndex]->AttachPlugin(&connectionGraphPlugin[peerIndex]);
		rakPeer[peerIndex]->AttachPlugin(&fullyConnectedMeshPlugin[peerIndex]);
		rakPeer[peerIndex]->AttachPlugin(&readyEventPlugin[peerIndex]);
		rakPeer[peerIndex]->SetMaximumIncomingConnections(NUM_PEERS);
	}


	// Initialize the peers
	for (peerIndex=0; peerIndex < NUM_PEERS; peerIndex++)
	{
		SocketDescriptor socketDescriptor(60000+peerIndex,0);
		rakPeer[peerIndex]->Startup(NUM_PEERS, 0, &socketDescriptor, 1);
	}

	// Give the threads time to properly start
	RakSleep(200);

	printf("Peers initialized.\n");

	printf("'C' to connect a system\n");
	printf("'D' to disconnect a system\n");
	printf("'S' to signal a system\n");
	printf("'U' to unsignal a system\n");
	printf("'F' to force all systems to be completed (cannot be unset)\n");
	printf("'Q' to quit\n");
	printf("' ' to print wait statuses\n");

	char str[128];
	char ch=0;
	while (1)
	{
		if (kbhit())
			ch=getch();

		if (ch=='s' || ch=='S')
		{
			ch=0;
			printf("Which system? 0 to %i\n", NUM_PEERS-1);
			gets(str);
			int sysIndex = atoi(str);
			if (sysIndex>=0 && sysIndex<NUM_PEERS)
			{
				if (readyEventPlugin[sysIndex].SetEvent(0,true))
					printf("Set system %i to signaled\n", sysIndex);
				else
					printf("Set system %i to signaled FAILED\n", sysIndex);
			}
			else
			{
				printf("Invalid range\n");
			}
		}
		if (ch=='u' || ch=='U')
		{
			ch=0;
			printf("Which system? 0 to %i\n", NUM_PEERS-1);
			gets(str);
			int sysIndex = atoi(str);
			if (sysIndex>=0 && sysIndex<NUM_PEERS)
			{
				if (readyEventPlugin[sysIndex].SetEvent(0,false))
					printf("Set index %i to unsignaled\n", sysIndex);
				else
					printf("Set index %i to unsignaled FAILED\n", sysIndex);
			}
			else
			{
				printf("Invalid range\n");
			}
		}
		if (ch=='c' || ch=='C')
		{
			ch=0;
			printf("Which system? 0 to %i\n", NUM_PEERS-1);
			gets(str);
			int sysIndex = atoi(str);
			if (sysIndex>=0 && sysIndex<NUM_PEERS)
			{
				rakPeer[sysIndex]->Connect("127.0.0.1", 60000, 0, 0, 0);
				printf("Connecting system %i.\n", sysIndex);
			}
			else
			{
				printf("Invalid range\n");
			}
		}
		if (ch=='d' || ch=='D')
		{
			ch=0;
			printf("Which system? 0 to %i\n", NUM_PEERS-1);
			gets(str);
			int sysIndex = atoi(str);
			if (sysIndex>=0 && sysIndex<NUM_PEERS)
			{
				rakPeer[sysIndex]->Shutdown(100,0);
				SocketDescriptor socketDescriptor(60000+sysIndex,0);
				rakPeer[sysIndex]->Startup(NUM_PEERS, 0, &socketDescriptor, 1);
				printf("Restarting system %i.\n", sysIndex);
			}
			else
			{
				printf("Invalid range\n");
			}
		}
		if (ch=='f' || ch=='F')
		{
			ch=0;
			printf("Which system? 0 to %i\n", NUM_PEERS-1);
			gets(str);
			int sysIndex = atoi(str);
			if (sysIndex>=0 && sysIndex<NUM_PEERS)
			{
				if (readyEventPlugin[sysIndex].ForceCompletion(0))
					printf("Set system %i to force complete\n", sysIndex);
				else
					printf("Set system %i to force complete FAILED\n", sysIndex);
			}
			else
			{
				printf("Invalid range\n");
			}
		}
		if (ch==' ')
		{
			SystemAddress sysAddr;
			sysAddr.SetBinaryAddress("127.0.0.1");
			unsigned j;
			printf("\n");
			PrintConnections();
			for (i=0; i < NUM_PEERS; i++)
			{
				printf("System %i, ", i);
				if (readyEventPlugin[i].IsEventSet(0))
					printf("Set=True, ");
				else
					printf("Set=False, ");

				if (readyEventPlugin[i].IsEventCompleted(0))
					printf("Completed=True\n");
				else if (readyEventPlugin[i].IsEventCompletionProcessing(0))
					printf("Completed=InProgress\n");
				else
					printf("Completed=False\n");

				for (j=0; j < NUM_PEERS; j++)
				{
					if (i!=j)
					{

						ReadyEventSystemStatus ress;
						sysAddr.port=60000+j;
						ress = readyEventPlugin[i].GetReadyStatus(0, sysAddr);
						printf("  Remote system %i, status = ", j);
						
						switch (ress)
						{
						case RES_NOT_WAITING:
							printf("RES_NOT_WAITING\n");
							break;
						case RES_WAITING:
							printf("RES_WAITING\n");
							break;
						case RES_READY:
							printf("RES_READY\n");
							break;
						case RES_ALL_READY:
							printf("RES_ALL_READY\n");
							break;
						case RES_UNKNOWN_EVENT:
							printf("RES_UNKNOWN_EVENT\n");
							break;

						}
					}
				}
			}
			ch=0;
		}
		if (ch=='Q')
		{
			break;
		}

		for (i=0; i < NUM_PEERS; i++)
		{
			Packet *p = rakPeer[i]->Receive();
			if (p)
			{
				switch (p->data[0])
				{
				case ID_NEW_INCOMING_CONNECTION:
					readyEventPlugin[i].AddToWaitList(0, p->systemAddress);
					break;
				case ID_CONNECTION_REQUEST_ACCEPTED:
					readyEventPlugin[i].AddToWaitList(0, p->systemAddress);
					break;
				case ID_READY_EVENT_ALL_SET:
					printf("Got ID_READY_EVENT_ALL_SET from %s\n", p->systemAddress.ToString(true));
					break;
				}

				rakPeer[i]->DeallocatePacket(p);
			}			
		}

		// Keep raknet threads responsive
		RakSleep(30);
	}
	
	for (i=0; i < NUM_PEERS; i++)
		RakNetworkFactory::DestroyRakPeerInterface(rakPeer[i]);

	return 1;
}
Exemplo n.º 15
0
int PingTestsTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
{

	RakPeerInterface *sender,*sender2, *receiver;
	destroyList.Clear(false,_FILE_AND_LINE_);

	TestHelpers::StandardClientPrep(sender,destroyList);

	TestHelpers::StandardClientPrep(sender2,destroyList);

	receiver=RakPeerInterface::GetInstance();
	destroyList.Push(receiver,_FILE_AND_LINE_);
	receiver->Startup(2, &SocketDescriptor(60000,0), 1);
	receiver->SetMaximumIncomingConnections(2);
	Packet * packet;

	SystemAddress currentSystem;

	currentSystem.SetBinaryAddress("127.0.0.1");
	currentSystem.port=60000;

	printf("Connecting sender2\n");
	if (!TestHelpers::WaitAndConnectTwoPeersLocally(sender2,receiver,5000))
	{

		if (isVerbose)
			DebugTools::ShowError("Could not connect after 5 seconds\n",!noPauses && isVerbose,__LINE__,__FILE__);

		return 2;

	}

	printf("Getting ping data for lastping and lowestping\n");
	sender2->SetOccasionalPing(false);//Test the lowest ping and such without  occassionalping,occasional ping comes later
	RakTimer timer(1500);

	int lastPing=0;
	int lowestPing=0;
	TimeMS nextPing=0;

	while(!timer.IsExpired())
	{
		for (packet=receiver->Receive();packet;receiver->DeallocatePacket(packet),packet=receiver->Receive())
		{
			if (isVerbose)
				printf("Receive packet id %i\n",packet->data[0]);
		}

		for (packet=sender2->Receive();packet;sender2->DeallocatePacket(packet),packet=sender2->Receive())
		{
			if (isVerbose)
				printf("Send packet id %i\n",packet->data[0]);

		}

		if (GetTimeMS()>nextPing)
		{
			sender2->Ping(currentSystem);
			nextPing=GetTimeMS()+30;
		}

		RakSleep(3);
	}

	int averagePing=sender2->GetAveragePing(currentSystem);
	if (isVerbose)
		printf("Average Ping time %i\n",averagePing);

	lastPing=sender2->GetLastPing(currentSystem);
	lowestPing=sender2->GetLowestPing(currentSystem);

	if (isVerbose)
		printf("Last Ping time %i\n",lastPing);

	if (isVerbose)
		printf("Lowest Ping time %i\n",lowestPing);

	int returnVal=TestAverageValue(averagePing,__LINE__, noPauses, isVerbose);

	if (returnVal!=0)
	{

		return returnVal;
	}

	if (lastPing>100)//100 MS for localhost?
	{
		if (isVerbose)
			DebugTools::ShowError("Problem with the last ping time,greater then 100MS for localhost\n",!noPauses && isVerbose,__LINE__,__FILE__);

		return 3;
	}

	if (lowestPing>10)//The lowest ping for localhost should drop below 10MS at least once
	{

		if (isVerbose)
			DebugTools::ShowError("The lowest ping for localhost should drop below 10MS at least once\n",!noPauses && isVerbose,__LINE__,__FILE__);

		return 4;
	}

	if (lastPing<lowestPing)
	{

		if (isVerbose)
			DebugTools::ShowError("There is a problem if the lastping is lower than the lowestping stat\n",!noPauses && isVerbose,__LINE__,__FILE__);

		return 5;
	}

	CommonFunctions::DisconnectAndWait(sender2,"127.0.0.1",60000);//Eliminate variables.

	printf("Connecting sender\n");
	if (!TestHelpers::WaitAndConnectTwoPeersLocally(sender,receiver,5000))
	{

		if (isVerbose)
			DebugTools::ShowError("Could not connect after 5 seconds\n",!noPauses && isVerbose,__LINE__,__FILE__);

		return 2;

	}

	lastPing=0;
	lowestPing=0;
	sender->SetOccasionalPing(true);

	printf("Testing SetOccasionalPing\n");

	timer.Start();
	while(!timer.IsExpired())
	{
		for (packet=receiver->Receive();packet;receiver->DeallocatePacket(packet),packet=receiver->Receive())
		{
			if (isVerbose)
				printf("Receive packet id %i\n",packet->data[0]);
		}

		for (packet=sender->Receive();packet;sender->DeallocatePacket(packet),packet=sender->Receive())
		{
			if (isVerbose)
				printf("Send packet id %i\n",packet->data[0]);

		}

		RakSleep(3);
	}

	averagePing=sender->GetAveragePing(currentSystem);
	if (isVerbose)
		printf("Average Ping time %i\n",averagePing);

	returnVal=TestAverageValue(averagePing,__LINE__, noPauses, isVerbose);

	if (returnVal!=0)
	{

		return returnVal;
	}

	return 0;

}
/*
What is being done here is having 256 clients connect to a server, disconnect, connect again.

Do this for about 10 seconds. Then allow them all to connect for one last time.

This version waits for connect and such in a loop, blocking execution so it is a blocking test.

Good ideas for changes:
After the last check run a eightpeers like test an add the conditions
of that test as well.

Make sure that if we initiate the connection we get a proper message
and if not we get a proper message. Add proper conditions.

Randomize sending the disconnect notes

Success conditions:
All connected normally.

Failure conditions:
Doesn't reconnect normally.

During the very first connect loop any connect returns false.

Connect function returns false and peer is not connected to anything and does not have anything pending.

*/
int ManyClientsOneServerBlockingTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
{

	const int clientNum= 256;

	RakPeerInterface *clientList[clientNum];//A list of clients
	RakPeerInterface *server;

	SystemAddress currentSystem;

	destroyList.Clear(false,_FILE_AND_LINE_);

	//Initializations of the arrays
	for (int i=0;i<clientNum;i++)
	{

		clientList[i]=RakPeerInterface::GetInstance();
		destroyList.Push(clientList[i],_FILE_AND_LINE_);

		clientList[i]->Startup(1,&SocketDescriptor(), 1);

	}

	server=RakPeerInterface::GetInstance();
	destroyList.Push(server,_FILE_AND_LINE_);
	server->Startup(clientNum, &SocketDescriptor(60000,0), 1);
	server->SetMaximumIncomingConnections(clientNum);

	//Connect all the clients to the server

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

		if (clientList[i]->Connect("127.0.0.1", 60000, 0,0)!=CONNECTION_ATTEMPT_STARTED)
		{

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

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

		}

	}

	TimeMS entryTime=GetTimeMS();//Loop entry time

	DataStructures::List< SystemAddress  > systemList;
	DataStructures::List< RakNetGUID > guidList;

	printf("Entering disconnect loop \n");

	while(GetTimeMS()-entryTime<10000)//Run for 10 Secoonds
	{

		//Disconnect all clients IF connected to any from client side
		for (int i=0;i<clientNum;i++)
		{

			clientList[i]->GetSystemList(systemList,guidList);//Get connectionlist
			int len=systemList.Size();

			for (int j=0;j<len;j++)//Disconnect them all
			{

				clientList[i]->CloseConnection (systemList[j],true,0,LOW_PRIORITY); 	
			}

		}

		RakSleep(100);

		//Connect

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

			currentSystem.SetBinaryAddress("127.0.0.1");
			currentSystem.port=60000;
			if(!CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,true,true,true,true) )//Are we connected or is there a pending operation ?
			{

				if (clientList[i]->Connect("127.0.0.1", 60000, 0,0)!=CONNECTION_ATTEMPT_STARTED)
				{

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

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

				}
			}

		}

		WaitAndPrintResults(clientList,clientNum,isVerbose,server);

	}

	WaitAndPrintResults(clientList,clientNum,isVerbose,server);

	printf("Connecting clients\n");

	//Connect

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

		currentSystem.SetBinaryAddress("127.0.0.1");
		currentSystem.port=60000;

		if(!CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,true,true,true,true) )//Are we connected or is there a pending operation ?
		{
			printf("Calling Connect() for client %i.\n",i);

			if (clientList[i]->Connect("127.0.0.1", 60000, 0,0)!=CONNECTION_ATTEMPT_STARTED)
			{
				clientList[i]->GetSystemList(systemList,guidList);//Get connectionlist
				int len=systemList.Size();

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

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

			}
		}
		else
		{
			if (CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,false,false,false,true)==false)
				printf("Not calling Connect() for client %i because it is disconnecting.\n",i);
			else if (CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,false,true,true)==false)
				printf("Not calling Connect() for client %i  because it is connecting.\n",i);
			else if (CommonFunctions::ConnectionStateMatchesOptions (clientList[i],currentSystem,true)==false)
				printf("Not calling Connect() for client %i because it is connected).\n",i);
		}

	}

	WaitAndPrintResults(clientList,clientNum,isVerbose,server);

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

		clientList[i]->GetSystemList(systemList,guidList);
		int connNum=guidList.Size();//Get the number of connections for the current peer
		if (connNum!=1)//Did we connect all?
		{

			if (isVerbose)
			{
				printf("Not all clients reconnected normally.\nFailed on client number %i\n",i);

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

			return 2;

		}

	}

	

	if (isVerbose)
		printf("Pass\n");
	return 0;

}