예제 #1
0
void
CRakMasterServer::RegisterServer(RakNet::SystemAddress& _rServerAddress, RakNet::RakNetGUID& _rServerGuid, uchar* _ucpData, uint _uiLength)
{
	std::map<uint64, TServerDetails*>::iterator Entry = m_mRegisteredServers.find(_rServerGuid.g);


	if (Entry == m_mRegisteredServers.end())
	{
		TServerDetails* tpServerDetails = new TServerDetails();


		char sServerIp[256];
		_rServerAddress.ToString_Old(false, sServerIp);


		tpServerDetails->tAddress = _rServerAddress;
		tpServerDetails->tGuid = _rServerGuid;
		tpServerDetails->fUnregisterTimer = s_kfRegistrationTimeout;


		m_mRegisteredServers.insert( std::pair<uint64, TServerDetails*>(_rServerGuid.g, tpServerDetails) );


		LOG_MESSAGE("Registered Server. IP(%s) GUID(%llu)", _rServerAddress.ToString(), _rServerGuid.g);
	}
	else
	{
		Entry->second->fUnregisterTimer = s_kfRegistrationTimeout;


		LOG_MESSAGE("Re-registered Server. IP(%s) GUID(%llu)", _rServerAddress.ToString(), _rServerGuid.g);
	}
}
예제 #2
0
파일: Network.cpp 프로젝트: Razish/xsngine
	void PrintStatus( void ) {
		// enumerate local addresses
		size_t numAddresses = peer->GetNumberOfAddresses();
		if ( numAddresses ) {
			console.Print( PrintLevel::Normal, "Network primed on:\n" );
			for ( size_t i = 0u; i < numAddresses; i++ ) {
				Indent indent( 1u );
				console.Print( PrintLevel::Normal, "%i. %s\n",
					i + 1,
					peer->GetLocalIP( i )
				);
			}
		}
		else {
			console.Print( PrintLevel::Normal, "Network primed on %s\n",
				peer->GetMyBoundAddress().ToString()
			);
		}
		console.Print( PrintLevel::Normal, "GUID: %" PRIX64 "\n",
			myGUID
		);

		// get a list of remote connections
		uint16_t numRemoteSystems;
		peer->GetConnectionList( nullptr, &numRemoteSystems );
		RakNet::SystemAddress *remoteSystems = new RakNet::SystemAddress[numRemoteSystems];
		peer->GetConnectionList( remoteSystems, &numRemoteSystems );

		console.Print( PrintLevel::Normal, "%i connections (max: %i)\n",
			numRemoteSystems,
			peer->GetMaximumIncomingConnections()
		);
		if ( numRemoteSystems ) {
			console.Print( PrintLevel::Normal, "Listing active connections...\n" );
			for ( size_t i = 0u; i < numRemoteSystems; i++ ) {
				RakNet::SystemAddress *sa = &remoteSystems[i];
				Indent indent( 1u );

				std::string type;
				if ( sa->IsLANAddress() ) {
					type = " LAN";
				}
				else if ( sa->IsLoopback() ) {
					type = "LOOP";
				}
				else {
					type = "INET";
				}

				console.Print( PrintLevel::Normal, "%s: %s - %s\n",
					type.c_str(),
					sa->ToString(),
					connectionStateMessages[peer->GetConnectionState( *sa )]
				);
			}
		}
		delete[] remoteSystems;
	}
