示例#1
0
static net_client_t *NET_SV_Controller(void)
{
    net_client_t *best;
    int i;

    // Find the oldest client (first to connect).

    best = NULL;

    for (i=0; i<MAXNETNODES; ++i)
    {
        // Can't be controller?

        if (!ClientConnected(&clients[i]) || clients[i].drone)
        {
            continue;
        }

        if (best == NULL || clients[i].connect_time < best->connect_time)
        {
            best = &clients[i];
        }
    }

    return best;
}
示例#2
0
static void NET_SV_AssignPlayers(void)
{
    int i;
    int pl;

    pl = 0;

    for (i=0; i<MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i]))
        {
            if (!clients[i].drone)
            {
                sv_players[pl] = &clients[i];
                sv_players[pl]->player_number = pl;
                ++pl;
            }
            else
            {
                clients[i].player_number = -1;
            }
        }
    }

    for (; pl<MAXPLAYERS; ++pl)
    {
        sv_players[pl] = NULL;
    }
}
示例#3
0
void TCPServer::newConnection()
{
    socket = server->nextPendingConnection();
    connect(socket, &QTcpSocket::readyRead, this, &TCPServer::readyReadHandler);

    emit ClientConnected();
}
void NET_SV_Run(void)
{
    net_addr_t *addr;
    net_packet_t *packet;
    int i;

    if (!server_initialized)
    {
        return;
    }

    while (NET_RecvPacket(server_context, &addr, &packet))
    {
        NET_SV_Packet(packet, addr);
        NET_FreePacket(packet);
        NET_ReleaseAddress(addr);
    }

    if (master_server != NULL)
    {
        UpdateMasterServer();
    }

    // "Run" any clients that may have things to do, independent of responses
    // to received packets

    for (i=0; i<MAXNETNODES; ++i)
    {
        if (clients[i].active)
        {
            NET_SV_RunClient(&clients[i]);
        }
    }

    switch (server_state)
    {
        case SERVER_WAITING_LAUNCH:
            break;

        case SERVER_WAITING_START:
            CheckStartGame();
            break;

        case SERVER_IN_GAME:
            NET_SV_AdvanceWindow();

            for (i = 0; i < NET_MAXPLAYERS; ++i)
            {
                if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
                {
                    NET_SV_CheckResends(sv_players[i]);
                }
            }
            break;
    }
}
示例#5
0
static void NET_SV_AdvanceWindow(void)
{
    unsigned int lowtic;
    int i;

    if (NET_SV_NumPlayers() <= 0)
    {
        return;
    }

    lowtic = NET_SV_LatestAcknowledged();

    // Advance the recv window until it catches up with lowtic

    while (recvwindow_start < lowtic)
    {    
        boolean should_advance;

        // Check we have tics from all players for first tic in
        // the recv window
        
        should_advance = true;

        for (i=0; i<NET_MAXPLAYERS; ++i)
        {
            if (sv_players[i] == NULL || !ClientConnected(sv_players[i]))
            {
                continue;
            }

            if (!recvwindow[0][i].active)
            {
                should_advance = false;
                break;
            }
        }

        if (!should_advance)
        {
            // The first tic is not complete: ie. we have not 
            // received tics from all connected players.  This can
            // happen if only one player is in the game.

            break;
        }
        
        // Advance the window

        memmove(recvwindow, recvwindow + 1,
                sizeof(*recvwindow) * (BACKUPTICS - 1));
        memset(&recvwindow[BACKUPTICS-1], 0, sizeof(*recvwindow));
        ++recvwindow_start;

        //printf("SV: advanced to %i\n", recvwindow_start);
    }
}
示例#6
0
static void SendAllWaitingData(void)
{
    unsigned int i;

    for (i = 0; i < MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i]) && clients[i].ready)
        {
            NET_SV_SendWaitingData(&clients[i]);
        }
    }
}
示例#7
0
static int NET_SV_MaxPlayers(void)
{
    int i;

    for (i = 0; i < MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i]))
        {
            return clients[i].max_players;
        }
    }

    return NET_MAXPLAYERS;
}
示例#8
0
static boolean AllNodesReady(void)
{
    unsigned int i;

    for (i = 0; i < MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i]) && !clients[i].ready)
        {
            return false;
        }
    }

    return true;
}
示例#9
0
LRESULT CAppWindow::OnPowerBroadcast(WPARAM wParam)
{
	switch (wParam)
	{
	case PBT_APMSUSPEND:
		ClientDisconnected(CR_SUSPEND);
		break;

	case PBT_APMRESUMESUSPEND:
	case PBT_APMRESUMEAUTOMATIC:
		ClientConnected(CR_SUSPEND);
		break;
	}

	return TRUE;
}
示例#10
0
static int NET_SV_NumReadyPlayers(void)
{
    int result = 0;
    int i;

    for (i = 0; i < MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i])
         && !clients[i].drone && clients[i].ready)
        {
            ++result;
        }
    }

    return result;
}
示例#11
0
static int NET_SV_NumPlayers(void)
{
    int i;
    int result;

    result = 0;

    for (i=0; i<MAXPLAYERS; ++i)
    {
        if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
        {
            result += 1;
        }
    }

    return result;
}
示例#12
0
static int NET_SV_NumDrones(void)
{
    int i;
    int result;

    result = 0;

    for (i=0; i<MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i]) && clients[i].drone)
        {
            result += 1;
        }
    }

    return result;
}
示例#13
0
static int NET_SV_NumClients(void)
{
    int count;
    int i;

    count = 0;

    for (i=0; i<MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i]))
        {
            ++count;
        }
    }

    return count;
}
示例#14
0
static void NET_SV_ParseLaunch(net_packet_t *packet, net_client_t *client)
{
    net_packet_t *launchpacket;
    int num_players;
    unsigned int i;

    NET_Log("server: processing launch packet");

    // Only the controller can launch the game.

    if (client != NET_SV_Controller())
    {
        NET_Log("server: error: this client isn't the controller, %d != %d",
                client, NET_SV_Controller());
        return;
    }

    // Can only launch when we are in the waiting state.

    if (server_state != SERVER_WAITING_LAUNCH)
    {
        NET_Log("server: error: not in waiting launch state, state=%d",
                server_state);
        return;
    }

    // Forward launch on to all clients.
    NET_Log("server: sending launch to all clients");
    NET_SV_AssignPlayers();
    num_players = NET_SV_NumPlayers();

    for (i=0; i<MAXNETNODES; ++i)
    {
        if (!ClientConnected(&clients[i]))
            continue;

        launchpacket = NET_Conn_NewReliable(&clients[i].connection,
                                            NET_PACKET_TYPE_LAUNCH);
        NET_WriteInt8(launchpacket, num_players);
    }

    // Now in launch state.

    server_state = SERVER_WAITING_START;
}
示例#15
0
static unsigned int NET_SV_LatestAcknowledged(void)
{
    unsigned int lowtic = UINT_MAX;
    int i;

    for (i=0; i<MAXNETNODES; ++i) 
    {
        if (ClientConnected(&clients[i]))
        {
            if (clients[i].acknowledged < lowtic)
            {
                lowtic = clients[i].acknowledged;
            }
        }
    }

    return lowtic;
}
示例#16
0
LRESULT CAppWindow::OnWTSSessionChange(WPARAM wParam)
{
	switch (wParam)
	{
	case WTS_CONSOLE_CONNECT:
	case WTS_REMOTE_CONNECT:
	case WTS_SESSION_UNLOCK:
		ClientConnected(CR_LOCK);
		break;

	case WTS_CONSOLE_DISCONNECT:
	case WTS_REMOTE_DISCONNECT:
	case WTS_SESSION_LOCK:
		ClientDisconnected(CR_LOCK);
		break;
	}

	return 0;
}
示例#17
0
static void NET_SV_BroadcastMessage(char *s, ...)
{
    char buf[1024];
    va_list args;
    int i;

    va_start(args, s);
    vsnprintf(buf, sizeof(buf), s, args);
    va_end(args);
    
    for (i=0; i<MAXNETNODES; ++i)
    {
        if (ClientConnected(&clients[i]))
        {
            NET_SV_SendConsoleMessage(&clients[i], buf);
        }
    }

    NET_SafePuts(buf);
}
void FileTransferWidget::StartTransfer()
{
    m_currentStatus = FT_IDLE;
    m_speedBytes = 0;
    m_IPsHashIter = new QHashIterator<QString,quint32>(m_req.IPsDict);
    m_IPsHashIter->toFront();
    m_filesHashIter = new QHashIterator<QString,quint32>(m_req.FilesDict);
    m_filesHashIter->toFront();

    switch (m_transferMode)
    {
        case TM_RECIEVE_CLIENT:
        {
            m_socket = new QTcpSocket;
            connect(m_socket,SIGNAL(connected()),this,SLOT(ConnectedToPeer()));
            connect(m_socket,SIGNAL(readyRead()),this,SLOT(ReadyRead()));
            connect(m_socket,SIGNAL(disconnected()),this,SLOT(Disconnected()));
            connect(m_socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(SocketError(QAbstractSocket::SocketError)));
            QHash<QString, quint32>::const_iterator currIp = m_IPsHashIter->next();
            m_currentStatus = FT_CONNECTING;
            qDebug()<<"MRIM: FT: Connecting to "<<currIp.key()<<":"<<currIp.value();
            m_socket->connectToHost(currIp.key(),currIp.value());
        }
        break;
        case TM_SEND_SERVER:
        {
            m_sentFilesCount = 0;
            m_server = new QTcpServer();
            connect(m_server,SIGNAL(newConnection()),this,SLOT(ClientConnected()));
            qDebug()<<"MRIM: FT: Starting server @ 127.0.0.1:"<<m_req.IPsDict.values().at(0);
            m_currentStatus = FT_WAIT_FOR_CLIENT;
            m_server->listen(QHostAddress(QHostAddress::LocalHost),m_req.IPsDict.values().at(0));
        }
        break;
    }

}
示例#19
0
static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client)
{
    net_gamesettings_t settings;
    net_packet_t *startpacket;
    int nowtime;
    int i;
    
    if (client != NET_SV_Controller())
    {
        // Only the controller can start a new game

        return;
    }

    if (!NET_ReadSettings(packet, &settings))
    {
        // Malformed packet

        return;
    }

    // Check the game settings are valid

    if (!NET_ValidGameSettings(sv_gamemode, sv_gamemission, &settings))
    {
        return;
    }

    if (server_state != SERVER_WAITING_START)
    {
        // Can only start a game if we are in the waiting start state.

        return;
    }

    // Assign player numbers

    NET_SV_AssignPlayers();

    // Check if anyone is recording a demo and set lowres_turn if so.

    settings.lowres_turn = false;

    for (i=0; i<MAXPLAYERS; ++i)
    {
        if (sv_players[i] != NULL && sv_players[i]->recording_lowres)
        {
            settings.lowres_turn = true;
        }
    }

    nowtime = I_GetTimeMS();

    // Send start packets to each connected node

    for (i=0; i<MAXNETNODES; ++i) 
    {
        if (!ClientConnected(&clients[i]))
            continue;

        clients[i].last_gamedata_time = nowtime;

        startpacket = NET_Conn_NewReliable(&clients[i].connection,
                                           NET_PACKET_TYPE_GAMESTART);

        NET_WriteInt8(startpacket, NET_SV_NumPlayers());
        NET_WriteInt8(startpacket, clients[i].player_number);
        NET_WriteSettings(startpacket, &settings);
    }

    // Change server state

    server_state = SERVER_IN_GAME;
    sv_settings = settings;

    memset(recvwindow, 0, sizeof(recvwindow));
    recvwindow_start = 0;
}
MainController::MainController(MainView *view, QString settingsFilePath,
                               QObject *parent) :
  QObject(parent)
  ,m_view(view)
  ,m_settings(new Settings(this))
  ,m_heartbeatText(HEARTBEAT_TEXT)
  ,m_heartbeatResponseText(HEARTBEAT_RESPONSE_TEXT)
  ,m_heartbeat_interval(0)
  ,m_hearbeatTimer(new QTimer(this))
  ,m_errorTimer(new QTimer(this))
  ,m_appSettings(new ApplicationSettings(this))
{
    connect(m_appSettings, SIGNAL(error(QString)),this, SLOT(onAppSettingsError(QString)));

    /* load setting from the json file */
    if (m_appSettings->parseJSON(settingsFilePath))
    {
        m_screen = new Screen(view, m_appSettings->screenSaverTimeout(), m_appSettings->screenOriginalBrigtness(),
                              m_appSettings->screenDimBrigtness(), this);
        m_watchdog = new Watchdog(this, m_appSettings->enableWatchdog());
        m_beep = new Beep(this);

        /* Define objects that can be used in qml */
        m_view->rootContext()->setContextProperty("connection",this);
        m_view->rootContext()->setContextProperty("settings", m_settings);
        m_view->rootContext()->setContextProperty("screen", m_screen);
        m_view->rootContext()->setContextProperty("watchdog", m_watchdog);
        m_view->rootContext()->setContextProperty("beeper", m_beep);

        /* Enable or disable ack */
        if (m_appSettings->enableAck())
            enableLookupAck();
        else
            disableLookupAck();

        /* Enablle or disable heartbeat */
        connect(m_hearbeatTimer,SIGNAL(timeout()),this, SLOT(onHeartbeatTimerTimeout()));
        if (m_appSettings->enableHeartbeat())
            enableHeartbeat(m_appSettings->heartbeatInterval());
        else
            disableHeartbeat();

        /* Add a connection to the view statusChanged signal */
        connect(m_view, SIGNAL(statusChanged(QQuickView::Status)), this, SLOT(onViewStatusChanged(QQuickView::Status)));

        m_clients = 0;
        m_enableTranslator = false;
        m_startUpError = "";

        /* Create the TCP string servers and add connections */
        int i = 0;
        foreach(const StringServerSetting &server, m_appSettings->stringServers())
        {
            StringServer *stringServer =  new StringServer(this, server.port(), server.parseJson(),
                                                           server.translate(), server.translateId(),
                                                           server.primaryConnection());
            if (server.translate())
                m_enableTranslator = true;
            connect(stringServer, SIGNAL(PrimaryConnectionAvailable()), this, SLOT(onPrimaryConnectionAvailable()));
            connect(stringServer, SIGNAL(MessageAvailable(QByteArray, bool, bool, QString))
                    , this, SLOT(onMessageAvailable(QByteArray, bool, bool, QString)));
            connect(stringServer, SIGNAL(ClientConnected()), this, SLOT(onClientConnected()));
            connect(stringServer, SIGNAL(ClientDisconnected()), this, SLOT(onClientDisconnected()));

            if (stringServer->Start())
            {
                m_stringServerList.append(stringServer);
                i += 1;
            }
            else
            {
                delete stringServer;
            }
        }


        /* Create the Serial Servers and add the connections */
        i = 0;
        foreach(const SerialServerSetting &server, m_appSettings->serialServers())
        {
            SerialServer *serialServer = new SerialServer(server, this);
            connect(serialServer, SIGNAL(ClientConnected()), this, SLOT(onClientConnected()));
            connect(serialServer, SIGNAL(PrimaryConnectionAvailable()), this, SLOT(onPrimaryConnectionAvailable()));
            connect(serialServer, SIGNAL(MessageAvailable(QByteArray, bool, bool, QString))
                    , this, SLOT(onMessageAvailable(QByteArray, bool, bool, QString)));
            connect(serialServer, SIGNAL(Error(QString)), this, SLOT(showError(QString)));

            if (server.translate())
                m_enableTranslator = true;

            if (serialServer->Start())
            {
                m_serialServerList.append(serialServer);
                i += 1;
            }
            else
            {
                delete serialServer;
            }

        }

        if (m_enableTranslator){
            /* Initialize the Translator object */
            m_transLator = new Translator(m_appSettings->translateFile(), m_appSettings->translateMaxMapSize(), this);
            /* Load and parse the translate file. */
            m_transLator->loadTranslations();
        }

        /* check if we need to load a language translate file */
        if (m_appSettings->languageFile().length() > 0)
        {
            loadLanguageTranslator(m_appSettings->languageFile());
        }

        setMainViewPath(m_appSettings->mainView());
        m_view->show();
    }
示例#21
0
static void NET_SV_PumpSendQueue(net_client_t *client)
{
    net_full_ticcmd_t cmd;
    int recv_index;
    int num_players;
    int i;
    int starttic, endtic;

    // If a client has not sent any acknowledgments for a while,
    // wait until they catch up.

    if (client->sendseq - NET_SV_LatestAcknowledged() > 40)
    {
        return;
    }
    
    // Work out the index into the receive window
   
    recv_index = client->sendseq - recvwindow_start;

    if (recv_index < 0 || recv_index >= BACKUPTICS)
    {
        return;
    }

    // Check if we can generate a new entry for the send queue
    // using the data in recvwindow.

    num_players = 0;

    for (i=0; i<NET_MAXPLAYERS; ++i)
    {
        if (sv_players[i] == client)
        {
            // Client does not rely on itself for data

            continue;
        }

        if (sv_players[i] == NULL || !ClientConnected(sv_players[i]))
        {
            continue;
        }

        if (!recvwindow[recv_index][i].active)
        {
            // We do not have this player's ticcmd, so we cannot
            // generate a complete command yet.

            return;
        }

        ++num_players;
    }

    // If this is a game with only a single player in it, we might
    // be sending a ticcmd set containing 0 ticcmds. This is fine;
    // however, there's nothing to stop the game running on ahead
    // and never stopping. Don't let the server get too far ahead
    // of the client.

    if (num_players == 0 && client->sendseq > recvwindow_start + 10)
    {
        return;
    }

    // We have all data we need to generate a command for this tic.
    
    cmd.seq = client->sendseq;

    // Add ticcmds from all players

    cmd.latency = 0;

    for (i=0; i<NET_MAXPLAYERS; ++i)
    {
        net_client_recv_t *recvobj;

        if (sv_players[i] == client)
        {
            // Not the player we are sending to

            cmd.playeringame[i] = false;
            continue;
        }
        
        if (sv_players[i] == NULL || !recvwindow[recv_index][i].active)
        {
            cmd.playeringame[i] = false;
            continue;
        }

        cmd.playeringame[i] = true;

        recvobj = &recvwindow[recv_index][i];

        cmd.cmds[i] = recvobj->diff;

        if (recvobj->latency > cmd.latency)
            cmd.latency = recvobj->latency;
    }

    //printf("SV: %i: latency %i\n", client->player_number, cmd.latency);

    // Add into the queue

    client->sendqueue[client->sendseq % BACKUPTICS] = cmd;

    // Transmit the new tic to the client

    starttic = client->sendseq - sv_settings.extratics;
    endtic = client->sendseq;

    if (starttic < 0)
        starttic = 0;

    NET_Log("server: send tics %d-%d to %s", starttic, endtic,
            NET_AddrToString(client->addr));
    NET_SV_SendTics(client, starttic, endtic);

    ++client->sendseq;
}
示例#22
0
static void NET_SV_RunClient(net_client_t *client)
{
    // Run common code

    NET_Conn_Run(&client->connection);

    if (client->connection.state == NET_CONN_STATE_DISCONNECTED
     && client->connection.disconnect_reason == NET_DISCONNECT_TIMEOUT)
    {
        NET_Log("server: client at %s timed out",
                NET_AddrToString(client->addr));
        NET_SV_BroadcastMessage("Client '%s' timed out and disconnected",
                                client->name);
    }

    // Is this client disconnected?

    if (client->connection.state == NET_CONN_STATE_DISCONNECTED)
    {
        client->active = false;

        // If we were about to start a game, any player disconnecting
        // should cause an abort.

        if (server_state == SERVER_WAITING_START && !client->drone)
        {
            NET_SV_BroadcastMessage("Game startup aborted because "
                                    "player '%s' disconnected.",
                                    client->name);
            NET_SV_GameEnded();
        }

        free(client->name);
        NET_ReleaseAddress(client->addr);

        // Are there any clients left connected?  If not, return the
        // server to the waiting-for-players state.
        //
	// Disconnect any drones still connected.

        if (NET_SV_NumPlayers() <= 0)
        {
            NET_Log("server: no player clients left, game ended");
            NET_SV_GameEnded();
        }
    }

    if (!ClientConnected(client))
    {
        // client has not yet finished connecting

        return;
    }

    if (server_state == SERVER_WAITING_LAUNCH)
    {
        // Waiting for the game to start

        // Send information once every second

        if (client->last_send_time < 0 
         || I_GetTimeMS() - client->last_send_time > 1000)
        {
            NET_SV_SendWaitingData(client);
            client->last_send_time = I_GetTimeMS();
        }
    }

    if (server_state == SERVER_IN_GAME)
    {
        NET_SV_PumpSendQueue(client);
        NET_SV_CheckDeadlock(client);
    }
}
示例#23
0
//============================================================================
//		NMessageServer::ServerThread : Server thread.
//----------------------------------------------------------------------------
void NMessageServer::ServerThread(NSocket *theSocket)
{	NNetworkMessage			msgServerInfo, msgConnectRequest, msgConnectResponse;
	NStatus					theErr, acceptErr;
	NMessageHandshake		clientHandshake;
	NString					thePassword;
	NDictionary				serverInfo;
	bool					addClient;
	NEntityID				clientID;



	// Validate our state
	NN_ASSERT(mStatus == kNServerStarted);



	// Do the handshake
	theErr = ReadHandshake(theSocket, clientHandshake);

	if (theErr == kNoErr)
		theErr = WriteHandshake(theSocket, CreateHandshake());

	if (theErr == kNoErr)
		theErr = ValidateHandshake(clientHandshake);

	if (theErr != kNoErr)
		{
		theSocket->Close(theErr);
		return;
		}



	// Send the server info
	mLock.Lock();
	serverInfo    = GetConnectionInfo();
	msgServerInfo = CreateMessage(kNMessageServerInfoMsg, kNEntityEveryone);
	msgServerInfo.SetProperties(serverInfo);
	mLock.Unlock();

	theErr = WriteMessage(theSocket, msgServerInfo);
	if (theErr != kNoErr)
		{
		theSocket->Close(theErr);
		return;
		}



	// Read the connection request
	//
	// If the client does not wish to continue connecting, they will disconnect.
	theErr = ReadMessage(theSocket, msgConnectRequest);
	if (theErr != kNoErr)
		{
		theSocket->Close();
		return;
		}

	NN_ASSERT(msgConnectRequest.GetType()   == kNMessageConnectRequestMsg);
	NN_ASSERT(msgConnectRequest.GetSource() == kNEntityInvalid);



	// Accept the connection
	mLock.Lock();

	clientID  = GetNextClientID();
	acceptErr = AcceptConnection(serverInfo, msgConnectRequest.GetProperties(), clientID);

	msgConnectResponse = CreateMessage(kNMessageConnectResponseMsg, clientID);
	msgConnectResponse.SetValue(kNMessageStatusKey, acceptErr);

	theErr    = WriteMessage(theSocket, msgConnectResponse);
	addClient = (theErr == kNoErr && acceptErr == kNoErr);
	
	if (addClient)
		AddClient(clientID, theSocket);

	mLock.Unlock();

	if (!addClient)
		{
		theSocket->Close(theErr);
		return;
		}



	// Process messages
	ClientConnected(clientID);

	ProcessMessages(theSocket);
}
void SampleEscrowServerZmq::UpdateServer()
{
    //while (!Modules::shutDown)
    {
        zmq_msg_t request; // = new zmq_msg_t();
        zmq_msg_init(&request);

        // Wait for next request from client
        zmq_pollitem_t item;
        item.socket = this->serverSocket;
        item.fd = 0;
        item.events = ZMQ_POLLIN;
        item.revents = 0;
        /*zmq_pollitem_t items[] = { item }; //{ this->serverSocket, 0, ZMQ_POLLIN, 0 } };
        zmq_poll(&items[0], 1, 1000);

        // Return if no request
        if (!(items[0].revents & ZMQ_POLLIN))
        {
            zmq_msg_close(&request);
            return;
        }*/

#ifdef OT_USE_ZMQ4
        if(zmq_msg_recv(&request, this->serverSocket, ZMQ_DONTWAIT) == -1)
#else
        #ifndef Q_OS_MAC
        if(zmq_recv(this->serverSocket, &request, ZMQ_NOBLOCK) == -1)
#endif
#endif
        {
            zmq_msg_close(&request);
            return;
        }

        if(zmq_msg_size(&request) < NetMessageSizes[Unknown])
        {
            zmq_msg_close(&request);
            return;
        }

        NetMessageType messageType = static_cast<NetMessageType>(static_cast<BtcNetMsg*>(zmq_msg_data(&request))->MessageType);
        if(zmq_msg_size(&request) != NetMessageSizes[messageType])
        {
            zmq_msg_close(&request);
            return;
        }

        BtcNetMsg* replyPtr = new BtcNetMsg();

        switch(messageType)
        {
        case Unknown:
        {
            break;
        }
        case Connect:
        {
            BtcNetMsgConnectPtr message = BtcNetMsgConnectPtr(new BtcNetMsgConnect());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            ClientConnected(message);
            std::printf("client connected\n");
            std::cout.flush();
            break;
        }
        case ReqDeposit:
        {
            BtcNetMsgReqDepositPtr message = BtcNetMsgReqDepositPtr(new BtcNetMsgReqDeposit());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            bool accepted = RequestEscrowDeposit(message);

            BtcNetMsgDepositReply* replyMsg = new BtcNetMsgDepositReply();
            replyMsg->accepted = static_cast<int8_t>(accepted);
            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        case GetMultiSigAddr:
        {
            BtcNetMsgGetDepositAddrPtr message = BtcNetMsgGetDepositAddrPtr(new BtcNetMsgGetDepositAddr());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            std::string multiSigAddr = RequestDepositAddress(message);

            if(multiSigAddr.empty())
                break;

            BtcNetMsgDepositAddr* replyMsg = new BtcNetMsgDepositAddr();
            memcpy(replyMsg->address, multiSigAddr.c_str(), std::min(multiSigAddr.size(), sizeof(replyMsg->address)));
            std::printf("server %s sending multisig addr %s\n", this->serverName.c_str(), replyMsg->address);
            std::cout.flush();
            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        case GetMultiSigKey:
        {
            BtcNetMsgGetKeyPtr message = BtcNetMsgGetKeyPtr(new BtcNetMsgGetKey());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            std::string pubKey = GetPubKey(message);

            if(pubKey.empty())
                break;

            BtcNetMsgPubKey* replyMsg = new BtcNetMsgPubKey();
            memcpy(replyMsg->pubKey, pubKey.c_str(), std::min(pubKey.size(), sizeof(replyMsg->pubKey)));
            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        case GetBalance:
        {
            BtcNetMsgGetBalancePtr message = BtcNetMsgGetBalancePtr(new BtcNetMsgGetBalance());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            int64_t balance = GetClientBalance(message);

            BtcNetMsgBalance* replyMsg = new BtcNetMsgBalance();
            replyMsg->balance = balance;
            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        case GetTxCount:
        {
            BtcNetMsgGetTxCountPtr message = BtcNetMsgGetTxCountPtr(new BtcNetMsgGetTxCount());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            int32_t txCount = GetClientTransactionCount(message);

            BtcNetMsgTxCount* replyMsg = new BtcNetMsgTxCount();
            replyMsg->txCount = txCount;
            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        case GetTx:
        {
            BtcNetMsgGetTxPtr message = BtcNetMsgGetTxPtr(new BtcNetMsgGetTx());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            SampleEscrowTransactionPtr tx = GetClientTransaction(message);

            if(tx == NULL)
                break;

            BtcNetMsgTx* replyMsg = new BtcNetMsgTx();
            memcpy(replyMsg->txId, tx->txId.c_str(), std::min(tx->txId.size(), sizeof(replyMsg->txId)));
            memcpy(replyMsg->toAddress, tx->targetAddr.c_str(), std::min(tx->targetAddr.size(), sizeof(replyMsg->toAddress)));
            replyMsg->amount = tx->amountToSend;
            replyMsg->type = static_cast<int8_t>(tx->type);
            replyMsg->status = static_cast<int8_t>(tx->status);

            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        case RequestRelease:
        {      
            BtcNetMsgReqWithdrawPtr message = BtcNetMsgReqWithdrawPtr(new BtcNetMsgReqWithdraw());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            bool accepted = RequestEscrowWithdrawal(message);

            BtcNetMsgWithdrawReply* replyMsg = new BtcNetMsgWithdrawReply();
            replyMsg->accepted = static_cast<int8_t>(accepted);
            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        case ReqSignedTx:
        {
            BtcNetMsgReqSignedTxPtr message = BtcNetMsgReqSignedTxPtr(new BtcNetMsgReqSignedTx());
            memcpy(message->data, zmq_msg_data(&request), NetMessageSizes[messageType]);
            std::string partiallySignedTx = RequestSignedWithdrawal(message);

            if(partiallySignedTx.empty())
                break;

            BtcNetMsgSignedTx* replyMsg = new BtcNetMsgSignedTx();
            memcpy(replyMsg->rawTx, partiallySignedTx.c_str(), std::min(partiallySignedTx.size(), sizeof(replyMsg->rawTx)));
            replyPtr = (BtcNetMsg*)replyMsg;
            break;
        }
        default:
            std::printf("received malformed message\n");
            std::cout.flush();
            break;
        }

        zmq_msg_close(&request);

        // Send reply back to client
        size_t size = NetMessageSizes[(NetMessageType)replyPtr->MessageType];
        zmq_msg_t reply;
        zmq_msg_init_size(&reply, size);
        zmq_msg_init_data(&reply, replyPtr->data, size, &DeleteNetMsg, replyPtr);

#ifdef OT_USE_ZMQ4
        zmq_msg_send(&reply, this->serverSocket, 0);
#else
        #ifndef Q_OS_MAC
        zmq_send(this->serverSocket, &reply, 0);
#endif
#endif

        // note: replyPtr is not deleted on purpose, see DeleteNetMsg()
    }
}
示例#25
0
static void NET_SV_RunClient(net_client_t *client)
{
    // Run common code

    NET_Conn_Run(&client->connection);
    
    if (client->connection.state == NET_CONN_STATE_DISCONNECTED
     && client->connection.disconnect_reason == NET_DISCONNECT_TIMEOUT)
    {
        NET_SV_BroadcastMessage("Client '%s' timed out and disconnected",
                                client->name);
    }
    
    // Is this client disconnected?

    if (client->connection.state == NET_CONN_STATE_DISCONNECTED)
    {
        // deactivate and free back 

        client->active = false;
        free(client->name);
        NET_FreeAddress(client->addr);

        // Are there any clients left connected?  If not, return the
        // server to the waiting-for-players state.
        //
	// Disconnect any drones still connected.

        if (NET_SV_NumPlayers() <= 0)
        {
            NET_SV_GameEnded();
        }
    }
    
    if (!ClientConnected(client))
    {
        // client has not yet finished connecting

        return;
    }

    if (server_state == SERVER_WAITING_START)
    {
        // Waiting for the game to start

        // Send information once every second

        if (client->last_send_time < 0 
         || I_GetTimeMS() - client->last_send_time > 1000)
        {
            NET_SV_SendWaitingData(client);
            client->last_send_time = I_GetTimeMS();
        }
    }

    if (server_state == SERVER_IN_GAME)
    {
        NET_SV_PumpSendQueue(client);
        NET_SV_CheckDeadlock(client);
    }
}
示例#26
0
static void NET_SV_PumpSendQueue(net_client_t *client)
{
    net_full_ticcmd_t cmd;
    int recv_index;
    int i;
    int starttic, endtic;

    // If a client has not sent any acknowledgments for a while,
    // wait until they catch up.

    if (client->sendseq - NET_SV_LatestAcknowledged() > 40)
    {
        return;
    }
    
    // Work out the index into the receive window
   
    recv_index = client->sendseq - recvwindow_start;

    if (recv_index < 0 || recv_index >= BACKUPTICS)
    {
        return;
    }

    // Check if we can generate a new entry for the send queue
    // using the data in recvwindow.

    for (i=0; i<MAXPLAYERS; ++i)
    {
        if (sv_players[i] == client)
        {
            // Client does not rely on itself for data

            continue;
        }

        if (sv_players[i] == NULL || !ClientConnected(sv_players[i]))
        {
            continue;
        }

        if (!recvwindow[recv_index][i].active)
        {
            // We do not have this player's ticcmd, so we cannot
            // generate a complete command yet.

            return;
        }
    }

    //printf("SV: have complete ticcmd for %i\n", client->sendseq);

    // We have all data we need to generate a command for this tic.
    
    cmd.seq = client->sendseq;

    // Add ticcmds from all players

    cmd.latency = 0;

    for (i=0; i<MAXPLAYERS; ++i)
    {
        net_client_recv_t *recvobj;

        if (sv_players[i] == client)
        {
            // Not the player we are sending to

            cmd.playeringame[i] = false;
            continue;
        }
        
        if (sv_players[i] == NULL || !recvwindow[recv_index][i].active)
        {
            cmd.playeringame[i] = false;
            continue;
        }

        cmd.playeringame[i] = true;

        recvobj = &recvwindow[recv_index][i];

        cmd.cmds[i] = recvobj->diff;

        if (recvobj->latency > cmd.latency)
            cmd.latency = recvobj->latency;
    }

    //printf("SV: %i: latency %i\n", client->player_number, cmd.latency);

    // Add into the queue

    client->sendqueue[client->sendseq % BACKUPTICS] = cmd;

    // Transmit the new tic to the client

    starttic = client->sendseq - sv_settings.extratics;
    endtic = client->sendseq;

    if (starttic < 0)
        starttic = 0;

    NET_SV_SendTics(client, starttic, endtic);

    ++client->sendseq;
}
示例#27
0
static void StartGame(void)
{
    net_packet_t *startpacket;
    unsigned int i;
    int nowtime;

    // Assign player numbers

    NET_SV_AssignPlayers();

    // Check if anyone is recording a demo and set lowres_turn if so.

    sv_settings.lowres_turn = false;

    for (i = 0; i < NET_MAXPLAYERS; ++i)
    {
        if (sv_players[i] != NULL && sv_players[i]->recording_lowres)
        {
            sv_settings.lowres_turn = true;
        }
    }

    sv_settings.num_players = NET_SV_NumPlayers();

    // Copy player classes:

    for (i = 0; i < NET_MAXPLAYERS; ++i)
    {
        if (sv_players[i] != NULL)
        {
            sv_settings.player_classes[i] = sv_players[i]->player_class;
        }
        else
        {
            sv_settings.player_classes[i] = 0;
        }
    }

    nowtime = I_GetTimeMS();

    // Send start packets to each connected node

    for (i = 0; i < MAXNETNODES; ++i)
    {
        if (!ClientConnected(&clients[i]))
            continue;

        clients[i].last_gamedata_time = nowtime;

        startpacket = NET_Conn_NewReliable(&clients[i].connection,
                                           NET_PACKET_TYPE_GAMESTART);

        sv_settings.consoleplayer = clients[i].player_number;

        NET_WriteSettings(startpacket, &sv_settings);
    }

    // Change server state

    server_state = SERVER_IN_GAME;

    memset(recvwindow, 0, sizeof(recvwindow));
    recvwindow_start = 0;
}