Exemplo n.º 1
0
int main (int argc, char ** argv)
{
	startGameTimer = -1;
	if (board == NULL) {
		board = new TileBoard();
	}
	lastHexbankUpdate = enet_time_get();
	lastCooldownUpdate = enet_time_get();
	lastLocationUpdate = enet_time_get();
	server.Initialize(); // Should only be called once at most
	server.RegisterHandlers(&HandleConnect, &HandleDisconnect, &HandlePacket, &TimedEvent); // registers the event handlers
	server.SetupServer(4000); // Can be called multiple times with different ports... say if you wanted to host multiple games with a single server
	server.RunDedicated(); // Run it as a standalone dedicated server (Note: Does not return!)
}
Exemplo n.º 2
0
/** Sends any queued packets on the host specified to its designated peers.

    @param host   host to flush
    @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service().
    @ingroup host
*/
void
enet_host_flush (ENetHost * host)
{
    timeCurrent = enet_time_get ();

    enet_protocol_send_outgoing_commands (host, NULL, 0);
}
Exemplo n.º 3
0
void TimedEvent() {
	int curTime = enet_time_get();

	// if game has not started
	if (!board->isStarted()) {
		// check to see if more than one player and if all players are ready.
		if (board->getPlayerCount() > 1 && board->getReadyPlayers().size() == board->getPlayerCount()) {
			if (startGameTimer == -1) {
				// start game timer
				startGameTimer = curTime;
				printf("Game will start in 1 seconds.\n");
			}
			// check to see if 10 seconds have elapsed and start game.
			else if (curTime - startGameTimer >= 1000) {
				if (board->startBoard()) {
					printf ("GAME HAS STARTED.\n");
					Broadcast ("SG\0");
				} else
					printf ("Error starting game.\n");
			}
		} else {
			if (startGameTimer!=-1)
				printf("Start game timer reset.\n");
			// reset timer if players not all ready.
			startGameTimer = -1;
		}

	} 
	// if game has started and not ended
	else if (!board->isEnded()) {	
		// check for a winner
		if (board->isWinner()) {
			board->endBoard();
			printf ("Game ended. Winner is Player %d.\n",board->getWinner()->getId());
			Broadcast ("W");
		}
		else {
			if (curTime - lastHexbankUpdate > 5000)
			{
				board->incHexBank(); // increment player hexbanks every 5 secs
				lastHexbankUpdate = curTime;
				printf ("Hexbanks incremented.\n");
				Broadcast ("TH");
			}
			if (curTime - lastCooldownUpdate > 125)
			{
				board->minusCooldown(); // run every tic.
				lastCooldownUpdate = curTime;
				Broadcast ("TC");
			}
			if (curTime - lastLocationUpdate > 125)
			{
				char packet[256];
				if (board->updateCharacterLocation(packet)) {
				Broadcast(packet);
				}
			}
		}
	}
}
Exemplo n.º 4
0
u32 CNetServerSession::GetLastReceivedTime() const
{
	if (!m_Peer)
		return 0;

	return enet_time_get() - m_Peer->lastReceiveTime;
}
Exemplo n.º 5
0
static void GetRandomishBytes(u8* buf, size_t size)
{
	// We don't need high quality random numbers (which might not be available),
	// just non-repeating numbers!
	srand(enet_time_get());
	for (size_t i = 0; i < size; i++)
		buf[i] = rand() & 0xff;
}
Exemplo n.º 6
0
    int currtime()
    {
#ifdef SERVER
        return enet_time_get();
#else /* CLIENT */
        return SDL_GetTicks() - clockrealbase;
#endif
    }