예제 #3
0
bool Network::is_in_same_network(std::string const& other) const {
  RakNet::SystemAddress o;
  RakNet::SystemAddress self;
  if (o.FromString(other.c_str()) && self.FromString(external_id_.c_str())) {
    if (o.EqualsExcludingPort(self)) {
      return true;
    }
  }
  return false;
}
예제 #4
0
파일: CProxy.cpp 프로젝트: alexis-/iwe
// Returning false prevents the proxy from forwarding current packet to the client
bool
CProxy::HandleLoginSrvPacket(RakNet::Packet* pPacket, RakNet::SystemAddress& clientAddr, RakNet::BitStream& inStr, uchar opCode)
{
  uint off = inStr.GetReadOffset();

  switch (opCode)
  {
  case Opcodes::OP_LOGIN:
    bool bLoggedIn = false;

    inStr.Read(bLoggedIn);

    if (bLoggedIn)
    {
      ff::fmt(pan::debug, "({0}) Player successfully logged in.", clientAddr.ToString(false));

      // Do the switch to Area server here
    }

    break;
  }

  inStr.SetReadOffset(off);

  return true;
}
예제 #5
0
bool NetworkEngine::canConnected(RakNet::SystemAddress id)
{
	RakNet::SystemAddress connecteds[MAX_PLAYERS];
	unsigned short size = MAX_PLAYERS;
	//unsigned short pos = peer->NumberOfConnections();
	//peer->GetConnectionList(connecteds,&pos);
	peer->GetConnectionList((RakNet::SystemAddress*) &connecteds,&size);

	if(disconnecteds.size() > 0)
	{
		std::vector<RakNet::SystemAddress>::iterator it = disconnecteds.begin();
		do
		{
			if(id.EqualsExcludingPort(*it))
			{
				disconnecteds.erase(it);
				return true;
			}
			it++;
		}while(it != disconnecteds.end());
	}

	for(int i=0;i<MAX_PLAYERS;i++)
	{
		if(connecteds[i].EqualsExcludingPort(id))
		{
			return false;
		}
	}

	return false;
}
예제 #6
0
void Connector::connect( RakNet::SystemAddress server ){
   
	if (raknetInterface == nullptr){
        LOG("Client is not started!");
        return;
    }

    char * ip = new char[64]; // must be new char[]! Not char ip[], BAD_ACCESS!!
    for(int i=0; i<64; i++){ ip[i] = 0; }
        
    server.ToString(false, ip);

	int result = raknetInterface->Connect(ip, server.GetPort(), RAKNET_PASSWORD, (int)strlen(RAKNET_PASSWORD));
    LOG("[Connector] Connecting to %s", ip);
    if(result == RakNet::CONNECTION_ATTEMPT_STARTED)
    {
        LOG("[Connector] Connecting to %s started.", ip);
    }
    else if (result == RakNet::INVALID_PARAMETER)
    {
        LOG("[Connector] INVALID_PARAMETER");
    }
    else if (result == RakNet::CANNOT_RESOLVE_DOMAIN_NAME)
    {
        LOG("[Connector] CANNOT_RESOLVE_DOMAIN_NAME");
    }

    else if (result == RakNet::ALREADY_CONNECTED_TO_ENDPOINT)
    {
        LOG("[Connector] ALREADY_CONNECTED_TO_ENDPOINT");
    }

    else if (result == RakNet::CONNECTION_ATTEMPT_ALREADY_IN_PROGRESS)
    {
        LOG("[Connector] CONNECTION_ATTEMPT_ALREADY_IN_PROGRESS");
    }

    else if (result == RakNet::SECURITY_INITIALIZATION_FAILED)
    {
        LOG("[Connector] SECURITY_INITIALIZATION_FAILED");
    }
    else{
        LOG("[Connector] connecting atempt failed for unknown reason!!!");
    }
    
    delete [] ip;
}
예제 #7
0
void NetworkEngine::sendMessagePlayerReconnected(RakNet::SystemAddress systemAddress)
{
	//Envia un ID_SERVER_MESSAGE con un RakNet::String;
	RakNet::BitStream bitStream;
	RakNet::RakString string("Player %s has reconnected to the game\n", systemAddress.ToString());
	bitStream.Write((unsigned char)ID_SERVER_STRING_MESSAGE);
	bitStream.Write(string);
	peer->Send(&bitStream, HIGH_PRIORITY, RELIABLE, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
}
	void ClientChatNetPackageSender::sendData( const char* data, int lenght )
	{
		const NetworkAddress& networkAddress(getPeer()->getNetworkAddress());
		RakNet::SystemAddress target;
		target.FromStringExplicitPort(networkAddress.getServerIp(),networkAddress.getServerPort());

		// HIGH_PRIORITY doesn't actually matter here because we don't use any other priority
		// RELIABLE_ORDERED means make sure the message arrives in the right order
		// We arbitrarily pick 0 for the ordering stream
		// target.FromStringExplicitPort created the address to send the data to
		// false means send the message to the given target address

		RakNet::RakPeerInterface* rakNetPeer(getPeer()->accessRakNetPeer());
		// note: better check if the peer is connected in the first place
		if(rakNetPeer != nullptr)	{
			rakNetPeer->Send(data, lenght, 
				HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false);
		}
	}
예제 #9
0
///加条发送的消息
void  SimulateClientMainFrame::addReceiveMessage(const std::string& message,const RakNet::SystemAddress& Address)
{
	wxString tem;
	tem+=Address.ToString();
	tem+=": ";
	tem+=message;
	tem+="\n";
	m_receiveText->AppendText(tem);

}
예제 #10
0
//------------------------------------------------------------------------------------
void PlayerManager::processDatabasePlayer(NetPack* pPack)
{
	///把数据转发给客户端

	Tag_PlayerCollect* players=static_cast<Tag_PlayerCollect*>(pPack->getData());

	
	if(players->m_Count==0)///表示这个帐号还没有新建角色
	{


	}else                      ///把所有角色发给客户端
	{

	}

	RakNet::SystemAddress address;
	address.SetBinaryAddress(players->m_ip);
	NetWorkServer::getSingleton().send(GM_REQUEST_PLAYERS,(const char*)pPack->getData(),pPack->getDataLength(),address);


	return ;
}
예제 #11
0
파일: CProxy.cpp 프로젝트: alexis-/iwe
void
CProxy::OnClosedConnection(const RakNet::SystemAddress&       systemAddress,
                           RakNet::RakNetGUID                 rakNetGUID,
                           RakNet::PI2_LostConnectionReason   lostConnectionReason)
{
  ff::fmt(pan::notice, "({0}) Closed connection", systemAddress.ToString(false));

  s_clientInfos* pInfos = m_mapClientAddr[systemAddress];

  m_mapClientAddr.erase(systemAddress);

  std::map<uint, s_clientInfos*>::iterator it = m_mapClientId.find(pInfos->m_uID);
  if (it != m_mapClientId.end())
    m_mapClientId.erase(it);
}
예제 #12
0
void Network_module::run()
{
    print_config();

    using namespace RakNet;
    RakNet::RakPeerInterface* l_rakpeer = RakNet::RakPeerInterface::GetInstance();

    int l_addr_count = l_rakpeer->GetNumberOfAddresses();
    NET_MOD_INFO("获取到本机IP数量%d个", l_addr_count);

    for (int i = 0; i < l_addr_count; i++)
    {
        RakNet::SystemAddress addr = l_rakpeer->GetLocalIP(i);
        NET_MOD_INFO("第%d个IP地址为:%s", i + 1, addr.ToString(false));
    }

    RakNet::SocketDescriptor l_socket_descriptor;
    l_socket_descriptor.port = m_local_port;

    if (l_rakpeer->Startup(m_max_connection, &l_socket_descriptor, 1) != RakNet::RAKNET_STARTED)
    {
        NET_MOD_ERROR("启动网络引擎失败");
        RakNet::RakPeerInterface::DestroyInstance(l_rakpeer);
        return;
    }

    l_rakpeer->SetMaximumIncomingConnections(m_max_income_connection);

    NET_MOD_INFO("启动网络引擎成功,监控地址为%s", l_rakpeer->GetMyBoundAddress().ToString(false));

    NET_MOD_INFO("开始载入打孔插件");
    m_punch_proxy = new NatPunchProxy;
    m_punch_proxy->init_proxy(l_rakpeer);

    start_network_loop(l_rakpeer);
}
예제 #13
0
파일: CProxy.cpp 프로젝트: alexis-/iwe
// Triggered when a new client connect to the proxy.
void
CProxy::OnNewConnection(const RakNet::SystemAddress&      systemAddress,
                        RakNet::RakNetGUID                rakNetGUID,
                        bool                              isIncoming)
{
  ff::fmt(pan::notice, "({0}) New connection", systemAddress.ToString(false));

  // Setup client infos
  s_clientInfos* pInfos = new s_clientInfos();
  pInfos->m_clientAddr = systemAddress;
  pInfos->m_pMainSrv = m_pLoginSrvInterface;
  pInfos->m_rakGUID = rakNetGUID;
  pInfos->m_uID = 0;
  pInfos->m_sendFunc =
    FastDelegate<RakNet::PluginReceiveResult(RakNet::Packet*, s_clientInfos*)>(this, &CProxy::OnLoginClientReceive);

  // For now we can only identify this client by his address.
  m_mapClientAddr[systemAddress] = pInfos;
}
예제 #14
0
int main(int argc, char **argv)
{
    const char *DEFAULT_SERVER_ADDRESS="test.dnsalias.net";
    const unsigned short DEFAULT_SERVER_PORT=60000;

    const char *serverAddress;
    unsigned short serverPort;


#ifndef _DEBUG
    // Only use DEFAULT_SERVER_ADDRESS for debugging
    if (argc<2)
    {
        PrintHelp();
        return false;
    }
#endif

    if (argc<2) serverAddress=DEFAULT_SERVER_ADDRESS;
    else serverAddress=argv[1];

    if (argc<3) serverPort=DEFAULT_SERVER_PORT;
    else serverPort=atoi(argv[2]);

    // ---- RAKPEER -----
    RakNet::RakPeerInterface *rakPeer;
    rakPeer=RakNet::RakPeerInterface::GetInstance();
    static const unsigned short clientLocalPort=0;
    RakNet::SocketDescriptor sd(clientLocalPort,0); // Change this if you want
    RakNet::StartupResult sr = rakPeer->Startup(1,&sd,1); // Change this if you want
    rakPeer->SetMaximumIncomingConnections(0); // Change this if you want
    if (sr!=RakNet::RAKNET_STARTED)
    {
        printf("Startup failed. Reason=%i\n", (int) sr);
        return 1;
    }

    RakNet::CloudClient cloudClient;
    rakPeer->AttachPlugin(&cloudClient);

    RakNet::ConnectionAttemptResult car = rakPeer->Connect(serverAddress, serverPort, 0, 0);
    if (car==RakNet::CANNOT_RESOLVE_DOMAIN_NAME)
    {
        printf("Cannot resolve domain name\n");
        return 1;
    }

    printf("Connecting to %s...\n", serverAddress);
    bool didRebalance=false; // So we only reconnect to a lower load server once, for load balancing
    RakNet::Packet *packet;
    while (1)
    {
        for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive())
        {
            switch (packet->data[0])
            {
            case ID_CONNECTION_LOST:
                printf("Lost connection to server.\n");
                return 1;
            case ID_CONNECTION_ATTEMPT_FAILED:
                printf("Failed to connect to server at %s.\n", packet->systemAddress.ToString(true));
                return 1;
            case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY:
            case ID_OUR_SYSTEM_REQUIRES_SECURITY:
            case ID_PUBLIC_KEY_MISMATCH:
            case ID_INVALID_PASSWORD:
            case ID_CONNECTION_BANNED:
                // You won't see these unless you modified CloudServer
                printf("Server rejected the connection.\n");
                return 1;
            case ID_INCOMPATIBLE_PROTOCOL_VERSION:
                printf("Server is running an incompatible RakNet version.\n");
                return 1;
            case ID_NO_FREE_INCOMING_CONNECTIONS:
                printf("Server has no free connections\n");
                return 1;
            case ID_IP_RECENTLY_CONNECTED:
                printf("Recently connected. Retrying.");
                rakPeer->Connect(serverAddress, serverPort, 0, 0);
                break;
            case ID_CONNECTION_REQUEST_ACCEPTED:
                printf("Connected to server.\n");
                UploadInstanceToCloud(&cloudClient, packet->guid);
                GetClientSubscription(&cloudClient, packet->guid);
                GetServers(&cloudClient, packet->guid);
                break;
            case ID_CLOUD_GET_RESPONSE:
            {
                RakNet::CloudQueryResult cloudQueryResult;
                cloudClient.OnGetReponse(&cloudQueryResult, packet);
                unsigned int rowIndex;
                const bool wasCallToGetServers=cloudQueryResult.cloudQuery.keys[0].primaryKey=="CloudConnCount";
                printf("\n");
                if (wasCallToGetServers)
                    printf("Downloaded server list. %i servers.\n", cloudQueryResult.rowsReturned.Size());
                else
                    printf("Downloaded client list. %i clients.\n", cloudQueryResult.rowsReturned.Size());

                unsigned short connectionsOnOurServer=65535;
                unsigned short lowestConnectionsServer=65535;
                RakNet::SystemAddress lowestConnectionAddress;

                for (rowIndex=0; rowIndex < cloudQueryResult.rowsReturned.Size(); rowIndex++)
                {
                    RakNet::CloudQueryRow *row = cloudQueryResult.rowsReturned[rowIndex];
                    if (wasCallToGetServers)
                    {
                        unsigned short connCount;
                        RakNet::BitStream bsIn(row->data, row->length, false);
                        bsIn.Read(connCount);
                        printf("%i. Server found at %s with %i connections\n", rowIndex+1, row->serverSystemAddress.ToString(true), connCount);

                        unsigned short connectionsExcludingOurselves;
                        if (row->serverGUID==packet->guid)
                            connectionsExcludingOurselves=connCount-1;
                        else
                            connectionsExcludingOurselves=connCount;


                        // Find the lowest load server (optional)
                        if (packet->guid==row->serverGUID)
                        {
                            connectionsOnOurServer=connectionsExcludingOurselves;
                        }
                        else if (connectionsExcludingOurselves < lowestConnectionsServer)
                        {
                            lowestConnectionsServer=connectionsExcludingOurselves;
                            lowestConnectionAddress=row->serverSystemAddress;
                        }
                    }
                    else
                    {
                        printf("%i. Client found at %s", rowIndex+1, row->clientSystemAddress.ToString(true));
                        if (row->clientGUID==rakPeer->GetMyGUID())
                            printf(" (Ourselves)");
                        RakNet::BitStream bsIn(row->data, row->length, false);
                        RakNet::RakString clientData;
                        bsIn.Read(clientData);
                        printf(" Data: %s", clientData.C_String());
                        printf("\n");
                    }
                }


                // Do load balancing by reconnecting to lowest load server (optional)
                if (didRebalance==false && wasCallToGetServers && cloudQueryResult.rowsReturned.Size()>0 && connectionsOnOurServer>lowestConnectionsServer)
                {
                    printf("Reconnecting to lower load server %s\n", lowestConnectionAddress.ToString(false));

                    rakPeer->CloseConnection(packet->guid, true);
                    // Wait for the thread to close, otherwise will immediately get back ID_CONNECTION_ATTEMPT_FAILED because no free outgoing connection slots
                    // Alternatively, just call Startup() with 2 slots instead of 1
                    RakSleep(500);

                    rakPeer->Connect(lowestConnectionAddress.ToString(false), lowestConnectionAddress.GetPort(), 0, 0);
                    didRebalance=true;
                }

                cloudClient.DeallocateWithDefaultAllocator(&cloudQueryResult);
            }

            break;
            case ID_CLOUD_SUBSCRIPTION_NOTIFICATION:
            {
                bool wasUpdated;
                RakNet::CloudQueryRow cloudQueryRow;
                cloudClient.OnSubscriptionNotification(&wasUpdated, &cloudQueryRow, packet, 0 );
                if (wasUpdated)
                    printf("New client at %s\n", cloudQueryRow.clientSystemAddress.ToString(true));
                else
                    printf("Lost client at %s\n", cloudQueryRow.clientSystemAddress.ToString(true));
                cloudClient.DeallocateWithDefaultAllocator(&cloudQueryRow);
            }

            break;
            }
        }

        // Any additional client processing can go here
        RakSleep(30);
    }

    RakNet::RakPeerInterface::DestroyInstance(rakPeer);
    return 0;
}
예제 #15
0
void Player::ban() const
{
    auto netCtrl = mwmp::Networking::getPtr();
    RakNet::SystemAddress addr = netCtrl->getSystemAddress(guid);
    netCtrl->banAddress(addr.ToString(false));
}
예제 #16
0
	virtual void OnSendAborted( RakNet::SystemAddress systemAddress )
	{
		char str[32];
		systemAddress.ToString(true, (char*) str);
		RAKNET_DEBUG_PRINTF("Send aborted to %s\n", str);	
	}
