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 #include "client-vala.h"
30 #include "image.h"
31 #include "main.h"
32 #include "mapdata.h"
33 #include "metaserver.h"
34 #include "script.h"
35 #include "sound.h"
36 #include "gtk2proto.h"
37 
38 /* Sets up the basic colors. */
39 static const char *const colorname[NUM_COLORS] = {
40  "Black", /* 0 */
41  "White", /* 1 */
42  "Navy", /* 2 */
43  "Red", /* 3 */
44  "Orange", /* 4 */
45  "DodgerBlue", /* 5 */
46  "DarkOrange2", /* 6 */
47  "SeaGreen", /* 7 */
48  "DarkSeaGreen", /* 8 *//* Used for window background color */
49  "Grey50", /* 9 */
50  "Sienna", /* 10 */
51  "Gold", /* 11 */
52  "Khaki" /* 12 */
53 };
54 
55 static gboolean updatekeycodes = FALSE;
56 
57 /* TODO: Move these declarations to actual header files. */
58 extern bool time_map_redraw;
59 extern bool profile_latency;
60 extern int MINLOG;
62 
63 static bool playing = FALSE; // Set to true when main window is up, gates self-generated ticks
64 
65 static char *connect_server = NULL;
66 
67 static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error);
68 
70 static GOptionEntry options[] = {
71  { "server", 's', 0, G_OPTION_ARG_STRING, &connect_server,
72  "Connect to the given server", "SERVER[:PORT]" },
73  { "cache", 0, 0, G_OPTION_ARG_NONE, &want_config[CONFIG_CACHE],
74  "Cache images", NULL },
75  { "prefetch", 0, 0, G_OPTION_ARG_NONE, &want_config[CONFIG_DOWNLOAD],
76  "Download images before playing", NULL },
77  { "faceset", 0, 0, G_OPTION_ARG_STRING, &face_info.want_faceset,
78  "Use the given faceset (if available)", "FACESET" },
79 
80  { "sound_server", 0, 0, G_OPTION_ARG_FILENAME, &sound_server,
81  "Path to the sound server", "PATH" },
82  { "updatekeycodes", 0, 0, G_OPTION_ARG_NONE, &updatekeycodes,
83  "Update the saved bindings for this keyboard", NULL },
84 
85  { "loginmethod", 0, 0, G_OPTION_ARG_INT, &wantloginmethod,
86  "Login method to request from server", NULL },
87  { "profile-latency", 0, 0, G_OPTION_ARG_NONE, &profile_latency,
88  "Log command acknowledgement latency to stdout", NULL },
89  { "profile-redraw", 0, 0, G_OPTION_ARG_NONE, &time_map_redraw,
90  "Print map redraw times to stdout", NULL },
91  { "verbose", 'v', 0, G_OPTION_ARG_INT, &MINLOG,
92  "Set verbosity (0 is the most verbose)", "LEVEL" },
93  { "debug-protocol", 0, 0, G_OPTION_ARG_NONE, &debug_protocol,
94  "Print commands to and from the server", NULL },
95  { "script", 0, 0, G_OPTION_ARG_CALLBACK, &script_launch,
96  "Launch client script at start (can be used multiple times)", "SCRIPT_NAME" },
97  { NULL }
98 };
99 
101 
103 
104 GtkBuilder *dialog_xml, *window_xml;
106 GtkNotebook *main_notebook;
107 
108 extern time_t last_command_sent;
109 extern bool is_afk;
110 
111 #ifdef WIN32 /* Win32 scripting support */
112 static int do_scriptout() {
113  script_process(NULL);
114  return (TRUE);
115 }
116 #endif /* WIN32 */
117 
118 static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error)
119 {
120  (void)option_name; // always "--script"
121  (void)data; // Not used
122  (void)error; // Not used
123  script_init(value);
124  return TRUE;
125 }
126 
131 static gboolean redraw(gpointer data) {
132  // Add a check for client_is_connected so that forced socket termination
133  // does not erroneously attempt to redraw the map after it has been destroyed.
134  if (client_is_connected()) {
135  if (have_new_image) {
136  if (cpl.container) {
138  }
139  cpl.ob->inv_updated = 1;
140  have_new_image = 0;
141  }
142  draw_map();
143  draw_lists();
144  }
145  return FALSE;
146 }
147 
148 static void on_auto_afk_response(GtkDialog *self, gint response_id, gpointer user_data) {
149  // It is possible for is_afk to be false because dialog is non-modal.
150  switch (response_id) {
151  case 1:
152  gtk_widget_destroy(GTK_WIDGET(self));
153  break;
154  case 2:
155  if (is_afk) {
156  send_command("afk", 0, true);
157  }
159  config_check();
160  save_defaults();
161  gtk_widget_destroy(GTK_WIDGET(self));
162  break;
163  default:
164  // includes closing the pop-up
165  if (is_afk) {
166  send_command("afk", 0, true);
167  }
168  gtk_widget_destroy(GTK_WIDGET(self));
169  break;
170  }
171 }
172 
173 static void auto_afk() {
174  send_command("afk", 0, true);
175  GtkWidget *dialog = gtk_dialog_new_with_buttons("Auto-AFK", GTK_WINDOW(window_root), GTK_DIALOG_DESTROY_WITH_PARENT,
176  "Return to game", 0, "Return to game, but stay AFK", 1, "Return to game, disable auto-AFK", 2, NULL);
177  GtkWidget *label, *content_area;
178  content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
179  label = gtk_label_new("You have been automatically marked as being away.");
180  gtk_container_add(GTK_CONTAINER(content_area), label);
181  g_signal_connect_swapped(dialog, "response", G_CALLBACK(on_auto_afk_response), dialog);
182  gtk_widget_show_all(dialog);
183 }
184 
188 void client_tick(guint32 tick) {
189  if (cpl.showmagic) {
190  if (gtk_notebook_get_current_page(GTK_NOTEBOOK(map_notebook)) !=
191  MAGIC_MAP_PAGE) {
192  // Stop flashing when the user switches back to the map window.
193  cpl.showmagic = 0;
194  } else {
196  cpl.showmagic ^= 2;
197  }
198  }
199  if (cpl.spells_updated) {
201  }
202 
204  inventory_tick();
206 }
210 void on_window_destroy_event(GtkWidget *object, gpointer user_data) {
211  script_killall();
212  LOG(LOG_DEBUG, "main.c::client_exit", "Exiting with return value 0.");
213  exit(0);
214 }
215 
219 static gboolean do_network(GObject *stream, gpointer data) {
220  struct timeval timeout = {0, 0};
221  fd_set tmp_read;
222  int pollret;
223 
224  if (!client_is_connected()) {
225  gtk_main_quit();
226  LOG(LOG_INFO, "main.c::do_network", "Trying to do network when not connected.");
227  return FALSE;
228  }
229 
230  client_run();
231 
232  FD_ZERO(&tmp_read);
233  int maxfd;
234  script_fdset(&maxfd, &tmp_read);
235  pollret = select(maxfd, &tmp_read, NULL, NULL, &timeout);
236  if (pollret < 0) {
237 #ifndef WIN32
238  // FIXME: For whatever reason, we get errors claiming "no error" here in Windows
239  LOG(LOG_ERROR, "do_network", "script select() failed: %s", strerror(errno));
240 #endif
241  } else if (pollret > 0) {
242  script_process(&tmp_read);
243  }
244 
245  return TRUE;
246 }
247 
248 static gboolean self_tick(gpointer data) {
249  if (playing) {
250  g_idle_add(redraw, NULL);
251 
252  if (!is_afk && use_config[CONFIG_AUTO_AFK] != 0 && time(NULL) > (last_command_sent + use_config[CONFIG_AUTO_AFK])) {
253  auto_afk();
254  }
256  client_tick(0);
257  }
258  return TRUE;
259  }
260  return FALSE;
261 }
262 
266 static void event_loop() {
267 #ifdef WIN32
268  g_timeout_add(250, G_SOURCE_FUNC(do_scriptout), NULL);
269 #endif
270 
271  GSource *net_source = client_get_source();
272  if (net_source == NULL) {
273  error_dialog("Server unexpectedly disconnected",
274  "The server unexpectedly disconnected.");
276  return;
277  }
278  g_source_set_callback(net_source, (GSourceFunc)do_network, NULL, NULL);
279  g_source_attach(net_source, NULL);
280  gtk_main();
281 
282  LOG(LOG_DEBUG, "event_loop", "Disconnected");
283 }
284 
296 static void parse_args(int argc, char *argv[]) {
297  GOptionContext *context = g_option_context_new("- Crossfire GTKv2 Client");
298  GError *error = NULL;
299 
300  g_option_context_add_main_entries(context, options, NULL);
301  g_option_context_add_group(context, gtk_get_option_group(TRUE));
302 
303  if (!g_option_context_parse(context, &argc, &argv, &error)) {
304  g_print("%s\n", error->message);
305  g_error_free(error);
306  exit(EXIT_FAILURE);
307  }
308 
309  g_option_context_free(context);
310 
311  /*
312  * Move this after the parsing of command line options, since that can
313  * change the default log level.
314  */
315  LOG(LOG_DEBUG, "Client Version", VERSION_INFO);
316  if (MINLOG <= 0) {
317  g_setenv("CF_SOUND_DEBUG", "yes", false);
318  }
319 }
320 
326 void error_dialog(char *error, char *message) {
327  GtkWidget *dialog = gtk_message_dialog_new(
328  NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
329  GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", error);
330  gtk_window_set_title(GTK_WINDOW(dialog), "Crossfire Client");
331  gtk_message_dialog_format_secondary_markup(
332  GTK_MESSAGE_DIALOG(dialog), "%s", message);
333  gtk_dialog_run(GTK_DIALOG(dialog));
334  gtk_widget_destroy(dialog);
335 }
336 
349 void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level,
350  const gchar *message, gpointer user_data) {
351  g_usleep(1 * 1e6);
352 }
353 
354 static void init_sockets() {
355 #ifndef WIN32
356  signal(SIGPIPE, SIG_IGN);
357 #endif
358 }
359 
363 static char *init_ui_layout(const char *name) {
364  guint retval = gtk_builder_add_from_file(window_xml, name, NULL);
365  if (retval > 0 && strlen(name) > 0) {
366  if (window_xml_file != name) { // FIXME: caught by Valgrind
367  strncpy(window_xml_file, name, sizeof(window_xml_file));
368  }
369  return window_xml_file;
370  } else {
371  return NULL;
372  }
373 }
374 
375 static void init_ui() {
376  GError *error = NULL;
377  GdkGeometry geometry;
378  int i;
379 
380  /* Load dialog windows using GtkBuilder. */
381  dialog_xml = gtk_builder_new();
382  if (!gtk_builder_add_from_file(dialog_xml, DIALOG_FILENAME, &error)) {
383  error_dialog("Couldn't load UI dialogs.", error->message);
384  g_warning("Couldn't load UI dialogs: %s", error->message);
385  g_error_free(error);
386  exit(EXIT_FAILURE);
387  }
388  LOG(LOG_DEBUG, "init_ui", "loaded dialog_xml '%s'", DIALOG_FILENAME);
389 
390  /* Load main window using GtkBuilder. */
391  window_xml = gtk_builder_new();
392  if (init_ui_layout(window_xml_file) == NULL) {
393  LOG(LOG_DEBUG, "init_ui_layout", "Could not initialize '%s', using default layout", window_xml_file);
394  if (init_ui_layout(DEFAULT_UI) == NULL) {
395  g_error("Could not load default layout!");
396  }
397  }
398  LOG(LOG_DEBUG, "init_ui", "loaded window_xml '%s'", window_xml_file);
399 
400  connect_window = GTK_WIDGET(gtk_builder_get_object(dialog_xml, "connect_window"));
401  gtk_window_set_transient_for(GTK_WINDOW(connect_window),
402  GTK_WINDOW(window_root));
403  g_signal_connect(connect_window, "destroy",
404  G_CALLBACK(on_window_destroy_event), NULL);
405  main_notebook =
406  GTK_NOTEBOOK(gtk_builder_get_object(dialog_xml, "main_notebook"));
407 
408  /* Begin connecting signals for the root window. */
409  window_root = GTK_WIDGET(gtk_builder_get_object(window_xml, "window_root"));
410  if (window_root == NULL) {
411  error_dialog("Could not load main window",
412  "Check that your layout files are not corrupt.");
413  exit(EXIT_FAILURE);
414  }
415 
416  /* Request the window to receive focus in and out events */
417  gtk_widget_add_events((gpointer) window_root, GDK_FOCUS_CHANGE_MASK);
418  g_signal_connect((gpointer) window_root, "focus-out-event",
419  G_CALLBACK(focusoutfunc), NULL);
420 
421  g_signal_connect_swapped((gpointer) window_root, "key_press_event",
422  G_CALLBACK(keyfunc), GTK_WIDGET(window_root));
423  g_signal_connect_swapped((gpointer) window_root, "key_release_event",
424  G_CALLBACK(keyrelfunc), GTK_WIDGET(window_root));
425  g_signal_connect((gpointer) window_root, "destroy",
426  G_CALLBACK(on_window_destroy_event), NULL);
427 
428  /* Purely arbitrary min window size */
429  geometry.min_width=640;
430  geometry.min_height=480;
431 
432  gtk_window_set_geometry_hints(GTK_WINDOW(window_root), window_root,
433  &geometry, GDK_HINT_MIN_SIZE);
434 
435  magic_map = GTK_WIDGET(gtk_builder_get_object(window_xml,
436  "drawingarea_magic_map"));
437 
438  g_signal_connect((gpointer) magic_map, "expose_event",
439  G_CALLBACK(on_drawingarea_magic_map_expose_event), NULL);
440 
441  /* Set up colors before doing the other initialization functions */
442  for (i = 0; i < NUM_COLORS; i++) {
443  if (!gdk_color_parse(colorname[i], &root_color[i])) {
444  fprintf(stderr, "gdk_color_parse failed (%s)\n", colorname[i]);
445  }
446  if (!gdk_colormap_alloc_color(gtk_widget_get_colormap(window_root),
447  &root_color[i], FALSE, FALSE)) {
448  fprintf(stderr, "gdk_color_alloc failed\n");
449  }
450  }
451 
452  LOG(LOG_DEBUG, "init_ui", "sub init");
462 
463  LOG(LOG_DEBUG, "init_ui", "window positions");
465 
466  LOG(LOG_DEBUG, "init_ui", "init themes");
467  init_theme();
468  LOG(LOG_DEBUG, "init_ui", "load themes");
469  load_theme(TRUE);
470  LOG(LOG_DEBUG, "init_ui", "menu items");
471  init_menu_items();
472 }
473 
479  if (!playing) {
480  // Prevent double-time if show_main_client() is called multiple times (it's possible)
481  g_timeout_add(1000/8, G_SOURCE_FUNC(self_tick), NULL);
482  }
483  playing = TRUE;
485  gtk_widget_show(window_root);
488 
489  // Reset auto-AFK data.
490  is_afk = false;
491  last_command_sent = time(NULL);
492 }
493 
499  playing = FALSE;
500  gtk_widget_hide(window_root);
502  /*
503  * We know the following is the private map structure in item.c. But
504  * we don't have direct access to it, so we still use locate.
505  */
507 
508  cf_play_music("NONE");
509  gtk_widget_show(connect_window);
510 }
511 
515 int main(int argc, char *argv[]) {
516  global_time = g_timer_new();
517 #ifdef ENABLE_NLS
518  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
519  bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
520  textdomain(GETTEXT_PACKAGE);
521 #endif
522 
523  // Initialize GTK and client library.
524  gtk_init(&argc, &argv);
525  parse_args(argc, argv);
526  client_init();
527 
528  // Set defaults, load configuration, and parse arguments.
529  config_load();
530  config_check();
531  char *layout = g_path_get_basename(window_xml_file);
532  snprintf(VERSION_INFO, MAX_BUF,
533  "GTKv2 Client " FULL_VERSION " (%s)", layout);
534  g_free(layout);
535 
536  // Initialize UI, sockets, and sound server.
537  LOG(LOG_DEBUG, "main", "init UI");
538  init_ui();
539  LOG(LOG_DEBUG, "main", "init sockets");
540  init_sockets();
541 
542  LOG(LOG_DEBUG, "main", "init sound");
543  if (!want_config[CONFIG_SOUND] || !init_sounds()) {
544  use_config[CONFIG_SOUND] = FALSE;
545  } else {
546  use_config[CONFIG_SOUND] = TRUE;
547  }
548 
549  /* Load cached pixmaps. */
550  LOG(LOG_DEBUG, "main", "init image cache");
552 
553  LOG(LOG_DEBUG, "main", "init done");
554 
555  while (true) {
556  gtk_widget_show(connect_window);
557  if (connect_server == NULL) {
559  gtk_main();
560  } else {
562  if (csocket.fd == NULL) {
563  LOG(LOG_ERROR, "main", "Unable to connect to %s!", connect_server);
564  break;
565  }
567  }
568 
570  if (serverloginmethod) {
572  } else {
574  }
575 
576  /* The event_loop will block until connection to the server is lost. */
577  event_loop();
578 
580 
581  /*
582  * Need to reset the images so they match up properly and prevent
583  * memory leaks.
584  */
586  client_reset();
587  }
588 }
589 
601 void get_window_coord(GtkWidget *win, int *x, int *y, int *wx, int *wy,
602  int *w, int *h) {
603  /* Position of a window relative to its parent window. */
604  gdk_window_get_geometry(gtk_widget_get_window(win), x, y, w, h, NULL);
605  /* Position of the window in root window coordinates. */
606  gdk_window_get_origin(gtk_widget_get_window(win), wx, wy);
607  *wx -= *x;
608  *wy -= *y;
609 }
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:436
updatekeycodes
static gboolean updatekeycodes
Definition: main.c:55
redraw
static gboolean redraw(gpointer data)
Redraw the map.
Definition: main.c:131
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:92
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:1567
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:848
Player_Struct::input_state
Input_State input_state
What the input state is.
Definition: client.h:341
client_disconnect
void client_disconnect()
Closes the connection to the server.
Definition: client.c:175
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:296
client_reset
void client_reset()
Clear client variables between connections to different servers.
Definition: init.c:245
CONFIG_DOWNLOAD
#define CONFIG_DOWNLOAD
Definition: client.h:183
show_main_client
void show_main_client()
Show main client window.
Definition: main.c:478
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:106
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:188
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:63
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:513
options
static GOptionEntry options[]
Command line options, descriptions, and parameters.
Definition: main.c:70
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:320
have_new_image
int have_new_image
Definition: image.c:37
client_connect
void client_connect(const char hostname[static 1])
Definition: client.c:289
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:266
mapdata.h
on_auto_afk_response
static void on_auto_afk_response(GtkDialog *self, gint response_id, gpointer user_data)
Definition: main.c:148
client_get_source
GSource * client_get_source()
Return a source triggered when input from the server is available.
Definition: client.c:324
CONFIG_CACHE
#define CONFIG_CACHE
Definition: client.h:187
Player_Struct::container
item * container
open container
Definition: client.h:339
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:363
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:1526
MINLOG
int MINLOG
Log level, or the threshold below which messages are suppressed.
Definition: misc.c:34
Player_Struct::ob
item * ob
Player object.
Definition: client.h:336
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:498
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:1162
Face_Information_struct::want_faceset
char * want_faceset
Definition: client.h:409
root_color
GdkColor root_color[NUM_COLORS]
Definition: main.c:102
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:528
load_theme
void load_theme(int reload)
Definition: config.c:154
window_xml_file
char window_xml_file[MAX_BUF]
Path to the current UI file.
Definition: main.c:100
want_config
gint16 want_config[CONFIG_NUMS]
Definition: init.c:43
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:354
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:349
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:375
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:648
error_dialog
void error_dialog(char *error, char *message)
Display an error message dialog.
Definition: main.c:326
main
int main(int argc, char *argv[])
Main client entry point.
Definition: main.c:515
keyrelfunc
void keyrelfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
GTK callback function used to handle client key release events.
Definition: keys.c:1552
dialog_xml
GtkBuilder * dialog_xml
Definition: main.c:104
Player_Struct::showmagic
guint8 showmagic
If 0, show the normal map, otherwise show the magic map.
Definition: client.h:364
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:438
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:51
connect_server
static char * connect_server
Definition: main.c:65
inventory_tick
void inventory_tick(void)
This is called periodically from main.c - basically a timeout, used to animate the inventory.
Definition: inventory.c:1301
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:219
config_init
void config_init(GtkWidget *window_root)
Definition: config.c:539
item_struct::inv_updated
guint16 inv_updated
Definition: item.h:77
magic_map
GtkWidget * magic_map
Definition: main.c:105
debug_protocol
bool debug_protocol
Definition: main.c:61
script.h
self_tick
static gboolean self_tick(gpointer data)
Definition: main.c:248
account_show_login
void account_show_login()
Definition: account.c:1302
use_config
gint16 use_config[CONFIG_NUMS]
Definition: client.h:244
colorname
static const char *const colorname[NUM_COLORS]
Definition: main.c:39
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:190
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:105
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:601
maxfd
int maxfd
Definition: client.c:58
auto_afk
static void auto_afk()
Definition: main.c:173
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:210
NUM_COLORS
#define NUM_COLORS
Definition: main.h:22
mapdata_animation
void mapdata_animation(void)
Definition: mapdata.c:1387
script_launch
static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error)
Definition: main.c:118
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:353
connect_window
GtkWidget * connect_window
Definition: main.c:105
LOG_DEBUG
@ LOG_DEBUG
Useful debugging information.
Definition: client.h:435
config_load
void config_load()
Load settings from the user's configuration file into want_config.
Definition: config.c:442
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:209
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:331
window_xml
GtkBuilder * window_xml
Definition: main.c:104
client_negotiate
void client_negotiate(int sound)
This function negotiates the characteriistics of a connection to the server.
Definition: client.c:329