Crossfire Client, Trunk
main.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 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 
19 #include "client.h"
20 
21 #include <errno.h>
22 #include <gtk/gtk.h>
23 #include <stdbool.h>
24 
25 #ifndef WIN32
26 #include <signal.h>
27 #endif
28 
29 #ifdef HAVE_CAPSICUM
30 #include <sys/capsicum.h>
31 #endif
32 
33 #include "client-vala.h"
34 #include "image.h"
35 #include "main.h"
36 #include "mapdata.h"
37 #include "metaserver.h"
38 #include "script.h"
39 #include "sound.h"
40 #include "gtk2proto.h"
41 
42 /* Sets up the basic colors. */
43 static const char *const colorname[NUM_COLORS] = {
44  "Black", /* 0 */
45  "White", /* 1 */
46  "Navy", /* 2 */
47  "Red", /* 3 */
48  "Orange", /* 4 */
49  "DodgerBlue", /* 5 */
50  "DarkOrange2", /* 6 */
51  "SeaGreen", /* 7 */
52  "DarkSeaGreen", /* 8 *//* Used for window background color */
53  "Grey50", /* 9 */
54  "Sienna", /* 10 */
55  "Gold", /* 11 */
56  "Khaki" /* 12 */
57 };
58 
59 static gboolean updatekeycodes = FALSE;
60 
61 /* TODO: Move these declarations to actual header files. */
62 extern bool time_map_redraw;
63 extern bool profile_latency;
64 extern int MINLOG;
66 
67 static bool playing = FALSE; // Set to true when main window is up, gates self-generated ticks
68 
69 static char *connect_server = NULL;
70 
71 static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error);
72 
74 static GOptionEntry options[] = {
75  { "server", 's', 0, G_OPTION_ARG_STRING, &connect_server,
76  "Connect to the given server", "SERVER[:PORT]" },
77  { "cache", 0, 0, G_OPTION_ARG_NONE, &want_config[CONFIG_CACHE],
78  "Cache images", NULL },
79  { "prefetch", 0, 0, G_OPTION_ARG_NONE, &want_config[CONFIG_DOWNLOAD],
80  "Download images before playing", NULL },
81  { "faceset", 0, 0, G_OPTION_ARG_STRING, &face_info.want_faceset,
82  "Use the given faceset (if available)", "FACESET" },
83 
84  { "sound_server", 0, 0, G_OPTION_ARG_FILENAME, &sound_server,
85  "Path to the sound server", "PATH" },
86  { "updatekeycodes", 0, 0, G_OPTION_ARG_NONE, &updatekeycodes,
87  "Update the saved bindings for this keyboard", NULL },
88 
89  { "loginmethod", 0, 0, G_OPTION_ARG_INT, &wantloginmethod,
90  "Login method to request from server", NULL },
91  { "profile-latency", 0, 0, G_OPTION_ARG_NONE, &profile_latency,
92  "Log command acknowledgement latency to stdout", NULL },
93  { "profile-redraw", 0, 0, G_OPTION_ARG_NONE, &time_map_redraw,
94  "Print map redraw times to stdout", NULL },
95  { "verbose", 'v', 0, G_OPTION_ARG_INT, &MINLOG,
96  "Set verbosity (0 is the most verbose)", "LEVEL" },
97  { "debug-protocol", 0, 0, G_OPTION_ARG_NONE, &debug_protocol,
98  "Print commands to and from the server", NULL },
99  { "script", 0, 0, G_OPTION_ARG_CALLBACK, &script_launch,
100  "Launch client script at start (can be used multiple times)", "SCRIPT_NAME" },
101  { NULL }
102 };
103 
105 
107 
108 GtkBuilder *dialog_xml, *window_xml;
110 GtkNotebook *main_notebook;
111 
112 GtkCheckButton *sandbox_enable;
113 
114 extern time_t last_command_sent;
115 extern bool is_afk;
116 
117 #ifdef WIN32 /* Win32 scripting support */
118 static int do_scriptout() {
119  script_process(NULL);
120  return (TRUE);
121 }
122 #endif /* WIN32 */
123 
124 static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error)
125 {
126  (void)option_name; // always "--script"
127  (void)data; // Not used
128  (void)error; // Not used
129  script_init(value);
130  return TRUE;
131 }
132 
137 static gboolean redraw(gpointer data) {
138  // Add a check for client_is_connected so that forced socket termination
139  // does not erroneously attempt to redraw the map after it has been destroyed.
140  if (client_is_connected()) {
141  if (have_new_image) {
142  if (cpl.container) {
144  }
145  cpl.ob->inv_updated = 1;
146  have_new_image = 0;
147  }
148  draw_map();
149  draw_lists();
150  }
151  return FALSE;
152 }
153 
154 static void on_auto_afk_response(GtkDialog *self, gint response_id, gpointer user_data) {
155  // It is possible for is_afk to be false because dialog is non-modal.
156  switch (response_id) {
157  case 1:
158  gtk_widget_destroy(GTK_WIDGET(self));
159  break;
160  case 2:
161  if (is_afk) {
162  send_command("afk", 0, true);
163  }
165  config_check();
166  save_defaults();
167  gtk_widget_destroy(GTK_WIDGET(self));
168  break;
169  default:
170  // includes closing the pop-up
171  if (is_afk) {
172  send_command("afk", 0, true);
173  }
174  gtk_widget_destroy(GTK_WIDGET(self));
175  break;
176  }
177 }
178 
179 static void auto_afk() {
180  send_command("afk", 0, true);
181  GtkWidget *dialog = gtk_dialog_new_with_buttons("Auto-AFK", GTK_WINDOW(window_root), GTK_DIALOG_DESTROY_WITH_PARENT,
182  "Return to game", 0, "Return to game, but stay AFK", 1, "Return to game, disable auto-AFK", 2, NULL);
183  GtkWidget *label, *content_area;
184  content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
185  label = gtk_label_new("You have been automatically marked as being away.");
186  gtk_container_add(GTK_CONTAINER(content_area), label);
187  g_signal_connect_swapped(dialog, "response", G_CALLBACK(on_auto_afk_response), dialog);
188  gtk_widget_show_all(dialog);
189 }
190 
194 void client_tick(guint32 tick) {
195  if (cpl.showmagic) {
196  if (gtk_notebook_get_current_page(GTK_NOTEBOOK(map_notebook)) !=
197  MAGIC_MAP_PAGE) {
198  // Stop flashing when the user switches back to the map window.
199  cpl.showmagic = 0;
200  } else {
202  cpl.showmagic ^= 2;
203  }
204  }
205  if (cpl.spells_updated) {
207  }
208 
210  inventory_tick();
212 }
216 void on_window_destroy_event(GtkWidget *object, gpointer user_data) {
217  script_killall();
218  LOG(LOG_DEBUG, "main.c::client_exit", "Exiting with return value 0.");
219  exit(0);
220 }
221 
225 static gboolean do_network(GObject *stream, gpointer data) {
226  struct timeval timeout = {0, 0};
227  fd_set tmp_read;
228  int pollret;
229 
230  if (!client_is_connected()) {
231  // It would be better to call gtk_main_quit() after client_disconnect(). But that function
232  // is in common, so we just check here.
233  gtk_main_quit();
234  return FALSE;
235  }
236 
237  client_run();
238 
239  FD_ZERO(&tmp_read);
240  int maxfd;
241  script_fdset(&maxfd, &tmp_read);
242  pollret = select(maxfd, &tmp_read, NULL, NULL, &timeout);
243  if (pollret < 0) {
244 #ifndef WIN32
245  // FIXME: For whatever reason, we get errors claiming "no error" here in Windows
246  LOG(LOG_ERROR, "do_network", "script select() failed: %s", strerror(errno));
247 #endif
248  } else if (pollret > 0) {
249  script_process(&tmp_read);
250  }
251 
252  return TRUE;
253 }
254 
255 static gboolean self_tick(gpointer data) {
256  if (playing) {
257  g_idle_add(redraw, NULL);
258 
259  if (!is_afk && use_config[CONFIG_AUTO_AFK] != 0 && time(NULL) > (last_command_sent + use_config[CONFIG_AUTO_AFK])) {
260  auto_afk();
261  }
263  client_tick(0);
264  }
265  return TRUE;
266  }
267  return FALSE;
268 }
269 
273 static void event_loop() {
274 #ifdef WIN32
275  g_timeout_add(250, G_SOURCE_FUNC(do_scriptout), NULL);
276 #endif
277 
278  // Set up network callback
279  GSource *net_source = client_get_source();
280  g_assert(net_source != NULL); // crashes if input stream is not a pollable input stream
281  g_source_set_callback(net_source, (GSourceFunc)do_network, NULL, NULL);
282  g_source_attach(net_source, NULL);
283 
284  gtk_main();
285 }
286 
298 static void parse_args(int argc, char *argv[]) {
299  GOptionContext *context = g_option_context_new("- Crossfire GTKv2 Client");
300  GError *error = NULL;
301 
302  g_option_context_add_main_entries(context, options, NULL);
303  g_option_context_add_group(context, gtk_get_option_group(TRUE));
304 
305  if (!g_option_context_parse(context, &argc, &argv, &error)) {
306  g_print("%s\n", error->message);
307  g_error_free(error);
308  exit(EXIT_FAILURE);
309  }
310 
311  g_option_context_free(context);
312 
313  /*
314  * Move this after the parsing of command line options, since that can
315  * change the default log level.
316  */
317  LOG(LOG_DEBUG, "Client Version", VERSION_INFO);
318  if (MINLOG <= 0) {
319  g_setenv("CF_SOUND_DEBUG", "yes", false);
320  }
321 }
322 
328 void error_dialog(char *error, char *message) {
329  LOG(LOG_ERROR, error, message);
330  GtkWidget *dialog = gtk_message_dialog_new(
331  NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
332  GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", error);
333  gtk_window_set_title(GTK_WINDOW(dialog), "Crossfire Client");
334  gtk_message_dialog_format_secondary_markup(
335  GTK_MESSAGE_DIALOG(dialog), "%s", message);
336  gtk_dialog_run(GTK_DIALOG(dialog));
337  gtk_widget_destroy(dialog);
338 }
339 
352 void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level,
353  const gchar *message, gpointer user_data) {
354  g_usleep(1 * 1e6);
355 }
356 
357 static void init_sockets() {
358 #ifndef WIN32
359  signal(SIGPIPE, SIG_IGN);
360 #endif
361 }
362 
366 static char *init_ui_layout(const char *name) {
367  guint retval = gtk_builder_add_from_file(window_xml, name, NULL);
368  if (retval > 0 && strlen(name) > 0) {
369  if (window_xml_file != name) { // FIXME: caught by Valgrind
370  strncpy(window_xml_file, name, sizeof(window_xml_file));
371  }
372  return window_xml_file;
373  } else {
374  return NULL;
375  }
376 }
377 
378 static void init_ui() {
379  GError *error = NULL;
380  GdkGeometry geometry;
381  int i;
382 
383  /* Load dialog windows using GtkBuilder. */
384  dialog_xml = gtk_builder_new();
385  if (!gtk_builder_add_from_file(dialog_xml, DIALOG_FILENAME, &error)) {
386  error_dialog("Couldn't load UI dialogs.", error->message);
387  g_error_free(error);
388  exit(EXIT_FAILURE);
389  }
390  LOG(LOG_DEBUG, "init_ui", "loaded dialog_xml '%s'", DIALOG_FILENAME);
391 
392  /* Load main window using GtkBuilder. */
393  window_xml = gtk_builder_new();
394  if (init_ui_layout(window_xml_file) == NULL) {
395  LOG(LOG_DEBUG, "init_ui_layout", "Could not initialize '%s', using default layout", window_xml_file);
396  if (init_ui_layout(DEFAULT_UI) == NULL) {
397  g_error("Could not load default layout!");
398  }
399  }
400  LOG(LOG_DEBUG, "init_ui", "loaded window_xml '%s'", window_xml_file);
401 
402  connect_window = GTK_WIDGET(gtk_builder_get_object(dialog_xml, "connect_window"));
403  gtk_window_set_transient_for(GTK_WINDOW(connect_window),
404  GTK_WINDOW(window_root));
405  g_signal_connect(connect_window, "destroy",
406  G_CALLBACK(on_window_destroy_event), NULL);
407  main_notebook =
408  GTK_NOTEBOOK(gtk_builder_get_object(dialog_xml, "main_notebook"));
409 
410  /* Begin connecting signals for the root window. */
411  window_root = GTK_WIDGET(gtk_builder_get_object(window_xml, "window_root"));
412  if (window_root == NULL) {
413  error_dialog("Could not load main window",
414  "Check that your layout files are not corrupt.");
415  exit(EXIT_FAILURE);
416  }
417 
418  /* Request the window to receive focus in and out events */
419  gtk_widget_add_events((gpointer) window_root, GDK_FOCUS_CHANGE_MASK);
420  g_signal_connect((gpointer) window_root, "focus-out-event",
421  G_CALLBACK(focusoutfunc), NULL);
422 
423  g_signal_connect_swapped((gpointer) window_root, "key_press_event",
424  G_CALLBACK(keyfunc), GTK_WIDGET(window_root));
425  g_signal_connect_swapped((gpointer) window_root, "key_release_event",
426  G_CALLBACK(keyrelfunc), GTK_WIDGET(window_root));
427  g_signal_connect((gpointer) window_root, "destroy",
428  G_CALLBACK(on_window_destroy_event), NULL);
429 
430  /* Purely arbitrary min window size */
431  geometry.min_width=640;
432  geometry.min_height=480;
433 
434  gtk_window_set_geometry_hints(GTK_WINDOW(window_root), window_root,
435  &geometry, GDK_HINT_MIN_SIZE);
436 
437  magic_map = GTK_WIDGET(gtk_builder_get_object(window_xml,
438  "drawingarea_magic_map"));
439 
440  g_signal_connect((gpointer) magic_map, "expose_event",
441  G_CALLBACK(on_drawingarea_magic_map_expose_event), NULL);
442 
443  /* Set up colors before doing the other initialization functions */
444  for (i = 0; i < NUM_COLORS; i++) {
445  if (!gdk_color_parse(colorname[i], &root_color[i])) {
446  fprintf(stderr, "gdk_color_parse failed (%s)\n", colorname[i]);
447  }
448  if (!gdk_colormap_alloc_color(gtk_widget_get_colormap(window_root),
449  &root_color[i], FALSE, FALSE)) {
450  fprintf(stderr, "gdk_color_alloc failed\n");
451  }
452  }
453 
454  LOG(LOG_DEBUG, "init_ui", "sub init");
464  sandbox_enable = GTK_CHECK_BUTTON(gtk_builder_get_object(dialog_xml, "sandbox_enable"));
465 #ifdef HAVE_CAPSICUM
466  gtk_widget_set_sensitive(GTK_WIDGET(sandbox_enable), true);
467 #else
468  gtk_widget_set_sensitive(GTK_WIDGET(sandbox_enable), false);
469 #endif
470 
471  LOG(LOG_DEBUG, "init_ui", "window positions");
473 
474  LOG(LOG_DEBUG, "init_ui", "init themes");
475  init_theme();
476  LOG(LOG_DEBUG, "init_ui", "load themes");
477  load_theme(TRUE);
478  LOG(LOG_DEBUG, "init_ui", "menu items");
479  init_menu_items();
480 }
481 
487  if (!playing) {
488  // Prevent double-time if show_main_client() is called multiple times (it's possible)
489  g_timeout_add(1000/8, G_SOURCE_FUNC(self_tick), NULL);
490  }
491  playing = TRUE;
493  gtk_widget_show(window_root);
496 
497  // Reset auto-AFK data.
498  is_afk = false;
499  last_command_sent = time(NULL);
500 }
501 
507  playing = FALSE;
508  gtk_widget_hide(window_root);
510  /*
511  * We know the following is the private map structure in item.c. But
512  * we don't have direct access to it, so we still use locate.
513  */
515 
516  cf_play_music("NONE");
517  gtk_widget_show(connect_window);
518 }
519 
523 int main(int argc, char *argv[]) {
524  global_time = g_timer_new();
525 #ifdef ENABLE_NLS
526  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
527  bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
528  textdomain(GETTEXT_PACKAGE);
529 #endif
530 
531  // Initialize GTK and client library.
532  gtk_init(&argc, &argv);
533  parse_args(argc, argv);
534  client_init();
535 
536  // Set defaults, load configuration, and parse arguments.
537  config_load();
538  config_check();
539  char *layout = g_path_get_basename(window_xml_file);
540  snprintf(VERSION_INFO, MAX_BUF,
541  "GTKv2 Client " FULL_VERSION " (%s)", layout);
542  g_free(layout);
543 
544  // Initialize UI, sockets, and sound server.
545  LOG(LOG_DEBUG, "main", "init UI");
546  init_ui();
547  LOG(LOG_DEBUG, "main", "init sockets");
548  init_sockets();
549 
550  LOG(LOG_DEBUG, "main", "init sound");
551  if (!want_config[CONFIG_SOUND] || !init_sounds()) {
552  use_config[CONFIG_SOUND] = FALSE;
553  } else {
554  use_config[CONFIG_SOUND] = TRUE;
555  }
556 
557  /* Load cached pixmaps. */
558  LOG(LOG_DEBUG, "main", "init image cache");
560 
561  LOG(LOG_DEBUG, "main", "init done");
562  bool sandbox_enabled = false;
563 
564  while (true) {
565  gtk_widget_show(connect_window);
566  if (connect_server == NULL) {
568  gtk_main();
569  } else {
571  if (csocket.fd == NULL) {
572  LOG(LOG_ERROR, "main", "Unable to connect to %s!", connect_server);
573  break;
574  }
576  }
577 
578  sandbox_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sandbox_enable));
579  if (sandbox_enabled) {
580 #ifdef HAVE_CAPSICUM
581  if (cap_enter() != 0) {
582  error_dialog("Failed to enter sandbox", "Sandboxing was enabled, but the running kernel does not support sandboxing.");
583  break;
584  }
585  LOG(LOG_INFO, "main", "Entering sandbox");
586 #endif
587  }
588 
590  if (serverloginmethod) {
592  } else {
594  }
595 
596  /* The event_loop will block until connection to the server is lost. */
597  event_loop();
598  } else {
599  LOG(LOG_ERROR, "main", "Failed to negotiate connection with server");
600  }
601 
603 
604  /*
605  * Need to reset the images so they match up properly and prevent
606  * memory leaks.
607  */
609  client_reset();
610 
611  if (connect_server != NULL || sandbox_enabled) {
612  break;
613  }
614  }
615 }
616 
628 void get_window_coord(GtkWidget *win, int *x, int *y, int *wx, int *wy,
629  int *w, int *h) {
630  /* Position of a window relative to its parent window. */
631  gdk_window_get_geometry(gtk_widget_get_window(win), x, y, w, h, NULL);
632  /* Position of the window in root window coordinates. */
633  gdk_window_get_origin(gtk_widget_get_window(win), wx, wy);
634  *wx -= *x;
635  *wy -= *y;
636 }
last_command_sent
time_t last_command_sent
Time when last command was sent.
Definition: player.c:49
LOG_INFO
@ LOG_INFO
Minor, non-harmful issues.
Definition: client.h:437
updatekeycodes
static gboolean updatekeycodes
Definition: main.c:59
redraw
static gboolean redraw(gpointer data)
Redraw the map.
Definition: main.c:137
init_menu_items
void init_menu_items()
Initialize menu bar items and connect their signals to their handlers.
Definition: menubar.c:89
init_theme
void init_theme()
Definition: config.c:95
Playing
@ Playing
Definition: client.h:145
script_killall
void script_killall(void)
Definition: script.c:541
keyfunc
void keyfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
GTK Callback function used to handle client key press events.
Definition: keys.c:1573
metaserver.h
DIALOG_FILENAME
#define DIALOG_FILENAME
Definition: main.h:37
CONFIG_SERVER_TICKS
#define CONFIG_SERVER_TICKS
Definition: client.h:218
load_window_positions
void load_window_positions(GtkWidget *window_root)
Resize the client window and its panels using saved window positions.
Definition: config.c:864
Player_Struct::input_state
Input_State input_state
What the input state is.
Definition: client.h:342
ClientSocket::fd
GSocketConnection * fd
Definition: client.h:124
parse_args
static void parse_args(int argc, char *argv[])
parse_args: Parses command line options, and does variable initialization.
Definition: main.c:298
client_reset
void client_reset()
Clear client variables between connections to different servers.
Definition: init.c:247
CONFIG_DOWNLOAD
#define CONFIG_DOWNLOAD
Definition: client.h:183
show_main_client
void show_main_client()
Show main client window.
Definition: main.c:486
DEFAULT_UI
#define DEFAULT_UI
Definition: main.h:36
FULL_VERSION
#define FULL_VERSION
Definition: version.h:1
main_notebook
GtkNotebook * main_notebook
Definition: main.c:110
remove_item_inventory
void remove_item_inventory(item *op)
Definition: item.c:344
client_tick
void client_tick(guint32 tick)
Called whenever the server sends a tick command.
Definition: main.c:194
map_init
void map_init(GtkWidget *window_root)
This initializes the stuff we need for the map.
Definition: map.c:86
hide_all_login_windows
void hide_all_login_windows(void)
Hides all the login related windows.
Definition: account.c:96
face_info
Face_Information face_info
Definition: image.c:169
playing
static bool playing
Definition: main.c:67
msgctrl_init
void msgctrl_init(GtkWidget *window_root)
Initialize the message control panel by populating it with descriptions of each message type along wi...
Definition: info.c:1348
save_defaults
void save_defaults(void)
This function saves user settings chosen using the configuration popup dialog.
Definition: config.c:517
options
static GOptionEntry options[]
Command line options, descriptions, and parameters.
Definition: main.c:74
script_process
void script_process(fd_set *set)
Definition: script.c:573
map_notebook
GtkWidget * map_notebook
Definition: map.c:37
client_is_connected
bool client_is_connected()
Definition: client.c:321
have_new_image
int have_new_image
Definition: image.c:37
client_connect
void client_connect(const char hostname[static 1])
Definition: client.c:290
sandbox_enable
GtkCheckButton * sandbox_enable
Definition: main.c:112
MAGIC_MAP_PAGE
#define MAGIC_MAP_PAGE
Notebook page of the magic map.
Definition: main.h:42
VERSION_INFO
char VERSION_INFO[MAX_BUF]
Definition: client.c:48
wantloginmethod
int wantloginmethod
Definition: client.c:61
event_loop
static void event_loop()
Set up, enter, and exit event loop.
Definition: main.c:273
mapdata.h
on_auto_afk_response
static void on_auto_afk_response(GtkDialog *self, gint response_id, gpointer user_data)
Definition: main.c:154
client_get_source
GSource * client_get_source()
Return a source triggered when input from the server is available.
Definition: client.c:325
CONFIG_CACHE
#define CONFIG_CACHE
Definition: client.h:187
Player_Struct::container
item * container
open container
Definition: client.h:340
pickup_init
void pickup_init(GtkWidget *window_root)
Maps the menuitem lists into pickup values.
Definition: pickup.c:401
MAX_BUF
#define MAX_BUF
Definition: client.h:40
info_init
void info_init(GtkWidget *window_root)
Initialize the information panels in the client.
Definition: info.c:632
reset_image_data
void reset_image_data(void)
Connecting to different servers, try to clear out any old images.
Definition: image.c:276
init_ui_layout
static char * init_ui_layout(const char *name)
Load the UI from the given path.
Definition: main.c:366
focusoutfunc
void focusoutfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
When the main window looses its focus, act as if all keys have been released.
Definition: keys.c:1532
MINLOG
int MINLOG
Log level, or the threshold below which messages are suppressed.
Definition: misc.c:34
client_negotiate
bool client_negotiate(int sound)
This function negotiates the characteriistics of a connection to the server.
Definition: client.c:330
Player_Struct::ob
item * ob
Player object.
Definition: client.h:337
hide_main_client
void hide_main_client()
Called if event_loop() exits, or whenever the character selection window comes up (before logging in,...
Definition: main.c:506
clear_stat_mapping
void clear_stat_mapping(void)
Definition: stats.c:771
init_image_cache_data
void init_image_cache_data(void)
Initializes the data for image caching Create question mark to display in each supported rendering mo...
Definition: image.c:376
gtk2proto.h
client_run
void client_run()
Read available packets from the server and handle commands until there are no more,...
Definition: client.c:202
draw_lists
void draw_lists(void)
Redraws inventory and look windows when necessary.
Definition: inventory.c:1151
Face_Information_struct::want_faceset
char * want_faceset
Definition: client.h:410
root_color
GdkColor root_color[NUM_COLORS]
Definition: main.c:106
LOG
void LOG(LogLevel level, const char *origin, const char *format,...)
Log messages of a certain importance to stderr.
Definition: misc.c:111
inventory_init
void inventory_init(GtkWidget *window_root)
Set up the inventory viewer.
Definition: inventory.c:517
load_theme
void load_theme(int reload)
Definition: config.c:157
window_xml_file
char window_xml_file[MAX_BUF]
Path to the current UI file.
Definition: main.c:104
want_config
gint16 want_config[CONFIG_NUMS]
Definition: init.c:44
csocket
ClientSocket csocket
Definition: client.c:70
metaserver_show_prompt
void metaserver_show_prompt(void)
Constructs the metaserver dialog and handles metaserver selection.
Definition: metaserver.c:215
image.h
metaserver_ui_init
void metaserver_ui_init()
Initialize the metaserver user interface.
Definition: metaserver.c:75
init_sockets
static void init_sockets()
Definition: main.c:357
my_log_handler
void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
This goes with the g_log_set_handler below in main().
Definition: main.c:352
magic_map_flash_pos
void magic_map_flash_pos(void)
Flash the player's position on the magic map.
Definition: magicmap.c:77
init_ui
static void init_ui()
Definition: main.c:378
CONFIG_AUTO_AFK
#define CONFIG_AUTO_AFK
Definition: client.h:215
keys_init
void keys_init(GtkWidget *window_root)
One-time initialization of windows and signals for the keybindings dialog.
Definition: keys.c:650
error_dialog
void error_dialog(char *error, char *message)
Display an error message dialog.
Definition: main.c:328
main
int main(int argc, char *argv[])
Main client entry point.
Definition: main.c:523
keyrelfunc
void keyrelfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
GTK callback function used to handle client key release events.
Definition: keys.c:1558
dialog_xml
GtkBuilder * dialog_xml
Definition: main.c:108
Player_Struct::showmagic
guint8 showmagic
If 0, show the normal map, otherwise show the magic map.
Definition: client.h:365
is_afk
bool is_afk
Best guess whether or not we are currently AFK or not.
Definition: player.c:46
send_command
int send_command(const char *command, int repeat, int must_send)
Definition: player.c:231
init_create_character_window
void init_create_character_window()
Initializes the create character window.
Definition: create_char.c:791
on_drawingarea_magic_map_expose_event
gboolean on_drawingarea_magic_map_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
LOG_ERROR
@ LOG_ERROR
Warning that something definitely didn't work.
Definition: client.h:439
CONFIG_SOUND
#define CONFIG_SOUND
Definition: client.h:195
update_spell_information
void update_spell_information(void)
When spell information updates, the treeview is cleared and re-populated.
Definition: spells.c:190
locate_item
item * locate_item(gint32 tag)
Definition: item.c:278
main.h
cpl
Client_Player cpl
Player object.
Definition: client.c:69
time_map_redraw
bool time_map_redraw
Definition: config.c:53
connect_server
static char * connect_server
Definition: main.c:69
inventory_tick
void inventory_tick(void)
This is called periodically from main.c - basically a timeout, used to animate the inventory.
Definition: inventory.c:1290
global_time
GTimer * global_time
Definition: misc.c:31
do_network
static gboolean do_network(GObject *stream, gpointer data)
Callback from the event loop triggered when server input is available.
Definition: main.c:225
config_init
void config_init(GtkWidget *window_root)
Definition: config.c:548
item_struct::inv_updated
guint16 inv_updated
Definition: item.h:77
magic_map
GtkWidget * magic_map
Definition: main.c:109
debug_protocol
bool debug_protocol
Definition: main.c:65
script.h
self_tick
static gboolean self_tick(gpointer data)
Definition: main.c:255
account_show_login
void account_show_login()
Definition: account.c:1302
use_config
gint16 use_config[CONFIG_NUMS]
Definition: client.h:245
colorname
static const char *const colorname[NUM_COLORS]
Definition: main.c:43
info_buffer_tick
void info_buffer_tick(void)
Output count/sync buffer maintainer adds buffer time and output messages.
Definition: info.c:1069
sound_server
char * sound_server
Definition: client.c:51
client_init
void client_init()
Called ONCE during client startup to initialize configuration and other variables to reasonable defau...
Definition: init.c:192
script_fdset
void script_fdset(int *maxfd, fd_set *set)
Definition: script.c:558
window_root
GtkWidget * window_root
In main.c.
Definition: main.c:109
init_sounds
int init_sounds(void)
Definition: sound.c:26
get_window_coord
void get_window_coord(GtkWidget *win, int *x, int *y, int *wx, int *wy, int *w, int *h)
Gets the coordinates of a specified window.
Definition: main.c:628
maxfd
int maxfd
Definition: client.c:58
auto_afk
static void auto_afk()
Definition: main.c:179
script_init
void script_init(const char *cparams)
Definition: script.c:205
on_window_destroy_event
void on_window_destroy_event(GtkWidget *object, gpointer user_data)
Handles client shutdown.
Definition: main.c:216
NUM_COLORS
#define NUM_COLORS
Definition: main.h:22
mapdata_animation
void mapdata_animation(void)
Definition: mapdata.c:1400
script_launch
static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error)
Definition: main.c:124
serverloginmethod
int serverloginmethod
Definition: client.c:62
profile_latency
bool profile_latency
Definition: player.c:36
sound.h
draw_map
void draw_map(void)
Draw the map window using the appropriate backend.
Definition: map.c:525
Player_Struct::spells_updated
guint32 spells_updated
Whether or not spells updated.
Definition: client.h:354
connect_window
GtkWidget * connect_window
Definition: main.c:109
LOG_DEBUG
@ LOG_DEBUG
Useful debugging information.
Definition: client.h:436
config_load
void config_load()
Load settings from the user's configuration file into want_config.
Definition: config.c:446
client.h
stats_init
void stats_init(GtkWidget *window_root)
Associate the XML-defined widgets with pointers by name reference.
Definition: stats.c:147
cf_play_music
void cf_play_music(const char *music_name)
Play a music file.
Definition: cfsndserv.c:213
config_check
void config_check(void)
Check that want_config is valid, copy the new configuration to use_config, and apply the new configur...
Definition: config.c:334
window_xml
GtkBuilder * window_xml
Definition: main.c:108