diff options
Diffstat (limited to 'src/server.cpp')
-rw-r--r-- | src/server.cpp | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/src/server.cpp b/src/server.cpp index 71a349b08..4b54c2398 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -90,6 +90,15 @@ void *ServerThread::run() DSTACK(FUNCTION_NAME); BEGIN_DEBUG_EXCEPTION_HANDLER + /* + * The real business of the server happens on the ServerThread. + * How this works: + * AsyncRunStep() runs an actual server step as soon as enough time has + * passed (dedicated_server_loop keeps track of that). + * Receive() blocks at least(!) 30ms waiting for a packet (so this loop + * doesn't busy wait) and will process any remaining packets. + */ + m_server->AsyncRunStep(true); while (!stopRequested()) { @@ -100,7 +109,6 @@ void *ServerThread::run() m_server->Receive(); - } catch (con::NoIncomingDataException &e) { } catch (con::PeerNotFoundException &e) { infostream<<"Server: PeerNotFoundException"<<std::endl; } catch (ClientNotFoundException &e) { @@ -1052,30 +1060,45 @@ void Server::Receive() DSTACK(FUNCTION_NAME); SharedBuffer<u8> data; u16 peer_id; - try { - NetworkPacket pkt; - m_con.Receive(&pkt); - peer_id = pkt.getPeerId(); - ProcessData(&pkt); - } - catch(con::InvalidIncomingDataException &e) { - infostream<<"Server::Receive(): " - "InvalidIncomingDataException: what()=" - <<e.what()<<std::endl; - } - catch(SerializationError &e) { - infostream<<"Server::Receive(): " - "SerializationError: what()=" - <<e.what()<<std::endl; - } - catch(ClientStateError &e) { - errorstream << "ProcessData: peer=" << peer_id << e.what() << std::endl; - DenyAccess_Legacy(peer_id, L"Your client sent something server didn't expect." - L"Try reconnecting or updating your client"); - } - catch(con::PeerNotFoundException &e) { - // Do nothing - } + bool first = true; + NetworkPacket pkt; + for (;;) { + pkt.clear(); + peer_id = 0; + try { + /* + In the first iteration *wait* for a packet, afterwards process + all packets that are immediately available (no waiting). + */ + if (first) { + m_con.Receive(&pkt); + first = false; + } else { + if (!m_con.TryReceive(&pkt)) + return; + } + + peer_id = pkt.getPeerId(); + ProcessData(&pkt); + + } catch (const con::InvalidIncomingDataException &e) { + infostream << "Server::Receive(): InvalidIncomingDataException: what()=" + << e.what() << std::endl; + } catch (const SerializationError &e) { + infostream << "Server::Receive(): SerializationError: what()=" + << e.what() << std::endl; + } catch (const ClientStateError &e) { + errorstream << "ProcessData: peer=" << peer_id << " what()=" + << e.what() << std::endl; + DenyAccess_Legacy(peer_id, L"Your client sent something server didn't expect." + L"Try reconnecting or updating your client"); + } catch (const con::PeerNotFoundException &e) { + // Do nothing + } catch (const con::NoIncomingDataException &e) { + return; + } + } + } PlayerSAO* Server::StageTwoClientInit(u16 peer_id) @@ -3682,6 +3705,11 @@ void dedicated_server_loop(Server &server, bool &kill) static const float profiler_print_interval = g_settings->getFloat("profiler_print_interval"); + /* + * The dedicated server loop only does time-keeping (in Server::step) and + * provides a way to main.cpp to kill the server externally (bool &kill). + */ + for(;;) { // This is kind of a hack but can be done like this // because server.step() is very light |