void Server::broadcastFaultyData(const char* data, unsigned int size) { packetNumber++; // lose messages every so often if (randf() * 100 < m_packetlossPercentage) return; // delay messages every so often if (randf() * 100 < m_delayPercentage) { DelayedBroadcast* b = new DelayedBroadcast; b->stream.Write((RakNet::MessageID)GameMessages::ID_ENTITY_LIST); b->stream.Write(size); b->stream.Write(packetNumber); b->stream.Write(data, size); float delay = randf() * m_delayRange; b->delayMicroseconds = (double)(delay * 1000.0 * 1000.0); m_delayedMessages.push_back(b); } else { // just send the stream RakNet::BitStream stream; stream.Write((RakNet::MessageID)GameMessages::ID_ENTITY_LIST); stream.Write(size); stream.Write(packetNumber); stream.Write(data, size); sendBitStream(&stream); } }
void Server::run() { // startup the server, and start it listening to clients std::cout << "Starting up the server..." << std::endl; std::cout << "Press ESCAPE to close the server..." << std::endl; // create a socket descriptor to describe this connection RakNet::SocketDescriptor sd(SERVER_PORT, 0); // now call startup - max of 1024 connections, on the assigned port m_peerInterface->Startup(1024, &sd, 1); m_peerInterface->SetMaximumIncomingConnections(1024); std::cout << "Server IP: " << m_peerInterface->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString() << std::endl << std::endl; RakNet::Packet* packet = nullptr; auto previousTime = std::chrono::high_resolution_clock::now(); double microsecondCounter = 0; while (true) { // update entities at 60fps auto time = std::chrono::high_resolution_clock::now(); double deltaMicroseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(time - previousTime).count() / 1000.0f; microsecondCounter += deltaMicroseconds; // if 16666 microseconds have passed then update and broadcast entities while (microsecondCounter > 16666) { updateAIEntities(0.016666667f); microsecondCounter -= 16666; } previousTime = time; // remove any finished delayed threads for (auto iter = m_delayedMessages.begin(); iter != m_delayedMessages.end(); ) { (*iter)->delayMicroseconds -= deltaMicroseconds; if ((*iter)->delayMicroseconds <= 0) { sendBitStream(&(*iter)->stream); delete (*iter); iter = m_delayedMessages.erase(iter); } else ++iter; } // handle received messages for ( packet = m_peerInterface->Receive(); packet; m_peerInterface->DeallocatePacket(packet), packet = m_peerInterface->Receive()) { switch (packet->data[0]) { case ID_NEW_INCOMING_CONNECTION: { std::cout << "A connection is incoming.\n"; break; } case ID_DISCONNECTION_NOTIFICATION: std::cout << "A client has disconnected.\n"; break; case ID_CONNECTION_LOST: std::cout << "A client lost the connection.\n"; break; default: std::cout << "Received a message with a unknown id: " << packet->data[0]; break; } } if (GetAsyncKeyState(VK_ESCAPE)) break; } }
void NetworkServer::rawSend(const BitStream& bs, const NetworkPacket& packet, const User& user) { assert(isConnected()); sendBitStream(*_peer, bs, packet.params(), user.address()); }