diff --git a/functions.h b/functions.h index 54595290d6..03b5a95307 100644 --- a/functions.h +++ b/functions.h @@ -160,7 +160,6 @@ void NetworkGameLoop(void); void NetworkUDPGameLoop(void); bool NetworkServerStart(void); bool NetworkClientConnectGame(const byte* host, unsigned short port); -void NetworkQueryServer(const byte* host, unsigned short port, bool game_info); void NetworkReboot(); void NetworkDisconnect(); void NetworkSend_Command(uint32 tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback); diff --git a/network.c b/network.c index 35061f7b59..5f885892ac 100644 --- a/network.c +++ b/network.c @@ -774,24 +774,23 @@ static void NetworkInitialize(void) NetworkUDPInitialize(); // add all servers from the config file to our list - for (i=0; i != lengthof(_network_server_list); i++) { - if (_network_server_list[i] == NULL) break; - NetworkAddServer(_network_server_list[i]); + for (i=0; i != lengthof(_network_host_list); i++) { + if (_network_host_list[i] == NULL) break; + NetworkAddServer(_network_host_list[i]); } } // Query a server to fetch his game-info // If game_info is true, only the gameinfo is fetched, // else only the client_info is fetched -void NetworkQueryServer(const byte* host, unsigned short port, bool game_info) +NetworkGameList *NetworkQueryServer(const byte* host, unsigned short port, bool game_info) { - if (!_network_available) return; + if (!_network_available) return NULL; NetworkDisconnect(); if (game_info) { - NetworkUDPQueryServer(host, port); - return; + return NetworkUDPQueryServer(host, port); } NetworkInitialize(); @@ -807,18 +806,22 @@ void NetworkQueryServer(const byte* host, unsigned short port, bool game_info) // We are connected if (_networking) { SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)(); - return; + return NULL; } // No networking, close everything down again NetworkDisconnect(); + return NULL; } -// validates an address entered as a string and adds the server to -// the list +/* Validates an address entered as a string and adds the server to + * the list. If you use this functions, the games will be marked + * as manually added. */ void NetworkAddServer(const byte *b) { if (*b != '\0') { + NetworkGameList *item; + uint i; const byte *port = NULL; const byte *player = NULL; byte host[NETWORK_HOSTNAME_LENGTH]; @@ -834,7 +837,26 @@ void NetworkAddServer(const byte *b) if (player != NULL) _network_playas = atoi(player); if (port != NULL) rport = atoi(port); - NetworkQueryServer(host, rport, true); + item = NetworkQueryServer(host, rport, true); + item->manually = true; + } +} + +/* Generates the list of manually added hosts from NetworkGameList and + * dumps them into the array _network_host_list. This array is needed + * by the function that generates the config file. */ +void NetworkRebuildHostList() +{ + int i=0; + NetworkGameList *item = _network_game_list; + while (item != NULL && i!=lengthof(_network_host_list)) { + if (item->manually) + _network_host_list[i++] = strdup(item->info.hostname); + item = item->next; + } + + for (; inext; + free(remove); + DEBUG(net, 4) ("[NET][GameList] Removed server from list"); + return; + } + + // examine each item + while ( item->next != NULL ) { + if ( item->next == remove ) + { + item->next = remove->next; + free(remove); + DEBUG(net, 4) ("[NET][GameList] Removed server from list"); + return; + } + item = item->next; + } +} + void NetworkGameListAddQueriedItem(const NetworkGameInfo *info, bool server_online) { // We queried a server and now we are going to add it to the list diff --git a/network_gamelist.h b/network_gamelist.h index 5ccc4b0545..5883ff1be0 100644 --- a/network_gamelist.h +++ b/network_gamelist.h @@ -3,6 +3,7 @@ void NetworkGameListClear(void); NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port); +void NetworkGameListRemoveItem(NetworkGameList *remove); void NetworkGameListAddQueriedItem(const NetworkGameInfo *info, bool server_online); #endif /* NETWORK_GAMELIST_H */ diff --git a/network_gui.c b/network_gui.c index 809511b87e..aa73b854f4 100644 --- a/network_gui.c +++ b/network_gui.c @@ -9,6 +9,7 @@ #include "table/strings.h" #include "network_data.h" +#include "network_gamelist.h" #include "window.h" #include "gui.h" #include "gfx.h" @@ -299,13 +300,15 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e) break; case WE_KEYPRESS: - if (_selected_field != 3) - break; - - switch (HandleEditBoxKey(w, 3, e)) { - case 1: - HandleButtonClick(w, 8); - break; + if (_selected_field != 3) { + if ( e->keypress.keycode == WKC_DELETE ) { // press 'delete' to remove servers + if (_selected_item != NULL && _selected_item->manually) { + NetworkGameListRemoveItem(_selected_item); + NetworkRebuildHostList(); + SetWindowDirty(w); + _selected_item = NULL; + } + } } // The name is only allowed when it starts with a letter! @@ -318,6 +321,7 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e) case WE_ON_EDIT_TEXT: { NetworkAddServer(e->edittext.str); + NetworkRebuildHostList(); } break; case WE_CREATE: { diff --git a/network_udp.c b/network_udp.c index da5aa807e4..03884591eb 100644 --- a/network_udp.c +++ b/network_udp.c @@ -434,7 +434,7 @@ void NetworkUDPSearchGame(void) _network_udp_broadcast = 300; // Stay searching for 300 ticks } -void NetworkUDPQueryServer(const byte* host, unsigned short port) +NetworkGameList *NetworkUDPQueryServer(const byte* host, unsigned short port) { struct sockaddr_in out_addr; Packet *p; @@ -444,7 +444,7 @@ void NetworkUDPQueryServer(const byte* host, unsigned short port) // No UDP-socket yet.. if (_udp_client_socket == INVALID_SOCKET) if (!NetworkUDPListen(0, 0)) - return; + return NULL; ttd_strlcpy(hostname, host, sizeof(hostname)); @@ -467,6 +467,7 @@ void NetworkUDPQueryServer(const byte* host, unsigned short port) free(p); UpdateNetworkGameWindow(false); + return item; } /* Register us to the master server diff --git a/network_udp.h b/network_udp.h index f92dd87d0e..03ff36579f 100644 --- a/network_udp.h +++ b/network_udp.h @@ -5,7 +5,7 @@ void NetworkUDPInitialize(void); bool NetworkUDPListen(uint32 host, uint16 port); void NetworkUDPReceive(void); void NetworkUDPSearchGame(void); -void NetworkUDPQueryServer(const byte* host, unsigned short port); +NetworkGameList *NetworkUDPQueryServer(const byte* host, unsigned short port); void NetworkUDPAdvertise(void); #endif /* NETWORK_LAN_H */ diff --git a/settings.c b/settings.c index 35cffb08ea..da980d49fa 100644 --- a/settings.c +++ b/settings.c @@ -923,12 +923,37 @@ static void LoadList(IniFile *ini, const char *grpname, char **list, int len) } } +static void SaveList(IniFile *ini, const char *grpname, char **list, int len) +{ + IniGroup *group = ini_getgroup(ini, grpname, -1); + IniItem *item; + int i; + bool first = true; + + if (!group) + return; + for ( i=0; i != len; i++) { + if ( list[i] == '\0' ) continue; + + if (first) { // add first item to the head of the group + item = ini_item_alloc(group, list[i], strlen(list[i])); + item->value = item->name; + group->item = item; + first = false; + } else { // all other items are attached to the previous one + item->next = ini_item_alloc(group, list[i], strlen(list[i])); + item = item->next; + item->value = item->name; + } + } +} + void LoadFromConfig() { IniFile *ini = ini_load(_config_file); HandleSettingDescs(ini, load_setting_desc); LoadList(ini, "newgrf", _newgrf_files, lengthof(_newgrf_files)); - LoadList(ini, "servers", _network_server_list, lengthof(_network_server_list)); + LoadList(ini, "servers", _network_host_list, lengthof(_network_host_list)); ini_free(ini); } @@ -936,6 +961,7 @@ void SaveToConfig() { IniFile *ini = ini_load(_config_file); HandleSettingDescs(ini, save_setting_desc); + SaveList(ini, "servers", _network_host_list, lengthof(_network_host_list)); ini_save(_config_file, ini); ini_free(ini); }