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; }
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; } }
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; } }
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); } }
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]); } } }
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; }
static boolean AllNodesReady(void) { unsigned int i; for (i = 0; i < MAXNETNODES; ++i) { if (ClientConnected(&clients[i]) && !clients[i].ready) { return false; } } return true; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; } }
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(); }
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; }
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); } }
//============================================================================ // 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() } }
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); } }
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; }
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; }