- reworked dialog for adding master

- added popup menu for master server tree
- added function for renaming master servers


git-svn-id: http://svn.code.sf.net/p/xqf/code/trunk@153 d2ac09be-c843-0410-8b1f-f8a84130e0ec
This commit is contained in:
Ludwig Nussel 2002-02-12 00:32:07 +00:00 committed by l-n
parent 35df2f5782
commit d7c2f96b60
10 changed files with 840 additions and 365 deletions

View File

@ -1,3 +1,8 @@
Feb 12, 2002: Ludwig Nussel <l-n@users.sourceforge.net>
- reworked dialog for adding master
- added popup menu for master server tree
- added function for renaming master servers
Feb 01, 2002: Ludwig Nussel <l-n@users.sourceforge.net>
- fix display of gametypes > MAX_Q3A_TYPES

File diff suppressed because it is too large Load Diff

View File

@ -30,19 +30,56 @@
#include "addmaster.h"
#include "srv-prop.h"
static struct history *master_history_addr = NULL;
static struct history *master_history_name = NULL;
static struct history *master_history_addr;
static struct history *master_history_name;
static char *master_addr_result;
static char *master_name_result;
static enum server_type *master_type;
static enum server_type master_type;
static struct master *master_to_add;
// currently active radio button
static enum master_query_type current_master_query_type = MASTER_NATIVE;
static GtkWidget *master_addr_combo;
static GtkWidget *master_name_combo;
static GtkWidget *master_query_type_radios[MASTER_NUM_QUERY_TYPES];
// get text from master address entry, check if prefix matches radio buttons,
// modify and write back if needed
static void master_check_master_addr_prefix()
{
char *pos;
char *master_addr;
static void master_combo_activate_callback (GtkWidget *widget, gpointer data) {
char *str;
master_addr= gtk_entry_get_text(GTK_ENTRY (GTK_COMBO
(master_addr_combo)->entry));
if(!master_addr|| !strlen(master_addr)) return;
if (g_strncasecmp(master_addr, master_prefixes[current_master_query_type],
strlen(master_prefixes[current_master_query_type])))
{
pos = lowcasestrstr(master_addr,"://");
if(!pos)
{
pos = master_addr;
}
else
{
// +"://"
pos+=3;
}
master_addr =
g_strconcat(master_prefixes[current_master_query_type],pos,NULL);
gtk_entry_set_text(GTK_ENTRY (GTK_COMBO (master_addr_combo)->entry),master_addr);
}
}
static void master_okbutton_callback (GtkWidget *widget, GtkWidget* window)
{
master_check_master_addr_prefix();
master_addr_result = strdup_strip (gtk_entry_get_text (
GTK_ENTRY (GTK_COMBO (master_addr_combo)->entry)));
@ -50,42 +87,78 @@ static void master_combo_activate_callback (GtkWidget *widget, gpointer data) {
GTK_ENTRY (GTK_COMBO (master_name_combo)->entry)));
config_set_string ("/" CONFIG_FILE "/Add Master/game",
type2id (*master_type));
if (master_addr_result)
history_add (master_history_addr, master_addr_result);
if (master_name_result)
history_add (master_history_name, master_name_result);
if (master_name_result == NULL || master_addr_result == NULL) {
if (master_name_result) {
g_free (master_name_result);
master_name_result = NULL;
}
if (master_addr_result) {
g_free (master_addr_result);
master_addr_result = NULL;
}
type2id (master_type));
if(!master_addr_result || !master_name_result)
{
dialog_ok (NULL, _("You have to specify a name and an address."));
return;
}
/* No prefix? Add "master://" */
master_to_add = add_master (master_addr_result, master_name_result, master_type, TRUE, FALSE);
if(!master_to_add)
{
dialog_ok (NULL, _("Master address \"%s\" is not valid."),
master_addr_result);
}
else
{
if (strstr (master_addr_result, "://") == NULL) {
str = g_malloc (strlen (master_addr_result) + sizeof (PREFIX_MASTER));
strcpy (str, PREFIX_MASTER);
strcpy (str + sizeof (PREFIX_MASTER) - 1, master_addr_result);
g_free (master_addr_result);
master_addr_result = str;
if (master_addr_result)
history_add (master_history_addr, master_addr_result);
if (master_name_result)
history_add (master_history_name, master_name_result);
gtk_widget_destroy(window);
}
}
static void select_master_type_callback (GtkWidget *widget,
enum server_type type) {
*master_type = type;
static void select_master_type_callback (GtkWidget *widget, enum server_type type)
{
master_type = type;
gtk_widget_set_state (master_query_type_radios[MASTER_NATIVE], GTK_STATE_NORMAL);
if(!games[type].default_master_port)
{
gtk_widget_set_sensitive
(GTK_WIDGET(master_query_type_radios[MASTER_NATIVE]),FALSE);
if(current_master_query_type==MASTER_NATIVE)
{
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON(master_query_type_radios[MASTER_GAMESPY]),TRUE);
}
}
else
{
gtk_widget_set_sensitive
(GTK_WIDGET(master_query_type_radios[MASTER_NATIVE]),TRUE);
}
}
static void master_type_radio_callback (GtkWidget *widget, enum master_query_type type)
{
current_master_query_type = type;
master_check_master_addr_prefix();
}
static void master_activate_radio_for_type( enum master_query_type type )
{
if( type < MASTER_NATIVE || type >= MASTER_NUM_QUERY_TYPES )
type=MASTER_NATIVE;
if(master_query_type_radios[type])
{
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON(master_query_type_radios[type]),TRUE);
}
}
static void master_address_from_history_selected_callback (GtkWidget *widget,
gpointer data)
{
char* str = gtk_entry_get_text( GTK_ENTRY (GTK_COMBO (master_addr_combo)->entry));
enum master_query_type type = get_master_query_type_from_address(str);
master_activate_radio_for_type(type);
}
static GtkWidget *create_master_type_menu (void) {
GtkWidget *menu;
@ -109,8 +182,42 @@ static GtkWidget *create_master_type_menu (void) {
return menu;
}
char *master2url( struct master *m )
{
char *query_type;
char *address;
char *result;
char *add_master_dialog (enum server_type *type, char **desc) {
if ( m->master_type >= MASTER_NATIVE
&& m->master_type < MASTER_NUM_QUERY_TYPES )
{
query_type = master_prefixes[m->master_type];
}
else
return NULL;
if( m->master_type == MASTER_HTTP )
{
result = strdup(m->url);
}
else
{
if(m->host)
{
address = inet_ntoa(m->host->ip);
}
else
{
address = m->hostname;
}
result = g_strdup_printf("%s%s:%d",query_type,address,m->port);
}
return result;
}
struct master *add_master_dialog (struct master *m) {
GtkWidget *window;
GtkWidget *main_vbox;
GtkWidget *table;
@ -120,22 +227,48 @@ char *add_master_dialog (enum server_type *type, char **desc) {
GtkWidget *button;
GtkWidget *hseparator;
char *typestr;
enum master_query_type i;
struct master *master_to_edit;
char *windowtitle;
master_name_result = NULL;
master_addr_result = NULL;
master_type = type;
current_master_query_type = MASTER_NATIVE;
typestr = config_get_string ("/" CONFIG_FILE "/Add Master/game");
if (typestr) {
*type = id2type (typestr);
g_free (typestr);
}
else {
*type = QW_SERVER;
}
master_to_edit = NULL;
master_to_add = NULL;
for (i=MASTER_NATIVE;i<MASTER_NUM_QUERY_TYPES;i++)
master_query_type_radios[i]=NULL;
window = dialog_create_modal_transient_window (_("Add Master"),
TRUE, FALSE, NULL);
master_to_edit = m;
if(master_to_edit)
{
current_master_query_type = master_to_edit->master_type;
master_type = master_to_edit->type;
}
else
{
typestr = config_get_string ("/" CONFIG_FILE "/Add Master/game");
if (typestr) {
master_type = id2type (typestr);
g_free (typestr);
}
else {
master_type = QW_SERVER;
}
}
if (master_to_edit)
{
windowtitle=_("Rename Master");
}
else
{
windowtitle=_("Add Master");
}
window = dialog_create_modal_transient_window(windowtitle, TRUE, FALSE, NULL);
main_vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), main_vbox);
@ -163,12 +296,9 @@ char *add_master_dialog (enum server_type *type, char **desc) {
gtk_combo_set_case_sensitive (GTK_COMBO (master_name_combo), TRUE);
gtk_combo_set_use_arrows_always (GTK_COMBO (master_name_combo), TRUE);
gtk_combo_disable_activate (GTK_COMBO (master_name_combo));
gtk_signal_connect (
gtk_signal_connect(
GTK_OBJECT (GTK_COMBO (master_name_combo)->entry), "activate",
GTK_SIGNAL_FUNC (master_combo_activate_callback), NULL);
gtk_signal_connect_object (
GTK_OBJECT (GTK_COMBO (master_name_combo)->entry), "activate",
GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (window));
GTK_SIGNAL_FUNC (master_okbutton_callback), GTK_OBJECT (window));
GTK_WIDGET_SET_FLAGS (GTK_COMBO (master_name_combo)->entry, GTK_CAN_FOCUS);
GTK_WIDGET_UNSET_FLAGS (GTK_COMBO (master_name_combo)->button, GTK_CAN_FOCUS);
@ -179,13 +309,27 @@ char *add_master_dialog (enum server_type *type, char **desc) {
if (master_history_name->items)
combo_set_vals (master_name_combo, master_history_name->items, "");
if(master_to_edit)
{
gtk_entry_set_text(GTK_ENTRY (GTK_COMBO
(master_name_combo)->entry),strdup(master_to_edit->name));
}
/* Master Type Option Menu */
option_menu = gtk_option_menu_new ();
gtk_box_pack_start (GTK_BOX (hbox), option_menu, FALSE, FALSE, 0);
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu),
create_master_type_menu ());
gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), *type);
gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), master_type);
if(master_to_edit)
{
gtk_widget_set_state (option_menu, GTK_STATE_NORMAL);
gtk_widget_set_sensitive (GTK_WIDGET(option_menu),FALSE);
}
gtk_widget_show (option_menu);
gtk_widget_show (hbox);
@ -206,20 +350,66 @@ char *add_master_dialog (enum server_type *type, char **desc) {
gtk_combo_disable_activate (GTK_COMBO (master_addr_combo));
gtk_signal_connect (
GTK_OBJECT (GTK_COMBO (master_addr_combo)->entry), "activate",
GTK_SIGNAL_FUNC (master_combo_activate_callback), NULL);
gtk_signal_connect_object (
GTK_OBJECT (GTK_COMBO (master_addr_combo)->entry), "activate",
GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (window));
GTK_SIGNAL_FUNC (master_okbutton_callback), GTK_OBJECT (window));
gtk_signal_connect (
GTK_OBJECT (GTK_COMBO (master_addr_combo)->list),
"selection-changed",
GTK_SIGNAL_FUNC
(master_address_from_history_selected_callback),NULL);
GTK_WIDGET_SET_FLAGS (GTK_COMBO (master_addr_combo)->entry, GTK_CAN_FOCUS);
GTK_WIDGET_UNSET_FLAGS (GTK_COMBO (master_addr_combo)->button, GTK_CAN_FOCUS);
gtk_widget_grab_focus (GTK_COMBO (master_addr_combo)->entry);
// gtk_widget_grab_focus (GTK_COMBO (master_addr_combo)->entry);
gtk_widget_show (master_addr_combo);
if (master_history_addr->items)
combo_set_vals (master_addr_combo, master_history_addr->items, "");
if(master_to_edit)
{
gtk_entry_set_text(GTK_ENTRY (GTK_COMBO
(master_addr_combo)->entry),master2url(master_to_edit));
gtk_widget_set_state (master_addr_combo, GTK_STATE_NORMAL);
gtk_widget_set_sensitive (GTK_WIDGET(master_addr_combo),FALSE);
}
gtk_widget_show (table);
/* query type */
hbox = gtk_hbox_new (TRUE, 8);
for (i=MASTER_NATIVE;i<MASTER_NUM_QUERY_TYPES;i++)
{
master_query_type_radios[i] =
gtk_radio_button_new_with_label_from_widget(
i==MASTER_NATIVE?NULL:GTK_RADIO_BUTTON(master_query_type_radios[MASTER_NATIVE]),
_(master_designation[i]));
if(master_to_edit)
{
gtk_widget_set_sensitive (GTK_WIDGET(master_query_type_radios[i]),FALSE);
}
gtk_signal_connect(GTK_OBJECT (master_query_type_radios[i]), "toggled",
GTK_SIGNAL_FUNC (master_type_radio_callback), (gpointer)i);
gtk_widget_show (master_query_type_radios[i]);
gtk_box_pack_start (GTK_BOX (hbox),master_query_type_radios[i], FALSE, FALSE, 0);
}
if(master_to_edit)
{
master_activate_radio_for_type(current_master_query_type);
}
else if(!games[master_type].default_master_port &&
current_master_query_type == MASTER_NATIVE)
{
gtk_widget_set_state (master_query_type_radios[MASTER_NATIVE], GTK_STATE_NORMAL);
gtk_widget_set_sensitive
(GTK_WIDGET(master_query_type_radios[MASTER_NATIVE]),FALSE);
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON(master_query_type_radios[MASTER_GAMESPY]),TRUE);
}
gtk_widget_show (hbox);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
/* Separator */
@ -248,11 +438,8 @@ char *add_master_dialog (enum server_type *type, char **desc) {
button = gtk_button_new_with_label ("OK");
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_set_usize (button, 80, -1);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (master_combo_activate_callback),
GTK_OBJECT (GTK_COMBO (master_name_combo)->entry));
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (window));
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(master_okbutton_callback), window);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
@ -266,8 +453,7 @@ char *add_master_dialog (enum server_type *type, char **desc) {
unregister_window (window);
*desc = master_name_result;
return master_addr_result;
return master_to_add;
}

