diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-03-29 17:20:21 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-03-29 17:20:21 +0000 |
| commit | 370cbbe79f8dbc8ef00dca28e27480c05789670f (patch) | |
| tree | f8adbab00c2a8e8e506f0f47beb753c47d592fb2 | |
| parent | fcd9709c36ff014c270ef14f236e0141c8266695 (diff) | |
| download | zcatch-370cbbe79f8dbc8ef00dca28e27480c05789670f.tar.gz zcatch-370cbbe79f8dbc8ef00dca28e27480c05789670f.zip | |
server browser improvements. much improved quick search. sorted the player list.
| -rw-r--r-- | src/engine/client/ec_client.c | 21 | ||||
| -rw-r--r-- | src/engine/client/ec_srvbrowse.c | 26 | ||||
| -rw-r--r-- | src/engine/e_if_client.h | 19 | ||||
| -rw-r--r-- | src/engine/e_system.c | 29 | ||||
| -rw-r--r-- | src/engine/e_system.h | 2 | ||||
| -rw-r--r-- | src/game/client/gc_menu.cpp | 109 |
6 files changed, 142 insertions, 64 deletions
diff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.c index b12fa503..142c8b70 100644 --- a/src/engine/client/ec_client.c +++ b/src/engine/client/ec_client.c @@ -643,6 +643,18 @@ static const char *client_load_map_search(const char *mapname, int wanted_crc) return error; } + +static int player_score_comp(const void *a, const void *b) +{ + SERVER_INFO_PLAYER *p0 = (SERVER_INFO_PLAYER *)a; + SERVER_INFO_PLAYER *p1 = (SERVER_INFO_PLAYER *)b; + if(p0->score == p1->score) + return 0; + if(p0->score < p1->score) + return 1; + return -1; +} + static void client_process_packet(NETPACKET *packet) { if(packet->client_id == -1) @@ -721,13 +733,16 @@ static void client_process_packet(NETPACKET *packet) for(i = 0; i < info.num_players; i++) { - str_copy(info.player_names[i], unpacker_get_string(&up), sizeof(info.player_names[i])); - info.player_scores[i] = atol(unpacker_get_string(&up)); + str_copy(info.players[i].name, unpacker_get_string(&up), sizeof(info.players[i].name)); + info.players[i].score = atol(unpacker_get_string(&up)); } - /* TODO: unpack players aswell */ if(!up.error) + { + /* sort players */ + qsort(info.players, info.num_players, sizeof(*info.players), player_score_comp); client_serverbrowse_set(&packet->address, 0, &info); + } } } } diff --git a/src/engine/client/ec_srvbrowse.c b/src/engine/client/ec_srvbrowse.c index c4fe3080..fcab2fc8 100644 --- a/src/engine/client/ec_srvbrowse.c +++ b/src/engine/client/ec_srvbrowse.c @@ -128,7 +128,7 @@ static int client_serverbrowse_sort_compare_numplayers(const void *ai, const voi static void client_serverbrowse_filter() { - int i = 0; + int i = 0, p = 0; num_sorted_servers = 0; /* allocate the sorted list */ @@ -159,7 +159,29 @@ static void client_serverbrowse_filter() filtered = 1; else if(config.b_filter_string[0] != 0) { - if(strstr(serverlist[i]->info.name, config.b_filter_string) == 0) + int matchfound = 0; + + serverlist[i]->info.quicksearch_hit = 0; + + /* match against server name */ + if(str_find_nocase(serverlist[i]->info.name, config.b_filter_string)) + { + matchfound = 1; + serverlist[i]->info.quicksearch_hit |= BROWSEQUICK_SERVERNAME; + } + + /* match against players */ + for(p = 0; p < serverlist[i]->info.num_players; p++) + { + if(str_find_nocase(serverlist[i]->info.players[p].name, config.b_filter_string)) + { + matchfound = 1; + serverlist[i]->info.quicksearch_hit |= BROWSEQUICK_PLAYERNAME; + break; + } + } + + if(!matchfound) filtered = 1; } diff --git a/src/engine/e_if_client.h b/src/engine/e_if_client.h index 3f490079..e06d3e6b 100644 --- a/src/engine/e_if_client.h +++ b/src/engine/e_if_client.h @@ -51,7 +51,10 @@ enum BROWSESORT_MAP, BROWSESORT_GAMETYPE, BROWSESORT_PROGRESSION, - BROWSESORT_NUMPLAYERS + BROWSESORT_NUMPLAYERS, + + BROWSEQUICK_SERVERNAME=1, + BROWSEQUICK_PLAYERNAME=2 }; /* @@ -59,6 +62,15 @@ enum */ /* + Structure: SERVER_INFO_PLAYER +*/ +typedef struct +{ + char name[48]; + int score; +} SERVER_INFO_PLAYER; + +/* Structure: SERVER_INFO */ typedef struct @@ -66,6 +78,8 @@ typedef struct int sorted_index; int server_index; + int quicksearch_hit; + int progression; int game_type; int max_players; @@ -76,8 +90,7 @@ typedef struct char map[32]; char version[32]; char address[24]; - char player_names[16][48]; - int player_scores[16]; + SERVER_INFO_PLAYER players[16]; } SERVER_INFO; /* diff --git a/src/engine/e_system.c b/src/engine/e_system.c index 2b24ab7c..9545369d 100644 --- a/src/engine/e_system.c +++ b/src/engine/e_system.c @@ -911,6 +911,35 @@ void str_sanitize(char *str_in) } } +/* case */ +int str_comp_nocase(const char *a, const char *b) +{ +#if defined(CONF_FAMILY_WINDOWS) + return _stricmp(a,b); +#else + return strcasecmp(a,b); +#endif +} + +const char *str_find_nocase(const char *haystack, const char *needle) +{ + while(*haystack) /* native implementation */ + { + const char *a = haystack; + const char *b = needle; + while(*a && *b && tolower(*a) == tolower(*b)) + { + a++; + b++; + } + if(!(*b)) + return haystack; + haystack++; + } + + return 0; +} + #if defined(__cplusplus) } #endif diff --git a/src/engine/e_system.h b/src/engine/e_system.h index 0f79908d..9902cb24 100644 --- a/src/engine/e_system.h +++ b/src/engine/e_system.h @@ -539,6 +539,8 @@ void str_copy(char *dst, const char *src, int dst_size); void str_format(char *buffer, int buffer_size, const char *format, ...); void str_sanitize_strong(char *str); void str_sanitize(char *str); +int str_comp_nocase(const char *a, const char *b); +const char *str_find_nocase(const char *haystack, const char *needle); typedef void (*DBG_LOGGER)(const char *line); void dbg_logger(DBG_LOGGER logger); diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp index c6c21a66..083cbcbf 100644 --- a/src/game/client/gc_menu.cpp +++ b/src/game/client/gc_menu.cpp @@ -809,59 +809,9 @@ static void menu2_render_serverbrowser(RECT main_view) int selected = strcmp(item->address, config.ui_server_address) == 0; //selected_index==item_index; - /* - if(selected) - { - selected_index = i; - - // selected server, draw the players on it - RECT whole; - int h = (item->num_players+2)/3; - - ui_hsplit_t(&view, 25.0f+h*15.0f, &whole, &view); - - select_hit_box = whole; - - RECT r = whole; - ui_margin(&r, 1.5f, &r); - ui_draw_rect(&r, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f); - - ui_hsplit_t(&whole, 20.0f, &row, &whole); - ui_vsplit_l(&whole, 50.0f, 0, &whole); - - - for(int p = 0; p < item->num_players; p+=3) - { - RECT player_row; - RECT player_rect; - RECT player_score; - RECT player_name; - ui_hsplit_t(&whole, 15.0f, &player_row, &whole); - - for(int a = 0; a < 3; a++) - { - if(p+a >= item->num_players) - break; - - ui_vsplit_l(&player_row, 170.0f, &player_rect, &player_row); - ui_vsplit_l(&player_rect, 30.0f, &player_score, &player_name); - ui_vsplit_l(&player_name, 10.0f, 0, &player_name); - char buf[32]; - sprintf(buf, "%d", item->player_scores[p+a]); - ui_do_label(&player_score, buf, 12.0f, 1); - ui_do_label(&player_name, item->player_names[p+a], 12.0f, -1); - } - } - - //k += h*3/4; - } - else - { - */ - ui_hsplit_t(&view, 17.0f, &row, &view); - select_hit_box = row; - //} - + ui_hsplit_t(&view, 17.0f, &row, &view); + select_hit_box = row; + if(selected) { selected_index = i; @@ -910,13 +860,37 @@ static void menu2_render_serverbrowser(RECT main_view) ui_draw_browse_icon(0x100, &button); } else if(id == COL_NAME) - ui_do_label(&button, item->name, 12.0f, -1); + { + TEXT_CURSOR cursor; + gfx_text_set_cursor(&cursor, button.x, button.y, 12.0f, TEXTFLAG_RENDER); + + if(config.b_filter_string[0] && (item->quicksearch_hit&BROWSEQUICK_SERVERNAME)) + { + // highlight the parts that matches + const char *s = str_find_nocase(item->name, config.b_filter_string); + if(s) + { + gfx_text_ex(&cursor, item->name, (int)(s-item->name)); + gfx_text_color(1,0.4f,0.4f,1); + gfx_text_ex(&cursor, s, strlen(config.b_filter_string)); + gfx_text_color(1,1,1,1); + gfx_text_ex(&cursor, s+strlen(config.b_filter_string), -1); + } + else + gfx_text_ex(&cursor, item->name, -1); + } + else + gfx_text_ex(&cursor, item->name, -1); + } else if(id == COL_MAP) ui_do_label(&button, item->map, 12.0f, -1); else if(id == COL_PLAYERS) { str_format(temp, sizeof(temp), "%i/%i", item->num_players, item->max_players); + if(config.b_filter_string[0] && (item->quicksearch_hit&BROWSEQUICK_PLAYERNAME)) + gfx_text_color(1,0.4f,0.4f,1); ui_do_label(&button, temp, 12.0f, 1); + gfx_text_color(1,1,1,1); } else if(id == COL_PING) { @@ -1038,11 +1012,34 @@ static void menu2_render_serverbrowser(RECT main_view) char temp[16]; ui_hsplit_t(&server_scoreboard, 16.0f, &row, &server_scoreboard); - str_format(temp, sizeof(temp), "%d", selected_server->player_scores[i]); + str_format(temp, sizeof(temp), "%d", selected_server->players[i].score); ui_do_label(&row, temp, font_size, -1); ui_vsplit_l(&row, 25.0f, 0x0, &row); - ui_do_label(&row, selected_server->player_names[i], font_size, -1); + + TEXT_CURSOR cursor; + gfx_text_set_cursor(&cursor, row.x, row.y, 12.0f, TEXTFLAG_RENDER); + + const char *name = selected_server->players[i].name; + if(config.b_filter_string[0]) + { + // highlight the parts that matches + const char *s = str_find_nocase(name, config.b_filter_string); + if(s) + { + gfx_text_ex(&cursor, name, (int)(s-name)); + gfx_text_color(1,0.4f,0.4f,1); + gfx_text_ex(&cursor, s, strlen(config.b_filter_string)); + gfx_text_color(1,1,1,1); + gfx_text_ex(&cursor, s+strlen(config.b_filter_string), -1); + } + else + gfx_text_ex(&cursor, name, -1); + } + else + gfx_text_ex(&cursor, name, -1); + + /*ui_do_label(&row, selected_server->player_names[i], font_size, -1);*/ } } |