diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-09-30 11:48:06 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-09-30 11:48:06 +0000 |
| commit | db999a250293ab72c2dcd5f103b353758163c83d (patch) | |
| tree | 7b0417c2a473fb2c371ee6784264a4cc62b53308 | |
| parent | 19aaea9bfd2b7a6df9f2966c91367eac6fd2d837 (diff) | |
| download | zcatch-db999a250293ab72c2dcd5f103b353758163c83d.tar.gz zcatch-db999a250293ab72c2dcd5f103b353758163c83d.zip | |
fixed more with the server browser. added filtering
| -rw-r--r-- | scripts/mass_server.py | 3 | ||||
| -rw-r--r-- | src/engine/client/client.c | 230 | ||||
| -rw-r--r-- | src/engine/config_variables.h | 6 | ||||
| -rw-r--r-- | src/engine/interface.h | 10 | ||||
| -rw-r--r-- | src/game/client/menu.cpp | 25 |
5 files changed, 182 insertions, 92 deletions
diff --git a/scripts/mass_server.py b/scripts/mass_server.py index 68d22d6d..42aed747 100644 --- a/scripts/mass_server.py +++ b/scripts/mass_server.py @@ -40,8 +40,7 @@ for s in xrange(0, 150): cmd += '-a "%s" ' % random.choice(maps[t]) cmd += '-g %d ' % random.randint(0, 100) cmd += '-t %d ' % t # dm, tdm, ctf - #cmd += "-f %d " % random.randint(0, 2) # dm, tdm, ctf - + cmd += "-f %d " % random.randint(0, 1) # password protected for p in xrange(0, random.randint(0, max)): cmd += '-p "%s" %d ' % (get_nick(), random.randint(0, 20)) diff --git a/src/engine/client/client.c b/src/engine/client/client.c index 970eae60..3269ab23 100644 --- a/src/engine/client/client.c +++ b/src/engine/client/client.c @@ -344,12 +344,15 @@ int *client_get_input(int tick) return 0; } -// ------ server browse ---- +/* ------ server browse ---- */ +/* TODO: move all this to a separate file */ + typedef struct SERVERENTRY_t SERVERENTRY; struct SERVERENTRY_t { NETADDR4 addr; int64 request_time; + int got_info; SERVER_INFO info; SERVERENTRY *next_ip; // ip hashed list @@ -358,19 +361,27 @@ struct SERVERENTRY_t SERVERENTRY *next_req; }; -HEAP *serverlist_heap = 0; -SERVERENTRY **serverlist = 0; +static HEAP *serverlist_heap = 0; +static SERVERENTRY **serverlist = 0; +static int *sorted_serverlist = 0; + +static SERVERENTRY *serverlist_ip[256] = {0}; // ip hash list -SERVERENTRY *serverlist_ip[256] = {0}; // ip hash list +static SERVERENTRY *first_req_server = 0; // request list +static SERVERENTRY *last_req_server = 0; +static int num_requests = 0; -SERVERENTRY *first_req_server = 0; // request list -SERVERENTRY *last_req_server = 0; +static int num_sorted_servers = 0; +static int num_sorted_servers_capacity = 0; +static int num_servers = 0; +static int num_server_capacity = 0; -int num_servers = 0; -int num_server_capasity = 0; +static int sorthash = 0; static int serverlist_lan = 1; +int client_serverbrowse_num() { return num_servers; } + SERVER_INFO *client_serverbrowse_get(int index) { if(index < 0 || index >= num_servers) @@ -378,61 +389,135 @@ SERVER_INFO *client_serverbrowse_get(int index) return &serverlist[index]->info; } -int client_serverbrowse_num() +int client_serverbrowse_sorted_num() { return num_sorted_servers; } + +SERVER_INFO *client_serverbrowse_sorted_get(int index) { - return num_servers; + if(index < 0 || index >= num_sorted_servers) + return 0; + return &serverlist[sorted_serverlist[index]]->info; } -static void client_serverbrowse_init() + +int client_serverbrowse_num_requests() { + return num_requests; } -static int serverbrowse_sort = BROWSESORT_NONE; +static void client_serverbrowse_init() +{ +} static int client_serverbrowse_sort_compare_name(const void *ai, const void *bi) { - SERVERENTRY **a = (SERVERENTRY **)ai; - SERVERENTRY **b = (SERVERENTRY **)bi; - return strcmp((*a)->info.name, (*b)->info.name); + SERVERENTRY *a = serverlist[*(const int*)ai]; + SERVERENTRY *b = serverlist[*(const int*)bi]; + return strcmp(a->info.name, b->info.name); } static int client_serverbrowse_sort_compare_map(const void *ai, const void *bi) { - SERVERENTRY **a = (SERVERENTRY **)ai; - SERVERENTRY **b = (SERVERENTRY **)bi; - return strcmp((*a)->info.map, (*b)->info.map); + SERVERENTRY *a = serverlist[*(const int*)ai]; + SERVERENTRY *b = serverlist[*(const int*)bi]; + return strcmp(a->info.map, b->info.map); } static int client_serverbrowse_sort_compare_ping(const void *ai, const void *bi) { - SERVERENTRY **a = (SERVERENTRY **)ai; - SERVERENTRY **b = (SERVERENTRY **)bi; - return (*a)->info.latency > (*b)->info.latency; + SERVERENTRY *a = serverlist[*(const int*)ai]; + SERVERENTRY *b = serverlist[*(const int*)bi]; + return a->info.latency > b->info.latency; } static int client_serverbrowse_sort_compare_numplayers(const void *ai, const void *bi) { - SERVERENTRY **a = (SERVERENTRY **)ai; - SERVERENTRY **b = (SERVERENTRY **)bi; - return (*a)->info.num_players > (*b)->info.num_players; + SERVERENTRY *a = serverlist[*(const int*)ai]; + SERVERENTRY *b = serverlist[*(const int*)bi]; + return a->info.num_players > b->info.num_players; +} + +static void client_serverbrowse_filter() +{ + int i = 0; + num_sorted_servers = 0; + + /* allocate the sorted list */ + if(num_sorted_servers_capacity < num_servers) + { + if(sorted_serverlist) + mem_free(sorted_serverlist); + num_sorted_servers_capacity = num_servers; + sorted_serverlist = mem_alloc(num_sorted_servers_capacity*sizeof(int), 1); + } + + /* filter the servers */ + for(i = 0; i < num_servers; i++) + { + int filtered = 0; + + if(config.b_filter_empty && serverlist[i]->info.num_players == 0) + filtered = 1; + else if(config.b_filter_full && serverlist[i]->info.num_players == serverlist[i]->info.max_players) + filtered = 1; + else if(config.b_filter_pw && serverlist[i]->info.flags&1) + filtered = 1; + + if(filtered == 0) + sorted_serverlist[num_sorted_servers++] = i; + } +} + +static int client_serverbrowse_sorthash() +{ + int i = config.b_sort&3; + i |= config.b_filter_empty<<4; + i |= config.b_filter_full<<5; + i |= config.b_filter_pw<<6; + return i; } static void client_serverbrowse_sort() { - if(serverbrowse_sort == BROWSESORT_NAME) - qsort(serverlist, num_servers, sizeof(SERVERENTRY *), client_serverbrowse_sort_compare_name); - else if(serverbrowse_sort == BROWSESORT_PING) - qsort(serverlist, num_servers, sizeof(SERVERENTRY *), client_serverbrowse_sort_compare_ping); - else if(serverbrowse_sort == BROWSESORT_MAP) - qsort(serverlist, num_servers, sizeof(SERVERENTRY *), client_serverbrowse_sort_compare_map); - else if(serverbrowse_sort == BROWSESORT_NUMPLAYERS) - qsort(serverlist, num_servers, sizeof(SERVERENTRY *), client_serverbrowse_sort_compare_numplayers); + int i; + + /* create filtered list */ + client_serverbrowse_filter(); + + /* sort */ + if(config.b_sort == BROWSESORT_NAME) + qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_name); + else if(config.b_sort == BROWSESORT_PING) + qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_ping); + else if(config.b_sort == BROWSESORT_MAP) + qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_map); + else if(config.b_sort == BROWSESORT_NUMPLAYERS) + qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_numplayers); + + /* set indexes */ + for(i = 0; i < num_sorted_servers; i++) + serverlist[sorted_serverlist[i]]->info.sorted_index = i; + + sorthash = client_serverbrowse_sorthash(); } -void client_serverbrowse_set_sort(int mode) +static void client_serverbrowse_remove_request(SERVERENTRY *entry) { - serverbrowse_sort = mode; - client_serverbrowse_sort(); /* resort */ + if(entry->prev_req || entry->next_req || first_req_server == entry) + { + if(entry->prev_req) + entry->prev_req->next_req = entry->next_req; + else + first_req_server = entry->next_req; + + if(entry->next_req) + entry->next_req->prev_req = entry->prev_req; + else + last_req_server = entry->prev_req; + + entry->prev_req = 0; + entry->next_req = 0; + num_requests--; + } } static void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *info) @@ -446,7 +531,12 @@ static void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *in /* update the server that we already have */ entry->info = *info; if(!request) + { entry->info.latency = (time_get()-entry->request_time)*1000/time_freq(); + client_serverbrowse_remove_request(entry); + } + + entry->got_info = 1; client_serverbrowse_sort(); return; } @@ -465,10 +555,10 @@ static void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *in entry->next_ip = serverlist_ip[hash]; serverlist_ip[hash] = entry; - if(num_servers == num_server_capasity) + if(num_servers == num_server_capacity) { - num_server_capasity += 100; - SERVERENTRY **newlist = mem_alloc(num_server_capasity*sizeof(SERVERENTRY*), 1); + num_server_capacity += 100; + SERVERENTRY **newlist = mem_alloc(num_server_capacity*sizeof(SERVERENTRY*), 1); memcpy(newlist, serverlist, num_servers*sizeof(SERVERENTRY*)); mem_free(serverlist); serverlist = newlist; @@ -476,12 +566,10 @@ static void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *in /* add to list */ serverlist[num_servers] = entry; + entry->info.server_index = num_servers; num_servers++; /* */ - entry->prev_req = 0; - entry->next_req = 0; - if(request) { /* add it to the list of servers that we should request info from */ @@ -491,6 +579,8 @@ static void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *in else first_req_server = entry; last_req_server = entry; + + num_requests++; } client_serverbrowse_sort(); @@ -503,10 +593,12 @@ void client_serverbrowse_refresh(int lan) memheap_destroy(serverlist_heap); serverlist_heap = memheap_create(); num_servers = 0; - num_server_capasity = 0; + num_sorted_servers = 0; mem_zero(serverlist_ip, sizeof(serverlist_ip)); first_req_server = 0; last_req_server = 0; + num_requests = 0; + /* */ serverlist_lan = lan; @@ -573,7 +665,6 @@ static void client_serverbrowse_update() { int64 timeout = time_freq(); int64 now = time_get(); - int max_requests = 10; int count; SERVERENTRY *entry, *next; @@ -590,15 +681,8 @@ static void client_serverbrowse_update() if(entry->request_time && entry->request_time+timeout < now) { /* timeout */ - if(entry->prev_req) - entry->prev_req->next_req = entry->next_req; - else - first_req_server = entry->next_req; - - if(entry->next_req) - entry->next_req->prev_req = entry->prev_req; - else - last_req_server = entry->prev_req; + client_serverbrowse_remove_request(entry); + num_requests--; } entry = next; @@ -612,7 +696,7 @@ static void client_serverbrowse_update() if(!entry) // no more entries break; - if(count == max_requests) // no more then 10 concurrent requests + if(count == config.b_max_requests) // no more then 10 concurrent requests break; if(entry->request_time == 0) @@ -621,6 +705,10 @@ static void client_serverbrowse_update() count++; entry = entry->next_req; } + + /* check if we need to resort */ + if(sorthash != client_serverbrowse_sorthash()) + client_serverbrowse_sort(); } // ------ state handling ----- @@ -770,7 +858,6 @@ static void client_process_packet(NETPACKET *packet) memcmp(packet->data, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)) == 0) { int size = packet->data_size-sizeof(SERVERBROWSE_LIST); - //mem_copy(servers.addresses, (char*)packet->data+sizeof(SERVERBROWSE_LIST), size); int num = size/sizeof(NETADDR4); NETADDR4 *addrs = (NETADDR4 *)((char*)packet->data+sizeof(SERVERBROWSE_LIST)); @@ -779,44 +866,22 @@ static void client_process_packet(NETPACKET *packet) { NETADDR4 addr = addrs[i]; SERVER_INFO info = {0}; + +#if defined(CONF_ARCH_ENDIAN_BIG) + const char *tmp = (const char *)&addr.port; + addr.port = (tmp[1]<<8) | tmp[0]; +#endif info.latency = 999; sprintf(info.address, "%d.%d.%d.%d:%d", addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3], addr.port); - sprintf(info.name, "%d.%d.%d.%d:%d", + sprintf(info.name, "\255%d.%d.%d.%d:%d", /* the \255 is to make sure that it's sorted last */ addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3], addr.port); client_serverbrowse_set(addrs+i, 1, &info); } - - // server listing - /* - int size = packet->data_size-sizeof(SERVERBROWSE_LIST); - mem_copy(servers.addresses, (char*)packet->data+sizeof(SERVERBROWSE_LIST), size); - servers.num = size/sizeof(NETADDR4); - - info_request_begin = 0; - info_request_end = 0; - - int i; - for(i = 0; i < servers.num; i++) - { - servers.infos[i].num_players = 0; - servers.infos[i].max_players = 0; - servers.infos[i].latency = 999; -#if defined(CONF_ARCH_ENDIAN_BIG) - const char *tmp = (const char *)&servers.addresses[i].port; - servers.addresses[i].port = (tmp[1]<<8) | tmp[0]; -#endif - sprintf(servers.infos[i].address, "%d.%d.%d.%d:%d", - servers.addresses[i].ip[0], servers.addresses[i].ip[1], servers.addresses[i].ip[2], - servers.addresses[i].ip[3], servers.addresses[i].port); - sprintf(servers.infos[i].name, "%d.%d.%d.%d:%d", - servers.addresses[i].ip[0], servers.addresses[i].ip[1], servers.addresses[i].ip[2], - servers.addresses[i].ip[3], servers.addresses[i].port); - }*/ } if(packet->data_size >= (int)sizeof(SERVERBROWSE_INFO) && @@ -845,7 +910,6 @@ static void client_process_packet(NETPACKET *packet) /* TODO: unpack players aswell */ client_serverbrowse_set(&packet->address, 0, &info); - } } else diff --git a/src/engine/config_variables.h b/src/engine/config_variables.h index cca544b8..4ce022f3 100644 --- a/src/engine/config_variables.h +++ b/src/engine/config_variables.h @@ -12,6 +12,12 @@ MACRO_CONFIG_INT(debug, 0, 0, 1) MACRO_CONFIG_INT(stress, 0, 0, 0) MACRO_CONFIG_STR(cl_stress_server, 32, "localhost") +MACRO_CONFIG_INT(b_filter_full, 0, 1, 0) +MACRO_CONFIG_INT(b_filter_empty, 0, 1, 0) +MACRO_CONFIG_INT(b_filter_pw, 0, 1, 0) +MACRO_CONFIG_INT(b_sort, 0, 0, 0) +MACRO_CONFIG_INT(b_max_requests, 10, 0, 0) + MACRO_CONFIG_INT(gfx_screen_width, 800, 0, 0) MACRO_CONFIG_INT(gfx_screen_height, 600, 0, 0) MACRO_CONFIG_INT(gfx_fullscreen, 1, 0, 1) diff --git a/src/engine/interface.h b/src/engine/interface.h index 2a4e203a..18a434dd 100644 --- a/src/engine/interface.h +++ b/src/engine/interface.h @@ -61,6 +61,9 @@ typedef struct typedef struct { + int sorted_index; + int server_index; + int progression; int game_type; int max_players; @@ -797,9 +800,14 @@ void client_quit(); void client_rcon(const char *cmd); void client_serverbrowse_refresh(int lan); + +SERVER_INFO *client_serverbrowse_sorted_get(int index); +int client_serverbrowse_sorted_num(); + SERVER_INFO *client_serverbrowse_get(int index); int client_serverbrowse_num(); -void client_serverbrowse_set_sort(int mode); + +int client_serverbrowse_num_requests(); /* undocumented graphics stuff */ void gfx_pretty_text(float x, float y, float size, const char *text, int max_width); diff --git a/src/game/client/menu.cpp b/src/game/client/menu.cpp index a5d6d5b6..d4fad920 100644 --- a/src/game/client/menu.cpp +++ b/src/game/client/menu.cpp @@ -631,7 +631,7 @@ static int do_server_list(float x, float y, int *scroll_index, int *selected_ind const float real_width = item_width + 20; const float real_height = item_height * visible_items + spacing * (visible_items - 1); - int num_servers = client_serverbrowse_num(); + int num_servers = client_serverbrowse_sorted_num(); int r = -1; @@ -643,7 +643,7 @@ static int do_server_list(float x, float y, int *scroll_index, int *selected_ind //ui_do_image(empty_item_texture, x, y + i * item_height + i * spacing, item_width, item_height); else { - SERVER_INFO *item = client_serverbrowse_get(item_index); + SERVER_INFO *item = client_serverbrowse_sorted_get(item_index); bool clicked = false; clicked = ui_do_button(item, item->name, 0, x, y + i * item_height + i * spacing, item_width, item_height, @@ -751,11 +751,24 @@ static int main_render() config_copy = config; screen = SCREEN_SETTINGS_GENERAL; } + + // render status text + if(client_serverbrowse_num_requests()) + { + char buf[512]; + sprintf(buf, "Refreshing %d servers...", client_serverbrowse_num_requests()); + ui_do_label(20, 400, buf, 28); + } + else + { + char buf[512]; + sprintf(buf, "%d of %d servers", client_serverbrowse_sorted_num(), client_serverbrowse_num()); + ui_do_label(20, 400, buf, 28); + } - /*static int editor_button; - if (ui_do_button(&editor_button, "Kerning Editor", 0, 20, 470, 170, 48, draw_teewars_button)) - screen = SCREEN_KERNING;*/ - + config.b_filter_empty = ui_do_check_box(&config.b_filter_empty, 20, 600-80, 32, 32, config.b_filter_empty); + config.b_filter_full = ui_do_check_box(&config.b_filter_full, 20+50, 600-80, 32, 32, config.b_filter_full); + config.b_filter_pw = ui_do_check_box(&config.b_filter_pw, 20+100, 600-80, 32, 32, config.b_filter_pw); return 0; } |