Exemplo n.º 1
0
//Used to verify that all clients are still connected
void NetServer::PingClients()
{
    ENetPeer * pCurrentPeer;

    for (pCurrentPeer = m_pServer-> peers;
         pCurrentPeer < & m_pServer->peers [m_pServer->peerCount];
         ++ pCurrentPeer)
    {
       if (pCurrentPeer->state != ENET_PEER_STATE_CONNECTED)
         continue;

       enet_peer_ping (pCurrentPeer);
    }
}
Exemplo n.º 2
0
static int
enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
{
    size_t packetsSent = 1;
    ENetProtocolHeader header;
    ENetPeer * currentPeer;
    int sentLength;

    while (packetsSent > 0)
    for (currentPeer = host -> peers,
           packetsSent = 0;
         currentPeer < & host -> peers [host -> peerCount];
         ++ currentPeer)
    {
        if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
            currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
          continue;

        host -> commandCount = 0;
        host -> bufferCount = 1;
        host -> packetSize = sizeof (ENetProtocolHeader);

        if (enet_list_empty (& currentPeer -> acknowledgements) == 0)
          enet_protocol_send_acknowledgements (host, currentPeer);

        if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol))
        {
            if (checkForTimeouts != 0 &&
                enet_list_empty (& currentPeer -> sentReliableCommands) == 0 &&
                ENET_TIME_GREATER_EQUAL (timeCurrent, currentPeer -> nextTimeout) &&
                enet_protocol_check_timeouts (host, currentPeer, event) == 1)
              return 1;
        }
        if (enet_list_empty (& currentPeer -> outgoingReliableCommands) == 0)
          enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
        else
        if (enet_list_empty (& currentPeer -> sentReliableCommands) &&
            ENET_TIME_DIFFERENCE (timeCurrent, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL &&
            currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
        {
            enet_peer_ping (currentPeer);
            enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
        }

        if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol) &&
            enet_list_empty (& currentPeer -> outgoingUnreliableCommands) == 0)
          enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);

        if (host -> commandCount == 0)
          continue;

        if (currentPeer -> packetLossEpoch == 0)
          currentPeer -> packetLossEpoch = timeCurrent;
        else
        if (ENET_TIME_DIFFERENCE (timeCurrent, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL &&
            currentPeer -> packetsSent > 0)
        {
           enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;

#ifdef ENET_DEBUG
#ifdef WIN32
           printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands));
#else
           fprintf (stderr, "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands));
#endif
#endif

           currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;

           if (packetLoss >= currentPeer -> packetLoss)
           {
              currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
              currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
           }
           else
           {
              currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
              currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
           }

           currentPeer -> packetLossEpoch = timeCurrent;
           currentPeer -> packetsSent = 0;
           currentPeer -> packetsLost = 0;
        }

        header.peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID);
        header.flags = 0;
        header.commandCount = host -> commandCount;
        header.sentTime = ENET_HOST_TO_NET_32 (timeCurrent);
        header.challenge = currentPeer -> challenge;

        host -> buffers -> data = & header;
        host -> buffers -> dataLength = sizeof (ENetProtocolHeader);

        currentPeer -> lastSendTime = timeCurrent;

        ++ packetsSent;

        sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);

        enet_protocol_remove_sent_unreliable_commands (currentPeer);

        if (sentLength < 0)
          return -1;
    }

    return 0;
}
Exemplo n.º 3
0
// Receive packets from the network and buffers and create ConnectionEvents
void Connection::receive()
{
	if (!m_enet_host) {
		return;
	}
	ENetEvent event;
	int ret = enet_host_service(m_enet_host, & event, 10);
	if (ret > 0)
	{
		m_last_recieved = porting::getTimeMs();
		m_last_recieved_warn = 0;
		switch (event.type)
		{
		case ENET_EVENT_TYPE_CONNECT:
			{
				//MutexAutoLock peerlock(m_peers_mutex);
				u16 peer_id = 0;
				static u16 last_try = PEER_ID_SERVER + 1;
				if (m_peers.size() > 0) {
					for (int i = 0; i < 1000; ++i) {
						if (last_try > 30000)
							last_try = PEER_ID_SERVER;
						++last_try;
						if (!m_peers.count(last_try)) {
							peer_id = last_try;
							break;
						}
					}
				} else {
					peer_id = last_try;
				}
				if (!peer_id)
					last_try = peer_id = m_peers.rbegin()->first + 1;

				m_peers.set(peer_id, event.peer);
				m_peers_address.set(peer_id, Address(event.peer->address.host, event.peer->address.port));

				event.peer->data = new u16;
				*((u16*)event.peer->data) = peer_id;

				// Create peer addition event
				ConnectionEvent e;
				e.peerAdded(peer_id);
				putEvent(e);
			}
			break;
		case ENET_EVENT_TYPE_RECEIVE:
			{
				ConnectionEvent e;
				SharedBuffer<u8> resultdata(event.packet->data, event.packet->dataLength);
				e.dataReceived(*(u16*)event.peer->data, resultdata);
				putEvent(e);
			}

			/* Clean up the packet now that we're done using it. */
			enet_packet_destroy (event.packet);
			break;
		case ENET_EVENT_TYPE_DISCONNECT:
			deletePeer(*((u16*)event.peer->data), false);

			/* Reset the peer's client information. */
			delete (u16*)event.peer->data;

			break;
		case ENET_EVENT_TYPE_NONE:
			break;
		}
	} else if (ret < 0) {
		infostream<<"recieve enet_host_service failed = "<< ret << std::endl;
		if (m_peers.count(PEER_ID_SERVER))
			deletePeer(PEER_ID_SERVER,  false);
	} else { //0
		if (m_peers.count(PEER_ID_SERVER) && m_last_recieved) { //ugly fix. todo: fix enet and remove
			unsigned int time = porting::getTimeMs();
			const unsigned int t1 = 10000, t2 = 30000 * timeout_mul, t3 = 60000 * timeout_mul;
			unsigned int wait = time - m_last_recieved;
			if (wait > t3 && m_last_recieved_warn > t2) {
				errorstream<<"connection lost [60s], disconnecting."<<std::endl;
#if defined(__has_feature)
#if __has_feature(thread_sanitizer) || __has_feature(address_sanitizer)
				if (0)
#endif
#endif
				{
					deletePeer(PEER_ID_SERVER,  false);
				}
				m_last_recieved_warn = 0;
				m_last_recieved = 0;
			} else if (wait > t2 && m_last_recieved_warn > t1 && m_last_recieved_warn < t2) {
				errorstream<<"connection lost [30s]!"<<std::endl;
				m_last_recieved_warn = time - m_last_recieved;
			} else if (wait > t1 && m_last_recieved_warn < t1) {
				errorstream<<"connection lost [10s]? ping."<<std::endl;
				enet_peer_ping(m_peers.get(PEER_ID_SERVER));
				m_last_recieved_warn = wait;
			}
		}
	}
}