From e1e2212e0e09c7739f2eb8a4421a9ed7982801f5 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 29 Apr 2021 16:30:42 +0200 Subject: Codechange: track version of network servers to prune once out-of-date --- src/network/network.cpp | 7 +++++-- src/network/network_gamelist.cpp | 31 ++++++++++++++++++++++++++++++- src/network/network_gamelist.h | 4 +++- src/network/network_internal.h | 2 +- src/network/network_udp.cpp | 2 ++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/network/network.cpp b/src/network/network.cpp index 930404872..c05634e00 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -699,9 +699,11 @@ void NetworkQueryLobbyServer(const std::string &connection_string) * the list. If you use this function, the games will be marked * as manually added. * @param connection_string The IP:port of the server to add. + * @param manually Whether the enter should be marked as manual added. + * @param never_expire Whether the entry can expire (removed when no longer found in the public listing). * @return The entry on the game list. */ -NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually) +NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually, bool never_expire) { if (connection_string.empty()) return nullptr; @@ -717,6 +719,7 @@ NetworkGameList *NetworkAddServer(const std::string &connection_string, bool man } if (manually) item->manually = true; + if (never_expire) item->version = INT32_MAX; return item; } @@ -1288,7 +1291,7 @@ extern "C" { void CDECL em_openttd_add_server(const char *connection_string) { - NetworkAddServer(connection_string, false); + NetworkAddServer(connection_string, false, true); } } diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index ae716070c..b4f34983f 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -20,7 +20,8 @@ #include "../safeguards.h" -NetworkGameList *_network_game_list = nullptr; +NetworkGameList *_network_game_list = nullptr; ///< Game list of this client. +int _network_game_list_version = 0; ///< Current version of all items in the list. /** The games to insert when the GUI thread has time for us. */ static std::atomic _network_game_delayed_insertion_list(nullptr); @@ -81,6 +82,7 @@ NetworkGameList *NetworkGameListAddItem(const std::string &connection_string) } item = new NetworkGameList(resolved_connection_string); + item->version = _network_game_list_version; if (prev_item == nullptr) { _network_game_list = item; @@ -120,6 +122,33 @@ void NetworkGameListRemoveItem(NetworkGameList *remove) } } +/** + * Remove all servers that have not recently been updated. + * Call this after you received all the servers from the Game Coordinator, so + * the ones that are no longer listed are removed. + */ +void NetworkGameListRemoveExpired() +{ + NetworkGameList **prev_item = &_network_game_list; + + for (NetworkGameList *item = _network_game_list; item != nullptr;) { + if (!item->manually && item->version < _network_game_list_version) { + NetworkGameList *remove = item; + item = item->next; + *prev_item = item; + + /* Remove GRFConfig information */ + ClearGRFConfigList(&remove->info.grfconfig); + delete remove; + } else { + prev_item = &item->next; + item = item->next; + } + } + + UpdateNetworkGameWindow(); +} + static const uint MAX_GAME_LIST_REQUERY_COUNT = 10; ///< How often do we requery in number of times per server? static const uint REQUERY_EVERY_X_GAMELOOPS = 60; ///< How often do we requery in time? static const uint REFRESH_GAMEINFO_X_REQUERIES = 50; ///< Refresh the game info itself after REFRESH_GAMEINFO_X_REQUERIES * REQUERY_EVERY_X_GAMELOOPS game loops diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h index 6ef9d8e41..2bab7626e 100644 --- a/src/network/network_gamelist.h +++ b/src/network/network_gamelist.h @@ -26,15 +26,17 @@ struct NetworkGameList { bool online = false; ///< False if the server did not respond (default status) bool manually = false; ///< True if the server was added manually uint8 retries = 0; ///< Number of retries (to stop requerying) + int version = 0; ///< Used to see which servers are no longer available on the Game Coordinator and can be removed. NetworkGameList *next = nullptr; ///< Next pointer to make a linked game list }; -/** Game list of this client */ extern NetworkGameList *_network_game_list; +extern int _network_game_list_version; void NetworkGameListAddItemDelayed(NetworkGameList *item); NetworkGameList *NetworkGameListAddItem(const std::string &connection_string); void NetworkGameListRemoveItem(NetworkGameList *remove); +void NetworkGameListRemoveExpired(); void NetworkGameListRequery(); #endif /* NETWORK_GAMELIST_H */ diff --git a/src/network/network_internal.h b/src/network/network_internal.h index b7e6f4ece..67e97bb07 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -91,7 +91,7 @@ void NetworkQueryServer(const std::string &connection_string); void NetworkQueryLobbyServer(const std::string &connection_string); void GetBindAddresses(NetworkAddressList *addresses, uint16 port); -struct NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually = true); +struct NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually = true, bool never_expire = false); void NetworkRebuildHostList(); void UpdateNetworkGameWindow(); diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 6ad84aa2e..5e5da27bb 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -327,6 +327,8 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd CheckGameCompatibility(item->info); /* Ensure we consider the server online. */ item->online = true; + /* Make sure this entry never expires. */ + item->version = INT32_MAX; { /* Checks whether there needs to be a request for names of GRFs and makes -- cgit v1.2.3-54-g00ecf