/************************************************************************** Output information about one auth option. **************************************************************************/ static void print_auth_option(int loglevel, enum show_source_type show_source, bool show_value, const struct auth_option *target) { char buffer[512]; bool real_show_source; buffer[0] = '\0'; real_show_source = (show_source == SST_ALL || (show_source == SST_DEFAULT && target->source == AOS_DEFAULT)); if (show_value || real_show_source) { /* We will print this line. Begin it. */ /* TRANS: Further information about option will follow. */ my_snprintf(buffer, sizeof(buffer), _("Auth option \"%s\":"), target->name); } if (show_value) { cat_snprintf(buffer, sizeof(buffer), " \"%s\"", target->value); } if (real_show_source) { switch(target->source) { case AOS_DEFAULT: if (show_source == SST_DEFAULT) { cat_snprintf(buffer, sizeof(buffer), /* TRANS: After 'Auth option "user":'******'\0') { /* There is line to print */ freelog(loglevel, "%s", buffer); } }
/************************************************************************** Log city messages, they will appear like this 2: Polish Romenna(5,35) [s1 d106 u11 g1] must have Archers ... **************************************************************************/ void real_city_log(const char *file, const char *function, int line, enum log_level level, bool notify, const struct city *pcity, const char *msg, ...) { char buffer[500]; char buffer2[500]; va_list ap; char aibuf[500] = "\0"; CALL_PLR_AI_FUNC(log_fragment_city, city_owner(pcity), aibuf, sizeof(aibuf), pcity); fc_snprintf(buffer, sizeof(buffer), "%s %s(%d,%d) [s%d] {%s} ", nation_rule_name(nation_of_city(pcity)), city_name(pcity), TILE_XY(pcity->tile), city_size_get(pcity), aibuf); va_start(ap, msg); fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (notify) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } do_log(file, function, line, FALSE, level, "%s", buffer); }
/************************************************************************** Log player tech messages. **************************************************************************/ void real_tech_log(const char *file, const char *function, int line, enum log_level level, bool notify, const struct player *pplayer, struct advance *padvance, const char *msg, ...) { char buffer[500]; char buffer2[500]; va_list ap; if (!valid_advance(padvance) || advance_by_number(A_NONE) == padvance) { return; } fc_snprintf(buffer, sizeof(buffer), "%s::%s (want %d, dist %d) ", player_name(pplayer), advance_name_by_player(pplayer, advance_number(padvance)), pplayer->ai_common.tech_want[advance_index(padvance)], num_unknown_techs_for_goal(pplayer, advance_number(padvance))); va_start(ap, msg); fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (notify) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } do_log(file, function, line, FALSE, level, "%s", buffer); }
/************************************************************************** Log player tech messages. **************************************************************************/ void TECH_LOG(int level, const struct player *pplayer, struct advance *padvance, const char *msg, ...) { char buffer[500]; char buffer2[500]; va_list ap; int minlevel = MIN(LOGLEVEL_TECH, level); if (!valid_advance(padvance) || advance_by_number(A_NONE) == padvance) { return; } if (BV_ISSET(pplayer->debug, PLAYER_DEBUG_TECH)) { minlevel = LOG_TEST; } else if (minlevel > fc_log_level) { return; } my_snprintf(buffer, sizeof(buffer), "%s::%s (want %d, dist %d) ", player_name(pplayer), advance_name_by_player(pplayer, advance_number(padvance)), pplayer->ai_data.tech_want[advance_index(padvance)], num_unknown_techs_for_goal(pplayer, advance_number(padvance))); va_start(ap, msg); my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (BV_ISSET(pplayer->debug, PLAYER_DEBUG_TECH)) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } freelog(minlevel, "%s", buffer); }
/************************************************************************** Log city messages, they will appear like this 2: Polish Romenna(5,35) [s1 d106 u11 g1] must have Archers ... **************************************************************************/ void CITY_LOG(int level, const struct city *pcity, const char *msg, ...) { char buffer[500]; char buffer2[500]; va_list ap; int minlevel = MIN(LOGLEVEL_CITY, level); if (pcity->debug) { minlevel = LOG_TEST; } else if (minlevel > fc_log_level) { return; } my_snprintf(buffer, sizeof(buffer), "%s %s(%d,%d) [s%d d%d u%d g%d] ", nation_rule_name(nation_of_city(pcity)), city_name(pcity), TILE_XY(pcity->tile), pcity->size, pcity->ai->danger, pcity->ai->urgency, pcity->ai->grave_danger); va_start(ap, msg); my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (pcity->debug) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } freelog(minlevel, "%s", buffer); }
/************************************************************************** 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; }
/************************************************************************** Log unit messages, they will appear like this 2: Polish Archers[139] (5,35)->(0,0){0,0} stays to defend city where [] is unit id, ()->() are coordinates present and goto, and {,} contains bodyguard and ferryboat ids. **************************************************************************/ void UNIT_LOG(int level, const struct unit *punit, const char *msg, ...) { char buffer[500]; char buffer2[500]; va_list ap; int minlevel = MIN(LOGLEVEL_UNIT, level); int gx, gy; bool messwin = FALSE; /* output to message window */ if (punit->debug) { minlevel = LOG_TEST; } else { /* Are we a virtual unit evaluated in a debug city?. */ if (punit->id == 0) { struct city *pcity = tile_city(punit->tile); if (pcity && pcity->debug) { minlevel = LOG_TEST; messwin = TRUE; } } if (minlevel > fc_log_level) { return; } } if (punit->goto_tile) { gx = punit->goto_tile->x; gy = punit->goto_tile->y; } else { gx = gy = -1; } my_snprintf(buffer, sizeof(buffer), "%s %s[%d] %s (%d,%d)->(%d,%d){%d,%d} ", nation_rule_name(nation_of_unit(punit)), unit_rule_name(punit), punit->id, get_activity_text(punit->activity), TILE_XY(punit->tile), gx, gy, punit->ai.bodyguard, punit->ai.ferryboat); va_start(ap, msg); my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (punit->debug || messwin) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } freelog(minlevel, "%s", buffer); }
/**************************************************************** Call ggz_embed_ensure_server() if ggz enabled. *****************************************************************/ void gui_ggz_embed_ensure_server(void) { #ifdef GGZ_GTK { char buf[128]; user_username(buf, sizeof(buf)); cat_snprintf(buf, sizeof(buf), "%d", myrand(100)); ggz_embed_ensure_server("Pubserver", "freeciv.ggzgamingzone.org", 5688, buf); } #endif /* GGZ_GTK */ }
/************************************************************************** Log message for bodyguards. They will appear like this 2: Polish Mech. Inf.[485] bodyguard (38,22){Riflemen:574@37,23} was ... note that these messages are likely to wrap if long. **************************************************************************/ void BODYGUARD_LOG(int level, const struct unit *punit, const char *msg) { char buffer[500]; int minlevel = MIN(LOGLEVEL_BODYGUARD, level); const struct unit *pcharge; const struct city *pcity; int id = -1; int charge_x = -1; int charge_y = -1; const char *type = "guard"; const char *s = "none"; if (punit->debug) { minlevel = LOG_TEST; } else if (minlevel > fc_log_level) { return; } pcity = game_find_city_by_number(punit->ai.charge); pcharge = game_find_unit_by_number(punit->ai.charge); if (pcharge) { charge_x = pcharge->tile->x; charge_y = pcharge->tile->y; id = pcharge->id; type = "bodyguard"; s = unit_rule_name(pcharge); } else if (pcity) { charge_x = pcity->tile->x; charge_y = pcity->tile->y; id = pcity->id; type = "cityguard"; s = city_name(pcity); } /* else perhaps the charge died */ my_snprintf(buffer, sizeof(buffer), "%s %s[%d] %s (%d,%d){%s:%d@%d,%d} ", nation_rule_name(nation_of_unit(punit)), unit_rule_name(punit), punit->id, type, TILE_XY(punit->tile), s, id, charge_x, charge_y); cat_snprintf(buffer, sizeof(buffer), "%s", msg); if (punit->debug) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } freelog(minlevel, "%s", buffer); }
/************************************************************************** Log unit messages, they will appear like this 2: Polish Archers[139] (5,35)->(0,0){0,0} stays to defend city where [] is unit id, ()->() are coordinates present and goto, and {,} contains bodyguard and ferryboat ids. **************************************************************************/ void real_unit_log(const char *file, const char *function, int line, enum log_level level, bool notify, const struct unit *punit, const char *msg, ...) { char buffer[500]; char buffer2[500]; va_list ap; int gx, gy; char aibuf[500] = "\0"; CALL_PLR_AI_FUNC(log_fragment_unit, unit_owner(punit), aibuf, sizeof(aibuf), punit); if (punit->goto_tile) { index_to_map_pos(&gx, &gy, tile_index(punit->goto_tile)); } else { gx = gy = -1; } fc_snprintf(buffer, sizeof(buffer), "%s %s[%d] %s (%d,%d)->(%d,%d){%s} ", nation_rule_name(nation_of_unit(punit)), unit_rule_name(punit), punit->id, get_activity_text(punit->activity), TILE_XY(unit_tile(punit)), gx, gy, aibuf); va_start(ap, msg); fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (notify) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } do_log(file, function, line, FALSE, level, "%s", buffer); }
/************************************************************************** Log player messages, they will appear like this where ti is timer, co countdown and lo love for target, who is e. **************************************************************************/ void DIPLO_LOG(int level, const struct player *pplayer, const struct player *aplayer, const char *msg, ...) { char buffer[500]; char buffer2[500]; va_list ap; int minlevel = MIN(LOGLEVEL_PLAYER, level); const struct ai_dip_intel *adip; if (BV_ISSET(pplayer->debug, PLAYER_DEBUG_DIPLOMACY)) { minlevel = LOG_TEST; } else if (minlevel > fc_log_level) { return; } /* Don't use ai_data_get since it can have side effects. */ adip = ai_diplomacy_get(pplayer, aplayer); my_snprintf(buffer, sizeof(buffer), "%s->%s(l%d,c%d,d%d%s): ", player_name(pplayer), player_name(aplayer), pplayer->ai_data.love[player_index(aplayer)], adip->countdown, adip->distance, adip->is_allied_with_enemy ? "?" : (adip->at_war_with_ally ? "!" : "")); va_start(ap, msg); my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (BV_ISSET(pplayer->debug, PLAYER_DEBUG_DIPLOMACY)) { notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer); } freelog(minlevel, "%s", buffer); }
/**************************************************************************** Read the request string (or part of it) from the metaserver. ****************************************************************************/ static void meta_read_response(struct server_scan *scan) { char buf[4096]; int result; if (!scan->meta.fp) { #ifdef WIN32_NATIVE char filename[MAX_PATH]; GetTempPath(sizeof(filename), filename); cat_snprintf(filename, sizeof(filename), "fctmp%d", myrand(1000)); scan->meta.fp = fc_fopen(filename, "w+b"); #else scan->meta.fp = tmpfile(); #endif if (!scan->meta.fp) { scan->error_func(scan, _("Could not open temp file.")); } } while (1) { result = fc_readsocket(scan->sock, buf, sizeof(buf)); if (result < 0) { if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { /* Keep waiting. */ return; } scan->error_func(scan, fc_strerror(fc_get_errno())); return; } else if (result == 0) { fz_FILE *f; char str[4096]; /* We're done! */ rewind(scan->meta.fp); f = fz_from_stream(scan->meta.fp); assert(f != NULL); /* skip HTTP headers */ /* XXX: TODO check for magic Content-Type: text/x-ini -vasc */ while (fz_fgets(str, sizeof(str), f) && strcmp(str, "\r\n") != 0) { /* nothing */ } /* XXX: TODO check for magic Content-Type: text/x-ini -vasc */ /* parse HTTP message body */ scan->servers = parse_metaserver_data(f); scan->meta.state = META_DONE; /* 'f' (hence 'meta.fp') was closed in parse_metaserver_data(). */ scan->meta.fp = NULL; if (NULL == scan->servers) { my_snprintf(str, sizeof(str), _("Failed to parse the metaserver data from http://%s."), scan->meta.name); scan->error_func(scan, str); } return; } else { if (fwrite(buf, 1, result, scan->meta.fp) != result) { scan->error_func(scan, fc_strerror(fc_get_errno())); } } } }