/************************************************************************** Autocompletes the input line with a player or user name. Returns FALSE if there is no string to complete. **************************************************************************/ static bool chatline_autocomplete(GtkEditable *editable) { #define MAX_MATCHES 10 const char *name[MAX_MATCHES]; char buf[MAX_LEN_NAME * MAX_MATCHES]; gint pos; gchar *chars, *p, *prev; int num, i; size_t prefix_len; /* Part 1: get the string to complete. */ pos = gtk_editable_get_position(editable); chars = gtk_editable_get_chars(editable, 0, pos); p = chars + strlen(chars); while ((prev = g_utf8_find_prev_char(chars, p))) { if (!g_unichar_isalnum(g_utf8_get_char(prev))) { break; } p = prev; } /* p points to the start of the last word, or the start of the string. */ prefix_len = g_utf8_strlen(p, -1); if (0 == prefix_len) { /* Empty: nothing to complete, propagate the event. */ g_free(chars); return FALSE; } /* Part 2: compare with player and user names. */ num = check_player_or_user_name(p, name, MAX_MATCHES); if (1 == num) { gtk_editable_delete_text(editable, pos - prefix_len, pos); pos -= prefix_len; gtk_editable_insert_text(editable, name[0], strlen(name[0]), &pos); gtk_editable_set_position(editable, pos); g_free(chars); return TRUE; } else if (num > 1) { if (get_common_prefix(name, num, buf, sizeof(buf)) > prefix_len) { gtk_editable_delete_text(editable, pos - prefix_len, pos); pos -= prefix_len; gtk_editable_insert_text(editable, buf, strlen(buf), &pos); gtk_editable_set_position(editable, pos); } sz_strlcpy(buf, name[0]); for (i = 1; i < num; i++) { cat_snprintf(buf, sizeof(buf), ", %s", name[i]); } /* TRANS: comma-separated list of player/user names for completion */ output_window_printf(ftc_client, _("Suggestions: %s."), buf); } g_free(chars); return TRUE; }
/**************************************************************************** Client connection close socket callback. It shouldn't be called directy. Use connection_close() instead. ****************************************************************************/ static void client_conn_close_callback(struct connection *pconn) { char reason[256]; if (NULL != pconn->closing_reason) { fc_strlcpy(reason, pconn->closing_reason, sizeof(reason)); } else { fc_strlcpy(reason, _("unknown reason"), sizeof(reason)); } close_socket_nomessage(pconn); /* If we lost connection to the internal server - kill it. */ client_kill_server(TRUE); log_error("Lost connection to server: %s.", reason); output_window_printf(ftc_client, _("Lost connection to server (%s)!"), reason); if (with_ggz) { client_exit(); } }
/************************************************************************** Start trying to autoconnect to civserver. Calls get_server_address(), then arranges for try_to_autoconnect(), which calls try_to_connect(), to be called roughly every AUTOCONNECT_INTERVAL milliseconds, until success, fatal error or user intervention. **************************************************************************/ void start_autoconnecting_to_server(void) { char buf[512]; output_window_printf(FTC_CLIENT_INFO, NULL, _("Auto-connecting to server \"%s\" at port %d " "as \"%s\" every %f second(s) for %d times"), server_host, server_port, user_name, 0.001 * AUTOCONNECT_INTERVAL, MAX_AUTOCONNECT_ATTEMPTS); if (get_server_address(server_host, server_port, buf, sizeof(buf)) < 0) { freelog(LOG_FATAL, _("Error contacting server \"%s\" at port %d " "as \"%s\":\n %s\n"), server_host, server_port, user_name, buf); exit(EXIT_FAILURE); } autoconnecting = TRUE; }