View File

@ -22,7 +22,7 @@
#include "xqf.h"
extern char *add_master_dialog (enum server_type *type, char **desc);
struct master *add_master_dialog (struct master *m);
extern void add_master_init (void);
extern void add_master_done (void);

View File

@ -216,7 +216,7 @@ static void server_filter_init (void) {
// 0 is no filter
for (i = 1; i <= MAX_SERVER_FILTERS; i++) {
sprintf( config_section, "/" CONFIG_FILE "/Server Filter/%d", i );
snprintf( config_section, 64, "/" CONFIG_FILE "/Server Filter/%d", i );
config_push_prefix (config_section );
/* server_filters[i] = g_malloc( sizeof( struct server_filter_vars )); */
server_filters[i].filter_retries = config_get_int ("retries=2");

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "gnuconfig.h"
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h> /* strtol */
@ -27,10 +29,6 @@
#include <arpa/inet.h> /* inet_aton, inet_ntoa */
#include <errno.h> /* errno */
#ifndef errno
extern int errno;
#endif
#include <gtk/gtk.h>
#include "xqf.h"
@ -47,17 +45,21 @@ extern int errno;
#include "zipped.h"
#include "stat.h"
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(string) gettext(string)
#else
#define _(string) (string)
#endif
struct master *favorites = NULL;
GSList *master_groups = NULL;
char* master_prefixes[MASTER_NUM_QUERY_TYPES] = {
"master://",
"gmaster://",
"http://"
};
char* master_designation[MASTER_NUM_QUERY_TYPES] = {
N_("Standard"),
N_("Gamespy"),
N_("http")
};
static GSList *all_masters = NULL;
@ -80,17 +82,15 @@ static void save_list (FILE *f, struct master *m) {
if (m->url) {
fprintf (f, "[%s %s]\n", games[m->type].id, m->url);
}
else {
if (m->master_type == 1)
{
fprintf (f, "[%s %s%s:%d]\n", games[m->type].id, PREFIX_GMASTER,
else if (m->master_type == MASTER_GAMESPY)
{
fprintf (f, "[%s %s%s:%d]\n", games[m->type].id, master_prefixes[MASTER_GAMESPY],
(m->hostname)? m->hostname : inet_ntoa (m->host->ip), m->port);
}
else
{
fprintf (f, "[%s %s%s:%d]\n", games[m->type].id, PREFIX_MASTER,
}
else
{
fprintf (f, "[%s %s%s:%d]\n", games[m->type].id, master_prefixes[MASTER_NATIVE],
(m->hostname)? m->hostname : inet_ntoa (m->host->ip), m->port);
}
}
}
@ -335,23 +335,23 @@ static struct master *read_list_parse_master (char *str, char *str2) {
if (favorites && !g_strcasecmp (str, favorites->name))
return favorites;
if (g_strncasecmp (str, PREFIX_MASTER, sizeof (PREFIX_MASTER) - 1) == 0) {
if (parse_address (str + sizeof (PREFIX_MASTER) - 1, &addr, &port)) {
if (g_strncasecmp (str, master_prefixes[MASTER_NATIVE], strlen(master_prefixes[MASTER_NATIVE])) == 0) {
if (parse_address (str + strlen(master_prefixes[MASTER_NATIVE]), &addr, &port)) {
m = find_master_server (addr, port, str2);
g_free (addr);
return m;
}
}
if (g_strncasecmp (str, PREFIX_GMASTER, sizeof (PREFIX_GMASTER) - 1) == 0) {
if (parse_address (str + sizeof (PREFIX_GMASTER) - 1, &addr, &port)) {
if (g_strncasecmp (str, master_prefixes[MASTER_GAMESPY], strlen (master_prefixes[MASTER_GAMESPY])) == 0) {
if (parse_address (str + strlen(master_prefixes[MASTER_GAMESPY]), &addr, &port)) {
m = find_master_server (addr, port, str2);
g_free (addr);
return m;
}
}
if (g_strncasecmp (str, PREFIX_URL_HTTP, sizeof (PREFIX_URL_HTTP) - 1) == 0) {
if (g_strncasecmp (str, master_prefixes[MASTER_HTTP], strlen(master_prefixes[MASTER_HTTP])) == 0) {
m = find_master_url (str);
return m;
}
@ -592,14 +592,118 @@ static struct master *create_master (char *name, enum server_type type,
struct master *add_master (char *path, char *name, enum server_type type,
int user, int lookup_only) {
char *addr;
unsigned short port;
char *addr = NULL;
unsigned short port = 0;
struct master *m = NULL;
struct host *h;
struct master *group;
struct host *h = NULL;
struct master *group = NULL;
enum master_query_type query_type;
if (g_strncasecmp (path, PREFIX_MASTER, sizeof (PREFIX_MASTER) - 1) == 0) {
if (parse_address (path + sizeof (PREFIX_MASTER) - 1, &addr, &port)) {
debug(6,"add_master(%s,%s,%d,%d,%d)",path,name,type,user,lookup_only);
query_type = get_master_query_type_from_address(path);
if( query_type == MASTER_INVALID_TYPE )
{
debug(1,"Invalid Master %s",path);
return NULL;
}
if( query_type == MASTER_NATIVE || query_type == MASTER_GAMESPY )
{
// check for valid hostname/ip
if (parse_address (path + strlen(master_prefixes[query_type]), &addr, &port))
{
// if no port was specified, add default master port if available or fail
if (!port)
{
// do not use default for gamespy
if (query_type != MASTER_GAMESPY && games[type].default_master_port)
{
port = games[type].default_master_port;
}
else
{
g_free (addr);
// translator: %s == url, eg gmaster://bla.blub.org
dialog_ok (NULL, _("You have to specify a port number for %s."),path);
return NULL;
}
}
m = find_master_server (addr, port, games[type].id);
}
}
else if( query_type == MASTER_HTTP )
{
m = find_master_url (path);
}
if (lookup_only)
{
g_free (addr);
return m;
}
if (m)
{
if (user)
{ // Master renaming is forced by user
g_free (m->name);
m->name = g_strdup (name);
m->user = TRUE;
}
else
{ // Automatically rename masters that are not edited by user
if (!m->user) {
g_free (m->name);
m->name = g_strdup (name);
}
}
g_free (addr);
return m;
}
// master was not known already, create new
if( query_type == MASTER_NATIVE || query_type == MASTER_GAMESPY )
{
m = create_master (name, type, FALSE);
h = host_add (addr);
if (h) {
m->host = h;
host_ref (h);
g_free (addr);
addr = NULL;
}
else {
m->hostname = addr;
}
m->port = port;
}
else if( query_type == MASTER_HTTP )
{
m = create_master (name, type, FALSE);
m->url = g_strdup (path);
}
m->master_type = query_type;
if (m) {
group = (struct master *) g_slist_nth_data (master_groups, type);
group->masters = g_slist_append (group->masters, m);
m->user = user;
}
return m;
}
#if 0
if (g_strncasecmp (path, master_prefixes[MASTER_NATIVE],
strlen(master_prefixes[MASTER_NATIVE])) == 0) {
if (parse_address (path + strlen(master_prefixes[MASTER_NATIVE]), &addr, &port)) {
if (!port) {
if (games[type].default_master_port) {
@ -639,7 +743,7 @@ struct master *add_master (char *path, char *name, enum server_type type,
{
m = create_master (name, type, FALSE);
m->master_type = 0; // Regular master
m->master_type = MASTER_NATIVE; // Regular master
h = host_add (addr);
if (h) {
@ -656,8 +760,9 @@ struct master *add_master (char *path, char *name, enum server_type type,
}
}
else if (g_strncasecmp (path, PREFIX_GMASTER, sizeof (PREFIX_GMASTER) - 1) == 0) {
if (parse_address (path + sizeof (PREFIX_GMASTER) - 1, &addr, &port)) {
else if (g_strncasecmp (path, master_prefixes[MASTER_GAMESPY],
strlen(master_prefixes[MASTER_GAMESPY])) == 0) {
if (parse_address (path + strlen(master_prefixes[MASTER_GAMESPY]), &addr, &port)) {
if (!port) {
if (games[type].default_master_port) {
@ -697,7 +802,7 @@ struct master *add_master (char *path, char *name, enum server_type type,
{
m = create_master (name, type, FALSE);
m->master_type = 1; // Gamespy master
m->master_type = MASTER_GAMESPY; // Gamespy master
h = host_add (addr);
if (h) {
@ -715,8 +820,8 @@ struct master *add_master (char *path, char *name, enum server_type type,
}
else {
if (g_strncasecmp (path, PREFIX_URL_HTTP, sizeof (PREFIX_URL_HTTP) - 1)
== 0) {
if (g_strncasecmp (path, master_prefixes[MASTER_HTTP],
strlen(master_prefixes[MASTER_HTTP])) == 0) {
m = find_master_url (path);
if (lookup_only) {
@ -745,7 +850,6 @@ struct master *add_master (char *path, char *name, enum server_type type,
}
}
}
if (m) {
group = (struct master *) g_slist_nth_data (master_groups, type);
group->masters = g_slist_append (group->masters, m);
@ -754,6 +858,7 @@ struct master *add_master (char *path, char *name, enum server_type type,
return m;
}
#endif
void free_master (struct master *m) {
@ -1002,11 +1107,11 @@ static void save_master_list (void) {
}
else {
if (m->master_type == 1)
addr = g_strdup_printf (PREFIX_GMASTER "%s:%d",
if (m->master_type == MASTER_GAMESPY)
addr = g_strdup_printf ("%s%s:%d", master_prefixes[MASTER_GAMESPY],
(m->hostname)? m->hostname : inet_ntoa (m->host->ip), m->port);
else
addr = g_strdup_printf (PREFIX_MASTER "%s:%d",
addr = g_strdup_printf ("%s%s:%d", master_prefixes[MASTER_NATIVE],
(m->hostname)? m->hostname : inet_ntoa (m->host->ip), m->port);
confstr = g_strjoin (" ", typeid, addr, m->name, NULL);
@ -1026,7 +1131,7 @@ void init_masters (int update) {
struct master *m;
int i;
favorites = create_master ("Favorites", UNKNOWN_SERVER, FALSE);
favorites = create_master (N_("Favorites"), UNKNOWN_SERVER, FALSE);
for (i = 0; i < GAMES_TOTAL; i++) {
m = create_master (games[i].name, i, TRUE);
@ -1200,3 +1305,29 @@ GSList *references_to_server (struct server *s) {
return res;
}
enum master_query_type get_master_query_type_from_address(char* address)
{
enum master_query_type type;
// check for known master prefix
debug(6,"get_master_query_type_from_address(%s)",address);
for (type=MASTER_NATIVE;type<MASTER_NUM_QUERY_TYPES;type++)
{
if(!g_strncasecmp( address, master_prefixes[type],
strlen(master_prefixes[type])))
{
debug(6,"get_master_query_type_from_address: found %s",master_prefixes[type]);
return type;
}
}
// only accept if there is no :// part at all
if(lowcasestrstr(address,"://"))
{
debug(6,"get_master_query_type_from_address: invalid");
return MASTER_INVALID_TYPE;
}
else
{
debug(6,"get_master_query_type_from_address: default native");
return MASTER_NATIVE;
}
}

View File

@ -26,13 +26,15 @@
#define FILENAME_LISTS "lists"
#define FILENAME_SRVINFO "srvinfo"
#define PREFIX_MASTER "master://"
#define PREFIX_GMASTER "gmaster://"
#define PREFIX_URL_HTTP "http://"
//#define PREFIX_MASTER "master://"
//#define PREFIX_GMASTER "gmaster://"
//#define PREFIX_URL_HTTP "http://"
#define ACTION_ADD "ADD"
#define ACTION_DELETE "DELETE"
extern char* master_prefixes[MASTER_NUM_QUERY_TYPES];
extern char* master_designation[MASTER_NUM_QUERY_TYPES];
extern struct master *favorites;
extern GSList *master_groups;
@ -61,6 +63,9 @@ extern int source_has_masters_to_delete (GSList *source);
extern GSList *references_to_server (struct server *s);
extern enum master_query_type get_master_query_type_from_address(char* address);
#endif /* __SOURCE_H__ */

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "gnuconfig.h"
#include <sys/types.h> /* kill */
#include <stdio.h> /* FILE, fopen, fclose, fprintf, ... */
#include <string.h> /* strchr, strcmp, strlen, strcpy, memchr, strtok */
@ -44,14 +46,6 @@
#include "dns.h"
#include "debug.h"
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(string) gettext(string)
#else
#define _(string) (string)
#endif
static void stat_next (struct stat_job *job);
@ -764,7 +758,7 @@ static struct stat_conn *stat_update_master_qstat (struct stat_job *job,
argv[argi++] = buf2;
if (m->master_type == 1)
if (m->master_type == MASTER_GAMESPY)
g_snprintf (buf2, 64, "-gsm,%s,outfile", games[m->type].qstat_str);
else
{

View File

@ -27,10 +27,6 @@
#include <time.h> /* time */
#include <string.h> /* strlen */
#ifdef ENABLE_NLS
#include <locale.h>
#endif
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@ -91,6 +87,7 @@ static char *progress_bar_str = NULL;
//static GtkWidget *server_filter_menu = NULL; /* baa */
static GtkWidget *server_menu = NULL;
static GtkWidget *source_menu = NULL;
static GtkWidget *player_menu = NULL;
static GtkWidget *connect_menu_item = NULL;
@ -112,10 +109,16 @@ static GtkWidget *edit_add_menu_item = NULL;
static GtkWidget *edit_delete_menu_item = NULL;
static GtkWidget *edit_update_master_builtin_menu_item = NULL;
static GtkWidget *edit_add_master_menu_item = NULL;
static GtkWidget *edit_edit_master_menu_item = NULL;
static GtkWidget *edit_delete_master_menu_item = NULL;
static GtkWidget *edit_find_player_menu_item = NULL;
static GtkWidget *edit_find_again_menu_item = NULL;
// rmb popup
static GtkWidget *source_add_master_menu_item = NULL;
static GtkWidget *source_edit_master_menu_item = NULL;
static GtkWidget *source_delete_master_menu_item = NULL;
static GtkWidget *view_refresh_menu_item = NULL;
static GtkWidget *view_refrsel_menu_item = NULL;
static GtkWidget *view_update_menu_item = NULL;
@ -254,6 +257,15 @@ void set_widgets_sensitivity (void) {
sens = (!stat_process && masters_to_delete);
gtk_widget_set_sensitive (edit_delete_master_menu_item, sens);
gtk_widget_set_sensitive (source_delete_master_menu_item, sens);
// you can only edit one server a time, no groups and no favorites
sens = (cur_source && cur_source->next == NULL
&& ! ((struct master *) cur_source->data)->isgroup
&& ! source_is_favorites );
gtk_widget_set_sensitive (source_edit_master_menu_item, sens);
gtk_widget_set_sensitive (edit_edit_master_menu_item, sens);
sens = (!stat_process && (server_clist->rows > 0));
@ -1190,32 +1202,33 @@ static void update_master_builtin_callback (GtkWidget *widget, gpointer data) {
}
static void add_master_callback (GtkWidget *widget, gpointer data) {
char *str;
char *desc;
enum server_type type;
struct master *m;
if (stat_process)
return;
str = add_master_dialog (&type, &desc);
if (!str || !*str)
return;
m = add_master (str, desc, type, TRUE, FALSE);
m = add_master_dialog(NULL);
if (m) {
source_ctree_add_master (source_ctree, m);
source_ctree_select_source (m);
}
else {
dialog_ok (NULL, _("Master address \"%s\" is not valid."), str);
}
g_free (str);
g_free (desc);
}
// does only work with one master selected
static void edit_master_callback (GtkWidget *widget, gpointer data) {
struct master *master_to_edit, *master_to_add;
if(!cur_source) return;
master_to_edit = (struct master *) cur_source->data;
source_ctree_select_source (master_to_edit);
master_to_add = add_master_dialog(master_to_edit);
if (master_to_add) {
source_ctree_add_master (source_ctree, master_to_add);
source_ctree_select_source (master_to_add);
}
}
static void del_master_callback (GtkWidget *widget, gpointer data) {
struct master *m;
@ -1250,8 +1263,12 @@ static void del_master_callback (GtkWidget *widget, gpointer data) {
}
if (!masters)
{
dialog_ok(NULL,_("You have to select the server you want to delete"));
return;
}
// FIXME: plural
delete = dialog_yesno (NULL, 1, _("Delete"), _("Cancel"),
_("Master%s to delete:\n\n%s"),
(g_slist_length (masters) > 1)? "s" : "",
@ -1434,6 +1451,66 @@ static void server_clist_keypress_callback (GtkWidget *widget, GdkEventKey *even
}
}
static int source_ctree_event_callback (GtkWidget *widget, GdkEvent *event) {
GdkEventButton *bevent = (GdkEventButton *) event;
GList *selection;
int row;
GtkCTreeNode *node, *node_under_mouse;
int node_is_in_selection = 0;
if (event->type == GDK_BUTTON_PRESS &&
bevent->window == GTK_CLIST(source_ctree)->clist_window) {
switch (bevent->button) {
case 3:
// lets see which row the cursor is on
if (gtk_clist_get_selection_info (GTK_CLIST(source_ctree),
bevent->x, bevent->y, &row, NULL)) {
// list of selected items
selection = GTK_CLIST(source_ctree)->selection;
// XXX: what is the first part of the && good for?
if (!g_list_find (selection, (gpointer) row) &&
(bevent->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == 0) {
node_under_mouse = gtk_ctree_node_nth(GTK_CTREE (source_ctree),row);
if(node_under_mouse)
{
// go through all selected masters and search if the one under the
// cursor is among them
while(selection)
{
node = GTK_CTREE_NODE(selection->data);
if(node == node_under_mouse)
{
node_is_in_selection = 1;
break;
}
selection = selection->next;
}
// clear selection and only select the one under the curser
if(!node_is_in_selection)
{
gtk_ctree_unselect_recursive(GTK_CTREE(source_ctree),NULL);
gtk_ctree_select (GTK_CTREE (source_ctree), node_under_mouse);
}
}
}
}
gtk_menu_popup (GTK_MENU (source_menu), NULL, NULL, NULL, NULL,
bevent->button, bevent->time);
return TRUE;
default:
return FALSE;
}
}
return FALSE;
}
static int server_clist_event_callback (GtkWidget *widget, GdkEvent *event) {
GdkEventButton *bevent = (GdkEventButton *) event;
@ -1497,7 +1574,8 @@ static void source_selection_changed (void) {
update_server_lists_from_selected_source ();
server_clist_set_list (cur_server_list);
// FIXME: plural form
print_status (main_status_bar, (server_clist->rows == 1) ?
_("%d server") : _("%d servers"), server_clist->rows);
}
@ -1505,6 +1583,7 @@ static void source_selection_changed (void) {
static void source_ctree_selection_changed_callback (GtkWidget *widget,
int row, int column, GdkEvent *event, GtkWidget *button) {
debug(6,"source_ctree_selection_changed_callback(%p,%d,%d,%p,%p)",widget,row,column,event,button);
source_selection_changed ();
}
@ -1770,6 +1849,25 @@ static const struct menuitem file_menu_items[] = {
{ MENU_END, NULL, 0, 0, NULL, NULL, NULL }
};
// appears on right click on a master server
static const struct menuitem source_ctree_popup_menu[] = {
{
MENU_ITEM, N_("Add _Master..."), 'M', GDK_CONTROL_MASK,
GTK_SIGNAL_FUNC (add_master_callback), NULL,
&source_add_master_menu_item
},
{
MENU_ITEM, N_("_Rename Master..."), 0, 0,
GTK_SIGNAL_FUNC (edit_master_callback), NULL,
&source_edit_master_menu_item
},
{
MENU_ITEM, N_("D_elete Master"), 0, 0,
GTK_SIGNAL_FUNC (del_master_callback), NULL,
&source_delete_master_menu_item
}
};
static const struct menuitem edit_menu_items[] = {
{
MENU_ITEM, N_("_Add Server..."), 'N', GDK_CONTROL_MASK,
@ -1805,6 +1903,11 @@ static const struct menuitem edit_menu_items[] = {
GTK_SIGNAL_FUNC (add_master_callback), NULL,
&edit_add_master_menu_item
},
{
MENU_ITEM, N_("_Rename Master..."), 0, 0,
GTK_SIGNAL_FUNC (edit_master_callback), NULL,
&edit_edit_master_menu_item
},
{
MENU_ITEM, N_("D_elete Master"), 0, 0,
GTK_SIGNAL_FUNC (del_master_callback), NULL,
@ -2303,6 +2406,7 @@ void create_main_window (void) {
#endif
server_menu = create_menu (srvopt_menu_items, accel_group);
source_menu = create_menu (source_ctree_popup_menu, accel_group);
/* We will call set_server_filter_menu_list_text (); below after we
have the filter status bar. It used to be here -baa */
@ -2368,6 +2472,8 @@ void create_main_window (void) {
GTK_SIGNAL_FUNC (source_ctree_selection_changed_callback), NULL);
gtk_signal_connect (GTK_OBJECT (source_ctree), "tree_unselect_row",
GTK_SIGNAL_FUNC (source_ctree_selection_changed_callback), NULL);
gtk_signal_connect (GTK_OBJECT (source_ctree), "event",
GTK_SIGNAL_FUNC (source_ctree_event_callback), NULL);
gtk_widget_show (scrollwin);

View File

@ -120,6 +120,14 @@ enum master_state {
SOURCE_ERROR
};
enum master_query_type {
MASTER_NATIVE=0,
MASTER_GAMESPY,
MASTER_HTTP,
MASTER_NUM_QUERY_TYPES,
MASTER_INVALID_TYPE
};
struct player {
char *name;
int time;
@ -195,7 +203,7 @@ struct master {
GSList *masters;
int master_type;
enum master_query_type master_type;
};
extern time_t xqf_start_time;