Exemplo n.º 7
0
void TraversalClient::ResendPacket(OutgoingTraversalPacketInfo* info)
{
  info->sendTime = enet_time_get();
  info->tries++;
  ENetBuffer buf;
  buf.data = &info->packet;
  buf.dataLength = sizeof(info->packet);
  if (enet_socket_send(m_NetHost->socket, &m_ServerAddress, &buf, 1) == -1)
    OnFailure(SocketSendError);
}
Exemplo n.º 8
0
void TraversalClient::HandlePing()
{
  enet_uint32 now = enet_time_get();
  if (m_State == Connected && now - m_PingTime >= 500)
  {
    TraversalPacket ping = {};
    ping.type = TraversalPacketPing;
    ping.ping.hostId = m_HostId;
    SendTraversalPacket(ping);
    m_PingTime = now;
  }
}
Exemplo n.º 9
0
void TraversalClient::HandleResends()
{
  enet_uint32 now = enet_time_get();
  for (auto& tpi : m_OutgoingTraversalPackets)
  {
    if (now - tpi.sendTime >= (u32)(300 * tpi.tries))
    {
      if (tpi.tries >= 5)
      {
        OnFailure(ResendTimeout);
        m_OutgoingTraversalPackets.clear();
        break;
      }
      else
      {
        ResendPacket(&tpi);
      }
    }
  }
  HandlePing();
}
Exemplo n.º 10
0
void
enet_host_bandwidth_throttle (ENetHost * host)
{
    enet_uint32 timeCurrent = enet_time_get (),
           elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
           peersTotal = 0,
           dataTotal = 0,
           peersRemaining,
           bandwidth,
           throttle = 0,
           bandwidthLimit = 0;
    int needsAdjustment;
    ENetPeer * peer;
    ENetProtocol command;

    if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
      return;

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

        ++ peersTotal;
        dataTotal += peer -> outgoingDataTotal;
    }

    if (peersTotal == 0)
      return;

    peersRemaining = peersTotal;
    needsAdjustment = 1;

    if (host -> outgoingBandwidth == 0)
      bandwidth = ~0;
    else
      bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;

    while (peersRemaining > 0 && needsAdjustment != 0)
    {
        needsAdjustment = 0;
        
        if (dataTotal < bandwidth)
          throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
        else
          throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;

        for (peer = host -> peers;
             peer < & host -> peers [host -> peerCount];
             ++ peer)
        {
            enet_uint32 peerBandwidth;
            
            if (peer -> state != ENET_PEER_STATE_CONNECTED ||
                peer -> incomingBandwidth == 0 ||
                peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
              continue;

            peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
            if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
              continue;

            peer -> packetThrottleLimit = (peerBandwidth * 
                                            ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
            
            if (peer -> packetThrottleLimit == 0)
              peer -> packetThrottleLimit = 1;
            
            if (peer -> packetThrottle > peer -> packetThrottleLimit)
              peer -> packetThrottle = peer -> packetThrottleLimit;

            peer -> outgoingBandwidthThrottleEpoch = timeCurrent;

            
            needsAdjustment = 1;
            -- peersRemaining;
            bandwidth -= peerBandwidth;
            dataTotal -= peerBandwidth;
        }
    }

    if (peersRemaining > 0)
    for (peer = host -> peers;
         peer < & host -> peers [host -> peerCount];
         ++ peer)
    {
        if (peer -> state != ENET_PEER_STATE_CONNECTED ||
            peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
          continue;

        peer -> packetThrottleLimit = throttle;

        if (peer -> packetThrottle > peer -> packetThrottleLimit)
          peer -> packetThrottle = peer -> packetThrottleLimit;
    }
    
    if (host -> recalculateBandwidthLimits)
    {
       host -> recalculateBandwidthLimits = 0;

       peersRemaining = peersTotal;
       bandwidth = host -> incomingBandwidth;
       needsAdjustment = 1;

       if (bandwidth == 0)
         bandwidthLimit = 0;
       else
       while (peersRemaining > 0 && needsAdjustment != 0)
       {
           needsAdjustment = 0;
           bandwidthLimit = bandwidth / peersRemaining;

           for (peer = host -> peers;
                peer < & host -> peers [host -> peerCount];
                ++ peer)
           {
               if (peer -> state != ENET_PEER_STATE_CONNECTED ||
                   peer -> incomingBandwidthThrottleEpoch == timeCurrent)
                 continue;

               if (peer -> outgoingBandwidth > 0 &&
                   bandwidthLimit > peer -> outgoingBandwidth)
                 continue;

               peer -> incomingBandwidthThrottleEpoch = timeCurrent;
 
               needsAdjustment = 1;
               -- peersRemaining;
               bandwidth -= peer -> outgoingBandwidth;
           }
       }

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

           command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT;
           command.header.channelID = 0xFF;
           command.header.flags = 0;
           command.header.commandLength = sizeof (ENetProtocolBandwidthLimit);
           command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);

           if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
           else
             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);

           enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
       } 
    }

    host -> bandwidthThrottleEpoch = timeCurrent;

    for (peer = host -> peers;
         peer < & host -> peers [host -> peerCount];
         ++ peer)
    {
        peer -> incomingDataTotal = 0;
        peer -> outgoingDataTotal = 0;
    }
}
Exemplo n.º 11
0
/** Waits for events on the host specified and shuttles packets between
    the host and its peers.

    @param host    host to service
    @param event   an event structure where event details will be placed if one occurs
    @param timeout number of milliseconds that ENet should wait for events
    @retval > 1 if an event occurred within the specified time limit
    @retval 0 if no event occurred
    @retval < 1 on failure
    @remarks enet_host_service should be called fairly regularly for adequate performance
    @ingroup host
*/
int
enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
{
    enet_uint32 waitCondition;

    event -> type = ENET_EVENT_TYPE_NONE;
    event -> peer = NULL;
    event -> packet = NULL;

    switch (enet_protocol_dispatch_incoming_commands (host, event))
    {
    case 1:
       return 1;

    case -1:
       perror ("Error dispatching incoming packets");

       return -1;

    default:
       break;
    }

    timeCurrent = enet_time_get ();

    timeout += timeCurrent;

    do
    {
       if (ENET_TIME_DIFFERENCE (timeCurrent, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
         enet_host_bandwidth_throttle (host);

       switch (enet_protocol_send_outgoing_commands (host, event, 1))
       {
       case 1:
          return 1;

       case -1:
          perror ("Error sending outgoing packets");

          return -1;

       default:
          break;
       }

       switch (enet_protocol_receive_incoming_commands (host, event))
       {
       case 1:
          return 1;

       case -1:
          perror ("Error receiving incoming packets");

          return -1;

       default:
          break;
       }

       switch (enet_protocol_send_outgoing_commands (host, event, 1))
       {
       case 1:
          return 1;

       case -1:
          perror ("Error sending outgoing packets");

          return -1;

       default:
          break;
       }

       switch (enet_protocol_dispatch_incoming_commands (host, event))
       {
       case 1:
          return 1;

       case -1:
          perror ("Error dispatching incoming packets");

          return -1;

       default:
          break;
       }

       timeCurrent = enet_time_get ();

       if (ENET_TIME_GREATER_EQUAL (timeCurrent, timeout))
         return 0;

       waitCondition = ENET_SOCKET_WAIT_RECEIVE;

       if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, timeCurrent)) != 0)
         return -1;

       timeCurrent = enet_time_get ();
    } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE);

    return 0;
}
Exemplo n.º 12
0
void Tunneld::promiseChannelCleanup(ToxTunChannel *chan)
{
    qDebug()<<chan<<sender();
    QObject *snderobj = (QObject*)sender();
    QTimer *repeat_timer = NULL;

    qDebug()<<snderobj->objectName()<<snderobj->metaObject()->className();
    if (chan == NULL) {
        repeat_timer = (QTimer*)snderobj;
        assert(repeat_timer != NULL);
        int conid = repeat_timer->property("conid").toInt();
        if (!m_conid_chans.contains(conid)) {
            qDebug()<<"maybe too late repeat check self sock close timer event";
            repeat_timer->deleteLater();
            return;
        }
        chan = m_conid_chans[conid];
        assert(chan != NULL);
    } else {
        // snderobj is ENetPoll or QTcpSocket
    }
    QTcpSocket *sock = chan->m_sock;
    ENetPeer *enpeer = chan->m_enpeer;

    //////////
    QHash<QString, bool> promise_results;

    promise_results["sock_closed"] = chan->sock_closed;
    // promise_results["enet_closed"] = chan->enet_closed;
    promise_results["peer_sock_closed"] = chan->peer_sock_closed;

    bool promise_result = true;
    for (auto it = promise_results.begin(); it != promise_results.end(); it ++) {
        QString key = it.key();
        bool val = it.value();
        promise_result = promise_result && val;
    }

    if (true) {
        // 检测对方最近的回包情况
        if (!promise_result && repeat_timer == NULL
            && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) {
            qDebug()<<"here";
            if (chan->last_recv_peer_pkt_time == QDateTime()) {
                qDebug()<<"maybe can close socket right now, because recv nothing forever";
            }
            
            QTimer *t = new QTimer();
            t->setInterval(500);
            t->setSingleShot(true);
            t->setProperty("conid", QVariant(chan->m_conid));
            // // QObject::connect(t, &QTimer::timeout, this, &Tunneld::promiseChannelCleanup, Qt::QueuedConnection);
            QObject::connect(t, SIGNAL(timeout()), this, SLOT(promiseChannelCleanup()), Qt::QueuedConnection);
            qDebug()<<"start repeat check sock close timer:";
            t->start();
        }
        if (!promise_result && repeat_timer != NULL
            && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) {
            //
            QDateTime now_time = QDateTime::currentDateTime();
            uint32_t last_recv_to_now_time = chan->last_recv_peer_pkt_time.msecsTo(now_time);
            qDebug()<<"here:"<<last_recv_to_now_time<<enpeer->lastReceiveTime;
            if (last_recv_to_now_time > 7000) {
                qDebug()<<"last recv to now, force close self socket:"<<last_recv_to_now_time
                        <<enpeer->incomingPeerID<<enpeer->outgoingPeerID;
                // 不能直接关闭,要在当前函数执行完后,即下一次事件的时候开始执行。
                QTimer::singleShot(1, sock, &QTcpSocket::close);
                // QTimer *t = new QTimer();
                // t->setSingleShot(true);
                // QObject::connect(t, &QTimer::timeout, sock, &QTcpSocket::close, Qt::QueuedConnection);
                // t->start(1);
                
                repeat_timer->deleteLater();
            } else {
                repeat_timer->start();
            }
        }
    }
    
    if (!promise_result) {
        qDebug()<<"promise nooooot satisfied:"<<promise_results<<chan->m_conid;
        return;
    }
    
    chan->promise_close_time = QDateTime::currentDateTime();
    qDebug()<<"promise satisfied."<<chan->m_conid;

    ///// do cleanup
    bool force_closed = chan->force_closed;
    
    // enpeer->toxchan = NULL;  // cleanup
    peerRemoveChan(enpeer, chan);
    
    this->m_sock_chans.remove(sock);
    // this->m_enpeer_chans.remove(enpeer);
    this->m_conid_chans.remove(chan->m_conid);

    delete chan;
    sock->disconnect();
    sock->deleteLater();
    if (repeat_timer != NULL) repeat_timer->deleteLater();
    qDebug()<<"curr chan size:"<<this->m_sock_chans.count()<<this->m_conid_chans.count();

    if (force_closed) {
        return;
    }

    // 延时关闭enet_peer
    QTimer *t = new QTimer();
    auto later_close_timeout = [enpeer, t]() {
        qDebug()<<enpeer<<enpeer->state;
        if (enpeer->state != ENET_PEER_STATE_CONNECTED) {
            qDebug()<<"warning, peer currently not connected:"<<enpeer->incomingPeerID;
        }

        if (! (enet_list_empty (& enpeer -> outgoingReliableCommands) &&
               enet_list_empty (& enpeer -> outgoingUnreliableCommands) && 
               enet_list_empty (& enpeer -> sentReliableCommands))) {
            qDebug()<<"warning, maybe has unsent packet:"<<enpeer->incomingPeerID;
        }

        qDebug()<<"last recv time:"<<enpeer->incomingPeerID
        <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get());

        qDebug()<<"restore peer timeout, ping interval";
        enet_peer_timeout(enpeer, ENET_PEER_TIMEOUT_LIMIT*2,
                          ENET_PEER_TIMEOUT_MINIMUM*2, ENET_PEER_TIMEOUT_MAXIMUM*2);
        enet_peer_ping_interval(enpeer, ENET_PEER_PING_INTERVAL*2);

        // enet_peer_disconnect_now(enpeer, qrand());
        enet_peer_disconnect_later(enpeer, qrand());
        t->deleteLater();
    };

    qDebug()<<"last recv time:"<<enpeer->incomingPeerID
            <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get());
    // QTimer::singleShot(5678, later_close_timeout);
    t->setInterval(5678);
    t->setSingleShot(true);
    QObject::connect(t, &QTimer::timeout, later_close_timeout);
    t->start();
}