예제 #17
0
    virtual void OnFilePushesComplete( RakNet::SystemAddress systemAddress, unsigned short setID )
	{
		char str[32];
		systemAddress.ToString(true, (char*) str);
		RAKNET_DEBUG_PRINTF("File pushes complete to %s\n", str);	
	}
예제 #18
0
bool TetrisServer::Init()
{
	m_interface = RakNet::RakPeerInterface::GetInstance();
	RakNet::RakNetStatistics *rss;
	m_interface->SetIncomingPassword("Rumpelstiltskin", (int)strlen("Rumpelstiltskin"));
	m_interface->SetTimeoutTime(30000, RakNet::UNASSIGNED_SYSTEM_ADDRESS);

	// Record the first client that connects to us so we can pass it to the ping function
	m_clientID = RakNet::UNASSIGNED_SYSTEM_ADDRESS;
	// Holds user data
	char* portstring = "1234";

	printf("This is a sample implementation of a text based chat server.\n");
	printf("Connect to the project 'Chat Example Client'.\n");
	printf("Difficulty: Beginner\n\n");

	printf("Starting server.\n");
	// Starting the server is very simple.  2 players allowed.
	// 0 means we don't care about a connectionValidationInteger, and false
	// for low priority threads
	// I am creating two socketDesciptors, to create two sockets. One using IPV6 and the other IPV4
	RakNet::SocketDescriptor socketDescriptors[2];
	socketDescriptors[0].port = atoi(portstring);
	socketDescriptors[0].socketFamily = AF_INET; // Test out IPV4
	socketDescriptors[1].port = atoi(portstring);
	socketDescriptors[1].socketFamily = AF_INET6; // Test out IPV6
	bool b = m_interface->Startup(4, socketDescriptors, 2) == RakNet::RAKNET_STARTED;
	m_interface->SetMaximumIncomingConnections(4);
	if (!b)
	{
		printf("Failed to start dual IPV4 and IPV6 ports. Trying IPV4 only.\n");

		// Try again, but leave out IPV6
		b = m_interface->Startup(4, socketDescriptors, 1) == RakNet::RAKNET_STARTED;
		if (!b)
		{
			printf("Server failed to start.  Terminating.\n");
			return false;
		}
	}
	m_interface->SetOccasionalPing(true);
	m_interface->SetUnreliableTimeout(1000);

	DataStructures::List< RakNet::RakNetSocket2* > sockets;
	m_interface->GetSockets(sockets);
	printf("Socket addresses used by RakNet:\n");
	for (unsigned int i = 0; i < sockets.Size(); i++)
	{
		printf("%i. %s\n", i + 1, sockets[i]->GetBoundAddress().ToString(true));
	}

	printf("\nMy IP addresses:\n");
	for (unsigned int i = 0; i < m_interface->GetNumberOfAddresses(); i++)
	{
		RakNet::SystemAddress sa = m_interface->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS, i);
		printf("%i. %s (LAN=%i)\n", i + 1, sa.ToString(false), sa.IsLANAddress());
	}

	printf("\nMy GUID is %s\n", m_interface->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());

	return true;
}
예제 #19
0
void TetrisServer::Loop()
{
	// This sleep keeps RakNet responsive
	RakSleep(16);

	// GetPacketIdentifier returns this
	unsigned char packetIdentifier;

	for (p = m_interface->Receive(); p; m_interface->DeallocatePacket(p), p = m_interface->Receive())
	{
		// We got a packet, get the identifier with our handy function
		packetIdentifier = GetPacketIdentifier(p);

		// Check if this is a network message packet
		switch (packetIdentifier)
		{
		case ID_DISCONNECTION_NOTIFICATION:
			// Connection lost normally
			printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));;
			break;

		case ID_NEW_INCOMING_CONNECTION:
			// Somebody connected.  We have their IP now
			printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString());
			m_clientID = p->systemAddress; // Record the player ID of the client

			printf("Remote internal IDs:\n");
			for (int index = 0; index < MAXIMUM_NUMBER_OF_INTERNAL_IDS; index++)
			{
				RakNet::SystemAddress internalId = m_interface->GetInternalID(p->systemAddress, index);
				if (internalId != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
				{
					printf("%i. %s\n", index + 1, internalId.ToString(true));
				}
			}

			break;

		case ID_INCOMPATIBLE_PROTOCOL_VERSION:
			printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n");
			break;

		case ID_CONNECTED_PING:
		case ID_UNCONNECTED_PING:
			printf("Ping from %s\n", p->systemAddress.ToString(true));
			break;

		case ID_CONNECTION_LOST:
			// Couldn't deliver a reliable packet - i.e. the other system was abnormally
			// terminated
			printf("ID_CONNECTION_LOST from %s\n", p->systemAddress.ToString(true));;
			break;

		default:
			break;
		}
	}

	if (sf::Keyboard::isKeyPressed(sf::Keyboard::B))
	{

		// Message now holds what we want to broadcast
		char message[2048] = "Hello!";

		// message2 is the data to send
		// strlen(message2)+1 is to send the null terminator
		// HIGH_PRIORITY doesn't actually matter here because we don't use any other priority
		// RELIABLE_ORDERED means make sure the message arrives in the right order
		// We arbitrarily pick 0 for the ordering stream
		// RakNet::UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast
		// true means broadcast the message to everyone connected
		m_interface->Send(message, (const int)strlen(message) + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
	}
}
예제 #20
0
void Network_module::run()
{
    print_config();

    using namespace RakNet;

    int l_addr_count = m_rakpeer->GetNumberOfAddresses();
    NET_MOD_INFO("获取到本机IP数量%d个", l_addr_count);

    for (int i = 0; i < l_addr_count; i++)
    {
        RakNet::SystemAddress addr = m_rakpeer->GetLocalIP(i);
        NET_MOD_INFO("第%d个IP地址为:%s", i + 1, addr.ToString(false));
    }

    RakNet::SocketDescriptor l_socket_descriptor;
    l_socket_descriptor.port = m_local_port;

    if (m_rakpeer->Startup(m_max_connection, &l_socket_descriptor, 1) != RakNet::RAKNET_STARTED)
    {
        NET_MOD_ERROR("启动网络引擎失败");
        RakNet::RakPeerInterface::DestroyInstance(m_rakpeer);
        return;
    }

    m_rakpeer->SetMaximumIncomingConnections(m_max_income_connection);

    NET_MOD_INFO("启动网络引擎成功,监控地址为%s", m_rakpeer->GetMyBoundAddress().ToString(false));

    NET_MOD_INFO("开始载入打孔插件");
    m_punch_proxy->init_proxy(m_rakpeer);

    if (m_rakpeer->Connect(DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, 0, 0) != RakNet::CONNECTION_ATTEMPT_STARTED)
    {
        NET_MOD_ERROR("网络引擎,尝试连接失败");
        return;
    }

    NET_MOD_INFO("尝试连接服务器IP地址为%s,端口为%d", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT);
    RakNet::Packet* packet = NULL;

    int flag = true;

    while (flag)
    {
        for (packet=m_rakpeer->Receive(); packet; m_rakpeer->DeallocatePacket(packet), packet=m_rakpeer->Receive())
        {
            if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
            {
                NET_MOD_INFO("连接服务器%s:%d成功", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT);

                if (m_server_addr)
                {
                    delete m_server_addr;
                }

                m_server_addr = new RakNet::SystemAddress;
                *m_server_addr = packet->systemAddress;
                flag = false;
                break;
            }
            else
            {
                NET_MOD_ERROR("连接服务器失败");
                return;
            }
        }
    }

    start_network_loop();
}
예제 #21
0
std::string Player::getIP() const
{
    RakNet::SystemAddress addr = mwmp::Networking::getPtr()->getSystemAddress(guid);
    return addr.ToString(false);
}
예제 #22
0
void Server::update(running_machine *machine)
{
    for(
        map<RakNet::RakNetGUID,vector< string > >::iterator it = unknownPeerInputs.begin();
        it != unknownPeerInputs.end();
        )
    {
        cout << "GOT UNKNOWN PEER INPUT\n";
        if(peerIDs.find(it->first)!=peerIDs.end())
        {
            int ID = peerIDs[it->first];
            for(int a=0;a<it->second.size();a++)
            {
                peerInputs[ID].push_back(it->second[a]);
            }
            map<RakNet::RakNetGUID,vector< string > >::iterator itold = it;
            it++;
            unknownPeerInputs.erase(itold);
        }
        else
        {
            it++;
        }
    }

    //cout << "SERVER TIME: " << RakNet::GetTimeMS()/1000.0f/60.0f << endl;
    //printf("Updating server\n");
    RakNet::Packet *p;
    for (p=rakInterface->Receive(); p; rakInterface->DeallocatePacket(p), p=rakInterface->Receive())
    {
        // We got a packet, get the identifier with our handy function
        unsigned char packetIdentifier = GetPacketIdentifier(p);

        //printf("GOT PACKET %d\n",int(packetIdentifier));

        // Check if this is a network message packet
        switch (packetIdentifier)
        {
        case ID_CONNECTION_LOST:
            // Couldn't deliver a reliable packet - i.e. the other system was abnormally
            // terminated
        case ID_DISCONNECTION_NOTIFICATION:
            // Connection lost normally
            printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));
            removePeer(p->guid,machine);
            break;


        case ID_NEW_INCOMING_CONNECTION:
            // Somebody connected.  We have their IP now
            printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString());
            if(syncHappend)
            {
                //Sorry, too late
                //rakInterface->CloseConnection(p->systemAddress,true);
            }
            break;

        case ID_CLIENT_INFO:
            cout << "GOT ID_CLIENT_INFO\n";
            //This client is requesting candidacy, set their info
            {
                char buf[4096];
                strcpy(buf,(char*)(p->data+1));
                candidateNames[p->systemAddress] = buf;
            }

            //Find a session index for the player
            {
                char buf[4096];
                buf[0] = ID_SETTINGS;
                memcpy(buf+1,&secondsBetweenSync,sizeof(int));
                strcpy(buf+1+sizeof(int),username.c_str());
                rakInterface->Send(
                    buf,
                    1+sizeof(int)+username.length()+1,
                    HIGH_PRIORITY,
                    RELIABLE_ORDERED,
                    ORDERING_CHANNEL_SYNC,
                    p->guid,
                    false
                );
            }
            if(acceptedPeers.size()>=maxPeerID-1)
            {
                //Sorry, no room
                rakInterface->CloseConnection(p->systemAddress,true);
            }
            else if(acceptedPeers.size())
            {
                printf("Asking other peers to accept %s\n",p->systemAddress.ToString());
                waitingForAcceptFrom[p->systemAddress] = std::vector<RakNet::RakNetGUID>();
                for(int a=0; a<acceptedPeers.size(); a++)
                {
                    RakNet::RakNetGUID guid = acceptedPeers[a];
                    waitingForAcceptFrom[p->systemAddress].push_back(guid);
                    cout << "SENDING ADVERTIZE TO " << guid.ToString() << endl;
                    char buf[4096];
                    buf[0] = ID_ADVERTISE_SYSTEM;
                    strcpy(buf+1,p->systemAddress.ToString(true));
                    rakInterface->Send(buf,1+strlen(p->systemAddress.ToString(true))+1,HIGH_PRIORITY,RELIABLE_ORDERED,ORDERING_CHANNEL_SYNC,guid,false);
                }
                printf("Asking other peers to accept\n");
            }
            else
            {
                //First client, automatically accept
                acceptPeer(p->systemAddress,machine);
            }
            break;

        case ID_INCOMPATIBLE_PROTOCOL_VERSION:
            printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n");
            break;

        case ID_ACCEPT_NEW_HOST:
        {
            printf("Accepting new host\n");
            RakNet::SystemAddress saToAccept;
            saToAccept.SetBinaryAddress(((char*)p->data)+1);
            for(int a=0; a<waitingForAcceptFrom[saToAccept].size(); a++)
            {
                if(waitingForAcceptFrom[saToAccept][a]==p->guid)
                {
                    waitingForAcceptFrom[saToAccept].erase(waitingForAcceptFrom[saToAccept].begin()+a);
                    break;
                }
            }
            if(waitingForAcceptFrom[saToAccept].empty())
            {
                cout << "Accepting: " << saToAccept.ToString() << endl;
                waitingForAcceptFrom.erase(waitingForAcceptFrom.find(saToAccept));
                acceptPeer(saToAccept,machine);
            }
        }
        break;

        case ID_REJECT_NEW_HOST:
        {
            RakNet::SystemAddress saToReject;
            saToReject.SetBinaryAddress(((char*)p->data)+1);
            printf("Rejecting new client\n");
            cout << p->guid.ToString() << " REJECTS " << saToReject.ToString() << endl;
            if(waitingForAcceptFrom.find(saToReject)==waitingForAcceptFrom.end())
                printf("Could not find waitingForAcceptFrom for this GUID, weird");
            else
                waitingForAcceptFrom.erase(waitingForAcceptFrom.find(saToReject));
            rakInterface->CloseConnection(saToReject,true);
        }
        break;

        case ID_CLIENT_INPUTS:
            if(peerIDs.find(p->guid)==peerIDs.end() || peerInputs.find(peerIDs[p->guid])==peerInputs.end())
            {
                cout << __FILE__ << ":" << __LINE__ << " OOPS!!!!\n";
            }
            //cout << "GOT CLIENT INPUTS\n";
            peerInputs[peerIDs[p->guid]].push_back(string((char*)GetPacketData(p),(int)GetPacketSize(p)));
            break;
        default:
            printf("UNEXPECTED PACKET ID: %d\n",int(packetIdentifier));
            break;
        }

    }
}
예제 #23
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.
	RakNet::NatPunchthroughClient natPunchthroughClient;
	char port[256];
	rakPeer = RakNet::RakPeerInterface::GetInstance();
	printf("Enter local port (enter for default): ");
	Gets(port, sizeof(port));
	if (port[0]==0)
		strcpy(port, "60000");
	RakNet::SocketDescriptor socketDescriptor(atoi(port),0);
	rakPeer->Startup(4, &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
	RakNet::SystemAddress facilitator;
	if (useNatPunchthrough)
	{
		printf("My GUID is %s\n", rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());

		printf("Enter IP of facilitator (enter for default): ");
		Gets(facilitatorIP,sizeof(facilitatorIP));
		if (facilitatorIP[0]==0)
			strcpy(facilitatorIP, "natpunch.jenkinssoftware.com");
		facilitator.FromString(facilitatorIP);
		facilitator.SetPortHostOrder(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");
	}


    
	RakNet::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)
				{
					RakNet::RakNetGUID destination;
					printf("Enter GUID of destination: ");
					char guidStr[256];
					while (1)
					{
						Gets(guidStr,sizeof(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, sizeof(ip));
					if (ip[0]==0)
						strcpy(ip, "127.0.0.1");
					printf("Enter port of remote system: ");
					Gets(port, sizeof(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];
				RakNet::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)
			{
				RakNet::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)
			{
				RakNet::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)
			{
				RakNet::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)
			{
				RakNet::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.GetPort(),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);
	RakNet::RakPeerInterface::DestroyInstance(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;
}
_CONSOLE_2_SetSystemProcessParams
#endif

int main(void)
{
	// Pointers to the interfaces of our server and client.
	// Note we can easily have both in the same program
	RakNet::RakPeerInterface *server=RakNet::RakPeerInterface::GetInstance();
	RakNet::RakNetStatistics *rss;
	server->SetIncomingPassword("Rumpelstiltskin", (int)strlen("Rumpelstiltskin"));
	server->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS);
//	RakNet::PacketLogger packetLogger;
//	server->AttachPlugin(&packetLogger);

#if LIBCAT_SECURITY==1
	cat::EasyHandshake handshake;
	char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
	char private_key[cat::EasyHandshake::PRIVATE_KEY_BYTES];
	handshake.GenerateServerKey(public_key, private_key);
	server->InitializeSecurity(public_key, private_key, false);
	FILE *fp = fopen("publicKey.dat","wb");
	fwrite(public_key,sizeof(public_key),1,fp);
	fclose(fp);
#endif

	// Holds packets
	RakNet::Packet* p;

	// GetPacketIdentifier returns this
	unsigned char packetIdentifier;

	// Record the first client that connects to us so we can pass it to the ping function
	RakNet::SystemAddress clientID=RakNet::UNASSIGNED_SYSTEM_ADDRESS;

	// Holds user data
	char portstring[30];

	printf("This is a sample implementation of a text based chat server.\n");
	printf("Connect to the project 'Chat Example Client'.\n");
	printf("Difficulty: Beginner\n\n");

	// A server
	puts("Enter the server port to listen on");
	Gets(portstring,sizeof(portstring));
	if (portstring[0]==0)
		strcpy(portstring, "1234");
	
	puts("Starting server.");
	// Starting the server is very simple.  2 players allowed.
	// 0 means we don't care about a connectionValidationInteger, and false
	// for low priority threads
	// I am creating two socketDesciptors, to create two sockets. One using IPV6 and the other IPV4
	RakNet::SocketDescriptor socketDescriptors[2];
	socketDescriptors[0].port=atoi(portstring);
	socketDescriptors[0].socketFamily=AF_INET; // Test out IPV4
	socketDescriptors[1].port=atoi(portstring);
	socketDescriptors[1].socketFamily=AF_INET6; // Test out IPV6
	bool b = server->Startup(4, socketDescriptors, 2 )==RakNet::RAKNET_STARTED;
	server->SetMaximumIncomingConnections(4);
	if (!b)
	{
		printf("Failed to start dual IPV4 and IPV6 ports. Trying IPV4 only.\n");

		// Try again, but leave out IPV6
		b = server->Startup(4, socketDescriptors, 1 )==RakNet::RAKNET_STARTED;
		if (!b)
		{
			puts("Server failed to start.  Terminating.");
			exit(1);
		}
	}
	server->SetOccasionalPing(true);
	server->SetUnreliableTimeout(1000);

	DataStructures::List< RakNet::RakNetSocket2* > sockets;
	server->GetSockets(sockets);
	printf("Socket addresses used by RakNet:\n");
	for (unsigned int i=0; i < sockets.Size(); i++)
	{
		printf("%i. %s\n", i+1, sockets[i]->GetBoundAddress().ToString(true));
	}

	printf("\nMy IP addresses:\n");
	for (unsigned int i=0; i < server->GetNumberOfAddresses(); i++)
	{
		RakNet::SystemAddress sa = server->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS, i);
		printf("%i. %s (LAN=%i)\n", i+1, sa.ToString(false), sa.IsLANAddress());
	}

	printf("\nMy GUID is %s\n", server->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());
	puts("'quit' to quit. 'stat' to show stats. 'ping' to ping.\n'pingip' to ping an ip address\n'ban' to ban an IP from connecting.\n'kick to kick the first connected player.\nType to talk.");
	char message[2048];

	// Loop for input
	while (1)
	{

	// This sleep keeps RakNet responsive
	RakSleep(30);

	if (kbhit())
	{
		// Notice what is not here: something to keep our network running.  It's
		// fine to block on gets or anything we want
		// Because the network engine was painstakingly written using threads.
		Gets(message,sizeof(message));

		if (strcmp(message, "quit")==0)
		{
			puts("Quitting.");
			break;
		}

		if (strcmp(message, "stat")==0)
		{
			rss=server->GetStatistics(server->GetSystemAddressFromIndex(0));
			StatisticsToString(rss, message, 2);
			printf("%s", message);
			printf("Ping %i\n", server->GetAveragePing(server->GetSystemAddressFromIndex(0)));
	
			continue;
		}

		if (strcmp(message, "ping")==0)
		{
			server->Ping(clientID);

			continue;
		}

		if (strcmp(message, "pingip")==0)
		{
			printf("Enter IP: ");
			Gets(message,sizeof(message));
			printf("Enter port: ");
			Gets(portstring,sizeof(portstring));
			if (portstring[0]==0)
				strcpy(portstring, "1234");
			server->Ping(message, atoi(portstring), false);

			continue;
		}

		if (strcmp(message, "kick")==0)
		{
			server->CloseConnection(clientID, true, 0);

			continue;
		}

		if (strcmp(message, "getconnectionlist")==0)
		{
			RakNet::SystemAddress systems[10];
			unsigned short numConnections=10;
			server->GetConnectionList((RakNet::SystemAddress*) &systems, &numConnections);
			for (int i=0; i < numConnections; i++)
			{
				printf("%i. %s\n", i+1, systems[i].ToString(true));
			}
			continue;
		}

		if (strcmp(message, "ban")==0)
		{
			printf("Enter IP to ban.  You can use * as a wildcard\n");
			Gets(message,sizeof(message));
			server->AddToBanList(message);
			printf("IP %s added to ban list.\n", message);

			continue;
		}


		// Message now holds what we want to broadcast
		char message2[2048];
		// Append Server: to the message so clients know that it ORIGINATED from the server
		// All messages to all clients come from the server either directly or by being
		// relayed from other clients
		message2[0]=0;
		strcpy(message2, "Server: ");
		strcat(message2, message);
	
		// message2 is the data to send
		// strlen(message2)+1 is to send the null terminator
		// HIGH_PRIORITY doesn't actually matter here because we don't use any other priority
		// RELIABLE_ORDERED means make sure the message arrives in the right order
		// We arbitrarily pick 0 for the ordering stream
		// RakNet::UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast
		// true means broadcast the message to everyone connected
		server->Send(message2, (const int) strlen(message2)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
	}

		// Get a packet from either the server or the client

		for (p=server->Receive(); p; server->DeallocatePacket(p), p=server->Receive())
		{
			// We got a packet, get the identifier with our handy function
			packetIdentifier = GetPacketIdentifier(p);

			// Check if this is a network message packet
			switch (packetIdentifier)
			{
			case ID_DISCONNECTION_NOTIFICATION:
				// Connection lost normally
				printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));;
				break;


			case ID_NEW_INCOMING_CONNECTION:
				// Somebody connected.  We have their IP now
				printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString());
				clientID=p->systemAddress; // Record the player ID of the client

				printf("Remote internal IDs:\n");
				for (int index=0; index < MAXIMUM_NUMBER_OF_INTERNAL_IDS; index++)
				{
					RakNet::SystemAddress internalId = server->GetInternalID(p->systemAddress, index);
					if (internalId!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
					{
						printf("%i. %s\n", index+1, internalId.ToString(true));
					}
				}

				break;

			case ID_INCOMPATIBLE_PROTOCOL_VERSION:
				printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n");
				break;

			case ID_CONNECTED_PING:
			case ID_UNCONNECTED_PING:
				printf("Ping from %s\n", p->systemAddress.ToString(true));
				break;

			case ID_CONNECTION_LOST:
				// Couldn't deliver a reliable packet - i.e. the other system was abnormally
				// terminated
				printf("ID_CONNECTION_LOST from %s\n", p->systemAddress.ToString(true));;
				break;

			default:
				// The server knows the static data of all clients, so we can prefix the message
				// With the name data
				printf("%s\n", p->data);

				// Relay the message.  We prefix the name for other clients.  This demonstrates
				// That messages can be changed on the server before being broadcast
				// Sending is the same as before
				sprintf(message, "%s", p->data);
				server->Send(message, (const int) strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true);

				break;
			}

		}
	}

	server->Shutdown(300);
	// We're done with the network
	RakNet::RakPeerInterface::DestroyInstance(server);

	return 0;
}
예제 #25
0
bool Connector::startAsServer(unsigned short maxPlayers)
{    
    server = RakNet::UNASSIGNED_SYSTEM_ADDRESS;
    
    // raknet interface configuration
    raknetInterface= RakNet::RakPeerInterface::GetInstance();
	raknetInterface->SetTimeoutTime(CONNECTION_LOST_TIMEOUT, RakNet::UNASSIGNED_SYSTEM_ADDRESS);
	raknetInterface->SetOccasionalPing(true);
	raknetInterface->SetIncomingPassword(RAKNET_PASSWORD, strlen(RAKNET_PASSWORD));
    raknetInterface->SetMaximumIncomingConnections(maxPlayers);
    
    // socket descriptor settings
    RakNet::SocketDescriptor socketDescriptors[1];
    socketDescriptors[0].port = (maxPlayers>1) ? SERVER_PORT : CLIENT_PORT;
    socketDescriptors[0].socketFamily=AF_INET; // IPV4
    
    // try 10 ports
    bool result = false;
    for(int i=0; i<PORT_RANGE; i++)
    {
        result = raknetInterface->Startup(maxPlayers, socketDescriptors, 1) == RakNet::RAKNET_STARTED; // last arg is socketDescriptor count
        if(result == true) {
            LOG("Servers started on port %d.\n", socketDescriptors[0].port);
            break;
        } else {
            LOG("Server failed to start on port %d. Trying next...\n", socketDescriptors[0].port);
            socketDescriptors[0].port++;
            continue;
        }
    }
    
    if (result == false){
        LOG("Server failed to start on EACH PORT!!.\n");
        RakNet::RakPeerInterface::DestroyInstance(raknetInterface);
        raknetInterface = nullptr;
        return false;
    }
    
    // logging used socket addresses
    
    DataStructures::List< RakNet::RakNetSocket2* > sockets;
	raknetInterface->GetSockets(sockets);
    
    /*LOG("Socket addresses used by Connector:\n==========================\n");
    for (unsigned int i=0; i < sockets.Size(); i++)
    {
        LOG("%i. %s\n", i+1, sockets[i]->GetBoundAddress().ToString(true));
    }*/
    
    LOG("\nMy IP addresses:\n");
	for (unsigned int i = 0; i < raknetInterface->GetNumberOfAddresses(); i++)
    {
		RakNet::SystemAddress sa = raknetInterface->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS, i);
        LOG("%i. %s:%i\n", i+1, sa.ToString(false), sa.GetPort());
    }
    
    // server name
    if(maxPlayers>1){
		raknetInterface->SetOfflinePingResponse("Unnamed Server", strlen("Unnamed Server") + 1); // '\0' is automatically added in "hello"
    }
    
    return true;
}
예제 #26
0
int main(int argc, char** argv) {
	RakNet::RakPeerInterface *server = RakNet::RakPeerInterface::GetInstance();
	RakNet::Packet* p;
	unsigned char packetIdentifier;
	RakNet::SystemAddress clientID = RakNet::UNASSIGNED_SYSTEM_ADDRESS;
	RakNet::RakNetStatistics *rss;
	RakNet::SocketDescriptor socketDescriptors[2];
	char portstring[30];

	socketDescriptors[0].port = SERVER_PORT;
	socketDescriptors[0].socketFamily = AF_INET; // Test out IPV4
	socketDescriptors[1].port = SERVER_PORT;
	socketDescriptors[1].socketFamily = AF_INET6; // Test out IPV6
	if (server->Startup(4, socketDescriptors, 2) != RakNet::RAKNET_STARTED) {
		std::cout << "IPV6 not supported, starting with IPV4-only interface..." << std::endl;
		if (server->Startup(4, socketDescriptors, 1) != RakNet::RAKNET_STARTED) {
			std::cerr << "Error creating server, exiting..." << std::endl;
			exit(-1);
		}
	}
	std::cout << "Server started successfully. Listening on port " << SERVER_PORT << std::endl;
	server->SetMaximumIncomingConnections(20);
	server->SetOccasionalPing(true);
	server->SetUnreliableTimeout(1000);

	DataStructures::List<RakNet::RakNetSocket2*> sockets;
	server->GetSockets(sockets);
	std::cout << "Socket addresses used by RakNet:" << std::endl;
	for (unsigned int i = 0; i < sockets.Size(); i++) {
		printf("%i. %s\n", i + 1, sockets[i]->GetBoundAddress().ToString(true));
	}
	char message[2048];

	// Loop for input
	while (1)
	{

		// This sleep keeps RakNet responsive
		RakSleep(30);

		if (kbhit())
		{
			// Notice what is not here: something to keep our network running.  It's
			// fine to block on gets or anything we want
			// Because the network engine was painstakingly written using threads.
			Gets(message, sizeof(message));

			if (strcmp(message, "quit") == 0)
			{
				puts("Quitting.");
				break;
			}

			if (strcmp(message, "stat") == 0)
			{
				rss = server->GetStatistics(server->GetSystemAddressFromIndex(0));
				StatisticsToString(rss, message, 2);
				printf("%s", message);
				printf("Ping %i\n", server->GetAveragePing(server->GetSystemAddressFromIndex(0)));

				continue;
			}

			if (strcmp(message, "ping") == 0)
			{
				server->Ping(clientID);

				continue;
			}

			if (strcmp(message, "pingip") == 0)
			{
				printf("Enter IP: ");
				Gets(message, sizeof(message));
				printf("Enter port: ");
				Gets(portstring, sizeof(portstring));
				if (portstring[0] == 0)
					strcpy(portstring, "1234");
				server->Ping(message, atoi(portstring), false);

				continue;
			}

			if (strcmp(message, "kick") == 0)
			{
				server->CloseConnection(clientID, true, 0);

				continue;
			}

			if (strcmp(message, "getconnectionlist") == 0)
			{
				printf("Connections:\n");
				RakNet::SystemAddress systems[10];
				unsigned short numConnections = 10;
				server->GetConnectionList((RakNet::SystemAddress*) &systems, &numConnections);
				for (int i = 0; i < numConnections; i++)
				{
					printf("%i. %s\n", i + 1, systems[i].ToString(true));
				}
				continue;
			}

			if (strcmp(message, "ban") == 0)
			{
				printf("Enter IP to ban.  You can use * as a wildcard\n");
				Gets(message, sizeof(message));
				server->AddToBanList(message);
				printf("IP %s added to ban list.\n", message);

				continue;
			}


			// Message now holds what we want to broadcast
			char message2[2048];
			// Append Server: to the message so clients know that it ORIGINATED from the server
			// All messages to all clients come from the server either directly or by being
			// relayed from other clients
			message2[0] = 0;
			const static char prefix[] = "Server: ";
			strncpy(message2, prefix, sizeof(message2));
			strncat(message2, message, sizeof(message2) - strlen(prefix) - 1);

			// message2 is the data to send
			// strlen(message2)+1 is to send the null terminator
			// HIGH_PRIORITY doesn't actually matter here because we don't use any other priority
			// RELIABLE_ORDERED means make sure the message arrives in the right order
			// We arbitrarily pick 0 for the ordering stream
			// RakNet::UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast
			// true means broadcast the message to everyone connected
			server->Send(message2, (const int)strlen(message2) + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
		}

		// Get a packet from either the server or the client

		for (p = server->Receive(); p; server->DeallocatePacket(p), p = server->Receive())
		{
			// We got a packet, get the identifier with our handy function
			packetIdentifier = GetPacketIdentifier(p);

			// Check if this is a network message packet
			switch (packetIdentifier)
			{
			case ID_DISCONNECTION_NOTIFICATION:
				// Connection lost normally
				printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));;
				break;


			case ID_NEW_INCOMING_CONNECTION:
				// Somebody connected.  We have their IP now
				printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString());
				clientID = p->systemAddress; // Record the player ID of the client

				printf("Remote internal IDs:\n");
				for (int index = 0; index < MAXIMUM_NUMBER_OF_INTERNAL_IDS; index++)
				{
					RakNet::SystemAddress internalId = server->GetInternalID(p->systemAddress, index);
					if (internalId != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
					{
						printf("%i. %s\n", index + 1, internalId.ToString(true));
					}
				}

				break;

			case ID_INCOMPATIBLE_PROTOCOL_VERSION:
				printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n");
				break;

			case ID_CONNECTED_PING:
			case ID_UNCONNECTED_PING:
				printf("Ping from %s\n", p->systemAddress.ToString(true));
				break;

			case ID_CONNECTION_LOST:
				// Couldn't deliver a reliable packet - i.e. the other system was abnormally
				// terminated
				printf("ID_CONNECTION_LOST from %s\n", p->systemAddress.ToString(true));;
				break;

			default:
				// The server knows the static data of all clients, so we can prefix the message
				// With the name data
				printf("%s\n", p->data);

				// Relay the message.  We prefix the name for other clients.  This demonstrates
				// That messages can be changed on the server before being broadcast
				// Sending is the same as before
				sprintf(message, "%s", p->data);
				server->Send(message, (const int)strlen(message) + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true);

				break;
			}

		}
	}

	server->Shutdown(300);
	// We're done with the network
	RakNet::RakPeerInterface::DestroyInstance(server);


}
예제 #27
0
void SimulateClientMainFrame::OnSend( wxCommandEvent& event )
{

	wxString serverName=m_serverList->GetStringSelection();
	wxString messageID=m_messagelist->GetStringSelection();
	wxString message= m_MessageText->GetValue();

	//if(serverName.empty()||messageID.empty()||messageID.empty())
	//{
	//	wxMessageBox("请选择服务器,消息id,和消息内容");
	//	return ;
	//}

	unsigned int  id=stringToMessageID(messageID.c_str());
	RakNet::SystemAddress address;
	address.SetBinaryAddress(serverName.c_str());

	if(id==GM_TEXT_MESSAGE)
	{
		NetWorkClient::getSingletonPtr()->getConnectInstance("statserver")->send(id,message.c_str(),message.Length()+1);
		m_MessageText->Clear();
		addSendMessage(message);

	}else if(GM_ACCOUNT_REQUEST==id)
	{

	    UserLogin userlogin;
		::ZeroMemory(&userlogin,sizeof(userlogin));
	    if(sscanf(message.c_str(),"%s = %s",userlogin.m_account,userlogin.m_password)>0)
		{
           NetWorkClient::getSingleton().getConnectInstance("statserver")->send(id,userlogin);
		}else
		{
            wxMessageBox("格式不正确请用;分格开用户名和密码");
		}


      
		// memcpy(userlogin.m_account,"palyer1",strlen("player1"));
		// memcpy(userlogin.m_password,"palyer1",strlen("player1"));
		
	}else if(id==GM_CHATMESSAGE)
	{
		NetWorkClient::getSingletonPtr()->getConnectInstance(GAMESERVER)->send(id,message.c_str(),message.Length()+1);
		m_MessageText->Clear();
		addSendMessage(message);


	}else if(id==GM_CONNECT_GAMESERVER)
	{
		///发送帐号id组游戏逻辑服务器
		long accountid=0;
		if(message.ToLong(&accountid))
		{
			UINT temid=accountid;
			NetWorkClient::getSingletonPtr()->getConnectInstance(GAMESERVER)->send(id,temid);
			m_MessageText->Clear();
		}
	




	}






	return ;



	

}
예제 #28
0
int main(int argc, char **argv)
{
	if (argc<8)
	{
		printf("Arguments: serverIP, pathToGame, gameName, patchImmediately, localPort, serverPort, fullScan");
		return 0;
	}

	RakNet::SystemAddress TCPServerAddress=RakNet::UNASSIGNED_SYSTEM_ADDRESS;
	RakNet::AutopatcherClient autopatcherClient;
	RakNet::FileListTransfer fileListTransfer;
	RakNet::CloudClient cloudClient;
	autopatcherClient.SetFileListTransferPlugin(&fileListTransfer);
	bool didRebalance=false; // So we only reconnect to a lower load server once, for load balancing

	bool fullScan = argv[7][0]=='1';

	unsigned short localPort;
	localPort=atoi(argv[5]);

	unsigned short serverPort=atoi(argv[6]);

	RakNet::PacketizedTCP packetizedTCP;
	if (packetizedTCP.Start(localPort,1)==false)
	{
		printf("Failed to start TCP. Is the port already in use?");
		return 1;
	}
	packetizedTCP.AttachPlugin(&autopatcherClient);
	packetizedTCP.AttachPlugin(&fileListTransfer);

	RakNet::RakPeerInterface *rakPeer;
	rakPeer = RakNet::RakPeerInterface::GetInstance();
	RakNet::SocketDescriptor socketDescriptor(localPort,0);
	rakPeer->Startup(1,&socketDescriptor, 1);
	rakPeer->AttachPlugin(&cloudClient);
	DataStructures::List<RakNet::RakNetSocket2* > sockets;
	rakPeer->GetSockets(sockets);
	printf("Started on port %i\n", sockets[0]->GetBoundAddress().GetPort());


	char buff[512];
	strcpy(buff, argv[1]);

	rakPeer->Connect(buff, serverPort, 0, 0);

	printf("Connecting...\n");
	char appDir[512];
	strcpy(appDir, argv[2]);
	char appName[512];
	strcpy(appName, argv[3]);

	bool patchImmediately=argc>=5 && argv[4][0]=='1';

	RakNet::Packet *p;
	while (1)
	{
		RakNet::SystemAddress notificationAddress;
		notificationAddress=packetizedTCP.HasCompletedConnectionAttempt();
		if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
		{
			printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
			TCPServerAddress=notificationAddress;
		}
		notificationAddress=packetizedTCP.HasNewIncomingConnection();
		if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
			printf("ID_NEW_INCOMING_CONNECTION\n");
		notificationAddress=packetizedTCP.HasLostConnection();
		if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
			printf("ID_CONNECTION_LOST\n");
		notificationAddress=packetizedTCP.HasFailedConnectionAttempt();
		if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
		{
			printf("ID_CONNECTION_ATTEMPT_FAILED TCP\n");
			autopatcherClient.SetFileListTransferPlugin(0);
			autopatcherClient.Clear();
			packetizedTCP.Stop();
			rakPeer->Shutdown(500,0);
			RakNet::RakPeerInterface::DestroyInstance(rakPeer);
			return 0;
		}


		p=packetizedTCP.Receive();
		while (p)
		{
			if (p->data[0]==ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR)
			{
				char buff[256];
				RakNet::BitStream temp(p->data, p->length, false);
				temp.IgnoreBits(8);
				RakNet::StringCompressor::Instance()->DecodeString(buff, 256, &temp);
				printf("ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR\n");
				printf("%s\n", buff);
				autopatcherClient.SetFileListTransferPlugin(0);
				autopatcherClient.Clear();
				packetizedTCP.Stop();
				rakPeer->Shutdown(500,0);
				RakNet::RakPeerInterface::DestroyInstance(rakPeer);
				return 0;
			}
			else if (p->data[0]==ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES)
			{
				printf("ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES\n");
				autopatcherClient.SetFileListTransferPlugin(0);
				autopatcherClient.Clear();
				packetizedTCP.Stop();
				rakPeer->Shutdown(500,0);
				RakNet::RakPeerInterface::DestroyInstance(rakPeer);
				return 0;
			}			
			else if (p->data[0]==ID_AUTOPATCHER_FINISHED)
			{
				printf("ID_AUTOPATCHER_FINISHED with server time %f\n", autopatcherClient.GetServerDate());
				double srvDate=autopatcherClient.GetServerDate();
				FILE *fp = fopen("srvDate", "wb");
				fwrite(&srvDate,sizeof(double),1,fp);
				fclose(fp);
				autopatcherClient.SetFileListTransferPlugin(0);
				autopatcherClient.Clear();
				packetizedTCP.Stop();
				rakPeer->Shutdown(500,0);
				RakNet::RakPeerInterface::DestroyInstance(rakPeer);
				return 0;
			}
			else if (p->data[0]==ID_AUTOPATCHER_RESTART_APPLICATION)
			{
				printf("ID_AUTOPATCHER_RESTART_APPLICATION");
				autopatcherClient.SetFileListTransferPlugin(0);
				autopatcherClient.Clear();
				packetizedTCP.Stop();
				rakPeer->Shutdown(500,0);
				RakNet::RakPeerInterface::DestroyInstance(rakPeer);
				return 0;
			}
			// Launch \"AutopatcherClientRestarter.exe autopatcherRestart.txt\"\nQuit this application immediately after to unlock files.\n");

			packetizedTCP.DeallocatePacket(p);
			p=packetizedTCP.Receive();
		}

		p=rakPeer->Receive();
		while (p)
		{
			if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
			{
				// UploadInstanceToCloud(&cloudClient, p->guid);
				// GetClientSubscription(&cloudClient, p->guid);
				GetServers(&cloudClient, p->guid);
				break;
			}
			else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED)
			{
				printf("ID_CONNECTION_ATTEMPT_FAILED UDP\n");
				autopatcherClient.SetFileListTransferPlugin(0);
				autopatcherClient.Clear();
				packetizedTCP.Stop();
				rakPeer->Shutdown(500,0);
				RakNet::RakPeerInterface::DestroyInstance(rakPeer);
				return 0;
			}
			else if (p->data[0]==ID_CLOUD_GET_RESPONSE)
			{
				RakNet::CloudQueryResult cloudQueryResult;
				cloudClient.OnGetReponse(&cloudQueryResult, p);
				unsigned int rowIndex;
				const bool wasCallToGetServers=cloudQueryResult.cloudQuery.keys[0].primaryKey=="CloudConnCount";
				printf("\n");
				if (wasCallToGetServers)
					printf("Downloaded server list. %i servers.\n", cloudQueryResult.rowsReturned.Size());

				unsigned short connectionsOnOurServer=65535;
				unsigned short lowestConnectionsServer=65535;
				RakNet::SystemAddress lowestConnectionAddress;

				for (rowIndex=0; rowIndex < cloudQueryResult.rowsReturned.Size(); rowIndex++)
				{
					RakNet::CloudQueryRow *row = cloudQueryResult.rowsReturned[rowIndex];
					if (wasCallToGetServers)
					{
						unsigned short connCount;
						RakNet::BitStream bsIn(row->data, row->length, false);
						bsIn.Read(connCount);
						printf("%i. Server found at %s with %i connections\n", rowIndex+1, row->serverSystemAddress.ToString(true), connCount);

						unsigned short connectionsExcludingOurselves;
						if (row->serverGUID==p->guid)
							connectionsExcludingOurselves=connCount-1;
						else
							connectionsExcludingOurselves=connCount;

						// Find the lowest load server (optional)
						if (p->guid==row->serverGUID)
						{
							connectionsOnOurServer=connectionsExcludingOurselves;
						}
						else if (connectionsExcludingOurselves < lowestConnectionsServer)
						{
							lowestConnectionsServer=connectionsExcludingOurselves;
							lowestConnectionAddress=row->serverSystemAddress;
						}
					}
				}


				// Do load balancing by reconnecting to lowest load server (optional)
				if (didRebalance==false && wasCallToGetServers)
				{
					if (cloudQueryResult.rowsReturned.Size()>0 && connectionsOnOurServer>lowestConnectionsServer)
					{
						printf("Reconnecting to lower load server %s\n", lowestConnectionAddress.ToString(false));

						rakPeer->CloseConnection(p->guid, true);
						// Wait for the thread to close, otherwise will immediately get back ID_CONNECTION_ATTEMPT_FAILED because no free outgoing connection slots
						// Alternatively, just call Startup() with 2 slots instead of 1
						RakSleep(500);

						rakPeer->Connect(lowestConnectionAddress.ToString(false), lowestConnectionAddress.GetPort(), 0, 0);

						// TCP Connect to new IP address
						packetizedTCP.Connect(lowestConnectionAddress.ToString(false),serverPort,false);
					}
					else
					{
						// TCP Connect to original IP address
						packetizedTCP.Connect(buff,serverPort,false);
					}

					didRebalance=true;
				}

				cloudClient.DeallocateWithDefaultAllocator(&cloudQueryResult);
			}

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

		if (TCPServerAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS && patchImmediately==true)
		{
			patchImmediately=false;
			char restartFile[512];
			strcpy(restartFile, appDir);
			strcat(restartFile, "/autopatcherRestart.txt");

			double lastUpdateDate;

			if (fullScan==false)
			{
				FILE *fp = fopen("srvDate", "rb");
				if (fp)
				{
					fread(&lastUpdateDate, sizeof(lastUpdateDate), 1, fp);
					fclose(fp);
				}
				else
					lastUpdateDate=0;
			}
			else
				lastUpdateDate=0;

			if (autopatcherClient.PatchApplication(appName, appDir, lastUpdateDate, TCPServerAddress, &transferCallback, restartFile, argv[0]))
			{
				printf("Patching process starting.\n");
			}
			else
			{
				printf("Failed to start patching.\n");
				autopatcherClient.SetFileListTransferPlugin(0);
				autopatcherClient.Clear();
				packetizedTCP.Stop();
				rakPeer->Shutdown(500,0);
				RakNet::RakPeerInterface::DestroyInstance(rakPeer);
				return 0;
			}
		}
		RakSleep(30);
	}

	// Dereference so the destructor doesn't crash
	autopatcherClient.SetFileListTransferPlugin(0);

	autopatcherClient.Clear();
	packetizedTCP.Stop();
	rakPeer->Shutdown(500,0);
	RakNet::RakPeerInterface::DestroyInstance(rakPeer);
	return 1;
}