Files
@ r25395:65af9d4639ed
Branch filter:
Location: cpp/openttd-patchpack/source/src/network/network_gamelist.cpp - annotation
r25395:65af9d4639ed
6.2 KiB
text/x-c
Codechange: add DrawString(Multiline) that accepts std::string&
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r6121:a8ff6abe7fb2 r6121:a8ff6abe7fb2 r6121:a8ff6abe7fb2 r6121:a8ff6abe7fb2 r6121:a8ff6abe7fb2 r5584:545d748cc681 r5584:545d748cc681 r17279:76addfee8711 r9428:6800206a6c0d r5897:753985117bdb r5917:d8ebeb21f83f r23588:660d91a03749 r5917:d8ebeb21f83f r21383:942c32fb8b0e r21383:942c32fb8b0e r23607:36c15679007d r5897:753985117bdb r17629:21e9dfd343cd r23607:36c15679007d r10824:4036289a0b3d r15610:623a23fb6560 r15610:623a23fb6560 r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r23588:660d91a03749 r23588:660d91a03749 r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r23588:660d91a03749 r23588:660d91a03749 r23607:36c15679007d r23607:36c15679007d r10824:4036289a0b3d r25388:32b23efdcf4e r10824:4036289a0b3d r23607:36c15679007d r10824:4036289a0b3d r14186:5477bcdd03f5 r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r11560:52827dc8eb76 r12533:86f2de494688 r19182:8f0b5a1acb1c r10824:4036289a0b3d r25390:7b2cc712ea32 r10824:4036289a0b3d r10824:4036289a0b3d r10824:4036289a0b3d r15610:623a23fb6560 r15610:623a23fb6560 r5584:545d748cc681 r11555:622725a26a6d r15613:193c12018337 r15613:193c12018337 r25388:32b23efdcf4e r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r25388:32b23efdcf4e r25388:32b23efdcf4e r25388:32b23efdcf4e r23607:36c15679007d r23607:36c15679007d r25388:32b23efdcf4e r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r25390:7b2cc712ea32 r5584:545d748cc681 r23607:36c15679007d r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r19182:8f0b5a1acb1c r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r15610:623a23fb6560 r15610:623a23fb6560 r15613:193c12018337 r15613:193c12018337 r5584:545d748cc681 r5584:545d748cc681 r23607:36c15679007d r23607:36c15679007d r5584:545d748cc681 r23607:36c15679007d r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r25390:7b2cc712ea32 r5584:545d748cc681 r5584:545d748cc681 r12533:86f2de494688 r19182:8f0b5a1acb1c r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r5584:545d748cc681 r15175:66e0817dc450 r15175:66e0817dc450 r15175:66e0817dc450 r5897:753985117bdb r5897:753985117bdb r6247:96e840dbefcc r5897:753985117bdb r10824:4036289a0b3d r10824:4036289a0b3d r5897:753985117bdb r5897:753985117bdb r7331:9df263aec9d0 r5897:753985117bdb r5897:753985117bdb r23607:36c15679007d r7331:9df263aec9d0 r7331:9df263aec9d0 r5897:753985117bdb r5897:753985117bdb r5897:753985117bdb r25388:32b23efdcf4e r7331:9df263aec9d0 r5897:753985117bdb r5897:753985117bdb r5897:753985117bdb r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r23607:36c15679007d r19821:021f5f9159cc r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r23607:36c15679007d r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r16246:b0e8840a555e r23607:36c15679007d r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r19821:021f5f9159cc r17403:bbaee031fd60 r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r19821:021f5f9159cc r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r17403:bbaee031fd60 r17403:bbaee031fd60 r17403:bbaee031fd60 r17403:bbaee031fd60 r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r13054:319ef5c8a6c7 r17279:76addfee8711 r17279:76addfee8711 r13054:319ef5c8a6c7 | /*
* This file is part of OpenTTD.
* 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.
* 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.
* 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/>.
*/
/**
* @file network_gamelist.cpp This file handles the GameList
* Also, it handles the request to a server for data about the server
*/
#include "../stdafx.h"
#include "../debug.h"
#include "../window_func.h"
#include "network_internal.h"
#include "network_udp.h"
#include "network_gamelist.h"
#include <atomic>
#include "../safeguards.h"
NetworkGameList *_network_game_list = nullptr;
/** The games to insert when the GUI thread has time for us. */
static std::atomic<NetworkGameList *> _network_game_delayed_insertion_list(nullptr);
/**
* Add a new item to the linked gamelist, but do it delayed in the next tick
* or so to prevent race conditions.
* @param item the item to add. Will be freed once added.
*/
void NetworkGameListAddItemDelayed(NetworkGameList *item)
{
item->next = _network_game_delayed_insertion_list.load(std::memory_order_relaxed);
while (!_network_game_delayed_insertion_list.compare_exchange_weak(item->next, item, std::memory_order_acq_rel)) {}
}
/** Perform the delayed (thread safe) insertion into the game list */
static void NetworkGameListHandleDelayedInsert()
{
while (true) {
NetworkGameList *ins_item = _network_game_delayed_insertion_list.load(std::memory_order_relaxed);
while (ins_item != nullptr && !_network_game_delayed_insertion_list.compare_exchange_weak(ins_item, ins_item->next, std::memory_order_acq_rel)) {}
if (ins_item == nullptr) break; // No item left.
NetworkGameList *item = NetworkGameListAddItem(ins_item->connection_string);
if (item != nullptr) {
if (StrEmpty(item->info.server_name)) {
ClearGRFConfigList(&item->info.grfconfig);
memset(&item->info, 0, sizeof(item->info));
strecpy(item->info.server_name, ins_item->info.server_name, lastof(item->info.server_name));
item->online = false;
}
item->manually |= ins_item->manually;
if (item->manually) NetworkRebuildHostList();
UpdateNetworkGameWindow();
}
delete ins_item;
}
}
/**
* Add a new item to the linked gamelist. If the IP and Port match
* return the existing item instead of adding it again
* @param address the address of the to-be added item
* @return a point to the newly added or already existing item
*/
NetworkGameList *NetworkGameListAddItem(const std::string &connection_string)
{
NetworkGameList *item, *prev_item;
/* Parse the connection string to ensure the default port is there. */
const std::string resolved_connection_string = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false);
prev_item = nullptr;
for (item = _network_game_list; item != nullptr; item = item->next) {
if (item->connection_string == resolved_connection_string) return item;
prev_item = item;
}
item = new NetworkGameList(resolved_connection_string);
if (prev_item == nullptr) {
_network_game_list = item;
} else {
prev_item->next = item;
}
UpdateNetworkGameWindow();
return item;
}
/**
* Remove an item from the gamelist linked list
* @param remove pointer to the item to be removed
*/
void NetworkGameListRemoveItem(NetworkGameList *remove)
{
NetworkGameList *prev_item = nullptr;
for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
if (remove == item) {
if (prev_item == nullptr) {
_network_game_list = remove->next;
} else {
prev_item->next = remove->next;
}
/* Remove GRFConfig information */
ClearGRFConfigList(&remove->info.grfconfig);
delete remove;
DEBUG(net, 4, "[gamelist] removed server from list");
NetworkRebuildHostList();
UpdateNetworkGameWindow();
return;
}
prev_item = item;
}
}
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
/** Requeries the (game) servers we have not gotten a reply from */
void NetworkGameListRequery()
{
NetworkGameListHandleDelayedInsert();
static uint8 requery_cnt = 0;
if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return;
requery_cnt = 0;
for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
item->retries++;
if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue;
/* item gets mostly zeroed by NetworkUDPQueryServer */
uint8 retries = item->retries;
NetworkUDPQueryServer(item->connection_string);
item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
}
}
/**
* Rebuild the GRFConfig's of the servers in the game list as we did
* a rescan and might have found new NewGRFs.
*/
void NetworkAfterNewGRFScan()
{
for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
/* Reset compatibility state */
item->info.compatible = item->info.version_compatible;
for (GRFConfig *c = item->info.grfconfig; c != nullptr; c = c->next) {
assert(HasBit(c->flags, GCF_COPY));
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum);
if (f == nullptr) {
/* Don't know the GRF, so mark game incompatible and the (possibly)
* already resolved name for this GRF (another server has sent the
* name of the GRF already. */
c->name = FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true);
c->status = GCS_NOT_FOUND;
/* If we miss a file, we're obviously incompatible. */
item->info.compatible = false;
} else {
c->filename = f->filename;
c->name = f->name;
c->info = f->info;
c->status = GCS_UNKNOWN;
}
}
}
InvalidateWindowClassesData(WC_NETWORK_WINDOW);
}
|