tron@2186: /* $Id$ */ tron@2186: celestar@6447: /** celestar@6447: * @file network_gamelist.cpp This file handles the GameList celestar@6447: * Also, it handles the request to a server for data about the server celestar@6447: */ celestar@6447: Darkvater@4826: #ifdef ENABLE_NETWORK Darkvater@4826: rubidium@5720: #include "../stdafx.h" rubidium@5720: #include "../debug.h" rubidium@5720: #include "../newgrf_config.h" rubidium@5838: #include "../helpers.hpp" rubidium@6168: #include "core/game.h" rubidium@6148: #include "network_udp.h" rubidium@6168: #include "network_gamelist.h" rubidium@6168: #include "network_gui.h" rubidium@6168: rubidium@6168: NetworkGameList *_network_game_list = NULL; rubidium@6148: rubidium@6148: /** Should we stop/contiue requerying of offline servers? */ rubidium@6148: static bool _stop_requerying = false; truelight@543: Darkvater@2885: /** Add a new item to the linked gamelist. If the IP and Port match Darkvater@2885: * return the existing item instead of adding it again Darkvater@2885: * @param ip the IP-address (inet_addr) of the to-be added item Darkvater@2885: * @param port the port the server is running on Darkvater@2885: * @return a point to the newly added or already existing item */ truelight@543: NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port) truelight@543: { Darkvater@2881: NetworkGameList *item, *prev_item; truelight@543: Darkvater@2881: prev_item = NULL; Darkvater@2881: for (item = _network_game_list; item != NULL; item = item->next) { Darkvater@2881: if (item->ip == ip && item->port == port) return item; Darkvater@2881: prev_item = item; truelight@543: } truelight@543: KUDr@5860: item = MallocT(1); truelight@543: memset(item, 0, sizeof(*item)); truelight@543: item->next = NULL; truelight@543: item->ip = ip; truelight@543: item->port = port; Darkvater@2881: tron@4077: if (prev_item == NULL) { tron@4077: _network_game_list = item; tron@4077: } else { tron@4077: prev_item->next = item; tron@4077: } Darkvater@5568: DEBUG(net, 4, "[gamelist] added server to list"); truelight@543: truelight@543: UpdateNetworkGameWindow(false); rubidium@6148: _stop_requerying = false; truelight@543: truelight@543: return item; truelight@543: } truelight@543: Darkvater@2885: /** Remove an item from the gamelist linked list Darkvater@2885: * @param remove pointer to the item to be removed */ dominik@738: void NetworkGameListRemoveItem(NetworkGameList *remove) dominik@738: { Darkvater@2881: NetworkGameList *item, *prev_item; dominik@738: Darkvater@2881: prev_item = NULL; Darkvater@2881: for (item = _network_game_list; item != NULL; item = item->next) { Darkvater@2881: if (remove == item) { tron@4077: if (prev_item == NULL) { tron@4077: _network_game_list = remove->next; tron@4077: } else { tron@4077: prev_item->next = remove->next; tron@4077: } dominik@738: rubidium@5339: /* Remove GRFConfig information */ Darkvater@5347: ClearGRFConfigList(&remove->info.grfconfig); Darkvater@5347: free(remove); Darkvater@5347: remove = NULL; rubidium@5339: Darkvater@5568: DEBUG(net, 4, "[gamelist] removed server from list"); Darkvater@2881: UpdateNetworkGameWindow(false); dominik@738: return; dominik@738: } Darkvater@2881: prev_item = item; dominik@738: } dominik@738: } dominik@738: rubidium@6148: enum { rubidium@6148: MAX_GAME_LIST_REQUERY_COUNT = 5, rubidium@6166: REQUERY_EVERY_X_GAMELOOPS = 60, rubidium@6148: }; rubidium@6148: rubidium@6148: /** Requeries the (game) servers we have not gotten a reply from */ celestar@9895: void NetworkGameListRequery() rubidium@6148: { rubidium@6148: static uint8 requery_cnt = 0; rubidium@6148: rubidium@6148: if (_stop_requerying || ++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return; rubidium@6148: rubidium@6148: requery_cnt = 0; rubidium@6148: _stop_requerying = true; rubidium@6148: rubidium@6148: struct in_addr ip; rubidium@6148: NetworkGameList *item; rubidium@6148: rubidium@6148: for (item = _network_game_list; item != NULL; item = item->next) { rubidium@6148: if (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT) continue; rubidium@6148: rubidium@6148: ip.s_addr = item->ip; rubidium@6148: rubidium@6148: /* item gets mostly zeroed by NetworkUDPQueryServer */ rubidium@6148: uint8 retries = item->retries; rubidium@6148: NetworkUDPQueryServer(inet_ntoa(ip), item->port); rubidium@6148: item->retries = retries + 1; rubidium@6148: rubidium@6148: _stop_requerying = false; rubidium@6148: } rubidium@6148: rubidium@6148: } rubidium@6148: truelight@543: #endif /* ENABLE_NETWORK */