tron@2186: /* $Id$ */ tron@2186: celestar@6121: /** celestar@6121: * @file network_gamelist.cpp This file handles the GameList celestar@6121: * Also, it handles the request to a server for data about the server celestar@6121: */ celestar@6121: Darkvater@4826: #ifdef ENABLE_NETWORK Darkvater@4826: rubidium@5469: #include "../stdafx.h" rubidium@5469: #include "../debug.h" rubidium@5469: #include "../newgrf_config.h" rubidium@5587: #include "../helpers.hpp" rubidium@5917: #include "core/game.h" rubidium@5897: #include "network_udp.h" rubidium@5917: #include "network_gamelist.h" rubidium@5917: #include "network_gui.h" rubidium@5917: rubidium@5917: NetworkGameList *_network_game_list = NULL; rubidium@5897: 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@5609: 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@5380: DEBUG(net, 4, "[gamelist] added server to list"); truelight@543: truelight@543: UpdateNetworkGameWindow(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@5380: 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@5897: enum { rubidium@7331: MAX_GAME_LIST_REQUERY_COUNT = 5, ///< How often do we requery in number of times per server? rubidium@7331: REQUERY_EVERY_X_GAMELOOPS = 60, ///< How often do we requery in time? rubidium@7331: REFRESH_GAMEINFO_X_REQUERIES = 50, ///< Refresh the game info itself after REFRESH_GAMEINFO_X_REQUERIES * REQUERY_EVERY_X_GAMELOOPS game loops rubidium@5897: }; rubidium@5897: rubidium@5897: /** Requeries the (game) servers we have not gotten a reply from */ rubidium@6247: void NetworkGameListRequery() rubidium@5897: { rubidium@5897: static uint8 requery_cnt = 0; rubidium@5897: rubidium@7331: if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return; rubidium@5897: requery_cnt = 0; rubidium@5897: rubidium@5897: struct in_addr ip; rubidium@5897: NetworkGameList *item; rubidium@5897: rubidium@5897: for (item = _network_game_list; item != NULL; item = item->next) { rubidium@7331: item->retries++; rubidium@7331: if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue; rubidium@5897: rubidium@5897: ip.s_addr = item->ip; rubidium@5897: rubidium@5897: /* item gets mostly zeroed by NetworkUDPQueryServer */ rubidium@5897: uint8 retries = item->retries; rubidium@5897: NetworkUDPQueryServer(inet_ntoa(ip), item->port); rubidium@7331: item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries; rubidium@5897: } rubidium@5897: } rubidium@5897: truelight@543: #endif /* ENABLE_NETWORK */