network_gamelist.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #ifdef ENABLE_NETWORK
00016
00017 #include "../stdafx.h"
00018 #include "../debug.h"
00019 #include "../thread/thread.h"
00020 #include "network_internal.h"
00021 #include "network_udp.h"
00022 #include "network_gamelist.h"
00023 #include "../newgrf_text.h"
00024
00025 NetworkGameList *_network_game_list = NULL;
00026
00027 static ThreadMutex *_network_game_list_mutex = ThreadMutex::New();
00028 static NetworkGameList *_network_game_delayed_insertion_list = NULL;
00029
00035 void NetworkGameListAddItemDelayed(NetworkGameList *item)
00036 {
00037 _network_game_list_mutex->BeginCritical();
00038 item->next = _network_game_delayed_insertion_list;
00039 _network_game_delayed_insertion_list = item;
00040 _network_game_list_mutex->EndCritical();
00041 }
00042
00044 static void NetworkGameListHandleDelayedInsert()
00045 {
00046 _network_game_list_mutex->BeginCritical();
00047 while (_network_game_delayed_insertion_list != NULL) {
00048 NetworkGameList *ins_item = _network_game_delayed_insertion_list;
00049 _network_game_delayed_insertion_list = ins_item->next;
00050
00051 NetworkGameList *item = NetworkGameListAddItem(ins_item->address);
00052
00053 if (item != NULL) {
00054 if (StrEmpty(item->info.server_name)) {
00055 ClearGRFConfigList(&item->info.grfconfig);
00056 memset(&item->info, 0, sizeof(item->info));
00057 strecpy(item->info.server_name, ins_item->info.server_name, lastof(item->info.server_name));
00058 strecpy(item->info.hostname, ins_item->info.hostname, lastof(item->info.hostname));
00059 item->online = false;
00060 }
00061 item->manually |= ins_item->manually;
00062 if (item->manually) NetworkRebuildHostList();
00063 UpdateNetworkGameWindow(false);
00064 }
00065 free(ins_item);
00066 }
00067 _network_game_list_mutex->EndCritical();
00068 }
00069
00077 NetworkGameList *NetworkGameListAddItem(NetworkAddress address)
00078 {
00079 const char *hostname = address.GetHostname();
00080
00081
00082 if (StrEmpty(hostname) ||
00083 strcmp(hostname, "0.0.0.0") == 0 ||
00084 strcmp(hostname, "::") == 0) {
00085 return NULL;
00086 }
00087
00088 NetworkGameList *item, *prev_item;
00089
00090 prev_item = NULL;
00091 for (item = _network_game_list; item != NULL; item = item->next) {
00092 if (item->address == address) return item;
00093 prev_item = item;
00094 }
00095
00096 item = CallocT<NetworkGameList>(1);
00097 item->next = NULL;
00098 item->address = address;
00099
00100 if (prev_item == NULL) {
00101 _network_game_list = item;
00102 } else {
00103 prev_item->next = item;
00104 }
00105 DEBUG(net, 4, "[gamelist] added server to list");
00106
00107 UpdateNetworkGameWindow(false);
00108
00109 return item;
00110 }
00111
00116 void NetworkGameListRemoveItem(NetworkGameList *remove)
00117 {
00118 NetworkGameList *prev_item = NULL;
00119 for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
00120 if (remove == item) {
00121 if (prev_item == NULL) {
00122 _network_game_list = remove->next;
00123 } else {
00124 prev_item->next = remove->next;
00125 }
00126
00127
00128 ClearGRFConfigList(&remove->info.grfconfig);
00129 free(remove);
00130 remove = NULL;
00131
00132 DEBUG(net, 4, "[gamelist] removed server from list");
00133 NetworkRebuildHostList();
00134 UpdateNetworkGameWindow(false);
00135 return;
00136 }
00137 prev_item = item;
00138 }
00139 }
00140
00141 static const uint MAX_GAME_LIST_REQUERY_COUNT = 10;
00142 static const uint REQUERY_EVERY_X_GAMELOOPS = 60;
00143 static const uint REFRESH_GAMEINFO_X_REQUERIES = 50;
00144
00146 void NetworkGameListRequery()
00147 {
00148 NetworkGameListHandleDelayedInsert();
00149
00150 static uint8 requery_cnt = 0;
00151
00152 if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return;
00153 requery_cnt = 0;
00154
00155 for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
00156 item->retries++;
00157 if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue;
00158
00159
00160 uint8 retries = item->retries;
00161 NetworkUDPQueryServer(NetworkAddress(item->address));
00162 item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
00163 }
00164 }
00165
00170 void NetworkAfterNewGRFScan()
00171 {
00172 for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
00173
00174 item->info.compatible = item->info.version_compatible;
00175
00176 for (GRFConfig *c = item->info.grfconfig; c != NULL; c = c->next) {
00177 assert(HasBit(c->flags, GCF_COPY));
00178
00179 const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum);
00180 if (f == NULL) {
00181
00182
00183
00184 AddGRFTextToList(&c->name, FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true));
00185 c->status = GCS_NOT_FOUND;
00186
00187
00188 item->info.compatible = false;
00189 } else {
00190 c->filename = f->filename;
00191 CleanUpGRFText(c->name);
00192 c->name = DuplicateGRFText(f->name);
00193 c->info = f->info;
00194 c->status = GCS_UNKNOWN;
00195 }
00196 }
00197 }
00198 }
00199
00200 #endif