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
00024 NetworkGameList *_network_game_list = NULL;
00025
00026 static ThreadMutex *_network_game_list_mutex = ThreadMutex::New();
00027 static NetworkGameList *_network_game_delayed_insertion_list = NULL;
00028
00033 void NetworkGameListAddItemDelayed(NetworkGameList *item)
00034 {
00035 _network_game_list_mutex->BeginCritical();
00036 item->next = _network_game_delayed_insertion_list;
00037 _network_game_delayed_insertion_list = item;
00038 _network_game_list_mutex->EndCritical();
00039 }
00040
00042 static void NetworkGameListHandleDelayedInsert()
00043 {
00044 _network_game_list_mutex->BeginCritical();
00045 while (_network_game_delayed_insertion_list != NULL) {
00046 NetworkGameList *ins_item = _network_game_delayed_insertion_list;
00047 _network_game_delayed_insertion_list = ins_item->next;
00048
00049 NetworkGameList *item = NetworkGameListAddItem(ins_item->address);
00050
00051 if (item != NULL) {
00052 ClearGRFConfigList(&item->info.grfconfig);
00053 if (StrEmpty(item->info.server_name)) {
00054 memset(&item->info, 0, sizeof(item->info));
00055 strecpy(item->info.server_name, ins_item->info.server_name, lastof(item->info.server_name));
00056 strecpy(item->info.hostname, ins_item->info.hostname, lastof(item->info.hostname));
00057 item->online = false;
00058 }
00059 item->manually |= ins_item->manually;
00060 if (item->manually) NetworkRebuildHostList();
00061 UpdateNetworkGameWindow(false);
00062 }
00063 free(ins_item);
00064 }
00065 _network_game_list_mutex->EndCritical();
00066 }
00067
00073 NetworkGameList *NetworkGameListAddItem(NetworkAddress address)
00074 {
00075 const char *hostname = address.GetHostname();
00076
00077
00078 if (StrEmpty(hostname) ||
00079 strcmp(hostname, "0.0.0.0") == 0 ||
00080 strcmp(hostname, "::") == 0) {
00081 return NULL;
00082 }
00083
00084 NetworkGameList *item, *prev_item;
00085
00086 prev_item = NULL;
00087 for (item = _network_game_list; item != NULL; item = item->next) {
00088 if (item->address == address) return item;
00089 prev_item = item;
00090 }
00091
00092 item = CallocT<NetworkGameList>(1);
00093 item->next = NULL;
00094 item->address = address;
00095
00096 if (prev_item == NULL) {
00097 _network_game_list = item;
00098 } else {
00099 prev_item->next = item;
00100 }
00101 DEBUG(net, 4, "[gamelist] added server to list");
00102
00103 UpdateNetworkGameWindow(false);
00104
00105 return item;
00106 }
00107
00110 void NetworkGameListRemoveItem(NetworkGameList *remove)
00111 {
00112 NetworkGameList *prev_item = NULL;
00113 for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
00114 if (remove == item) {
00115 if (prev_item == NULL) {
00116 _network_game_list = remove->next;
00117 } else {
00118 prev_item->next = remove->next;
00119 }
00120
00121
00122 ClearGRFConfigList(&remove->info.grfconfig);
00123 free(remove);
00124 remove = NULL;
00125
00126 DEBUG(net, 4, "[gamelist] removed server from list");
00127 NetworkRebuildHostList();
00128 UpdateNetworkGameWindow(false);
00129 return;
00130 }
00131 prev_item = item;
00132 }
00133 }
00134
00135 enum {
00136 MAX_GAME_LIST_REQUERY_COUNT = 10,
00137 REQUERY_EVERY_X_GAMELOOPS = 60,
00138 REFRESH_GAMEINFO_X_REQUERIES = 50,
00139 };
00140
00142 void NetworkGameListRequery()
00143 {
00144 NetworkGameListHandleDelayedInsert();
00145
00146 static uint8 requery_cnt = 0;
00147
00148 if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return;
00149 requery_cnt = 0;
00150
00151 for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
00152 item->retries++;
00153 if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue;
00154
00155
00156 uint8 retries = item->retries;
00157 NetworkUDPQueryServer(NetworkAddress(item->address));
00158 item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
00159 }
00160 }
00161
00166 void NetworkAfterNewGRFScan()
00167 {
00168 for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
00169
00170 item->info.compatible = item->info.version_compatible;
00171
00172 for (GRFConfig *c = item->info.grfconfig; c != NULL; c = c->next) {
00173 assert(HasBit(c->flags, GCF_COPY));
00174
00175 const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum);
00176 if (f == NULL) {
00177
00178
00179
00180 c->name = FindUnknownGRFName(c->grfid, c->md5sum, true);
00181 c->status = GCS_NOT_FOUND;
00182
00183
00184 item->info.compatible = false;
00185 } else {
00186 c->filename = f->filename;
00187 c->name = f->name;
00188 c->info = f->info;
00189 c->status = GCS_UNKNOWN;
00190 }
00191 }
00192 }
00193 }
00194
00195 #endif