From 53c28a8ec9845a90f0c9e1ed83a87dbb7959d14d Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 25 Feb 2021 20:30:16 +0100 Subject: Codechange: [Network] replace _realtime_tick with std::chrono --- src/network/core/tcp_game.cpp | 5 +++-- src/network/core/tcp_game.h | 3 ++- src/network/network_admin.cpp | 8 ++++---- src/network/network_admin.h | 2 +- src/network/network_chat_gui.cpp | 6 +++--- src/network/network_client.cpp | 20 ++++++++------------ src/network/network_content.cpp | 10 +++++----- src/network/network_content.h | 4 ++-- src/network/network_server.cpp | 6 +++--- src/network/network_udp.cpp | 24 ++++++++---------------- 10 files changed, 39 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index e0835771e..06e56e229 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.cpp @@ -25,9 +25,10 @@ * @param s The socket to connect with. */ NetworkGameSocketHandler::NetworkGameSocketHandler(SOCKET s) : info(nullptr), client_id(INVALID_CLIENT_ID), - last_frame(_frame_counter), last_frame_server(_frame_counter), last_packet(_realtime_tick) + last_frame(_frame_counter), last_frame_server(_frame_counter) { this->sock = s; + this->last_packet = std::chrono::steady_clock::now(); } /** @@ -63,7 +64,7 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p) { PacketGameType type = (PacketGameType)p->Recv_uint8(); - this->last_packet = _realtime_tick; + this->last_packet = std::chrono::steady_clock::now(); switch (this->HasClientQuit() ? PACKET_END : type) { case PACKET_SERVER_FULL: return this->Receive_SERVER_FULL(p); diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index 9e3dcf197..95b5f8c6c 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -16,6 +16,7 @@ #include "tcp.h" #include "../network_type.h" #include "../../core/pool_type.hpp" +#include /** * Enum with all types of TCP packets. @@ -518,7 +519,7 @@ public: uint32 last_frame; ///< Last frame we have executed uint32 last_frame_server; ///< Last frame the server has executed CommandQueue incoming_queue; ///< The command-queue awaiting handling - uint last_packet; ///< Time we received the last frame. + std::chrono::steady_clock::time_point last_packet; ///< Time we received the last frame. NetworkRecvStatus CloseConnection(bool error = true) override; diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 20bd25f8f..aa2859ef8 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -37,7 +37,7 @@ NetworkAdminSocketPool _networkadminsocket_pool("NetworkAdminSocket"); INSTANTIATE_POOL_METHODS(NetworkAdminSocket) /** The timeout for authorisation of the client. */ -static const int ADMIN_AUTHORISATION_TIMEOUT = 10000; +static const std::chrono::seconds ADMIN_AUTHORISATION_TIMEOUT(10); /** Frequencies, which may be registered for a certain update type. */ @@ -64,7 +64,7 @@ ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : Net { _network_admins_connected++; this->status = ADMIN_STATUS_INACTIVE; - this->realtime_connect = _realtime_tick; + this->connect_time = std::chrono::steady_clock::now(); } /** @@ -95,8 +95,8 @@ ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler() /* static */ void ServerNetworkAdminSocketHandler::Send() { for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::Iterate()) { - if (as->status == ADMIN_STATUS_INACTIVE && as->realtime_connect + ADMIN_AUTHORISATION_TIMEOUT < _realtime_tick) { - DEBUG(net, 1, "[admin] Admin did not send its authorisation within %d seconds", ADMIN_AUTHORISATION_TIMEOUT / 1000); + if (as->status == ADMIN_STATUS_INACTIVE && std::chrono::steady_clock::now() > as->connect_time + ADMIN_AUTHORISATION_TIMEOUT) { + DEBUG(net, 1, "[admin] Admin did not send its authorisation within %d seconds", (uint32)std::chrono::duration_cast(ADMIN_AUTHORISATION_TIMEOUT).count()); as->CloseConnection(true); continue; } diff --git a/src/network/network_admin.h b/src/network/network_admin.h index 16bd57a4d..cf6cf6e7c 100644 --- a/src/network/network_admin.h +++ b/src/network/network_admin.h @@ -37,7 +37,7 @@ protected: NetworkRecvStatus SendPong(uint32 d1); public: AdminUpdateFrequency update_frequency[ADMIN_UPDATE_END]; ///< Admin requested update intervals. - uint32 realtime_connect; ///< Time of connection. + std::chrono::steady_clock::time_point connect_time; ///< Time of connection. NetworkAddress address; ///< Address of the admin. ServerNetworkAdminSocketHandler(SOCKET s); diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 83824e126..80a0b7869 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -40,7 +40,7 @@ static const uint NETWORK_CHAT_LINE_SPACING = 3; struct ChatMessage { char message[DRAW_STRING_BUFFER]; ///< The action message. TextColour colour; ///< The colour of the message. - uint32 remove_time; ///< The time to remove the message. + std::chrono::steady_clock::time_point remove_time; ///< The time to remove the message. }; /* used for chat window */ @@ -97,7 +97,7 @@ void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const char *m ChatMessage *cmsg = &_chatmsg_list[msg_count++]; strecpy(cmsg->message, buf, lastof(cmsg->message)); cmsg->colour = (colour & TC_IS_PALETTE_COLOUR) ? colour : TC_WHITE; - cmsg->remove_time = _realtime_tick + duration * 1000; + cmsg->remove_time = std::chrono::steady_clock::now() + std::chrono::seconds(duration); _chatmessage_dirty = true; } @@ -180,7 +180,7 @@ void NetworkChatMessageLoop() if (cmsg->message[0] == '\0') continue; /* Message has expired, remove from the list */ - if (cmsg->remove_time < _realtime_tick) { + if (std::chrono::steady_clock::now() > cmsg->remove_time) { /* Move the remaining messages over the current message */ if (i != MAX_CHAT_MESSAGES - 1) memmove(cmsg, cmsg + 1, sizeof(*cmsg) * (MAX_CHAT_MESSAGES - i - 1)); diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 7a7ec9f21..cd1904269 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -877,7 +877,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet bool load_success = SafeLoad({}, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf); /* Long savegame loads shouldn't affect the lag calculation! */ - this->last_packet = _realtime_tick; + this->last_packet = std::chrono::steady_clock::now(); if (!load_success) { DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); @@ -1178,27 +1178,23 @@ void ClientNetworkGameSocketHandler::CheckConnection() /* Only once we're authorized we can expect a steady stream of packets. */ if (this->status < STATUS_AUTHORIZED) return; - /* It might... sometimes occur that the realtime ticker overflows. */ - if (_realtime_tick < this->last_packet) this->last_packet = _realtime_tick; - - /* Lag is in milliseconds; 5 seconds are roughly twice the - * server's "you're slow" threshold (1 game day). */ - uint lag = (_realtime_tick - this->last_packet) / 1000; - if (lag < 5) return; + /* 5 seconds are roughly twice the server's "you're slow" threshold (1 game day). */ + std::chrono::steady_clock::duration lag = std::chrono::steady_clock::now() - this->last_packet; + if (lag < std::chrono::seconds(5)) return; /* 20 seconds are (way) more than 4 game days after which * the server will forcefully disconnect you. */ - if (lag > 20) { + if (lag > std::chrono::seconds(20)) { this->NetworkGameSocketHandler::CloseConnection(); return; } /* Prevent showing the lag message every tick; just update it when needed. */ - static uint last_lag = 0; - if (last_lag == lag) return; + static std::chrono::steady_clock::duration last_lag = {}; + if (std::chrono::duration_cast(last_lag) == std::chrono::duration_cast(lag)) return; last_lag = lag; - SetDParam(0, lag); + SetDParam(0, std::chrono::duration_cast(lag).count()); ShowErrorMessage(STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION, STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION, WL_INFO); } diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index 9ed6551c6..0220f890b 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -711,9 +711,9 @@ ClientNetworkContentSocketHandler::ClientNetworkContentSocketHandler() : http_response_index(-2), curFile(nullptr), curInfo(nullptr), - isConnecting(false), - lastActivity(_realtime_tick) + isConnecting(false) { + this->lastActivity = std::chrono::steady_clock::now(); } /** Clear up the mess ;) */ @@ -743,7 +743,7 @@ public: void OnConnect(SOCKET s) override { assert(_network_content_client.sock == INVALID_SOCKET); - _network_content_client.lastActivity = _realtime_tick; + _network_content_client.lastActivity = std::chrono::steady_clock::now(); _network_content_client.isConnecting = false; _network_content_client.sock = s; _network_content_client.Reopen(); @@ -780,7 +780,7 @@ void ClientNetworkContentSocketHandler::SendReceive() { if (this->sock == INVALID_SOCKET || this->isConnecting) return; - if (this->lastActivity + IDLE_TIMEOUT < _realtime_tick) { + if (std::chrono::steady_clock::now() > this->lastActivity + IDLE_TIMEOUT) { this->Close(); return; } @@ -788,7 +788,7 @@ void ClientNetworkContentSocketHandler::SendReceive() if (this->CanSendReceive()) { if (this->ReceivePackets()) { /* Only update activity once a packet is received, instead of every time we try it. */ - this->lastActivity = _realtime_tick; + this->lastActivity = std::chrono::steady_clock::now(); } } diff --git a/src/network/network_content.h b/src/network/network_content.h index fc33e72a1..f28821a0b 100644 --- a/src/network/network_content.h +++ b/src/network/network_content.h @@ -74,7 +74,7 @@ protected: FILE *curFile; ///< Currently downloaded file ContentInfo *curInfo; ///< Information about the currently downloaded file bool isConnecting; ///< Whether we're connecting - uint32 lastActivity; ///< The last time there was network activity + std::chrono::steady_clock::time_point lastActivity; ///< The last time there was network activity friend class NetworkContentConnecter; @@ -100,7 +100,7 @@ protected: void DownloadSelectedContentFallback(const ContentIDList &content); public: /** The idle timeout; when to close the connection because it's idle. */ - static const int IDLE_TIMEOUT = 60 * 1000; + static constexpr std::chrono::seconds IDLE_TIMEOUT = std::chrono::seconds(60); ClientNetworkContentSocketHandler(); ~ClientNetworkContentSocketHandler(); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index e03a60465..19e7d70dc 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1816,7 +1816,7 @@ void NetworkServer_Tick(bool send_frame) case NetworkClientSocket::STATUS_ACTIVE: if (lag > _settings_client.network.max_lag_time) { /* Client did still not report in within the specified limit. */ - IConsolePrintF(CC_ERROR, cs->last_packet + lag * MILLISECONDS_PER_TICK > _realtime_tick ? + IConsolePrintF(CC_ERROR, cs->last_packet + std::chrono::milliseconds(lag * MILLISECONDS_PER_TICK) > std::chrono::steady_clock::now() ? /* A packet was received in the last three game days, so the client is likely lagging behind. */ "Client #%d is dropped because the client's game state is more than %d ticks behind" : /* No packet was received in the last three game days; sounds like a lost connection. */ @@ -1827,11 +1827,11 @@ void NetworkServer_Tick(bool send_frame) } /* Report once per time we detect the lag, and only when we - * received a packet in the last 2000 milliseconds. If we + * received a packet in the last 2 seconds. If we * did not receive a packet, then the client is not just * slow, but the connection is likely severed. Mentioning * frame_freq is not useful in this case. */ - if (lag > (uint)DAY_TICKS && cs->lag_test == 0 && cs->last_packet + 2000 > _realtime_tick) { + if (lag > (uint)DAY_TICKS && cs->lag_test == 0 && cs->last_packet + std::chrono::seconds(2) > std::chrono::steady_clock::now()) { IConsolePrintF(CC_WARNING, "[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id); cs->lag_test = 1; } diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 771f51fbe..99939fab4 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -39,8 +39,8 @@ static std::mutex _network_udp_mutex; /** Session key to register ourselves to the master server */ static uint64 _session_key = 0; -static const uint32 ADVERTISE_NORMAL_INTERVAL = 15 * 60 * 1000; ///< interval between advertising in ms (15 minutes) -static const uint32 ADVERTISE_RETRY_INTERVAL = 10 * 1000; ///< re-advertise when no response after this many ms (10 seconds) +static const std::chrono::minutes ADVERTISE_NORMAL_INTERVAL(15); ///< interval between advertising. +static const std::chrono::seconds ADVERTISE_RETRY_INTERVAL(10); ///< re-advertise when no response after this amount of time. static const uint32 ADVERTISE_RETRY_TIMES = 3; ///< give up re-advertising after this much failed retries NetworkUDPSocketHandler *_udp_client_socket = nullptr; ///< udp client socket @@ -570,37 +570,29 @@ static void NetworkUDPAdvertiseThread() */ void NetworkUDPAdvertise() { - static uint32 _last_advertisement = 0; ///< The time of the last advertisement (used to check for wrapping of time) - static uint32 _next_advertisement = 0; ///< The next time we should perform a normal advertisement. - static uint32 _next_retry = 0; ///< The next time we should perform a retry of an advertisement. + static std::chrono::steady_clock::time_point _last_advertisement = {}; ///< The last time we performed an advertisement. /* Check if we should send an advertise */ if (!_networking || !_network_server || !_network_udp_server || !_settings_client.network.server_advertise) return; - if (_network_need_advertise || _realtime_tick < _last_advertisement) { - /* Forced advertisement, or a wrapping of time in which case we determine the advertisement/retry times again. */ + if (_network_need_advertise) { + /* Forced advertisement. */ _network_need_advertise = false; _network_advertise_retries = ADVERTISE_RETRY_TIMES; } else { /* Only send once every ADVERTISE_NORMAL_INTERVAL ticks */ if (_network_advertise_retries == 0) { - if (_realtime_tick <= _next_advertisement) return; + if (std::chrono::steady_clock::now() <= _last_advertisement + ADVERTISE_NORMAL_INTERVAL) return; _network_advertise_retries = ADVERTISE_RETRY_TIMES; } else { /* An actual retry. */ - if (_realtime_tick <= _next_retry) return; + if (std::chrono::steady_clock::now() <= _last_advertisement + ADVERTISE_RETRY_INTERVAL) return; } } _network_advertise_retries--; - _last_advertisement = _realtime_tick; - _next_advertisement = _realtime_tick + ADVERTISE_NORMAL_INTERVAL; - _next_retry = _realtime_tick + ADVERTISE_RETRY_INTERVAL; - - /* Make sure we do not have an overflow when checking these; when time wraps, we simply force an advertisement. */ - if (_next_advertisement < _last_advertisement) _next_advertisement = UINT32_MAX; - if (_next_retry < _last_advertisement) _next_retry = UINT32_MAX; + _last_advertisement = std::chrono::steady_clock::now(); if (!StartNewThread(nullptr, "ottd:udp-advert", &NetworkUDPAdvertiseThread)) { NetworkUDPAdvertiseThread(); -- cgit v1.2.3-54-g00ecf