Freeciv21
Develop your civilization from humble roots to a global empire
civmanual.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, or (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10  */
11 
12 #include <fc_config.h>
13 
14 #include <QFile>
15 #include <cstdlib>
16 #include <cstring>
17 
18 // Qt
19 #include <QCommandLineParser>
20 #include <QCoreApplication>
21 
22 // utility
23 #include "astring.h"
24 #include "fciconv.h"
25 #include "fcintl.h"
26 #include "log.h"
27 #include "registry.h"
28 #include "support.h"
29 
30 // common
31 #include "capstr.h"
32 #include "connection.h"
33 #include "events.h"
34 #include "fc_interface.h"
35 #include "fc_types.h" // LINE_BREAK
36 #include "game.h"
37 #include "government.h"
38 #include "helpdata.h"
39 #include "improvement.h"
40 #include "map.h"
41 #include "movement.h"
42 #include "player.h"
43 #include "version.h"
44 
45 // server
46 #include "commands.h"
47 #include "console.h"
48 #include "ruleset.h"
49 #include "sernet.h"
50 #include "settings.h"
51 #include "srv_main.h"
52 
53 /* tools/shared */
54 #include "tools_fc_interface.h"
55 
56 enum manuals {
66 };
67 
68 struct tag_types {
69  const char *file_ext;
70  const char *header;
71  const char *title_begin;
72  const char *title_end;
73  const char *sect_title_begin;
74  const char *sect_title_end;
75  const char *item_begin;
76  const char *item_end;
77  const char *subitem_begin;
78  const char *subitem_end;
79  const char *tail;
80 };
81 
82 struct tag_types html_tags = {
83  // file extension
84  "html",
85 
86  // header
87  "<html><head><link rel=\"stylesheet\" type=\"text/css\" "
88  "href=\"manual.css\"/><meta http-equiv=\"Content-Type\" "
89  "content=\"text/html; charset=UTF-8\"/></head><body>\n\n",
90 
91  // title begin
92  "<h1>",
93 
94  // title end
95  "</h1>",
96 
97  // section title begin
98  "<h3 class='section'>",
99 
100  // section title end
101  "</h3>",
102 
103  // item begin
104  "<div class='item' id='%s%d'>\n",
105 
106  // item end
107  "</div>\n",
108 
109  // subitem begin
110  "<pre class='%s'>",
111 
112  // subitem end
113  "</pre>\n",
114 
115  // tail
116  "</body></html>"};
117 
118 struct tag_types wiki_tags = {
119  // file extension
120  "mediawiki",
121 
122  // header
123  " ",
124 
125  // title begin
126  "=",
127 
128  // title end
129  "=",
130 
131  // section title begin
132  "===",
133 
134  // section title end
135  "===",
136 
137  // item begin
138  "----\n<!-- %s %d -->\n",
139 
140  // item end
141  "\n",
142 
143  // subitem begin
144  "<!-- %s -->\n",
145 
146  // subitem end
147  "\n",
148 
149  // tail
150  " "};
151 
152 static QString ruleset;
153 
157 static bool manual_command(struct tag_types *tag_info)
158 {
159  FILE *doc = nullptr;
160  char filename[40];
161  struct connection my_conn;
162 
163  // Default client access.
164  connection_common_init(&my_conn);
165  my_conn.access_level = ALLOW_CTRL;
166 
167  // Reset aifill to zero
168  game.info.aifill = 0;
169 
170  if (!load_rulesets(nullptr, nullptr, false, nullptr, false, false,
171  false)) {
172  // Failed to load correct ruleset
173  return false;
174  }
175 
176  for (int imanuals = 0; imanuals < MANUAL_COUNT; imanuals++) {
177  enum manuals manuals = static_cast<enum manuals>(imanuals);
178  int i;
179  int ri;
180 
181  fc_snprintf(filename, sizeof(filename), "%s%d.%s",
182  game.server.rulesetdir, manuals + 1, tag_info->file_ext);
183 
184  if (QFile::exists(filename) || !(doc = fc_fopen(filename, "w"))) {
185  qCritical(_("Could not write manual file %s."), filename);
186  return false;
187  }
188 
189  fprintf(doc, "%s", tag_info->header);
190  fprintf(doc, "<!-- Generated by freeciv21-manual version %s -->\n\n",
192 
193  switch (manuals) {
194  case MANUAL_SETTINGS:
195  // TRANS: markup ... Freeciv21 version ... ruleset name ... markup
196  fprintf(doc, _("%sFreeciv21 %s server options (%s)%s\n\n"),
197  tag_info->title_begin, freeciv21_version(), game.control.name,
198  tag_info->title_end);
199  settings_iterate(SSET_ALL, pset)
200  {
201  char buf[256];
202  const char *sethelp;
203 
204  fprintf(doc, tag_info->item_begin, "setting", setting_number(pset));
205  fprintf(doc, "%s%s - %s%s\n\n", tag_info->sect_title_begin,
206  setting_name(pset), _(setting_short_help(pset)),
207  tag_info->sect_title_end);
208  sethelp = _(setting_extra_help(pset, true));
209  if (strlen(sethelp) > 0) {
210  QString help = sethelp;
211  help = break_lines(help, LINE_BREAK);
212  help = help.toHtmlEscaped();
213  fprintf(doc, "<pre>%s</pre>\n\n", qUtf8Printable(help));
214  }
215  fprintf(doc, "<p class=\"misc\">");
216  fprintf(doc, _("Level: %s.<br>"),
217  _(sset_level_name(setting_level(pset))));
218  fprintf(doc, _("Category: %s.<br>"),
219  _(sset_category_name(setting_category(pset))));
220 
221  /* first check if the setting is locked because this is included in
222  * the function setting_is_changeable() */
223  if (setting_locked(pset)) {
224  fprintf(doc, _("Is locked by the ruleset."));
225  } else if (!setting_is_changeable(pset, &my_conn, nullptr, 0)) {
226  fprintf(doc, _("Can only be used in server console."));
227  }
228 
229  fprintf(doc, "</p>\n");
230  setting_default_name(pset, true, buf, sizeof(buf));
231  switch (setting_type(pset)) {
232  case SST_INT:
233  fprintf(doc, "\n<p class=\"bounds\">%s %d, %s %s, %s %d</p>\n",
234  _("Minimum:"), setting_int_min(pset), _("Default:"), buf,
235  _("Maximum:"), setting_int_max(pset));
236  break;
237  case SST_ENUM: {
238  const char *value;
239 
240  fprintf(doc, "\n<p class=\"bounds\">%s</p>",
241  _("Possible values:"));
242  for (i = 0; (value = setting_enum_val(pset, i, false)); i++) {
243  fprintf(doc, "\n<p class=\"bounds\"><li/> %s: \"%s\"</p>", value,
244  setting_enum_val(pset, i, true));
245  }
246  } break;
247  case SST_BITWISE: {
248  const char *value;
249 
250  fprintf(
251  doc, "\n<p class=\"bounds\">%s</p>",
252  _("Possible values (option can take any number of these):"));
253  for (i = 0; (value = setting_bitwise_bit(pset, i, false)); i++) {
254  fprintf(doc, "\n<p class=\"bounds\"><li/> %s: \"%s\"</p>", value,
255  setting_bitwise_bit(pset, i, true));
256  }
257  } break;
258  case SST_BOOL:
259  case SST_STRING:
260  break;
261  case SST_COUNT:
262  fc_assert(setting_type(pset) != SST_COUNT);
263  break;
264  }
265  if (SST_INT != setting_type(pset)) {
266  fprintf(doc, "\n<p class=\"bounds\">%s %s</p>\n", _("Default:"),
267  buf);
268  }
269  if (setting_non_default(pset)) {
270  fprintf(doc, _("\n<p class=\"changed\">Value set to %s</p>\n"),
271  setting_value_name(pset, true, buf, sizeof(buf)));
272  }
273 
274  fprintf(doc, "%s", tag_info->item_end);
275  }
277  break;
278 
279  case MANUAL_COMMANDS:
280  // TRANS: markup ... Freeciv21 version ... markup
281  fprintf(doc, _("%sFreeciv21 %s server commands%s\n\n"),
282  tag_info->title_begin, freeciv21_version(),
283  tag_info->title_end);
284  for (i = 0; i < CMD_NUM; i++) {
285  const struct command *cmd = command_by_number(i);
286 
287  fprintf(doc, tag_info->item_begin, "cmd", i);
288  fprintf(doc, "%s%s - %s%s\n\n", tag_info->sect_title_begin,
289  command_name(cmd), command_short_help(cmd),
290  tag_info->sect_title_end);
291  if (command_synopsis(cmd)) {
292  QString cmdstr = command_synopsis(cmd);
293  cmdstr = cmdstr.toHtmlEscaped();
294  fprintf(doc, _("<table>\n<tr>\n<td valign=\"top\">"
295  "<pre>Synopsis:</pre></td>\n<td>"));
296  fprintf(doc, "<pre>%s</pre></td></tr></table>",
297  qUtf8Printable(cmdstr));
298  }
299  fprintf(doc, _("<p class=\"level\">Level: %s</p>\n"),
300  cmdlevel_name(command_level(cmd)));
301  {
302  QString help = command_extra_help(cmd);
303  if (!help.isEmpty()) {
304  help = break_lines(help, LINE_BREAK);
305  help = help.toHtmlEscaped();
306  fprintf(doc, "\n");
307  fprintf(doc, _("<p>Description:</p>\n\n"));
308  fprintf(doc, "<pre>%s</pre>\n", qUtf8Printable(help));
309  }
310  }
311 
312  fprintf(doc, "%s", tag_info->item_end);
313  }
314  break;
315 
316  case MANUAL_TERRAIN:
317  // TRANS: markup ... Freeciv21 version ... ruleset name ... markup
318  fprintf(doc, _("%sFreeciv21 %s terrain help (%s)%s\n\n"),
319  tag_info->title_begin, freeciv21_version(), game.control.name,
320  tag_info->title_end);
321  fprintf(doc, "<table><tr bgcolor=#9bc3d1><th>%s</th>", _("Terrain"));
322  fprintf(doc, "<th>F/P/T</th><th>%s</th>", _("Resources"));
323  fprintf(doc, "<th>%s<br/>%s</th>", _("Move cost"), _("Defense bonus"));
324  fprintf(doc, "<th>%s<br/>%s<br/>%s<br/>%s<br/>%s<br/>%s<br/>(%s)</th>",
325  _("Irrigation"), _("Cultivate"), _("Mining"), _("Plant"),
326  _("Transform"),
327  // xgettext:no-c-format
328  _("% of Road bonus"), _("turns"));
329  fprintf(doc, "<th>%s<br/>%s</th>", _("Clean pollution"),
330  _("Clean fallout"));
331  ri = 0;
332  if (game.control.num_road_types > 0) {
333  fprintf(doc, "<th>");
334  }
335  extra_type_by_cause_iterate(EC_ROAD, pextra)
336  {
337  if (++ri < game.control.num_road_types) {
338  fprintf(doc, "%s<br/>", extra_name_translation(pextra));
339  } else {
340  // Last one
341  fprintf(doc, "%s</th>", extra_name_translation(pextra));
342  }
343  }
345  fprintf(doc, "</tr>\n\n");
346  terrain_type_iterate(pterrain)
347  {
348  struct extra_type **r;
349 
350  if (0 == qstrlen(terrain_rule_name(pterrain))) {
351  // Must be a disabled piece of terrain
352  continue;
353  }
354 
355  fprintf(doc, "<tr><td>%s</td>", terrain_name_translation(pterrain));
356  fprintf(doc, "<td>%d/%d/%d</td>\n", pterrain->output[O_FOOD],
357  pterrain->output[O_SHIELD], pterrain->output[O_TRADE]);
358 
359  fprintf(doc, "<td><table width=\"100%%\">\n");
360  for (r = pterrain->resources; *r; r++) {
361  fprintf(doc,
362  "<tr><td>%s</td><td align=\"right\">%d/%d/%d</td></tr>\n",
364  (*r)->data.resource->output[O_FOOD],
365  (*r)->data.resource->output[O_SHIELD],
366  (*r)->data.resource->output[O_TRADE]);
367  }
368  fprintf(doc, "</table></td>\n");
369 
370  fprintf(doc, "<td align=\"center\">%d<br/>+%d%%</td>\n",
371  pterrain->movement_cost, pterrain->defense_bonus);
372 
373  fprintf(doc, "<td><table width=\"100%%\">\n");
374  if (pterrain->irrigation_time != 0) {
375  fprintf(doc,
376  "<tr><td>+%d F</td><td align=\"right\">(%d)</td></tr>\n",
377  pterrain->irrigation_food_incr, pterrain->irrigation_time);
378  } else {
379  fprintf(doc, "<tr><td>%s</td></tr>\n", _("impossible"));
380  }
381  if (pterrain->irrigation_result != nullptr
382  && pterrain->irrigation_result != pterrain) {
383  fprintf(doc, "<tr><td>%s</td><td align=\"right\">(%d)</td></tr>\n",
384  terrain_name_translation(pterrain->irrigation_result),
385  pterrain->cultivate_time);
386  } else {
387  fprintf(doc, "<tr><td>%s</td></tr>\n", _("impossible"));
388  }
389  if (pterrain->mining_time != 0) {
390  fprintf(doc,
391  "<tr><td>+%d P</td><td align=\"right\">(%d)</td></tr>\n",
392  pterrain->mining_shield_incr, pterrain->mining_time);
393  } else {
394  fprintf(doc, "<tr><td>%s</td></tr>\n", _("impossible"));
395  }
396  if (pterrain->mining_result != nullptr
397  && pterrain->mining_result != pterrain) {
398  fprintf(doc, "<tr><td>%s</td><td align=\"right\">(%d)</td></tr>\n",
399  terrain_name_translation(pterrain->mining_result),
400  pterrain->plant_time);
401  } else {
402  fprintf(doc, "<tr><td>%s</td></tr>\n", _("impossible"));
403  }
404 
405  if (pterrain->transform_result) {
406  fprintf(doc, "<tr><td>%s</td><td align=\"right\">(%d)</td></tr>\n",
407  terrain_name_translation(pterrain->transform_result),
408  pterrain->transform_time);
409  } else {
410  fprintf(doc, "<tr><td>-</td><td align=\"right\">(-)</td></tr>\n");
411  }
412  fprintf(doc, "<tr><td>%d / %d / %d</td></tr>\n</table></td>\n",
413  pterrain->road_output_incr_pct[O_FOOD],
414  pterrain->road_output_incr_pct[O_SHIELD],
415  pterrain->road_output_incr_pct[O_TRADE]);
416 
417  fprintf(doc, "<td align=\"center\">%d / %d</td>",
418  pterrain->clean_pollution_time,
419  pterrain->clean_fallout_time);
420 
421  ri = 0;
422  if (game.control.num_road_types > 0) {
423  fprintf(doc, "<td>");
424  }
425  extra_type_by_cause_iterate(EC_ROAD, pextra)
426  {
427  if (++ri < game.control.num_road_types) {
428  fprintf(doc, "%d / ",
429  terrain_extra_build_time(pterrain, ACTIVITY_GEN_ROAD,
430  pextra));
431  } else {
432  fprintf(doc, "%d</td>",
433  terrain_extra_build_time(pterrain, ACTIVITY_GEN_ROAD,
434  pextra));
435  }
436  }
438  fprintf(doc, "</tr>\n\n");
439  }
441 
442  fprintf(doc, "</table>\n");
443 
444  break;
445 
446  case MANUAL_BUILDINGS:
447  case MANUAL_WONDERS:
448  if (manuals == MANUAL_BUILDINGS) {
449  // TRANS: markup ... Freeciv21 version ... ruleset name ... markup
450  fprintf(doc, _("%sFreeciv21 %s buildings help (%s)%s\n\n"),
451  tag_info->title_begin, freeciv21_version(),
452  game.control.name, tag_info->title_end);
453  } else {
454  // TRANS: markup ... Freeciv21 version ... ruleset name ... markup
455  fprintf(doc, _("%sFreeciv21 %s wonders help (%s)%s\n\n"),
456  tag_info->title_begin, freeciv21_version(),
457  game.control.name, tag_info->title_end);
458  }
459 
460  fprintf(doc,
461  "<table>\n<tr bgcolor=#9bc3d1><th>%s</th>"
462  "<th>%s<br/>%s</th><th>%s<br/>%s</th><th>%s</th></tr>\n\n",
463  _("Name"), _("Cost"), _("Upkeep"), _("Requirement"),
464  _("Obsolete by"), _("More info"));
465 
466  improvement_iterate(pimprove)
467  {
468  char buf[64000];
469  struct advance *obs_tech = nullptr;
470 
471  if (!valid_improvement(pimprove)
472  || is_great_wonder(pimprove) == (manuals == MANUAL_BUILDINGS)) {
473  continue;
474  }
475 
476  helptext_building(buf, sizeof(buf), nullptr, nullptr, pimprove,
477  nullptr);
478 
479  fprintf(doc,
480  "<tr><td>%s</td>\n"
481  "<td align=\"center\"><b>%d</b><br/>%d</td>\n<td>",
482  improvement_name_translation(pimprove), pimprove->build_cost,
483  pimprove->upkeep);
484 
485  requirement_vector_iterate(&pimprove->reqs, req)
486  {
487  char text[512], text2[512];
488  fc_snprintf(text2, sizeof(text2),
489  // TRANS: improvement requires a feature to be absent.
490  req->present ? "%s" : _("no %s"),
491  VUT_NONE != req->source.kind
492  ? universal_name_translation(&req->source, text,
493  sizeof(text))
494  : Q_("?req:None"));
495  fprintf(doc, "%s<br/>", text2);
496  }
498 
499  requirement_vector_iterate(&pimprove->obsolete_by, pobs)
500  {
501  if (pobs->source.kind == VUT_ADVANCE) {
502  obs_tech = pobs->source.value.advance;
503  break;
504  }
505  }
507 
508  fprintf(doc, "<em>%s</em></td>\n",
509  obs_tech != nullptr ? advance_name_translation(obs_tech)
510  : Q_("?tech:None"));
511  fprintf(doc, "<td>%s</td>\n</tr>\n\n", buf);
512  }
514  fprintf(doc, "</table>");
515  break;
516 
517  case MANUAL_GOVS:
518  /* Freeciv-web uses (parts of) the government HTML output in its own
519  * manual pages. */
520  // FIXME: this doesn't resemble the wiki manual at all.
521  // TRANS: markup ... Freeciv21 version ... ruleset name ... markup
522  fprintf(doc, _("%sFreeciv21 %s governments help (%s)%s\n\n"),
523  tag_info->title_begin, freeciv21_version(), game.control.name,
524  tag_info->title_end);
525  for (auto &pgov : governments) {
526  char buf[64000];
527  fprintf(doc, tag_info->item_begin, "gov", pgov.item_number);
528  fprintf(doc, "%s%s%s\n\n", tag_info->sect_title_begin,
530  tag_info->sect_title_end);
531  fprintf(doc, tag_info->subitem_begin, "helptext");
532  helptext_government(buf, sizeof(buf), nullptr, nullptr, &pgov);
533  fprintf(doc, "%s\n\n", buf);
534  fprintf(doc, "%s", tag_info->subitem_end);
535  fprintf(doc, "%s", tag_info->item_end);
536  };
537  break;
538 
539  case MANUAL_UNITS:
540  /* Freeciv-web uses (parts of) the unit type HTML output in its own
541  * manual pages. */
542  // FIXME: this doesn't resemble the wiki manual at all.
543  // TRANS: markup ... Freeciv21 version ... ruleset name ... markup
544  fprintf(doc, _("%sFreeciv21 %s unit types help (%s)%s\n\n"),
545  tag_info->title_begin, freeciv21_version(), game.control.name,
546  tag_info->title_end);
547  unit_type_iterate(putype)
548  {
549  char buf[64000];
550 
551  fprintf(doc, tag_info->item_begin, "utype", putype->item_number);
552  fprintf(doc, "%s%s%s\n\n", tag_info->sect_title_begin,
553  utype_name_translation(putype), tag_info->sect_title_end);
554  fprintf(doc, tag_info->subitem_begin, "cost");
555  fprintf(doc,
556  PL_("Cost: %d shield", "Cost: %d shields",
559  fprintf(doc, "%s", tag_info->subitem_end);
560  fprintf(doc, tag_info->subitem_begin, "upkeep");
561  fprintf(doc, _("Upkeep: %s"), helptext_unit_upkeep_str(putype));
562  fprintf(doc, "%s", tag_info->subitem_end);
563  fprintf(doc, tag_info->subitem_begin, "moves");
564  fprintf(doc, _("Moves: %s"),
565  move_points_text(putype->move_rate, true));
566  fprintf(doc, "%s", tag_info->subitem_end);
567  fprintf(doc, tag_info->subitem_begin, "vision");
568  fprintf(doc, _("Vision: %d"),
569  (int) sqrt((double) putype->vision_radius_sq));
570  fprintf(doc, "%s", tag_info->subitem_end);
571  fprintf(doc, tag_info->subitem_begin, "attack");
572  fprintf(doc, _("Attack: %d"), putype->attack_strength);
573  fprintf(doc, "%s", tag_info->subitem_end);
574  fprintf(doc, tag_info->subitem_begin, "defense");
575  fprintf(doc, _("Defense: %d"), putype->defense_strength);
576  fprintf(doc, "%s", tag_info->subitem_end);
577  fprintf(doc, tag_info->subitem_begin, "firepower");
578  fprintf(doc, _("Firepower: %d"), putype->firepower);
579  fprintf(doc, "%s", tag_info->subitem_end);
580  fprintf(doc, tag_info->subitem_begin, "hitpoints");
581  fprintf(doc, _("Hitpoints: %d"), putype->hp);
582  fprintf(doc, "%s", tag_info->subitem_end);
583  fprintf(doc, tag_info->subitem_begin, "obsolete");
584  fprintf(doc, _("Obsolete by: %s"),
585  U_NOT_OBSOLETED == putype->obsoleted_by
586  ? Q_("?utype:None")
587  : utype_name_translation(putype->obsoleted_by));
588  fprintf(doc, "%s", tag_info->subitem_end);
589  fprintf(doc, tag_info->subitem_begin, "helptext");
590  helptext_unit(buf, sizeof(buf), nullptr, "", putype, nullptr);
591  fprintf(doc, "%s", buf);
592  fprintf(doc, "%s", tag_info->subitem_end);
593  fprintf(doc, "%s", tag_info->item_end);
594  }
596  break;
597 
598  case MANUAL_TECHS:
599  // FIXME: this doesn't resemble the wiki manual at all.
600  // TRANS: markup ... Freeciv21 version ... ruleset name ... markup
601  fprintf(doc, _("%sFreeciv21 %s tech help (%s)%s\n\n"),
602  tag_info->title_begin, freeciv21_version(), game.control.name,
603  tag_info->title_end);
604  advance_iterate(A_FIRST, ptech)
605  {
606  if (valid_advance(ptech)) {
607  char buf[64000];
608 
609  fprintf(doc, tag_info->item_begin, "tech", ptech->item_number);
610  fprintf(doc, "%s%s%s\n\n", tag_info->sect_title_begin,
611  advance_name_translation(ptech), tag_info->sect_title_end);
612 
613  fprintf(doc, tag_info->subitem_begin, "helptext");
614  helptext_advance(buf, sizeof(buf), nullptr, "", ptech->item_number,
615  nullptr);
616  fprintf(doc, "%s", buf);
617  fprintf(doc, "%s", tag_info->subitem_end);
618 
619  fprintf(doc, "%s", tag_info->item_end);
620  }
621  }
623  break;
624 
625  case MANUAL_COUNT:
626  Q_UNREACHABLE();
627  break;
628  } // switch
629 
630  fprintf(doc, "%s", tag_info->tail);
631  fclose(doc);
632  qInfo(_("Manual file %s successfully written."), filename);
633  } // manuals
634 
635  return true;
636 }
637 
641 int main(int argc, char **argv)
642 {
643  int retval = EXIT_SUCCESS;
644  struct tag_types *tag_info = &html_tags;
645 
646  QCoreApplication app(argc, argv);
647  QCoreApplication::setApplicationVersion(freeciv21_version());
648 
649  init_nls();
651 
652  QCommandLineParser parser;
653  parser.addHelpOption();
654  parser.addVersionOption();
655 
656  bool ok = parser.addOptions({
657  {{"d", _("debug")},
658  // TRANS: Do not translate "fatal", "critical", "warning", "info" or
659  // "debug". It's exactly what the user must type.
660  _("Set debug log level (fatal/critical/warning/info/debug)."),
661  _("LEVEL"),
662  QStringLiteral("info")},
663  {{"F", "Fatal"}, _("Raise a signal on failed assertion.")},
664  {{"l", "log"},
665  _("Use FILE as logfile."),
666  // TRANS: Command-line argument
667  _("FILE")},
668  {{"r", "ruleset"},
669  _("Make manual for RULESET."),
670  // TRANS: Command-line argument
671  _("RULESET")},
672  {{"w", "wiki"}, _("Write manual in wiki format.")},
673  });
674  if (!ok) {
675  qFatal("Adding command line arguments failed.");
676  }
677 
678  // Parse
679  parser.process(app);
680 
681  // Process the parsed options
682  if (!log_init(parser.value(QStringLiteral("debug")))) {
683  exit(EXIT_FAILURE);
684  }
685  fc_assert_set_fatal(parser.isSet(QStringLiteral("Fatal")));
686  if (parser.isSet(QStringLiteral("ruleset"))) {
687  if (parser.values(QStringLiteral("ruleset")).size() > 1) {
688  fc_fprintf(stderr, _("Multiple rulesets requested. Only one ruleset "
689  "at time supported.\n"));
690  exit(EXIT_FAILURE);
691  } else {
692  ruleset = parser.value(QStringLiteral("ruleset"));
693  }
694  }
695  if (parser.isSet(QStringLiteral("log"))) {
696  srvarg.log_filename = parser.value(QStringLiteral("log"));
697  }
698  if (parser.isSet(QStringLiteral("wiki"))) {
699  tag_info = &wiki_tags;
700  }
701 
703 
704  // must be before con_log_init()
707  // logging available after this point
708 
709  // Get common code to treat us as a tool.
710  i_am_tool();
711 
712  /* Initialize the fc_interface functions needed to generate the help
713  * text. */
715 
716  // Initialize game with default values
717  game_init(false);
718 
719  // Set ruleset user requested in to use
720  if (!ruleset.isEmpty()) {
721  sz_strlcpy(game.server.rulesetdir, qUtf8Printable(ruleset));
722  }
723 
724  settings_init(false);
725 
726  if (!manual_command(tag_info)) {
727  retval = EXIT_FAILURE;
728  }
729 
730  con_log_close();
731  free_libfreeciv();
732  free_nls();
733 
734  return retval;
735 }
QString break_lines(const QString &src, int after)
Definition: astring.cpp:68
void init_our_capability()
Setup our internal network capability string.
Definition: capstr.cpp:83
int main(int argc, char **argv)
Entry point of whole freeciv-manual program.
Definition: civmanual.cpp:641
static QString ruleset
Definition: civmanual.cpp:152
manuals
Definition: civmanual.cpp:56
@ MANUAL_COUNT
Definition: civmanual.cpp:65
@ MANUAL_COMMANDS
Definition: civmanual.cpp:58
@ MANUAL_SETTINGS
Definition: civmanual.cpp:57
@ MANUAL_WONDERS
Definition: civmanual.cpp:61
@ MANUAL_TERRAIN
Definition: civmanual.cpp:59
@ MANUAL_TECHS
Definition: civmanual.cpp:64
@ MANUAL_UNITS
Definition: civmanual.cpp:63
@ MANUAL_GOVS
Definition: civmanual.cpp:62
@ MANUAL_BUILDINGS
Definition: civmanual.cpp:60
static bool manual_command(struct tag_types *tag_info)
Write a server manual, then quit.
Definition: civmanual.cpp:157
struct tag_types html_tags
Definition: civmanual.cpp:82
struct tag_types wiki_tags
Definition: civmanual.cpp:118
const char * command_name(const struct command *pcommand)
Return name of the command.
Definition: commands.cpp:710
const struct command * command_by_number(int i)
Return command by its number.
Definition: commands.cpp:701
const char * command_short_help(const struct command *pcommand)
Returns the short help text of the command (translated).
Definition: commands.cpp:734
char * command_extra_help(const struct command *pcommand)
Returns the extra help text of the command (translated).
Definition: commands.cpp:743
enum cmdlevel command_level(const struct command *pcommand)
What is the permissions level required for running the command?
Definition: commands.cpp:758
const char * command_synopsis(const struct command *pcommand)
Returns the synopsis text of the command (translated).
Definition: commands.cpp:726
@ CMD_NUM
Definition: commands.h:107
void connection_common_init(struct connection *pconn)
Initialize common part of connection structure.
Definition: connection.cpp:555
void con_log_init(const QString &log_filename)
Initialize logging via console.
Definition: console.cpp:111
void con_log_close()
Deinitialize logging.
Definition: console.cpp:123
const char * extra_name_translation(const struct extra_type *pextra)
Return the (translated) name of the extra type.
Definition: extras.cpp:165
#define extra_type_by_cause_iterate_end
Definition: extras.h:307
#define extra_type_by_cause_iterate(_cause, _extra)
Definition: extras.h:299
void free_libfreeciv()
Free misc resources allocated for libfreeciv.
@ O_SHIELD
Definition: fc_types.h:86
@ O_FOOD
Definition: fc_types.h:85
@ O_TRADE
Definition: fc_types.h:87
#define LINE_BREAK
Definition: fc_types.h:73
void fc_fprintf(FILE *stream, const char *format,...)
Do a fprintf from the internal charset into the local charset.
Definition: fciconv.cpp:132
void init_character_encodings(const char *my_internal_encoding, bool my_use_transliteration)
Must be called during the initialization phase of server and client to initialize the character encod...
Definition: fciconv.cpp:39
#define FC_DEFAULT_DATA_ENCODING
Definition: fciconv.h:69
#define Q_(String)
Definition: fcintl.h:53
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
struct civ_game game
Definition: game.cpp:47
void game_init(bool keep_ruleset_value)
Initialise all game settings.
Definition: game.cpp:420
static void i_am_tool()
Definition: game.h:295
std::vector< government > governments
Definition: government.cpp:28
const char * government_name_translation(const struct government *pgovern)
Return the (translated) name of the given government.
Definition: government.cpp:136
void helptext_advance(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, int i, const nation_set *nations_to_show)
Append misc dynamic text for advance/technology.
Definition: helpdata.cpp:2886
void helptext_government(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, struct government *gov)
Append text for government.
Definition: helpdata.cpp:3942
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype, const nation_set *nations_to_show)
Append misc dynamic text for units.
Definition: helpdata.cpp:1639
char * helptext_unit_upkeep_str(const struct unit_type *utype)
Returns pointer to static string with eg: "1 shield, 1 unhappy".
Definition: helpdata.cpp:4611
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove, const nation_set *nations_to_show)
FIXME: Also, in principle these could be auto-generated once, inserted into pitem->text,...
Definition: helpdata.cpp:1181
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
Returns pointer when the improvement_type "exists" in this game, returns nullptr otherwise.
bool is_great_wonder(const struct impr_type *pimprove)
Is this building a great wonder?
const char * improvement_name_translation(const struct impr_type *pimprove)
Return the (translated) name of the given improvement.
#define improvement_iterate_end
Definition: improvement.h:199
#define improvement_iterate(_p)
Definition: improvement.h:193
bool log_init(const QString &level_str, const QStringList &extra_rules)
Parses a log level string as provided by the user on the command line, and installs the corresponding...
Definition: log.cpp:55
void fc_assert_set_fatal(bool fatal)
Set what signal the assert* macros should raise on failed assertion (-1 to disable).
Definition: log.cpp:226
#define fc_assert(condition)
Definition: log.h:89
const char * move_points_text(int mp, bool reduce)
Simple version of move_points_text_full() – render positive movement points as text without any prefi...
Definition: movement.cpp:856
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Make user-friendly text for the source.
#define requirement_vector_iterate_end
Definition: requirements.h:80
#define requirement_vector_iterate(req_vec, preq)
Definition: requirements.h:78
bool load_rulesets(const char *restore, const char *alt, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Loads the rulesets.
Definition: ruleset.cpp:8582
void init_connections()
Initialize connection related stuff.
Definition: sernet.cpp:452
void settings_init(bool act)
Initialize stuff related to this code module.
Definition: settings.cpp:4761
int setting_number(const struct setting *pset)
Returns the id to the given setting.
Definition: settings.cpp:3056
enum sset_category setting_category(const struct setting *pset)
Access function for the setting category.
Definition: settings.cpp:3108
bool setting_locked(const struct setting *pset)
Returns if the setting is locked by the ruleset.
Definition: settings.cpp:4283
bool setting_non_default(const struct setting *pset)
Returns whether the setting has non-default value.
Definition: settings.cpp:4257
enum sset_type setting_type(const struct setting *pset)
Access function for the setting type.
Definition: settings.cpp:3092
int setting_int_max(const struct setting *pset)
Returns the maximal integer value for this setting.
Definition: settings.cpp:3447
enum sset_level setting_level(const struct setting *pset)
Access function for the setting level (used by the /show command).
Definition: settings.cpp:3100
const char * setting_enum_val(const struct setting *pset, int val, bool pretty)
Convert the integer to the string representation of an enumerator.
Definition: settings.cpp:3595
const char * setting_name(const struct setting *pset)
Access function for the setting name.
Definition: settings.cpp:3065
const char * setting_value_name(const struct setting *pset, bool pretty, char *buf, size_t buf_len)
Compute the name of the current value of the setting.
Definition: settings.cpp:3946
int setting_int_min(const struct setting *pset)
Returns the minimal integer value for this setting.
Definition: settings.cpp:3438
const char * setting_short_help(const struct setting *pset)
Access function for the short help (not translated yet) of the setting.
Definition: settings.cpp:3070
const char * setting_extra_help(const struct setting *pset, bool constant)
Access function for the long (extra) help of the setting.
Definition: settings.cpp:3080
bool setting_is_changeable(const struct setting *pset, struct connection *caller, char *reject_msg, size_t reject_msg_len)
Returns whether the specified server setting (option) can currently be changed by the caller.
Definition: settings.cpp:3191
const char * setting_bitwise_bit(const struct setting *pset, int bit, bool pretty)
Convert the bit number to its string representation.
Definition: settings.cpp:3775
const char * setting_default_name(const struct setting *pset, bool pretty, char *buf, size_t buf_len)
Compute the name of the default value of the setting.
Definition: settings.cpp:3982
#define settings_iterate(_level, _pset)
Definition: settings.h:168
#define settings_iterate_end
Definition: settings.h:175
void free_nls()
Free memory allocated by Native Language Support.
Definition: shared.cpp:931
void init_nls()
Setup for Native Language Support, if configured to use it.
Definition: shared.cpp:871
size_t size
Definition: specvec.h:64
struct server_arguments srvarg
Definition: srv_main.cpp:118
Definition: tech.h:113
struct civ_game::@28::@32 server
struct packet_ruleset_control control
Definition: game.h:74
struct packet_game_info info
Definition: game.h:80
enum cmdlevel access_level
Definition: connection.h:164
QString log_filename
Definition: srv_main.h:45
const char * tail
Definition: civmanual.cpp:79
const char * subitem_begin
Definition: civmanual.cpp:77
const char * header
Definition: civmanual.cpp:70
const char * item_begin
Definition: civmanual.cpp:75
const char * file_ext
Definition: civmanual.cpp:69
const char * sect_title_end
Definition: civmanual.cpp:74
const char * title_begin
Definition: civmanual.cpp:71
const char * item_end
Definition: civmanual.cpp:76
const char * sect_title_begin
Definition: civmanual.cpp:73
const char * title_end
Definition: civmanual.cpp:72
const char * subitem_end
Definition: civmanual.cpp:78
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
FILE * fc_fopen(const char *filename, const char *opentype)
Wrapper function for fopen() with filename conversion to local encoding on Windows.
Definition: support.cpp:255
#define sz_strlcpy(dest, src)
Definition: support.h:140
struct advance * valid_advance(struct advance *padvance)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Definition: tech.cpp:138
const char * advance_name_translation(const struct advance *padvance)
Return the (translated) name of the given advance/technology.
Definition: tech.cpp:274
#define advance_iterate(_start, _p)
Definition: tech.h:232
#define A_FIRST
Definition: tech.h:37
#define advance_iterate_end
Definition: tech.h:238
const char * terrain_rule_name(const struct terrain *pterrain)
Return the (untranslated) rule name of the terrain.
Definition: terrain.cpp:184
const char * terrain_name_translation(const struct terrain *pterrain)
Return the (translated) name of the terrain.
Definition: terrain.cpp:175
int terrain_extra_build_time(const struct terrain *pterrain, enum unit_activity activity, const struct extra_type *tgt)
Time to complete the extra building activity on the given terrain.
Definition: terrain.cpp:579
#define terrain_type_iterate(_p)
Definition: terrain.h:331
#define terrain_type_iterate_end
Definition: terrain.h:337
void fc_interface_init_tool()
Initialize tool specific functions.
int utype_build_shield_cost_base(const struct unit_type *punittype)
Returns the number of shields this unit type represents.
Definition: unittype.cpp:1168
const char * utype_name_translation(const struct unit_type *punittype)
Return the (translated) name of the unit type.
Definition: unittype.cpp:1256
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define unit_type_iterate_end
Definition: unittype.h:791
#define U_NOT_OBSOLETED
Definition: unittype.h:493
const char * freeciv21_version()
Returns the raw version string.
Definition: version.cpp:29