Fix #10490: Allow ships to exit depots if another is not moving at the exit point...
[openttd-github.git] / src / network / network_gamelist.cpp
blob3df2021830c2172dee6261f6b3dfb234c1677573
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
8 /**
9 * @file network_gamelist.cpp This file handles the GameList
10 * Also, it handles the request to a server for data about the server
13 #include "../stdafx.h"
14 #include "../debug.h"
15 #include "../window_func.h"
16 #include "network_internal.h"
17 #include "network_udp.h"
18 #include "network_gamelist.h"
19 #include <atomic>
21 #include "../safeguards.h"
23 NetworkGameList *_network_game_list = nullptr; ///< Game list of this client.
24 int _network_game_list_version = 0; ///< Current version of all items in the list.
26 /**
27 * Add a new item to the linked gamelist. If the IP and Port match
28 * return the existing item instead of adding it again
29 * @param connection_string the address of the to-be added item
30 * @return a point to the newly added or already existing item
32 NetworkGameList *NetworkGameListAddItem(const std::string &connection_string)
34 NetworkGameList *item, *prev_item;
36 /* Parse the connection string to ensure the default port is there. */
37 const std::string resolved_connection_string = ServerAddress::Parse(connection_string, NETWORK_DEFAULT_PORT).connection_string;
39 prev_item = nullptr;
40 for (item = _network_game_list; item != nullptr; item = item->next) {
41 if (item->connection_string == resolved_connection_string) return item;
42 prev_item = item;
45 item = new NetworkGameList(resolved_connection_string);
46 item->info.gamescript_version = -1;
47 item->version = _network_game_list_version;
49 if (prev_item == nullptr) {
50 _network_game_list = item;
51 } else {
52 prev_item->next = item;
55 UpdateNetworkGameWindow();
57 return item;
60 /**
61 * Remove an item from the gamelist linked list
62 * @param remove pointer to the item to be removed
64 void NetworkGameListRemoveItem(NetworkGameList *remove)
66 NetworkGameList *prev_item = nullptr;
67 for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
68 if (remove == item) {
69 if (prev_item == nullptr) {
70 _network_game_list = remove->next;
71 } else {
72 prev_item->next = remove->next;
75 /* Remove GRFConfig information */
76 ClearGRFConfigList(&remove->info.grfconfig);
77 delete remove;
79 NetworkRebuildHostList();
80 UpdateNetworkGameWindow();
81 return;
83 prev_item = item;
87 /**
88 * Remove all servers that have not recently been updated.
89 * Call this after you received all the servers from the Game Coordinator, so
90 * the ones that are no longer listed are removed.
92 void NetworkGameListRemoveExpired()
94 NetworkGameList **prev_item = &_network_game_list;
96 for (NetworkGameList *item = _network_game_list; item != nullptr;) {
97 if (!item->manually && item->version < _network_game_list_version) {
98 NetworkGameList *remove = item;
99 item = item->next;
100 *prev_item = item;
102 /* Remove GRFConfig information */
103 ClearGRFConfigList(&remove->info.grfconfig);
104 delete remove;
105 } else {
106 prev_item = &item->next;
107 item = item->next;
111 UpdateNetworkGameWindow();
115 * Rebuild the GRFConfig's of the servers in the game list as we did
116 * a rescan and might have found new NewGRFs.
118 void NetworkAfterNewGRFScan()
120 for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
121 /* Reset compatibility state */
122 item->info.compatible = item->info.version_compatible;
124 for (GRFConfig *c = item->info.grfconfig; c != nullptr; c = c->next) {
125 assert(HasBit(c->flags, GCF_COPY));
127 const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, &c->ident.md5sum);
128 if (f == nullptr) {
129 /* Don't know the GRF (anymore), so mark game incompatible. */
130 c->status = GCS_NOT_FOUND;
132 /* If we miss a file, we're obviously incompatible. */
133 item->info.compatible = false;
134 } else {
135 c->filename = f->filename;
136 c->name = f->name;
137 c->info = f->info;
138 c->status = GCS_UNKNOWN;
143 InvalidateWindowClassesData(WC_NETWORK_WINDOW);