Crossfire Client, Branch
R11627
|
00001 const char * const rcsid_gtk2_metaserver_c = 00002 "$Id: metaserver.c 9201 2008-06-01 17:32:45Z anmaster $"; 00003 /* 00004 Crossfire client, a client program for the crossfire program. 00005 00006 Copyright (C) 2005 Mark Wedel & Crossfire Development Team 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 00022 The author can be reached via e-mail to crossfire@metalforge.org 00023 */ 00024 00031 #ifdef HAVE_CONFIG_H 00032 # include <config.h> 00033 #endif 00034 00035 #include <gtk/gtk.h> 00036 #include <glade/glade.h> 00037 00038 #include "client.h" 00039 00040 #include "image.h" 00041 #include "gtk2proto.h" 00042 #include "metaserver.h" 00043 #include "main.h" 00044 #include <pthread.h> 00045 00046 static GtkWidget *metaserver_window, *treeview_metaserver, *metaserver_button, 00047 *metaserver_status, *metaserver_entry; 00048 static GtkListStore *store_metaserver; 00049 static GtkTreeSelection *metaserver_selection; 00050 00051 enum { 00052 LIST_HOSTNAME, LIST_IPADDR, LIST_IDLETIME, LIST_PLAYERS, LIST_VERSION, LIST_COMMENT 00053 }; 00054 00066 gboolean metaserver_selection_func ( 00067 GtkTreeSelection *selection, 00068 GtkTreeModel *model, 00069 GtkTreePath *path, 00070 gboolean path_currently_selected, 00071 gpointer userdata) 00072 { 00073 gtk_widget_set_sensitive(metaserver_button, TRUE); 00074 gtk_entry_set_text(GTK_ENTRY(metaserver_entry), ""); 00075 00076 return TRUE; 00077 } 00078 00082 void get_metaserver(void) 00083 { 00084 static int has_init=0; 00085 GtkTreeIter iter; 00086 int i, j; 00087 const gchar *metaserver_txt; 00088 GladeXML *xml_tree; 00089 GtkWidget *widget; 00090 00091 if (!has_init) { 00092 GtkTreeViewColumn *column; 00093 GtkCellRenderer *renderer; 00094 00095 metaserver_window = glade_xml_get_widget (dialog_xml, 00096 "metaserver_window"); 00097 xml_tree = glade_get_widget_tree(GTK_WIDGET(metaserver_window)); 00098 00099 gtk_window_set_transient_for(GTK_WINDOW(metaserver_window), GTK_WINDOW(window_root)); 00100 00101 treeview_metaserver = glade_xml_get_widget(xml_tree, 00102 "treeview_metaserver"); 00103 metaserver_button = 00104 glade_xml_get_widget(xml_tree, "metaserver_select"); 00105 metaserver_status = 00106 glade_xml_get_widget(xml_tree, "metaserver_status"); 00107 metaserver_entry = 00108 glade_xml_get_widget(xml_tree, "metaserver_text_entry"); 00109 00110 g_signal_connect ((gpointer) metaserver_window, "destroy", 00111 G_CALLBACK (on_window_destroy_event), NULL); 00112 g_signal_connect ((gpointer) treeview_metaserver, "row_activated", 00113 G_CALLBACK (on_treeview_metaserver_row_activated), NULL); 00114 g_signal_connect ((gpointer) metaserver_entry, "activate", 00115 G_CALLBACK (on_metaserver_text_entry_activate), NULL); 00116 g_signal_connect ((gpointer) metaserver_entry, "key_press_event", 00117 G_CALLBACK (on_metaserver_text_entry_key_press_event), NULL); 00118 g_signal_connect ((gpointer) metaserver_button, "clicked", 00119 G_CALLBACK (on_metaserver_select_clicked), NULL); 00120 00121 widget = glade_xml_get_widget(xml_tree, "button_metaserver_quit"); 00122 g_signal_connect ((gpointer) widget, "pressed", 00123 G_CALLBACK (on_button_metaserver_quit_pressed), NULL); 00124 g_signal_connect ((gpointer) widget, "activate", 00125 G_CALLBACK (on_button_metaserver_quit_pressed), NULL); 00126 00127 store_metaserver = gtk_list_store_new (6, 00128 G_TYPE_STRING, 00129 G_TYPE_STRING, 00130 G_TYPE_INT, 00131 G_TYPE_INT, 00132 G_TYPE_STRING, 00133 G_TYPE_STRING); 00134 00135 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_metaserver), GTK_TREE_MODEL(store_metaserver)); 00136 00137 renderer = gtk_cell_renderer_text_new (); 00138 column = gtk_tree_view_column_new_with_attributes ("Hostname", renderer, 00139 "text", LIST_HOSTNAME, 00140 NULL); 00141 gtk_tree_view_column_set_sort_column_id(column, LIST_HOSTNAME); 00142 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_metaserver), column); 00143 00144 renderer = gtk_cell_renderer_text_new (); 00145 column = gtk_tree_view_column_new_with_attributes ("Updated (Sec)", renderer, 00146 "text", LIST_IDLETIME, 00147 NULL); 00148 gtk_tree_view_column_set_sort_column_id(column, LIST_IDLETIME); 00149 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_metaserver), column); 00150 00151 renderer = gtk_cell_renderer_text_new (); 00152 column = gtk_tree_view_column_new_with_attributes ("Players", renderer, 00153 "text", LIST_PLAYERS, 00154 NULL); 00155 gtk_tree_view_column_set_sort_column_id(column, LIST_PLAYERS); 00156 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_metaserver), column); 00157 00158 renderer = gtk_cell_renderer_text_new (); 00159 column = gtk_tree_view_column_new_with_attributes ("Version", renderer, 00160 "text", LIST_VERSION, 00161 NULL); 00162 gtk_tree_view_column_set_sort_column_id(column, LIST_VERSION); 00163 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_metaserver), column); 00164 00165 renderer = gtk_cell_renderer_text_new (); 00166 column = gtk_tree_view_column_new_with_attributes ("Server Comment", renderer, 00167 "text", LIST_COMMENT, 00168 NULL); 00169 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_metaserver), column); 00170 00171 gtk_widget_realize(metaserver_window); 00172 metaserver_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_metaserver)); 00173 gtk_tree_selection_set_mode (metaserver_selection, GTK_SELECTION_BROWSE); 00174 gtk_tree_selection_set_select_function(metaserver_selection, metaserver_selection_func, NULL, NULL); 00175 00176 has_init=1; 00177 } 00178 gtk_widget_show(metaserver_window); 00179 00180 gtk_label_set_text(GTK_LABEL(metaserver_status), "Waiting for data from metaserver"); 00181 00182 metaserver_txt = gtk_entry_get_text(GTK_ENTRY(metaserver_entry)); 00183 if (*metaserver_txt == '\0') { 00184 gtk_widget_set_sensitive(metaserver_button, FALSE); 00185 } else { 00186 gtk_widget_set_sensitive(metaserver_button, TRUE); 00187 } 00188 00189 gtk_list_store_clear(store_metaserver); 00190 00191 while (metaserver_check_status()) { 00192 usleep(100); 00193 gtk_main_iteration_do(FALSE); 00194 } 00195 00196 pthread_mutex_lock(&ms2_info_mutex); 00197 00198 if (cached_servers_num) { 00199 for ( i = 0; i < cached_servers_num; i++ ) { 00200 for (j=0; j < meta_numservers; j++) { 00201 if (!strcmp(cached_servers_name[i], meta_servers[j].hostname)) 00202 break; 00203 } 00204 if (j == meta_numservers) { 00205 gtk_list_store_append(store_metaserver, &iter); 00206 gtk_list_store_set(store_metaserver, &iter, 00207 LIST_HOSTNAME, cached_servers_name[i], 00208 LIST_IPADDR, cached_servers_ip[i], 00209 LIST_COMMENT, "Cached server entry", 00210 -1); 00211 } 00212 } 00213 } 00214 00215 qsort(meta_servers, meta_numservers, sizeof(Meta_Info), (int (*)(const void *, const void *))meta_sort); 00216 00217 for (i=0; i<meta_numservers; i++) { 00218 if (check_server_version(i)){ 00219 gtk_list_store_append(store_metaserver, &iter); 00220 gtk_list_store_set(store_metaserver, &iter, 00221 LIST_HOSTNAME, meta_servers[i].hostname, 00222 LIST_IPADDR, meta_servers[i].hostname, 00223 LIST_IDLETIME, meta_servers[i].idle_time, 00224 LIST_PLAYERS, meta_servers[i].num_players, 00225 LIST_VERSION, meta_servers[i].version, 00226 LIST_COMMENT, meta_servers[i].text_comment, 00227 -1); 00228 } 00229 } 00230 pthread_mutex_unlock(&ms2_info_mutex); 00231 if (server) { 00232 gtk_list_store_append(store_metaserver, &iter); 00233 gtk_list_store_set(store_metaserver, &iter, 00234 LIST_HOSTNAME, server, 00235 LIST_COMMENT, "default server", 00236 -1); 00237 } 00238 00239 cpl.input_state = Metaserver_Select; 00240 gtk_label_set_text(GTK_LABEL(metaserver_status), "Waiting for user selection"); 00241 00242 enable_menu_items(FALSE); 00243 /* draw_map() is to just redraw the splash */ 00244 draw_map(FALSE); 00245 gtk_main(); 00246 00247 gtk_widget_hide(metaserver_window); 00248 } 00249 00256 void 00257 on_metaserver_select_clicked (GtkButton *button, 00258 gpointer user_data) 00259 { 00260 GtkTreeModel *model; 00261 GtkTreeIter iter; 00262 char *name=NULL, *ip=NULL, buf[256], *metaserver_txt; 00263 00264 metaserver_txt = (char*)gtk_entry_get_text(GTK_ENTRY(metaserver_entry)); 00265 if (gtk_tree_selection_get_selected (metaserver_selection, &model, &iter)) { 00266 gtk_tree_model_get(model, &iter, LIST_HOSTNAME, &name, LIST_IPADDR, &ip, -1); 00267 00268 } else if (*metaserver_txt == '\0') { 00269 00270 /* This can happen if user blanks out server name text field then hits 00271 * the connect button. 00272 */ 00273 gtk_label_set_text(GTK_LABEL(metaserver_status), "Error - nothing selected!\n"); 00274 gtk_widget_set_sensitive(metaserver_button, FALSE); 00275 return; 00276 } else { 00277 /* This shouldn't happen because the button should not be pressable 00278 * until the user selects something 00279 */ 00280 gtk_label_set_text(GTK_LABEL(metaserver_status), "Error - nothing selected!\n"); 00281 } 00282 if (!name) name = metaserver_txt; 00283 00284 snprintf(buf, 255, "Trying to connect to %s", name); 00285 00286 gtk_label_set_text(GTK_LABEL(metaserver_status), buf); 00287 00288 csocket.fd=init_connection(ip?ip:name, use_config[CONFIG_PORT]); 00289 if (csocket.fd==-1) { 00290 snprintf(buf, 255, "Unable to connect to %s!", name); 00291 gtk_label_set_text(GTK_LABEL(metaserver_status), buf); 00292 } else { 00293 snprintf(buf, 255, "Connected to %s!", name); 00294 gtk_label_set_text(GTK_LABEL(metaserver_status), buf); 00295 gtk_main_quit(); 00296 cpl.input_state = Playing; 00297 } 00298 } 00299 00308 static void metaserver_connect_to(const char *name, const char *ip) 00309 { 00310 char buf[256], *cp, newname[256]; 00311 int port=use_config[CONFIG_PORT]; 00312 00313 snprintf(buf, 255, "Trying to connect to %s", name); 00314 00315 gtk_label_set_text(GTK_LABEL(metaserver_status), buf); 00316 strncpy(newname, name, 255); 00317 newname[255]=0; 00318 00319 if ((cp=strchr(newname,':'))!=NULL) { 00320 port = atoi(cp+1); 00321 *cp=0; 00322 } 00323 00324 csocket.fd=init_connection((char*)(ip?ip:newname), port); 00325 if (csocket.fd==-1) { 00326 snprintf(buf, 255, "Unable to connect to %s!", name); 00327 gtk_label_set_text(GTK_LABEL(metaserver_status), buf); 00328 } else { 00329 snprintf(buf, 255, "Connected to %s!", name); 00330 gtk_label_set_text(GTK_LABEL(metaserver_status), buf); 00331 gtk_main_quit(); 00332 cpl.input_state = Playing; 00333 } 00334 } 00335 00345 void 00346 on_treeview_metaserver_row_activated (GtkTreeView *treeview, 00347 GtkTreePath *path, 00348 GtkTreeViewColumn *column, 00349 gpointer user_data) 00350 { 00351 GtkTreeIter iter; 00352 GtkTreeModel *model; 00353 char *name, *ip; 00354 00355 model = gtk_tree_view_get_model(treeview); 00356 if (gtk_tree_model_get_iter(model, &iter, path)) { 00357 gtk_tree_model_get(model, &iter, LIST_HOSTNAME, &name, LIST_IPADDR, &ip, -1); 00358 metaserver_connect_to(name, ip); 00359 } 00360 } 00361 00369 void 00370 on_metaserver_text_entry_activate (GtkEntry *entry, 00371 gpointer user_data) 00372 { 00373 const gchar *entry_text; 00374 00375 entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); 00376 00377 metaserver_connect_to(entry_text, NULL); 00378 } 00379 00387 void 00388 on_button_metaserver_quit_pressed (GtkButton *button, 00389 gpointer user_data) 00390 { 00391 #ifdef WIN32 00392 script_killall(); 00393 #endif 00394 exit(0); 00395 } 00396 00406 gboolean 00407 on_metaserver_text_entry_key_press_event 00408 (GtkWidget *widget, 00409 GdkEventKey *event, 00410 gpointer user_data) 00411 { 00412 00413 gtk_widget_set_sensitive(metaserver_button, TRUE); 00414 gtk_tree_selection_unselect_all(metaserver_selection); 00415 return FALSE; 00416 }