Crossfire Client, Trunk  R20996
metaserver.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
20 #include "client.h"
21 
22 #include <gtk/gtk.h>
23 #include <stdbool.h>
24 
25 #include "image.h"
26 #include "main.h"
27 #include "metaserver.h"
28 #include "gtk2proto.h"
29 
32 static GtkListStore *store_metaserver;
33 static GtkTreeSelection *metaserver_selection;
34 
36 
40 static gboolean on_selection_changed() {
41  GtkTreeModel *model;
42  GtkTreeIter iter;
43  char *selection;
44 
45  if (gtk_tree_selection_get_selected(metaserver_selection, &model, &iter)) {
46  gtk_tree_model_get(model, &iter, LIST_HOSTNAME, &selection, -1);
47  gtk_entry_set_text(GTK_ENTRY(metaserver_entry), selection);
48  g_free(selection);
49  gtk_widget_set_sensitive(metaserver_button, TRUE);
50  }
51  return FALSE;
52 }
53 
58 static gboolean on_server_entry_changed() {
59  if (gtk_entry_get_text_length(GTK_ENTRY(metaserver_entry)) != 0) {
60  gtk_tree_selection_unselect_all(metaserver_selection);
61  gtk_widget_set_sensitive(metaserver_button, TRUE);
62  } else {
63  gtk_widget_set_sensitive(metaserver_button, FALSE);
64  }
65  return FALSE;
66 }
67 
72  GtkCellRenderer *renderer;
73  GtkTreeViewColumn *column;
74  GtkWidget *widget;
75 
77  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "treeview_metaserver"));
79  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "metaserver_status"));
81  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "metaserver_select"));
82 
83  // Server list
84  g_signal_connect(treeview_metaserver, "row_activated",
85  G_CALLBACK(on_metaserver_select_clicked), NULL);
86 
87  // Server entry text box
89  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "metaserver_text_entry"));
90  g_signal_connect(metaserver_entry, "key_release_event",
91  G_CALLBACK(on_server_entry_changed), NULL);
92  g_signal_connect(metaserver_button, "clicked",
93  G_CALLBACK(on_metaserver_select_clicked), NULL);
94 
95  // Quit button
96  widget = GTK_WIDGET(
97  gtk_builder_get_object(dialog_xml, "button_metaserver_quit"));
98  g_signal_connect(widget, "clicked",
99  G_CALLBACK(on_button_metaserver_quit_pressed), NULL);
100 
101  // Initialize server list
103  gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
104  G_TYPE_STRING, G_TYPE_STRING);
105  gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_metaserver),
106  GTK_TREE_MODEL(store_metaserver));
107 
108  renderer = gtk_cell_renderer_text_new();
109  column = gtk_tree_view_column_new_with_attributes(
110  "Server", renderer, "text", LIST_HOSTNAME, NULL);
111  gtk_tree_view_column_set_sort_column_id(column, LIST_HOSTNAME);
112  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
113 
114  renderer = gtk_cell_renderer_text_new();
115  column = gtk_tree_view_column_new_with_attributes(
116  "Players", renderer, "text", LIST_PLAYERS, NULL);
117  gtk_tree_view_column_set_sort_column_id(column, LIST_PLAYERS);
118  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
119 
120  renderer = gtk_cell_renderer_text_new();
121  column = gtk_tree_view_column_new_with_attributes(
122  "Version", renderer, "text", LIST_VERSION, NULL);
123  gtk_tree_view_column_set_sort_column_id(column, LIST_VERSION);
124  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
125 
126  renderer = gtk_cell_renderer_text_new();
127  column = gtk_tree_view_column_new_with_attributes(
128  "Description", renderer, "text", LIST_COMMENT, NULL);
129  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
130 
132  gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_metaserver));
133  gtk_tree_selection_set_mode(metaserver_selection, GTK_SELECTION_BROWSE);
134  g_signal_connect(metaserver_selection, "changed",
135  G_CALLBACK(on_selection_changed), NULL);
136 
137  widget =
138  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "button_preferences"));
139  g_signal_connect((gpointer)widget, "clicked",
140  G_CALLBACK(on_configure_activate), NULL);
141 }
142 
146 static bool server_exists(const char *server) {
147  GtkTreeModel *model = GTK_TREE_MODEL(store_metaserver);
148  GtkTreeIter iter;
149 
150  bool valid = gtk_tree_model_get_iter_first(model, &iter);
151  while (valid) {
152  char *name;
153  gtk_tree_model_get(GTK_TREE_MODEL(store_metaserver), &iter,
154  LIST_HOSTNAME, &name, -1);
155  if (strcmp(server, name) == 0) {
156  return true;
157  }
158  g_free(name);
159  valid = gtk_tree_model_iter_next(model, &iter);
160  }
161  return false;
162 }
163 
164 static void server_add(char *server, int update, int players, char *version,
165  char *comment, bool compatible) {
166  if (compatible && !server_exists(server)) {
167  GtkTreeIter iter;
168  gtk_list_store_append(store_metaserver, &iter);
169  gtk_list_store_set(store_metaserver, &iter, LIST_HOSTNAME, server,
170  LIST_IPADDR, server, LIST_PLAYERS, players,
171  LIST_VERSION, version, LIST_COMMENT, comment, -1);
172  }
173 }
174 
179 static gpointer server_fetch() {
181  return NULL;
182 }
183 
190  gtk_notebook_set_current_page(main_notebook, 0);
191  gtk_widget_grab_default(metaserver_button);
192 
193  // Disable connect button if there is no text in the server entry box.
195 
196  gtk_list_store_clear(store_metaserver);
197 
198 #ifdef HAVE_CURL_CURL_H
199  // Start fetching server information in a separate thread.
200  g_thread_new("server_fetch", server_fetch, NULL);
201  gtk_label_set_text(GTK_LABEL(metaserver_status), "");
202 #else
203  gtk_widget_set_sensitive(GTK_WIDGET(treeview_metaserver), FALSE);
204  gtk_label_set_text(GTK_LABEL(metaserver_status),
205  "This client doesn't have metaserver support.");
206 #endif
208 
209 }
210 
218 static void metaserver_connect_to(const char *name) {
219  char buf[256];
220  /* Set client status and update GUI before continuing. */
221  snprintf(buf, sizeof(buf), "Connecting to '%s'...", name);
222  gtk_label_set_text(GTK_LABEL(metaserver_status), buf);
223  gtk_main_iteration();
224 
225  client_connect(name);
226  if (csocket.fd != NULL) {
227  LOG(LOG_DEBUG, "metaserver_connect_to", "Connected to '%s'!", name);
228  gtk_main_quit();
230  } else {
231  snprintf(buf, sizeof(buf), "Unable to connect to %s!", name);
232  gtk_label_set_text(GTK_LABEL(metaserver_status), buf);
233  }
234 }
235 
242 void on_metaserver_select_clicked(GtkButton *button, gpointer user_data) {
243  const char *entry_text = gtk_entry_get_text(GTK_ENTRY(metaserver_entry));
244  if (*entry_text != '\0') {
245  metaserver_connect_to(entry_text);
246  }
247 }
248 
256 void on_button_metaserver_quit_pressed(GtkButton *button, gpointer user_data) {
257  on_window_destroy_event(GTK_OBJECT(button), user_data);
258 }
void on_window_destroy_event(GtkObject *object, gpointer user_data)
Definition: main.c:153
static gpointer server_fetch()
Definition: metaserver.c:179
static void server_add(char *server, int update, int players, char *version, char *comment, bool compatible)
Definition: metaserver.c:164
GSocketConnection * fd
Definition: client.h:120
SoundServer * server
Definition: sound.c:25
void metaserver_show_prompt()
Definition: metaserver.c:189
static bool server_exists(const char *server)
Definition: metaserver.c:146
static void metaserver_connect_to(const char *name)
Definition: metaserver.c:218
ClientSocket csocket
Definition: client.c:67
void ms_fetch(ms_callback callback)
Definition: metaserver.c:269
static GtkWidget * metaserver_entry
Definition: metaserver.c:30
void on_metaserver_select_clicked(GtkButton *button, gpointer user_data)
Definition: metaserver.c:242
static GtkWidget * metaserver_button
Definition: metaserver.c:30
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:111
static gboolean on_server_entry_changed()
Definition: metaserver.c:58
static GtkWidget * metaserver_status
Definition: metaserver.c:30
static GtkWidget * treeview_metaserver
Definition: metaserver.c:30
Client_Player cpl
Definition: client.c:66
void on_configure_activate(GtkWidget *menuitem, gpointer user_data)
Definition: config.c:751
void client_connect(const char hostname[static 1])
Definition: client.c:269
static GtkTreeSelection * metaserver_selection
Definition: metaserver.c:33
Input_State input_state
Definition: client.h:341
void on_button_metaserver_quit_pressed(GtkButton *button, gpointer user_data)
Definition: metaserver.c:256
void metaserver_ui_init()
Definition: metaserver.c:71
GtkNotebook * main_notebook
Definition: main.c:98
static GtkListStore * store_metaserver
Definition: metaserver.c:32
GtkBuilder * dialog_xml
Definition: main.c:96
Useful debugging information.
Definition: client.h:441
static gboolean on_selection_changed()
Definition: metaserver.c:40