mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: [Network] replace _realtime_tick with std::chrono
This commit is contained in:
parent
dc7ba33b51
commit
53c28a8ec9
|
@ -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);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "tcp.h"
|
||||
#include "../network_type.h"
|
||||
#include "../../core/pool_type.hpp"
|
||||
#include <chrono>
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
|
|
|
@ -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<std::chrono::seconds>(ADMIN_AUTHORISATION_TIMEOUT).count());
|
||||
as->CloseConnection(true);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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<std::chrono::seconds>(last_lag) == std::chrono::duration_cast<std::chrono::seconds>(lag)) return;
|
||||
|
||||
last_lag = lag;
|
||||
SetDParam(0, lag);
|
||||
SetDParam(0, std::chrono::duration_cast<std::chrono::seconds>(lag).count());
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION, STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION, WL_INFO);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue