Crossfire Client, Trunk
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 
37 extern char* last_server;
38 
39 static void on_button_refresh(GtkButton *button, gpointer user_data);
40 
44 static gboolean on_selection_changed() {
45  GtkTreeModel *model;
46  GtkTreeIter iter;
47  char *selection;
48 
49  if (gtk_tree_selection_get_selected(metaserver_selection, &model, &iter)) {
50  gtk_tree_model_get(model, &iter, LIST_HOSTNAME, &selection, -1);
51  gtk_entry_set_text(GTK_ENTRY(metaserver_entry), selection);
52  g_free(selection);
53  gtk_widget_set_sensitive(metaserver_button, TRUE);
54  }
55  return FALSE;
56 }
57 
62 static gboolean on_server_entry_changed() {
63  if (gtk_entry_get_text_length(GTK_ENTRY(metaserver_entry)) != 0) {
64  gtk_tree_selection_unselect_all(metaserver_selection);
65  gtk_widget_set_sensitive(metaserver_button, TRUE);
66  } else {
67  gtk_widget_set_sensitive(metaserver_button, FALSE);
68  }
69  return FALSE;
70 }
71 
76  GtkCellRenderer *renderer;
77  GtkTreeViewColumn *column;
78  GtkWidget *widget;
79 
81  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "treeview_metaserver"));
83  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "metaserver_status"));
85  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "metaserver_select"));
86 
87  // Server list
88  g_signal_connect(treeview_metaserver, "row_activated",
89  G_CALLBACK(on_metaserver_select_clicked), NULL);
90 
91  // Server entry text box
93  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "metaserver_text_entry"));
94  g_signal_connect(metaserver_entry, "key_release_event",
95  G_CALLBACK(on_server_entry_changed), NULL);
96  g_signal_connect(metaserver_button, "clicked",
97  G_CALLBACK(on_metaserver_select_clicked), NULL);
98 
99  // Quit button
100  widget = GTK_WIDGET(
101  gtk_builder_get_object(dialog_xml, "button_metaserver_quit"));
102  g_signal_connect(widget, "clicked",
103  G_CALLBACK(on_button_metaserver_quit_pressed), NULL);
104 
105  // Refresh button
106  g_signal_connect(
107  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "button_refresh")),
108  "clicked", G_CALLBACK(on_button_refresh), NULL);
109 
110  // Initialize server list
112  gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
113  G_TYPE_STRING, G_TYPE_STRING);
114  gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_metaserver),
115  GTK_TREE_MODEL(store_metaserver));
116 
117  renderer = gtk_cell_renderer_text_new();
118  column = gtk_tree_view_column_new_with_attributes(
119  "Server", renderer, "text", LIST_HOSTNAME, NULL);
120  gtk_tree_view_column_set_sort_column_id(column, LIST_HOSTNAME);
121  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
122 
123  renderer = gtk_cell_renderer_text_new();
124  column = gtk_tree_view_column_new_with_attributes(
125  "Players", renderer, "text", LIST_PLAYERS, NULL);
126  gtk_tree_view_column_set_sort_column_id(column, LIST_PLAYERS);
127  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
128 
129  renderer = gtk_cell_renderer_text_new();
130  column = gtk_tree_view_column_new_with_attributes(
131  "Version", renderer, "text", LIST_VERSION, NULL);
132  gtk_tree_view_column_set_sort_column_id(column, LIST_VERSION);
133  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
134 
135  renderer = gtk_cell_renderer_text_new();
136  column = gtk_tree_view_column_new_with_attributes(
137  "Description", renderer, "text", LIST_COMMENT, NULL);
138  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_metaserver), column);
139 
141  gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_metaserver));
142  gtk_tree_selection_set_mode(metaserver_selection, GTK_SELECTION_BROWSE);
143  g_signal_connect(metaserver_selection, "changed",
144  G_CALLBACK(on_selection_changed), NULL);
145 
146  widget =
147  GTK_WIDGET(gtk_builder_get_object(dialog_xml, "button_preferences"));
148  g_signal_connect((gpointer)widget, "clicked",
149  G_CALLBACK(on_configure_activate), NULL);
150 }
151 
155 static bool server_exists(const char *server) {
156  GtkTreeModel *model = GTK_TREE_MODEL(store_metaserver);
157  GtkTreeIter iter;
158 
159  bool valid = gtk_tree_model_get_iter_first(model, &iter);
160  while (valid) {
161  char *name;
162  gtk_tree_model_get(GTK_TREE_MODEL(store_metaserver), &iter,
163  LIST_HOSTNAME, &name, -1);
164  if (strcmp(server, name) == 0) {
165  return true;
166  }
167  g_free(name);
168  valid = gtk_tree_model_iter_next(model, &iter);
169  }
170  return false;
171 }
172 
173 static void server_add(char *server, int update, int players, char *version,
174  char *comment, bool compatible) {
175  if (compatible && !server_exists(server)) {
176  GtkTreeIter iter;
177  gtk_list_store_append(store_metaserver, &iter);
178  gtk_list_store_set(store_metaserver, &iter, LIST_HOSTNAME, server,
179  LIST_IPADDR, server, LIST_PLAYERS, players,
180  LIST_VERSION, version, LIST_COMMENT, comment, -1);
181  }
182 }
183 
188 static gpointer server_fetch() {
190  return NULL;
191 }
192 
193 static void metaserver_refresh(void) {
194  gtk_list_store_clear(store_metaserver);
195 #ifdef HAVE_CURL_CURL_H
196  // Start fetching server information in a separate thread.
197  g_thread_new("server_fetch", server_fetch, NULL);
198  gtk_label_set_text(GTK_LABEL(metaserver_status), "");
199 #else
200  gtk_widget_set_sensitive(GTK_WIDGET(treeview_metaserver), FALSE);
201  gtk_label_set_text(GTK_LABEL(metaserver_status),
202  "This client doesn't have metaserver support.");
203 #endif
204 }
205 
206 static void on_button_refresh(GtkButton *button, gpointer user_data) {
208 }
209 
216  gtk_notebook_set_current_page(main_notebook, 0);
217  gtk_widget_grab_default(metaserver_button);
218 
219  gtk_entry_set_text(GTK_ENTRY(metaserver_entry), last_server);
220 
221  // Disable connect button if there is no text in the server entry box.
223 
226 }
227 
235 static void metaserver_connect_to(const char *name) {
236  char *name_dup = g_strdup(name);
237  g_strstrip(name_dup);
238  char buf[256];
239  /* Set client status and update GUI before continuing. */
240  snprintf(buf, sizeof(buf), "Connecting to '%s'...", name_dup);
241  gtk_label_set_text(GTK_LABEL(metaserver_status), buf);
242  gtk_main_iteration();
243 
244  client_connect(name_dup);
245  if (csocket.fd != NULL) {
246  LOG(LOG_DEBUG, "metaserver_connect_to", "Connected to '%s'!", name_dup);
247  if (last_server != NULL) {
248  g_free(last_server);
249  }
250  last_server = g_strdup(name);
251  save_defaults();
252  gtk_main_quit();
254  } else {
255  snprintf(buf, sizeof(buf), "Unable to connect to %s!", name_dup);
256  gtk_label_set_text(GTK_LABEL(metaserver_status), buf);
257  }
258  g_free(name_dup);
259 }
260 
267 void on_metaserver_select_clicked(GtkButton *button, gpointer user_data) {
268  const char *entry_text = gtk_entry_get_text(GTK_ENTRY(metaserver_entry));
269  if (*entry_text != '\0') {
270  metaserver_connect_to(entry_text);
271  }
272 }
273 
281 void on_button_metaserver_quit_pressed(GtkButton *button, gpointer user_data) {
282  on_window_destroy_event(GTK_WIDGET(button), user_data);
283 }
LIST_HOSTNAME
@ LIST_HOSTNAME
Definition: metaserver.c:35
LIST_COMMENT
@ LIST_COMMENT
Definition: metaserver.c:35
Playing
@ Playing
Definition: client.h:145
metaserver.h
metaserver_selection
static GtkTreeSelection * metaserver_selection
Definition: metaserver.c:33
Player_Struct::input_state
Input_State input_state
Definition: client.h:339
server_fetch
static gpointer server_fetch()
Definition: metaserver.c:188
ClientSocket::fd
GSocketConnection * fd
Definition: client.h:124
on_window_destroy_event
void on_window_destroy_event(GtkWidget *object, gpointer user_data)
Definition: main.c:213
metaserver_button
static GtkWidget * metaserver_button
Definition: metaserver.c:30
main_notebook
GtkNotebook * main_notebook
Definition: main.c:104
last_server
char * last_server
Definition: config.c:45
save_defaults
void save_defaults(void)
Definition: config.c:513
metaserver_entry
static GtkWidget * metaserver_entry
Definition: metaserver.c:31
client_connect
void client_connect(const char hostname[static 1])
Definition: client.c:289
on_selection_changed
static gboolean on_selection_changed()
Definition: metaserver.c:44
metaserver_status
static GtkWidget * metaserver_status
Definition: metaserver.c:31
metaserver_refresh
static void metaserver_refresh(void)
Definition: metaserver.c:193
gtk2proto.h
server_exists
static bool server_exists(const char *server)
Definition: metaserver.c:155
LOG
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:111
csocket
ClientSocket csocket
Definition: client.c:70
image.h
on_server_entry_changed
static gboolean on_server_entry_changed()
Definition: metaserver.c:62
ms_fetch
void ms_fetch(ms_callback callback)
Definition: metaserver.c:269
on_button_refresh
static void on_button_refresh(GtkButton *button, gpointer user_data)
Definition: metaserver.c:206
dialog_xml
GtkBuilder * dialog_xml
Definition: main.c:102
LIST_IPADDR
@ LIST_IPADDR
Definition: metaserver.c:35
server_add
static void server_add(char *server, int update, int players, char *version, char *comment, bool compatible)
Definition: metaserver.c:173
main.h
treeview_metaserver
static GtkWidget * treeview_metaserver
Definition: metaserver.c:30
cpl
Client_Player cpl
Definition: client.c:69
LIST_VERSION
@ LIST_VERSION
Definition: metaserver.c:35
Metaserver_Select
@ Metaserver_Select
Definition: client.h:147
metaserver_ui_init
void metaserver_ui_init()
Definition: metaserver.c:75
metaserver_connect_to
static void metaserver_connect_to(const char *name)
Definition: metaserver.c:235
on_button_metaserver_quit_pressed
void on_button_metaserver_quit_pressed(GtkButton *button, gpointer user_data)
Definition: metaserver.c:281
metaserver_show_prompt
void metaserver_show_prompt()
Definition: metaserver.c:215
store_metaserver
static GtkListStore * store_metaserver
Definition: metaserver.c:32
on_metaserver_select_clicked
void on_metaserver_select_clicked(GtkButton *button, gpointer user_data)
Definition: metaserver.c:267
LOG_DEBUG
@ LOG_DEBUG
Useful debugging information.
Definition: client.h:433
on_configure_activate
void on_configure_activate(GtkWidget *menuitem, gpointer user_data)
Definition: config.c:778
client.h
LIST_PLAYERS
@ LIST_PLAYERS
Definition: metaserver.c:35