Some miscellaneous updates to main help, for new features and otherwise.
[freeciv.git] / server / settings.c
bloba722730bf1dd26989cd22fb7386f5431ed3ac4dc
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996-2004 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "astring.h"
20 #include "fcintl.h"
21 #include "game.h"
22 #include "ioz.h"
23 #include "log.h"
24 #include "registry.h"
25 #include "shared.h"
26 #include "string_vector.h"
28 /* common */
29 #include "map.h"
31 /* server */
32 #include "gamehand.h"
33 #include "ggzserver.h"
34 #include "maphand.h"
35 #include "notify.h"
36 #include "plrhand.h"
37 #include "report.h"
38 #include "settings.h"
39 #include "srv_main.h"
40 #include "stdinhand.h"
42 /* The following classes determine what can be changed when.
43 * Actually, some of them have the same "changeability", but
44 * different types are separated here in case they have
45 * other uses.
46 * Also, SSET_GAME_INIT/SSET_RULES separate the two sections
47 * of server settings sent to the client.
48 * See the settings[] array and setting_is_changeable() for what
49 * these correspond to and explanations.
51 enum sset_class {
52 SSET_MAP_SIZE,
53 SSET_MAP_GEN,
54 SSET_MAP_ADD,
55 SSET_PLAYERS,
56 SSET_GAME_INIT,
57 SSET_RULES,
58 SSET_RULES_FLEXIBLE,
59 SSET_META
62 typedef bool (*bool_validate_func_t) (bool value, struct connection *pconn,
63 char *reject_msg,
64 size_t reject_msg_len);
65 typedef bool (*int_validate_func_t) (int value, struct connection *pconn,
66 char *reject_msg,
67 size_t reject_msg_len);
68 typedef bool (*string_validate_func_t) (const char * value,
69 struct connection *pconn,
70 char *reject_msg,
71 size_t reject_msg_len);
72 typedef bool (*enum_validate_func_t) (int value, struct connection *pconn,
73 char *reject_msg,
74 size_t reject_msg_len);
75 typedef bool (*bitwise_validate_func_t) (unsigned value,
76 struct connection *pconn,
77 char *reject_msg,
78 size_t reject_msg_len);
80 typedef void (*action_callback_func_t) (const struct setting *pset);
81 typedef const struct sset_val_name * (*val_name_func_t) (int value);
83 struct setting {
84 const char *name;
85 enum sset_class sclass;
86 bool to_client;
89 * Sould be less than 42 chars (?), or shorter if the values may
90 * have more than about 4 digits. Don't put "." on the end.
92 const char *short_help;
95 * May be empty string, if short_help is sufficient. Need not
96 * include embedded newlines (but may, for formatting); lines will
97 * be wrapped (and indented) automatically. Should have punctuation
98 * etc, and should end with a "."
100 const char *extra_help;
101 enum sset_type stype;
102 enum sset_category scategory;
103 enum sset_level slevel;
106 * About the *_validate functions: If the function is non-NULL, it
107 * is called with the new value, and returns whether the change is
108 * legal. The char * is an error message in the case of reject.
111 union {
112 /*** bool part ***/
113 struct {
114 bool *const pvalue;
115 const bool default_value;
116 const bool_validate_func_t validate;
117 const val_name_func_t name;
118 bool game_value;
119 } boolean;
120 /*** int part ***/
121 struct {
122 int *const pvalue;
123 const int default_value;
124 const int min_value;
125 const int max_value;
126 const int_validate_func_t validate;
127 int game_value;
128 } integer;
129 /*** string part ***/
130 struct {
131 char *const value;
132 const char *const default_value;
133 const size_t value_size;
134 const string_validate_func_t validate;
135 char *game_value;
136 } string;
137 /*** enumerator part ***/
138 struct {
139 void *const pvalue;
140 const int store_size;
141 const int default_value;
142 const enum_validate_func_t validate;
143 const val_name_func_t name;
144 int game_value;
145 } enumerator;
146 /*** bitwise part ***/
147 struct {
148 unsigned *const pvalue;
149 const unsigned default_value;
150 const bitwise_validate_func_t validate;
151 const val_name_func_t name;
152 unsigned game_value;
153 } bitwise;
156 /* action function */
157 const action_callback_func_t action;
159 /* ruleset lock for game settings */
160 bool locked;
163 static struct {
164 bool init;
165 struct setting_list *level[OLEVELS_NUM];
166 } setting_sorted = { .init = FALSE };
168 static void setting_set_to_default(struct setting *pset);
169 static bool setting_ruleset_one(struct section_file *file,
170 const char *name, const char *path);
171 static void setting_game_set(struct setting *pset, bool init);
172 static void setting_game_free(struct setting *pset);
173 static void setting_game_restore(struct setting *pset);
175 static void settings_list_init(void);
176 static void settings_list_free(void);
177 int settings_list_cmp(const struct setting *const *pset1,
178 const struct setting *const *pset2);
180 #define settings_snprintf(_buf, _buf_len, format, ...) \
181 if (_buf != NULL) { \
182 fc_snprintf(_buf, _buf_len, format, ## __VA_ARGS__); \
185 static bool set_enum_value(struct setting *pset, int val);
186 static int read_enum_value(const struct setting *pset);
188 /****************************************************************************
189 Enumerator name accessors.
191 Important note about compatibility:
192 1) you cannot modify the support name of an existant value. However, in a
193 developpement, you can modify it if it wasn't included in any stable
194 branch before.
195 2) Take care of modifiying the pretty name of an existant value: make sure
196 to modify the help texts which are using it.
197 ****************************************************************************/
199 #define NAME_CASE(_val, _support, _pretty) \
200 case _val: \
202 static const struct sset_val_name name = { _support, _pretty }; \
203 return &name; \
206 /****************************************************************************
207 Map size definition setting names accessor. This setting has an
208 hard-coded depedence in "server/meta.c".
209 ****************************************************************************/
210 static const struct sset_val_name *mapsize_name(int mapsize)
212 switch (mapsize) {
213 NAME_CASE(MAPSIZE_FULLSIZE, "FULLSIZE", N_("Number of tiles"));
214 NAME_CASE(MAPSIZE_PLAYER, "PLAYER", N_("Tiles per player"));
215 NAME_CASE(MAPSIZE_XYSIZE, "XYSIZE", N_("Width and height"));
217 return NULL;
220 /****************************************************************************
221 Topology setting names accessor.
222 ****************************************************************************/
223 static const struct sset_val_name *topology_name(int topology_bit)
225 switch (1 << topology_bit) {
226 NAME_CASE(TF_WRAPX, "WRAPX", N_("Wrap East-West"));
227 NAME_CASE(TF_WRAPY, "WRAPY", N_("Wrap North-South"));
228 NAME_CASE(TF_ISO, "ISO", N_("Isometric"));
229 NAME_CASE(TF_HEX, "HEX", N_("Hexagonal"));
231 return NULL;
234 /****************************************************************************
235 Generator setting names accessor.
236 ****************************************************************************/
237 static const struct sset_val_name *generator_name(int generator)
239 switch (generator) {
240 NAME_CASE(MAPGEN_SCENARIO, "SCENARIO", N_("Scenario map"));
241 NAME_CASE(MAPGEN_RANDOM, "RANDOM", N_("Fully random height"));
242 NAME_CASE(MAPGEN_FRACTAL, "FRACTAL", N_("Pseudo-fractal height"));
243 NAME_CASE(MAPGEN_ISLAND, "ISLAND", N_("Island-based"));
245 return NULL;
248 /****************************************************************************
249 Start position setting names accessor.
250 ****************************************************************************/
251 static const struct sset_val_name *startpos_name(int startpos)
253 switch (startpos) {
254 NAME_CASE(MAPSTARTPOS_DEFAULT, "DEFAULT",
255 N_("Generator's choice"));
256 NAME_CASE(MAPSTARTPOS_SINGLE, "SINGLE",
257 N_("One player per continent"));
258 NAME_CASE(MAPSTARTPOS_2or3, "2or3",
259 N_("Two or three players per continent"));
260 NAME_CASE(MAPSTARTPOS_ALL, "ALL",
261 N_("All players on a single continent"));
262 NAME_CASE(MAPSTARTPOS_VARIABLE, "VARIABLE",
263 N_("Depending on size of continents"));
265 return NULL;
268 /****************************************************************************
269 Autosaves setting names accessor.
270 ****************************************************************************/
271 static const struct sset_val_name *autosaves_name(int autosaves_bit)
273 switch (autosaves_bit) {
274 NAME_CASE(AS_TURN, "TURN", N_("New turn"));
275 NAME_CASE(AS_GAME_OVER, "GAMEOVER", N_("Game over"));
276 NAME_CASE(AS_QUITIDLE, "QUITIDLE", N_("No player connections"));
277 NAME_CASE(AS_INTERRUPT, "INTERRUPT", N_("Server interrupted"));
280 return NULL;
283 /****************************************************************************
284 Borders setting names accessor.
285 ****************************************************************************/
286 static const struct sset_val_name *borders_name(int borders)
288 switch (borders) {
289 NAME_CASE(BORDERS_DISABLED, "DISABLED", N_("Disabled"));
290 NAME_CASE(BORDERS_ENABLED, "ENABLED", N_("Enabled"));
291 NAME_CASE(BORDERS_SEE_INSIDE, "SEE_INSIDE",
292 N_("See everything inside borders"));
293 NAME_CASE(BORDERS_EXPAND, "EXPAND",
294 N_("Borders expand to unknown, revealing tiles"));
296 return NULL;
299 /****************************************************************************
300 Player colors configuration setting names accessor.
301 ****************************************************************************/
302 static const struct sset_val_name *plrcol_name(int plrcol)
304 switch (plrcol) {
305 NAME_CASE(PLRCOL_PLR_ORDER, "PLR_ORDER", N_("Per-player, in order"));
306 NAME_CASE(PLRCOL_PLR_RANDOM, "PLR_RANDOM", N_("Per-player, random"));
307 NAME_CASE(PLRCOL_PLR_SET, "PLR_SET", N_("Set manually"));
308 NAME_CASE(PLRCOL_TEAM_ORDER, "TEAM_ORDER", N_("Per-team, in order"));
309 NAME_CASE(PLRCOL_NATION_ORDER, "NATION_ORDER", N_("Per-nation, in order"));
311 return NULL;
314 /****************************************************************************
315 Diplomacy setting names accessor.
316 ****************************************************************************/
317 static const struct sset_val_name *diplomacy_name(int diplomacy)
319 switch (diplomacy) {
320 NAME_CASE(DIPLO_FOR_ALL, "ALL", N_("Enabled for everyone"));
321 NAME_CASE(DIPLO_FOR_HUMANS, "HUMAN",
322 N_("Only allowed between human players"));
323 NAME_CASE(DIPLO_FOR_AIS, "AI", N_("Only allowed between AI players"));
324 NAME_CASE(DIPLO_NO_AIS, "NOAI", N_("Only allowed when human involved"));
325 NAME_CASE(DIPLO_NO_MIXED, "NOMIXED", N_("Only allowed between two humans, or two AI players"));
326 NAME_CASE(DIPLO_FOR_TEAMS, "TEAM", N_("Restricted to teams"));
327 NAME_CASE(DIPLO_DISABLED, "DISABLED", N_("Disabled for everyone"));
329 return NULL;
332 /****************************************************************************
333 City names setting names accessor.
334 ****************************************************************************/
335 static const struct sset_val_name *citynames_name(int citynames)
337 switch (citynames) {
338 NAME_CASE(CNM_NO_RESTRICTIONS, "NO_RESTRICTIONS", N_("No restrictions"));
339 NAME_CASE(CNM_PLAYER_UNIQUE, "PLAYER_UNIQUE", N_("Unique to a player"));
340 NAME_CASE(CNM_GLOBAL_UNIQUE, "GLOBAL_UNIQUE", N_("Globally unique"));
341 NAME_CASE(CNM_NO_STEALING, "NO_STEALING", N_("No city name stealing"));
343 return NULL;
346 /****************************************************************************
347 Barbarian setting names accessor.
348 ****************************************************************************/
349 static const struct sset_val_name *barbarians_name(int barbarians)
351 switch (barbarians) {
352 NAME_CASE(BARBS_DISABLED, "DISABLED", N_("No barbarians"));
353 NAME_CASE(BARBS_HUTS_ONLY, "HUTS_ONLY", N_("Only in huts"));
354 NAME_CASE(BARBS_NORMAL, "NORMAL", N_("Normal rate of appearance"));
355 NAME_CASE(BARBS_FREQUENT, "FREQUENT", N_("Frequent barbarian uprising"));
356 NAME_CASE(BARBS_HORDES, "HORDES", N_("Raging hordes"));
358 return NULL;
361 /****************************************************************************
362 Revealmap setting names accessor.
363 ****************************************************************************/
364 static const struct sset_val_name *revealmap_name(int bit)
366 switch (1 << bit) {
367 NAME_CASE(REVEAL_MAP_START, "START", N_("Reveal map at game start"));
368 NAME_CASE(REVEAL_MAP_DEAD, "DEAD", N_("Unfog map for dead players"));
370 return NULL;
373 /****************************************************************************
374 Airlifting style setting names accessor.
375 ****************************************************************************/
376 static const struct sset_val_name *airliftingstyle_name(int bit)
378 switch (1 << bit) {
379 NAME_CASE(AIRLIFTING_ALLIED_SRC, "FROM_ALLIES",
380 N_("Allows units to be airlifted from allied cities"));
381 NAME_CASE(AIRLIFTING_ALLIED_DEST, "TO_ALLIES",
382 N_("Allows units to be airlifted to allied cities"));
383 NAME_CASE(AIRLIFTING_UNLIMITED_SRC, "SRC_UNLIMITED",
384 N_("Unlimited units from source city"));
385 NAME_CASE(AIRLIFTING_UNLIMITED_DEST, "DEST_UNLIMITED",
386 N_("Unlimited units to destination city"));
388 return NULL;
391 /****************************************************************************
392 Phase mode names accessor.
393 ****************************************************************************/
394 static const struct sset_val_name *phasemode_name(int phasemode)
396 switch (phasemode) {
397 NAME_CASE(PMT_CONCURRENT, "ALL", N_("All players move concurrently"));
398 NAME_CASE(PMT_PLAYERS_ALTERNATE,
399 "PLAYER", N_("All players alternate movement"));
400 NAME_CASE(PMT_TEAMS_ALTERNATE, "TEAM", N_("Team alternate movement"));
402 return NULL;
405 /****************************************************************************
406 Savegame compress type names accessor.
407 ****************************************************************************/
408 static const struct sset_val_name *
409 compresstype_name(enum fz_method compresstype)
411 switch (compresstype) {
412 NAME_CASE(FZ_PLAIN, "PLAIN", N_("No compression"));
413 #ifdef HAVE_LIBZ
414 NAME_CASE(FZ_ZLIB, "LIBZ", N_("Using zlib (gzip format)"));
415 #endif
416 #ifdef HAVE_LIBBZ2
417 NAME_CASE(FZ_BZIP2, "BZIP2", N_("Using bzip2"));
418 #endif
419 #ifdef HAVE_LIBLZMA
420 NAME_CASE(FZ_XZ, "XZ", N_("Using xz"));
421 #endif
423 return NULL;
426 /****************************************************************************
427 Names accessor for boolean settings (disable/enable).
428 ****************************************************************************/
429 static const struct sset_val_name *bool_name(int enable)
431 switch (enable) {
432 NAME_CASE(FALSE, "DISABLED", N_("disabled"));
433 NAME_CASE(TRUE, "ENABLED", N_("enabled"));
435 return NULL;
438 #undef NAME_CASE
441 /*************************************************************************
442 Action callback functions.
443 *************************************************************************/
445 /*************************************************************************
446 (De)initialze the score log.
447 *************************************************************************/
448 static void scorelog_action(const struct setting *pset)
450 if (*pset->boolean.pvalue) {
451 log_civ_score_init();
452 } else {
453 log_civ_score_free();
457 /*************************************************************************
458 Create the selected number of AI's.
459 *************************************************************************/
460 static void aifill_action(const struct setting *pset)
462 aifill(*pset->integer.pvalue);
465 /*************************************************************************
466 Restrict to the selected nation set.
467 *************************************************************************/
468 static void nationset_action(const struct setting *pset)
470 /* If any player's existing selection is invalid, abort it */
471 players_iterate(pplayer) {
472 if (pplayer->nation != NULL) {
473 if (!nation_is_in_current_set(pplayer->nation)) {
474 (void) player_set_nation(pplayer, NO_NATION_SELECTED);
475 send_player_info_c(pplayer, game.est_connections);
478 } players_iterate_end;
479 count_playable_nations();
480 aifill(game.info.aifill);
482 /* There might now be too many players for the available nations.
483 * Rather than getting rid of some players arbitrarily, we let the
484 * situation persist for all already-connected players; the server
485 * will simply refuse to start until someone reduces the number of
486 * players. This policy also avoids annoyance if nationset is
487 * accidentally and transiently set to an unintended value.
488 * (However, new connections will start out detached.) */
489 if (normal_player_count() > server.playable_nations) {
490 notify_conn(NULL, NULL, E_SETTING, ftc_server, "%s",
491 _("Warning: not enough nations for all current players."));
494 send_nation_availability(game.est_connections);
497 /*************************************************************************
498 Clear any user-set player colors in modes other than PLRCOL_PLR_SET.
499 *************************************************************************/
500 static void plrcol_action(const struct setting *pset)
502 if (!game_was_started()) {
503 if (read_enum_value(pset) != PLRCOL_PLR_SET) {
504 players_iterate(pplayer) {
505 server_player_set_color(pplayer, NULL);
506 } players_iterate_end;
508 /* Update clients with new color scheme. */
509 send_player_info_c(NULL, NULL);
513 /*************************************************************************
514 Toggle player AI status.
515 *************************************************************************/
516 static void autotoggle_action(const struct setting *pset)
518 if (*pset->boolean.pvalue) {
519 players_iterate(pplayer) {
520 if (!pplayer->ai_controlled && !pplayer->is_connected) {
521 toggle_ai_player_direct(NULL, pplayer);
522 send_player_info_c(pplayer, game.est_connections);
524 } players_iterate_end;
528 /*************************************************************************
529 Enact a change in the 'timeout' server setting immediately, if the game
530 is afoot.
531 *************************************************************************/
532 static void timeout_action(const struct setting *pset)
534 if (S_S_RUNNING == server_state()) {
535 int timeout = *pset->integer.pvalue;
536 /* This may cause the current turn to end immediately. */
537 game.info.seconds_to_phasedone = timeout;
538 send_game_info(NULL);
542 /*************************************************************************
543 Validation callback functions.
544 *************************************************************************/
546 /****************************************************************************
547 Verify the selected savename definition.
548 ****************************************************************************/
549 static bool savename_validate(const char *value, struct connection *caller,
550 char *reject_msg, size_t reject_msg_len)
552 char buf[MAX_LEN_PATH];
554 generate_save_name(value, buf, sizeof(buf), NULL);
556 if (!is_safe_filename(buf)) {
557 settings_snprintf(reject_msg, reject_msg_len,
558 _("Invalid save name definition: '%s' "
559 "(resolves to '%s')."), value, buf);
560 return FALSE;
563 return TRUE;
566 /****************************************************************************
567 Verify the value of the generator option (notably the MAPGEN_SCENARIO
568 case).
569 ****************************************************************************/
570 static bool generator_validate(int value, struct connection *caller,
571 char *reject_msg, size_t reject_msg_len)
573 if (map_is_empty()) {
574 if (MAPGEN_SCENARIO == value
575 && (NULL != caller || !game.scenario.is_scenario)) {
576 settings_snprintf(reject_msg, reject_msg_len,
577 _("You cannot disable the map generator."));
578 return FALSE;
580 return TRUE;
581 } else {
582 if (MAPGEN_SCENARIO != value) {
583 settings_snprintf(reject_msg, reject_msg_len,
584 _("You cannot require a map generator "
585 "when a map is loaded."));
586 return FALSE;
589 return TRUE;
592 /****************************************************************************
593 Verify the name for the score log file.
594 ****************************************************************************/
595 static bool scorefile_validate(const char *value, struct connection *caller,
596 char *reject_msg, size_t reject_msg_len)
598 if (!is_safe_filename(value)) {
599 settings_snprintf(reject_msg, reject_msg_len,
600 _("Invalid score name definition: '%s'."), value);
601 return FALSE;
604 return TRUE;
607 /*************************************************************************
608 Verify that a given demography string is valid. See
609 game.demography.
610 *************************************************************************/
611 static bool demography_callback(const char *value,
612 struct connection *caller,
613 char *reject_msg,
614 size_t reject_msg_len)
616 int error;
618 if (is_valid_demography(value, &error)) {
619 return TRUE;
620 } else {
621 settings_snprintf(reject_msg, reject_msg_len,
622 _("Demography string validation failed at character: "
623 "'%c'. Try \"help demography\"."), value[error]);
624 return FALSE;
628 /*************************************************************************
629 Verify that a given allowtake string is valid. See
630 game.allow_take.
631 *************************************************************************/
632 static bool allowtake_callback(const char *value,
633 struct connection *caller,
634 char *reject_msg,
635 size_t reject_msg_len)
637 int len = strlen(value), i;
638 bool havecharacter_state = FALSE;
640 /* We check each character individually to see if it's valid. This
641 * does not check for duplicate entries.
643 * We also track the state of the machine. havecharacter_state is
644 * true if the preceeding character was a primary label, e.g.
645 * NHhAadb. It is false if the preceeding character was a modifier
646 * or if this is the first character. */
648 for (i = 0; i < len; i++) {
649 /* Check to see if the character is a primary label. */
650 if (strchr("HhAadbOo", value[i])) {
651 havecharacter_state = TRUE;
652 continue;
655 /* If we've already passed a primary label, check to see if the
656 * character is a modifier. */
657 if (havecharacter_state && strchr("1234", value[i])) {
658 havecharacter_state = FALSE;
659 continue;
662 /* Looks like the character was invalid. */
663 settings_snprintf(reject_msg, reject_msg_len,
664 _("Allowed take string validation failed at "
665 "character: '%c'. Try \"help allowtake\"."),
666 value[i]);
667 return FALSE;
670 /* All characters were valid. */
671 return TRUE;
674 /*************************************************************************
675 Verify that a given startunits string is valid. See
676 game.server.start_units.
677 *************************************************************************/
678 static bool startunits_callback(const char *value,
679 struct connection *caller,
680 char *reject_msg,
681 size_t reject_msg_len)
683 int len = strlen(value), i;
685 /* We check each character individually to see if it's valid, and
686 * also make sure there is at least one city founder. */
688 for (i = 0; i < len; i++) {
689 /* TODO: add 'f' back in here when we can support ferry units */
690 if (strchr("cwxksdDaA", value[i])) {
691 continue;
694 /* Looks like the character was invalid. */
695 settings_snprintf(reject_msg, reject_msg_len,
696 _("Starting units string validation failed at "
697 "character '%c'. Try \"help startunits\"."),
698 value[i]);
699 return FALSE;
702 /* All characters were valid. */
703 return TRUE;
706 /*************************************************************************
707 Verify that a given endturn is valid.
708 *************************************************************************/
709 static bool endturn_callback(int value, struct connection *caller,
710 char *reject_msg, size_t reject_msg_len)
712 if (value < game.info.turn) {
713 /* Tried to set endturn earlier than current turn */
714 settings_snprintf(reject_msg, reject_msg_len,
715 _("Cannot set endturn earlier than current turn."));
716 return FALSE;
718 return TRUE;
721 /*************************************************************************
722 Verify that a given maxplayers string is valid.
723 *************************************************************************/
724 static bool maxplayers_callback(int value, struct connection *caller,
725 char *reject_msg, size_t reject_msg_len)
727 #ifdef GGZ_SERVER
728 if (with_ggz) {
729 /* In GGZ mode the maxplayers is the number of actual players - set
730 * when the game is lauched and not changed thereafter. This may be
731 * changed in future. */
732 settings_snprintf(reject_msg, reject_msg_len,
733 _("Cannot change maxplayers in GGZ mode."));
734 return FALSE;
736 #endif /* GGZ_SERVER */
737 if (value < player_count()) {
738 settings_snprintf(reject_msg, reject_msg_len,
739 _("Number of players (%d) is higher than requested "
740 "value (%d). Keeping old value."), player_count(),
741 value);
742 return FALSE;
744 /* If any start positions are defined by a scenario, we can only
745 * accommodate as many players as we have start positions. */
746 if (0 < map_startpos_count() && value > map_startpos_count()) {
747 settings_snprintf(reject_msg, reject_msg_len,
748 _("Requested value (%d) is greater than number of "
749 "available start positions (%d). Keeping old value."),
750 value, map_startpos_count());
751 return FALSE;
754 return TRUE;
757 /*************************************************************************
758 Validate the 'nationset' server setting.
759 *************************************************************************/
760 static bool nationset_callback(const char *value,
761 struct connection *caller,
762 char *reject_msg,
763 size_t reject_msg_len)
765 if (strlen(value) == 0) {
766 return TRUE;
767 } else if (nation_set_by_rule_name(value)) {
768 return TRUE;
769 } else {
770 settings_snprintf(reject_msg, reject_msg_len,
771 /* TRANS: do not translate 'list nationsets' */
772 _("Unknown nation set \"%s\". See '%slist nationsets' "
773 "for possible values."), value, caller ? "/" : "");
774 return FALSE;
778 /*************************************************************************
779 Validate the 'timeout' server setting.
780 *************************************************************************/
781 static bool timeout_callback(int value, struct connection *caller,
782 char *reject_msg, size_t reject_msg_len)
784 /* Disallow low timeout values for non-hack connections. */
785 if (caller && caller->access_level < ALLOW_HACK && value < 30) {
786 settings_snprintf(reject_msg, reject_msg_len,
787 _("You are not allowed to set timeout values less "
788 "than 30 seconds."));
789 return FALSE;
792 if (value == -1 && game.server.unitwaittime != 0) {
793 /* autogame only with 'unitwaittime' = 0 */
794 settings_snprintf(reject_msg, reject_msg_len,
795 /* TRANS: Do not translate setting names in ''. */
796 _("For autogames ('timeout' = -1) 'unitwaittime' "
797 "should be deactivated (= 0)."));
798 return FALSE;
801 if (value > 0 && value < game.server.unitwaittime * 3 / 2) {
802 /* for normal games 'timeout' should be at least 3/2 times the value
803 * of 'unitwaittime' */
804 settings_snprintf(reject_msg, reject_msg_len,
805 /* TRANS: Do not translate setting names in ''. */
806 _("'timeout' can not be lower than 3/2 of the "
807 "'unitwaittime' setting (= %d). Please change "
808 "'unitwaittime' first."), game.server.unitwaittime);
809 return FALSE;
812 return TRUE;
815 /*************************************************************************
816 Check 'timeout' setting if 'unitwaittime' is changed.
817 *************************************************************************/
818 static bool unitwaittime_callback(int value, struct connection *caller,
819 char *reject_msg, size_t reject_msg_len)
821 if (game.info.timeout == -1 && value != 0) {
822 settings_snprintf(reject_msg, reject_msg_len,
823 /* TRANS: Do not translate setting names in ''. */
824 _("For autogames ('timeout' = -1) 'unitwaittime' "
825 "should be deactivated (= 0)."));
826 return FALSE;
829 if (game.info.timeout > 0 && value > game.info.timeout * 2 / 3) {
830 settings_snprintf(reject_msg, reject_msg_len,
831 /* TRANS: Do not translate setting names in ''. */
832 _("'unitwaittime' has to be lower than 2/3 of the "
833 "'timeout' setting (= %d). Please change 'timeout' "
834 "first."), game.info.timeout);
835 return FALSE;
838 return TRUE;
841 /*************************************************************************
842 Topology setting validation callback.
843 *************************************************************************/
844 static bool mapsize_callback(int value, struct connection *caller,
845 char *reject_msg, size_t reject_msg_len)
847 if (value == MAPSIZE_XYSIZE && MAP_IS_ISOMETRIC &&
848 map.ysize % 2 != 0) {
849 /* An isometric map needs a even ysize. Is is calculated automatically
850 * for all settings but mapsize=XYSIZE. */
851 settings_snprintf(reject_msg, reject_msg_len,
852 _("For an isometric or hexagonal map the ysize must be "
853 "even."));
854 return FALSE;
857 return TRUE;
860 /*************************************************************************
861 xsize setting validation callback.
862 *************************************************************************/
863 static bool xsize_callback(int value, struct connection *caller,
864 char *reject_msg, size_t reject_msg_len)
866 int size = value * map.ysize;
868 if (size < MAP_MIN_SIZE * 1000) {
869 settings_snprintf(reject_msg, reject_msg_len,
870 _("The map size (%d * %d = %d) must be larger than "
871 "%d tiles."), value, map.ysize, size,
872 MAP_MIN_SIZE * 1000);
873 return FALSE;
874 } else if (size > MAP_MAX_SIZE * 1000) {
875 settings_snprintf(reject_msg, reject_msg_len,
876 _("The map size (%d * %d = %d) must be lower than "
877 "%d tiles."), value, map.ysize, size,
878 MAP_MAX_SIZE * 1000);
879 return FALSE;
882 return TRUE;
885 /*************************************************************************
886 ysize setting validation callback.
887 *************************************************************************/
888 static bool ysize_callback(int value, struct connection *caller,
889 char *reject_msg, size_t reject_msg_len)
891 int size = map.xsize * value;
893 if (size < MAP_MIN_SIZE * 1000) {
894 settings_snprintf(reject_msg, reject_msg_len,
895 _("The map size (%d * %d = %d) must be larger than "
896 "%d tiles."), map.xsize, value, size,
897 MAP_MIN_SIZE * 1000);
898 return FALSE;
899 } else if (size > MAP_MAX_SIZE * 1000) {
900 settings_snprintf(reject_msg, reject_msg_len,
901 _("The map size (%d * %d = %d) must be lower than "
902 "%d tiles."), map.xsize, value, size,
903 MAP_MAX_SIZE * 1000);
904 return FALSE;
905 } else if (map.server.mapsize == MAPSIZE_XYSIZE && MAP_IS_ISOMETRIC &&
906 value % 2 != 0) {
907 /* An isometric map needs a even ysize. Is is calculated automatically
908 * for all settings but mapsize=XYSIZE. */
909 settings_snprintf(reject_msg, reject_msg_len,
910 _("For an isometric or hexagonal map the ysize must be "
911 "even."));
912 return FALSE;
915 return TRUE;
918 /*************************************************************************
919 Topology setting validation callback.
920 *************************************************************************/
921 static bool topology_callback(unsigned value, struct connection *caller,
922 char *reject_msg, size_t reject_msg_len)
924 if (map.server.mapsize == MAPSIZE_XYSIZE &&
925 ((value & (TF_ISO)) != 0 || (value & (TF_HEX)) != 0) &&
926 map.ysize % 2 != 0) {
927 /* An isometric map needs a even ysize. Is is calculated automatically
928 * for all settings but mapsize=XYSIZE. */
929 settings_snprintf(reject_msg, reject_msg_len,
930 _("For an isometric or hexagonal map the ysize must be "
931 "even."));
932 return FALSE;
935 return TRUE;
938 /*************************************************************************
939 Validate that the player color mode can be used.
940 *************************************************************************/
941 static bool plrcol_validate(int value, struct connection *caller,
942 char *reject_msg, size_t reject_msg_len)
944 enum plrcolor_mode mode = value;
945 if (mode == PLRCOL_NATION_ORDER) {
946 nations_iterate(pnation) {
947 if (nation_color(pnation)) {
948 /* At least one nation has a color. Allow this mode. */
949 return TRUE;
951 } nations_iterate_end;
952 settings_snprintf(reject_msg, reject_msg_len,
953 _("No nations in the currently loaded ruleset have "
954 "associated colors."));
955 return FALSE;
957 return TRUE;
960 #define GEN_BOOL(name, value, sclass, scateg, slevel, to_client, \
961 short_help, extra_help, func_validate, func_action, \
962 _default) \
963 {name, sclass, to_client, short_help, extra_help, SSET_BOOL, \
964 scateg, slevel, \
965 {.boolean = {&value, _default, func_validate, bool_name, \
966 FALSE}}, func_action, FALSE},
968 #define GEN_INT(name, value, sclass, scateg, slevel, to_client, \
969 short_help, extra_help, func_validate, func_action, \
970 _min, _max, _default) \
971 {name, sclass, to_client, short_help, extra_help, SSET_INT, \
972 scateg, slevel, \
973 {.integer = {(int *) &value, _default, _min, _max, func_validate, \
974 0}}, \
975 func_action, FALSE},
977 #define GEN_STRING(name, value, sclass, scateg, slevel, to_client, \
978 short_help, extra_help, func_validate, func_action, \
979 _default) \
980 {name, sclass, to_client, short_help, extra_help, SSET_STRING, \
981 scateg, slevel, \
982 {.string = {value, _default, sizeof(value), func_validate, ""}}, \
983 func_action, FALSE},
985 #define GEN_ENUM(name, value, sclass, scateg, slevel, to_client, \
986 short_help, extra_help, func_validate, func_action, \
987 func_name, _default) \
988 { name, sclass, to_client, short_help, extra_help, SSET_ENUM, \
989 scateg, slevel, \
990 { .enumerator = { &value, sizeof(value), _default, \
991 func_validate, \
992 (val_name_func_t) func_name, 0 }}, func_action, FALSE},
994 #define GEN_BITWISE(name, value, sclass, scateg, slevel, to_client, \
995 short_help, extra_help, func_validate, func_action, \
996 func_name, _default) \
997 { name, sclass, to_client, short_help, extra_help, SSET_BITWISE, \
998 scateg, slevel, \
999 { .bitwise = { (unsigned *) (void *) &value, _default, func_validate, \
1000 func_name, 0 }}, func_action, FALSE},
1002 /* game settings */
1003 static struct setting settings[] = {
1005 /* These should be grouped by sclass */
1007 /* Map size parameters: adjustable if we don't yet have a map */
1008 GEN_ENUM("mapsize", map.server.mapsize, SSET_MAP_SIZE,
1009 SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1010 N_("Map size definition"),
1011 /* TRANS: The strings between double quotes are also translated
1012 * separately (they must match!). The strings between single
1013 * quotes are setting names and shouldn't be translated. The
1014 * strings between parentheses and in uppercase must stay as
1015 * untranslated. */
1016 N_("Chooses the method used to define the map size. Other options "
1017 "specify the parameters for each method.\n"
1018 "- \"Number of tiles\" (FULLSIZE): Map area (option 'size').\n"
1019 "- \"Tiles per player\" (PLAYER): Number of (land) tiles per "
1020 "player (option 'tilesperplayer').\n"
1021 "- \"Width and height\" (XYSIZE): Map width and height in "
1022 "tiles (options 'xsize' and 'ysize')."),
1023 mapsize_callback, NULL, mapsize_name, MAP_DEFAULT_MAPSIZE)
1025 GEN_INT("size", map.server.size, SSET_MAP_SIZE,
1026 SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1027 N_("Map area (in thousands of tiles)"),
1028 /* TRANS: The strings between double quotes are also translated
1029 * separately (they must match!). The strings between single
1030 * quotes are setting names and shouldn't be translated. The
1031 * strings between parentheses and in uppercase must stay as
1032 * untranslated. */
1033 N_("This value is used to determine the map area.\n"
1034 " size = 4 is a normal map of 4,000 tiles (default)\n"
1035 " size = 20 is a huge map of 20,000 tiles\n"
1036 "For this option to take effect, the \"Map size definition\" "
1037 "option ('mapsize') must be set to \"Number of tiles\" "
1038 "(FULLSIZE)."), NULL, NULL,
1039 MAP_MIN_SIZE, MAP_MAX_SIZE, MAP_DEFAULT_SIZE)
1041 GEN_INT("tilesperplayer", map.server.tilesperplayer, SSET_MAP_SIZE,
1042 SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1043 N_("Number of (land) tiles per player"),
1044 /* TRANS: The strings between double quotes are also translated
1045 * separately (they must match!). The strings between single
1046 * quotes are setting names and shouldn't be translated. The
1047 * strings between parentheses and in uppercase must stay as
1048 * untranslated. */
1049 N_("This value is used to determine the map dimensions. It "
1050 "calculates the map size at game start based on the number "
1051 "of players and the value of the setting 'landmass'.\n"
1052 "For this option to take effect, the \"Map size definition\" "
1053 "option ('mapsize') must be set to \"Tiles per player\" "
1054 "(PLAYER)."),
1055 NULL, NULL, MAP_MIN_TILESPERPLAYER,
1056 MAP_MAX_TILESPERPLAYER, MAP_DEFAULT_TILESPERPLAYER)
1058 GEN_INT("xsize", map.xsize, SSET_MAP_SIZE,
1059 SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1060 N_("Map width in tiles"),
1061 /* TRANS: The strings between double quotes are also translated
1062 * separately (they must match!). The strings between single
1063 * quotes are setting names and shouldn't be translated. The
1064 * strings between parentheses and in uppercase must stay as
1065 * untranslated. */
1066 N_("Defines the map width.\n"
1067 "For this option to take effect, the \"Map size definition\" "
1068 "option ('mapsize') must be set to \"Width and height\" "
1069 "(XYSIZE)."),
1070 xsize_callback, NULL,
1071 MAP_MIN_LINEAR_SIZE, MAP_MAX_LINEAR_SIZE, MAP_DEFAULT_LINEAR_SIZE)
1072 GEN_INT("ysize", map.ysize, SSET_MAP_SIZE,
1073 SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1074 N_("Map height in tiles"),
1075 /* TRANS: The strings between double quotes are also translated
1076 * separately (they must match!). The strings between single
1077 * quotes are setting names and shouldn't be translated. The
1078 * strings between parentheses and in uppercase must stay as
1079 * untranslated. */
1080 N_("Defines the map height.\n"
1081 "For this option to take effect, the \"Map size definition\" "
1082 "option ('mapsize') must be set to \"Width and height\" "
1083 "(XYSIZE)."),
1084 ysize_callback, NULL,
1085 MAP_MIN_LINEAR_SIZE, MAP_MAX_LINEAR_SIZE, MAP_DEFAULT_LINEAR_SIZE)
1087 GEN_BITWISE("topology", map.topology_id, SSET_MAP_SIZE,
1088 SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1089 N_("Map topology index"),
1090 /* TRANS: do not edit the ugly ASCII art */
1091 N_("Freeciv maps are always two-dimensional. They may wrap at "
1092 "the north-south and east-west directions to form a flat "
1093 "map, a cylinder, or a torus (donut). Individual tiles may "
1094 "be rectangular or hexagonal, with either a classic or "
1095 "isometric alignment - this should be set based on the "
1096 "tileset being used.\n"
1097 "Classic rectangular: Isometric rectangular:\n"
1098 " _________ /\\/\\/\\/\\/\\\n"
1099 " |_|_|_|_|_| /\\/\\/\\/\\/\\/\n"
1100 " |_|_|_|_|_| \\/\\/\\/\\/\\/\\\n"
1101 " |_|_|_|_|_| /\\/\\/\\/\\/\\/\n"
1102 " \\/\\/\\/\\/\\/\n"
1103 "Hex tiles: Iso-hex:\n"
1104 " /\\/\\/\\/\\/\\/\\ _ _ _ _ _\n"
1105 " | | | | | | | / \\_/ \\_/ \\_/ \\_/ \\\n"
1106 " \\/\\/\\/\\/\\/\\/\\"
1107 " \\_/ \\_/ \\_/ \\_/ \\_/\n"
1108 " | | | | | | | / \\_/ \\_/ \\_/ \\_/ \\\n"
1109 " \\/\\/\\/\\/\\/\\/"
1110 " \\_/ \\_/ \\_/ \\_/ \\_/\n"),
1111 topology_callback, NULL, topology_name, MAP_DEFAULT_TOPO)
1113 GEN_ENUM("generator", map.server.generator,
1114 SSET_MAP_GEN, SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1115 N_("Method used to generate map"),
1116 /* TRANS: The strings between double quotes are also translated
1117 * separately (they must match!). The strings between single
1118 * quotes (except 'fair') are setting names and shouldn't be
1119 * translated. The strings between parentheses and in uppercase
1120 * must stay as untranslated. */
1121 N_("Specifies the algorithm used to generate the map. If the "
1122 "default value of the 'startpos' option is used, then the "
1123 "chosen generator chooses an appropriate 'startpos' setting; "
1124 "otherwise, the generated map tries to accommodate the "
1125 "chosen 'startpos' setting.\n"
1126 "- \"Scenario map\" (SCENARIO): indicates a pre-generated map. "
1127 "By default, if the scenario does not specify start positions, "
1128 "they will be allocated depending on the size of continents.\n"
1129 "- \"Fully random height\" (RANDOM): generates maps with a "
1130 "number of equally spaced, relatively small islands. By default, "
1131 "start positions are allocated depending on continent size.\n"
1132 "- \"Pseudo-fractal height\" (FRACTAL): generates Earthlike "
1133 "worlds with one or more large continents and a scattering of "
1134 "smaller islands. By default, players are all placed on a "
1135 "single continent.\n"
1136 "- \"Island-based\" (ISLAND): generates 'fair' maps with a "
1137 "number of similarly-sized and -shaped islands, each with "
1138 "approximately the same ratios of terrain types. By default, "
1139 "each player gets their own island.\n"
1140 "If the requested generator is incompatible with other server "
1141 "settings, the server may fall back to another generator."),
1142 generator_validate, NULL, generator_name, MAP_DEFAULT_GENERATOR)
1144 GEN_ENUM("startpos", map.server.startpos,
1145 SSET_MAP_GEN, SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1146 N_("Method used to choose start positions"),
1147 /* TRANS: The strings between double quotes are also translated
1148 * separately (they must match!). The strings between single
1149 * quotes (except 'best') are setting names and shouldn't be
1150 * translated. The strings between parentheses and in uppercase
1151 * must stay as untranslated. */
1152 N_("The method used to choose where each player's initial units "
1153 "start on the map. (For scenarios which include pre-set "
1154 "start positions, this setting is ignored.)\n"
1155 "- \"Generator's choice\" (DEFAULT): the start position "
1156 "placement will depend on the map generator chosen. See the "
1157 "'generator' setting.\n"
1158 "- \"One player per continent\" (SINGLE): one player is "
1159 "placed on each of a set of continents of approximately "
1160 "equivalent value (if possible).\n"
1161 "- \"Two or three players per continent\" (2or3): similar "
1162 "to SINGLE except that two players will be placed on each "
1163 "continent, with three on the 'best' continent if there is an "
1164 "odd number of players.\n"
1165 "- \"All players on a single continent\" (ALL): all players "
1166 "will start on the 'best' available continent.\n"
1167 "- \"Depending on size of continents\" (VARIABLE): players "
1168 "will be placed on the 'best' available continents such that, "
1169 "as far as possible, the number of players on each continent "
1170 "is proportional to its value.\n"
1171 "If the server cannot satisfy the requested setting due to "
1172 "there being too many players for continents, it may fall "
1173 "back to one of the others. (However, map generators try to "
1174 "create the right number of continents for the choice of this "
1175 "'startpos' setting and the number of players, so this is "
1176 "unlikely to occur.)"),
1177 NULL, NULL, startpos_name, MAP_DEFAULT_STARTPOS)
1179 GEN_BOOL("tinyisles", map.server.tinyisles,
1180 SSET_MAP_GEN, SSET_GEOLOGY, SSET_RARE, SSET_TO_CLIENT,
1181 N_("Presence of 1x1 islands"),
1182 N_("This setting controls whether the map generator is allowed "
1183 "to make islands of one only tile size."), NULL, NULL,
1184 MAP_DEFAULT_TINYISLES)
1186 GEN_BOOL("separatepoles", map.server.separatepoles,
1187 SSET_MAP_GEN, SSET_GEOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1188 N_("Whether the poles are separate continents"),
1189 N_("If this setting is disabled, the continents may attach to "
1190 "poles."), NULL, NULL, MAP_DEFAULT_SEPARATE_POLES)
1192 GEN_BOOL("alltemperate", map.server.alltemperate,
1193 SSET_MAP_GEN, SSET_GEOLOGY, SSET_RARE, SSET_TO_CLIENT,
1194 N_("All the map is temperate"),
1195 N_("If this setting is enabled, the temperature will be "
1196 "equivalent everywhere on the map. As a result, the "
1197 "poles won't be generated."),
1198 NULL, NULL, MAP_DEFAULT_ALLTEMPERATE)
1200 GEN_INT("temperature", map.server.temperature,
1201 SSET_MAP_GEN, SSET_GEOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1202 N_("Average temperature of the planet"),
1203 N_("Small values will give a cold map, while larger values will "
1204 "give a hotter map.\n"
1205 "\n"
1206 "100 means a very dry and hot planet with no polar arctic "
1207 "zones, only tropical and dry zones.\n"
1208 " 70 means a hot planet with little polar ice.\n"
1209 " 50 means a temperate planet with normal polar, cold, "
1210 "temperate, and tropical zones; a desert zone overlaps "
1211 "tropical and temperate zones.\n"
1212 " 30 means a cold planet with small tropical zones.\n"
1213 " 0 means a very cold planet with large polar zones and no "
1214 "tropics."),
1215 NULL, NULL,
1216 MAP_MIN_TEMPERATURE, MAP_MAX_TEMPERATURE, MAP_DEFAULT_TEMPERATURE)
1218 GEN_INT("landmass", map.server.landpercent,
1219 SSET_MAP_GEN, SSET_GEOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1220 N_("Percentage of the map that is land"),
1221 N_("This setting gives the approximate percentage of the map "
1222 "that will be made into land."), NULL, NULL,
1223 MAP_MIN_LANDMASS, MAP_MAX_LANDMASS, MAP_DEFAULT_LANDMASS)
1225 GEN_INT("steepness", map.server.steepness,
1226 SSET_MAP_GEN, SSET_GEOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1227 N_("Amount of hills/mountains"),
1228 N_("Small values give flat maps, while higher values give a "
1229 "steeper map with more hills and mountains."), NULL, NULL,
1230 MAP_MIN_STEEPNESS, MAP_MAX_STEEPNESS, MAP_DEFAULT_STEEPNESS)
1232 GEN_INT("wetness", map.server.wetness,
1233 SSET_MAP_GEN, SSET_GEOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1234 N_("Amount of water on landmasses"),
1235 N_("Small values mean lots of dry, desert-like land; "
1236 "higher values give a wetter map with more swamps, "
1237 "jungles, and rivers."), NULL, NULL,
1238 MAP_MIN_WETNESS, MAP_MAX_WETNESS, MAP_DEFAULT_WETNESS)
1240 GEN_BOOL("globalwarming", game.info.global_warming,
1241 SSET_RULES, SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1242 N_("Global warming"),
1243 N_("If turned off, global warming will not occur "
1244 "as a result of pollution. This setting does not "
1245 "affect pollution."), NULL, NULL,
1246 GAME_DEFAULT_GLOBAL_WARMING)
1248 GEN_BOOL("nuclearwinter", game.info.nuclear_winter,
1249 SSET_RULES, SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1250 N_("Nuclear winter"),
1251 N_("If turned off, nuclear winter will not occur "
1252 "as a result of nuclear war."), NULL, NULL,
1253 GAME_DEFAULT_NUCLEAR_WINTER)
1255 GEN_INT("mapseed", map.server.seed,
1256 SSET_MAP_GEN, SSET_INTERNAL, SSET_RARE, SSET_SERVER_ONLY,
1257 N_("Map generation random seed"),
1258 N_("The same seed will always produce the same map; "
1259 "for zero (the default) a seed will be chosen based on "
1260 "the time to give a random map. This setting is usually "
1261 "only of interest while debugging the game."), NULL, NULL,
1262 MAP_MIN_SEED, MAP_MAX_SEED, MAP_DEFAULT_SEED)
1264 /* Map additional stuff: huts and specials. gameseed also goes here
1265 * because huts and specials are the first time the gameseed gets used (?)
1266 * These are done when the game starts, so these are historical and
1267 * fixed after the game has started.
1269 GEN_INT("gameseed", game.server.seed,
1270 SSET_MAP_ADD, SSET_INTERNAL, SSET_RARE, SSET_SERVER_ONLY,
1271 N_("Game random seed"),
1272 N_("For zero (the default) a seed will be chosen based "
1273 "on the current time. This setting is usually "
1274 "only of interest while debugging the game."), NULL, NULL,
1275 GAME_MIN_SEED, GAME_MAX_SEED, GAME_DEFAULT_SEED)
1277 GEN_INT("specials", map.server.riches,
1278 SSET_MAP_ADD, SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1279 N_("Amount of \"special\" resource tiles"),
1280 N_("Special resources improve the basic terrain type they "
1281 "are on. The server variable's scale is parts per "
1282 "thousand."), NULL, NULL,
1283 MAP_MIN_RICHES, MAP_MAX_RICHES, MAP_DEFAULT_RICHES)
1285 GEN_INT("huts", map.server.huts,
1286 SSET_MAP_ADD, SSET_GEOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1287 N_("Amount of huts (minor tribe villages)"),
1288 N_("This setting gives the exact number of huts that will be "
1289 "placed on the entire map. Huts are small tribal villages "
1290 "that may be investigated by units."), NULL, NULL,
1291 MAP_MIN_HUTS, MAP_MAX_HUTS, MAP_DEFAULT_HUTS)
1293 /* Options affecting numbers of players and AI players. These only
1294 * affect the start of the game and can not be adjusted after that.
1296 GEN_INT("minplayers", game.server.min_players,
1297 SSET_PLAYERS, SSET_INTERNAL, SSET_VITAL,
1298 SSET_TO_CLIENT,
1299 N_("Minimum number of players"),
1300 N_("There must be at least this many players (connected "
1301 "human players) before the game can start."),
1302 NULL, NULL,
1303 GAME_MIN_MIN_PLAYERS, GAME_MAX_MIN_PLAYERS, GAME_DEFAULT_MIN_PLAYERS)
1305 GEN_INT("maxplayers", game.server.max_players,
1306 SSET_PLAYERS, SSET_INTERNAL, SSET_VITAL, SSET_TO_CLIENT,
1307 N_("Maximum number of players"),
1308 N_("The maximal number of human and AI players who can be in "
1309 "the game. When this number of players are connected in "
1310 "the pregame state, any new players who try to connect "
1311 "will be rejected.\n"
1312 "When playing a scenario which defines player start positions, "
1313 "this setting cannot be set to greater than the number of "
1314 "defined start positions."),
1315 maxplayers_callback, NULL,
1316 GAME_MIN_MAX_PLAYERS, GAME_MAX_MAX_PLAYERS, GAME_DEFAULT_MAX_PLAYERS)
1318 GEN_INT("aifill", game.info.aifill,
1319 SSET_PLAYERS, SSET_INTERNAL, SSET_VITAL, SSET_TO_CLIENT,
1320 N_("Limited number of AI players"),
1321 N_("If set to a positive value, then AI players will be "
1322 "automatically created or removed to keep the total "
1323 "number of players at this amount. As more players join, "
1324 "these AI players will be replaced. When set to zero, "
1325 "all AI players will be removed."), NULL,
1326 aifill_action, GAME_MIN_AIFILL, GAME_MAX_AIFILL,
1327 GAME_DEFAULT_AIFILL)
1329 GEN_STRING("nationset", game.server.nationset,
1330 SSET_PLAYERS, SSET_INTERNAL, SSET_RARE, SSET_TO_CLIENT,
1331 N_("Set of nations to choose from"),
1332 /* TRANS: do not translate '/list nationsets' */
1333 N_("Controls the set of nations allowed in the game. The "
1334 "choices are defined by the ruleset.\n"
1335 "Only nations in the set selected here will be allowed in "
1336 "any circumstances, including new players and civil war; "
1337 "small sets may thus limit the number of players in a game.\n"
1338 "If this is left blank, the ruleset's default nation set is "
1339 "used.\n"
1340 "See '/list nationsets' for possible choices for the "
1341 "currently loaded ruleset."),
1342 nationset_callback, nationset_action, GAME_DEFAULT_NATIONSET)
1344 GEN_INT("ec_turns", game.server.event_cache.turns,
1345 SSET_RULES_FLEXIBLE, SSET_INTERNAL, SSET_SITUATIONAL,
1346 SSET_TO_CLIENT,
1347 N_("Event cache for this number of turns"),
1348 N_("Event messages are saved for this number of turns. A value of "
1349 "0 deactivates the event cache."),
1350 NULL, NULL, GAME_MIN_EVENT_CACHE_TURNS, GAME_MAX_EVENT_CACHE_TURNS,
1351 GAME_DEFAULT_EVENT_CACHE_TURNS)
1353 GEN_INT("ec_max_size", game.server.event_cache.max_size,
1354 SSET_RULES_FLEXIBLE, SSET_INTERNAL, SSET_SITUATIONAL,
1355 SSET_TO_CLIENT,
1356 N_("Size of the event cache"),
1357 N_("This defines the maximal number of events in the event cache."),
1358 NULL, NULL, GAME_MIN_EVENT_CACHE_MAX_SIZE,
1359 GAME_MAX_EVENT_CACHE_MAX_SIZE, GAME_DEFAULT_EVENT_CACHE_MAX_SIZE)
1361 GEN_BOOL("ec_chat", game.server.event_cache.chat,
1362 SSET_RULES_FLEXIBLE, SSET_INTERNAL, SSET_SITUATIONAL,
1363 SSET_TO_CLIENT,
1364 N_("Save chat messages in the event cache"),
1365 N_("If turned on, chat messages will be saved in the event "
1366 "cache."), NULL, NULL, GAME_DEFAULT_EVENT_CACHE_CHAT)
1368 GEN_BOOL("ec_info", game.server.event_cache.info,
1369 SSET_RULES_FLEXIBLE, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT,
1370 N_("Print turn and time for each cached event"),
1371 /* TRANS: Don't translate the text between single quotes. */
1372 N_("If turned on, all cached events will be marked by the turn "
1373 "and time of the event like '(T2 - 15:29:52)'."),
1374 NULL, NULL, GAME_DEFAULT_EVENT_CACHE_INFO)
1376 /* Game initialization parameters (only affect the first start of the game,
1377 * and not reloads). Can not be changed after first start of game.
1379 /* TODO: Add this line back when we can support Ferry units */
1380 /* " f = Ferryboat (eg., Trireme)\n" */
1381 GEN_STRING("startunits", game.server.start_units,
1382 SSET_GAME_INIT, SSET_SOCIOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1383 N_("List of players' initial units"),
1384 N_("This should be a string of characters, each of which "
1385 "specifies a unit role. There must be at least one city "
1386 "founder in the string. The characters and their "
1387 "meanings are:\n"
1388 " c = City founder (eg., Settlers)\n"
1389 " w = Terrain worker (eg., Engineers)\n"
1390 " x = Explorer (eg., Explorer)\n"
1391 " k = Gameloss (eg., King)\n"
1392 " s = Diplomat (eg., Diplomat)\n"
1393 " d = Ok defense unit (eg., Warriors)\n"
1394 " D = Good defense unit (eg., Phalanx)\n"
1395 " a = Fast attack unit (eg., Horsemen)\n"
1396 " A = Strong attack unit (eg., Catapult)\n"),
1397 startunits_callback, NULL, GAME_DEFAULT_START_UNITS)
1399 GEN_BOOL("startcity", game.server.start_city,
1400 SSET_GAME_INIT, SSET_SOCIOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1401 N_("Whether player starts with a city"),
1402 N_("If this is set, game will start with player's first "
1403 "city already founded to starting location."),
1404 NULL, NULL, GAME_DEFAULT_START_CITY)
1406 GEN_INT("dispersion", game.server.dispersion,
1407 SSET_GAME_INIT, SSET_SOCIOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1408 N_("Area where initial units are located"),
1409 N_("This is the radius within "
1410 "which the initial units are dispersed."), NULL, NULL,
1411 GAME_MIN_DISPERSION, GAME_MAX_DISPERSION, GAME_DEFAULT_DISPERSION)
1413 GEN_INT("gold", game.info.gold,
1414 SSET_GAME_INIT, SSET_ECONOMICS, SSET_VITAL, SSET_TO_CLIENT,
1415 N_("Starting gold per player"),
1416 N_("At the beginning of the game, each player is given this "
1417 "much gold."), NULL, NULL,
1418 GAME_MIN_GOLD, GAME_MAX_GOLD, GAME_DEFAULT_GOLD)
1420 GEN_INT("techlevel", game.info.tech,
1421 SSET_GAME_INIT, SSET_SCIENCE, SSET_VITAL, SSET_TO_CLIENT,
1422 N_("Number of initial techs per player"),
1423 /* TRANS: The string between single quotes is a setting name and
1424 * should not be translated. */
1425 N_("At the beginning of the game, each player is given this "
1426 "many technologies. The technologies chosen are random for "
1427 "each player. Depending on the value of tech_cost_style in "
1428 "the ruleset, a big value for 'techlevel' can make the next "
1429 "techs really expensive."), NULL, NULL,
1430 GAME_MIN_TECHLEVEL, GAME_MAX_TECHLEVEL, GAME_DEFAULT_TECHLEVEL)
1432 GEN_INT("sciencebox", game.info.sciencebox,
1433 SSET_RULES, SSET_SCIENCE, SSET_SITUATIONAL, SSET_TO_CLIENT,
1434 N_("Technology cost multiplier percentage"),
1435 N_("This affects how quickly players can research new "
1436 "technology. All tech costs are multiplied by this amount "
1437 "(as a percentage). The base tech costs are determined by "
1438 "the ruleset or other game settings."),
1439 NULL, NULL, GAME_MIN_SCIENCEBOX, GAME_MAX_SCIENCEBOX,
1440 GAME_DEFAULT_SCIENCEBOX)
1442 GEN_INT("techpenalty", game.server.techpenalty,
1443 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1444 N_("Percentage penalty when changing tech"),
1445 N_("If you change your current research technology, and you have "
1446 "positive research points, you lose this percentage of those "
1447 "research points. This does not apply when you have just gained "
1448 "a technology this turn."), NULL, NULL,
1449 GAME_MIN_TECHPENALTY, GAME_MAX_TECHPENALTY,
1450 GAME_DEFAULT_TECHPENALTY)
1452 GEN_INT("techlost_recv", game.server.techlost_recv,
1453 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1454 N_("Chance to lose an invention while receiving it"),
1455 N_("If you receive an invention via a treaty, this setting "
1456 "defines the chance that the invention is lost during the "
1457 "transfer."),
1458 NULL, NULL, GAME_MIN_TECHLOST_RECV, GAME_MAX_TECHLOST_RECV,
1459 GAME_DEFAULT_TECHLOST_RECV)
1461 GEN_INT("techlost_donor", game.server.techlost_donor,
1462 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1463 N_("Chance to lose an invention while giving it"),
1464 N_("If you give an invention via a treaty, this setting "
1465 "defines the chance that the invention is lost for your "
1466 "civilization during the transfer."),
1467 NULL, NULL, GAME_MIN_TECHLOST_DONOR, GAME_MAX_TECHLOST_DONOR,
1468 GAME_DEFAULT_TECHLOST_DONOR)
1470 GEN_BOOL("team_pooled_research", game.info.team_pooled_research,
1471 SSET_RULES, SSET_SCIENCE, SSET_VITAL, SSET_TO_CLIENT,
1472 N_("Team pooled research"),
1473 N_("If this setting is turned on, then the team mates will share "
1474 "the science research. Else, every player of the team will "
1475 "have to make its own."),
1476 NULL, NULL, GAME_DEFAULT_TEAM_POOLED_RESEARCH)
1478 GEN_INT("diplcost", game.server.diplcost,
1479 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1480 N_("Penalty when getting tech or gold from treaty"),
1481 N_("For each technology you gain from a diplomatic treaty, you "
1482 "lose research points equal to this percentage of the cost to "
1483 "research a new technology. If this is non-zero, you can end up "
1484 "with negative research points. Also applies to gold "
1485 "transfers in diplomatic treaties."),
1486 NULL, NULL,
1487 GAME_MIN_DIPLCOST, GAME_MAX_DIPLCOST, GAME_DEFAULT_DIPLCOST)
1489 GEN_INT("conquercost", game.server.conquercost,
1490 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1491 N_("Penalty when getting tech from conquering"),
1492 N_("For each technology you gain by conquering an enemy city, you "
1493 "lose research points equal to this percentage of the cost to "
1494 "research a new technology. If this is non-zero, you can end up "
1495 "with negative research points."),
1496 NULL, NULL,
1497 GAME_MIN_CONQUERCOST, GAME_MAX_CONQUERCOST,
1498 GAME_DEFAULT_CONQUERCOST)
1500 GEN_INT("freecost", game.server.freecost,
1501 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1502 N_("Penalty when getting a free tech"),
1503 /* TRANS: The strings between single quotes are setting names and
1504 * shouldn't be translated. */
1505 N_("For each technology you gain \"for free\" (other than "
1506 "covered by 'diplcost' or 'conquercost': for instance, from huts "
1507 "or from Great Library effects), you lose research points "
1508 "equal to this percentage of the cost to research a new "
1509 "technology. If this is non-zero, you can end up "
1510 "with negative research points."),
1511 NULL, NULL,
1512 GAME_MIN_FREECOST, GAME_MAX_FREECOST, GAME_DEFAULT_FREECOST)
1514 GEN_INT("techlossforgiveness", game.server.techloss_forgiveness,
1515 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1516 N_("Research point debt threshold for losing tech"),
1517 N_("When you have negative research points, and your shortfall is "
1518 "greater than this percentage of the cost of your current "
1519 "research, you forget a technology you already knew.\n"
1520 "The special value -1 prevents loss of technology regardless of "
1521 "research points."),
1522 NULL, NULL,
1523 GAME_MIN_TECHLOSSFG, GAME_MAX_TECHLOSSFG,
1524 GAME_DEFAULT_TECHLOSSFG)
1526 GEN_INT("techlossrestore", game.server.techloss_restore,
1527 SSET_RULES, SSET_SCIENCE, SSET_RARE, SSET_TO_CLIENT,
1528 N_("Research points restored after losing a tech"),
1529 N_("When you lose a technology due to a negative research balance "
1530 "(see 'techlossforgiveness'), this percentage of its research "
1531 "cost is credited to your research balance (this may not be "
1532 "sufficient to make it positive).\n"
1533 "The special value -1 means that your research balance is always "
1534 "restored to zero, regardless of your previous shortfall."),
1535 NULL, NULL,
1536 GAME_MIN_TECHLOSSREST, GAME_MAX_TECHLOSSREST,
1537 GAME_DEFAULT_TECHLOSSREST)
1539 GEN_INT("foodbox", game.info.foodbox,
1540 SSET_RULES, SSET_ECONOMICS, SSET_SITUATIONAL, SSET_TO_CLIENT,
1541 N_("Food required for a city to grow"),
1542 N_("This is the base amount of food required to grow a city. "
1543 "This value is multiplied by another factor that comes from "
1544 "the ruleset and is dependent on the size of the city."),
1545 NULL, NULL,
1546 GAME_MIN_FOODBOX, GAME_MAX_FOODBOX, GAME_DEFAULT_FOODBOX)
1548 GEN_INT("aqueductloss", game.server.aqueductloss,
1549 SSET_RULES, SSET_ECONOMICS, SSET_RARE, SSET_TO_CLIENT,
1550 N_("Percentage food lost when building needed"),
1551 N_("If a city would expand, but it can't because it needs "
1552 "an Aqueduct (or Sewer System), it loses this percentage "
1553 "of its foodbox (or half that amount when it has a "
1554 "Granary)."), NULL, NULL,
1555 GAME_MIN_AQUEDUCTLOSS, GAME_MAX_AQUEDUCTLOSS,
1556 GAME_DEFAULT_AQUEDUCTLOSS)
1558 GEN_INT("shieldbox", game.info.shieldbox,
1559 SSET_RULES, SSET_ECONOMICS, SSET_SITUATIONAL, SSET_TO_CLIENT,
1560 N_("Multiplier percentage for production costs"),
1561 N_("This affects how quickly units and buildings can be "
1562 "produced. The base costs are multiplied by this value (as "
1563 "a percentage)."),
1564 NULL, NULL, GAME_MIN_SHIELDBOX, GAME_MAX_SHIELDBOX,
1565 GAME_DEFAULT_SHIELDBOX)
1567 /* Notradesize and fulltradesize used to have callbacks to prevent them
1568 * from being set illegally (notradesize > fulltradesize). However this
1569 * provided a problem when setting them both through the client's settings
1570 * dialog, since they cannot both be set atomically. So the callbacks were
1571 * removed and instead the game now knows how to deal with invalid
1572 * settings. */
1573 GEN_INT("fulltradesize", game.info.fulltradesize,
1574 SSET_RULES, SSET_ECONOMICS, SSET_RARE, SSET_TO_CLIENT,
1575 N_("Minimum city size to get full trade"),
1576 /* TRANS: The strings between single quotes are setting names and
1577 * shouldn't be translated. */
1578 N_("There is a trade penalty in all cities smaller than this. "
1579 "The penalty is 100% (no trade at all) for sizes up to "
1580 "'notradesize', and decreases gradually to 0% (no penalty "
1581 "except the normal corruption) for size='fulltradesize'. "
1582 "See also 'notradesize'."), NULL, NULL,
1583 GAME_MIN_FULLTRADESIZE, GAME_MAX_FULLTRADESIZE,
1584 GAME_DEFAULT_FULLTRADESIZE)
1586 GEN_INT("notradesize", game.info.notradesize,
1587 SSET_RULES, SSET_ECONOMICS, SSET_RARE, SSET_TO_CLIENT,
1588 N_("Maximum size of a city without trade"),
1589 /* TRANS: The strings between single quotes are setting names and
1590 * shouldn't be translated. */
1591 N_("Cities do not produce any trade at all unless their size "
1592 "is larger than this amount. The produced trade increases "
1593 "gradually for cities larger than 'notradesize' and smaller "
1594 "than 'fulltradesize'. See also 'fulltradesize'."), NULL, NULL,
1595 GAME_MIN_NOTRADESIZE, GAME_MAX_NOTRADESIZE,
1596 GAME_DEFAULT_NOTRADESIZE)
1598 GEN_INT("citymindist", game.info.citymindist,
1599 SSET_RULES, SSET_SOCIOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1600 N_("Minimum distance between cities"),
1601 N_("When a player attempts to found a new city, it is prevented "
1602 "if the distance from any existing city is less than this "
1603 "setting. For example, when this setting is 3, there must be "
1604 "at least two clear tiles in any direction between all existing "
1605 "cities and the new city site. A value of 1 removes any such "
1606 "restriction on city placement."),
1607 NULL, NULL,
1608 GAME_MIN_CITYMINDIST, GAME_MAX_CITYMINDIST,
1609 GAME_DEFAULT_CITYMINDIST)
1611 GEN_BOOL("trading_tech", game.info.trading_tech,
1612 SSET_RULES, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1613 N_("Technology trading"),
1614 N_("If turned off, trading technologies in the diplomacy dialog "
1615 "is not allowed."), NULL, NULL,
1616 GAME_DEFAULT_TRADING_TECH)
1618 GEN_BOOL("trading_gold", game.info.trading_gold,
1619 SSET_RULES, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1620 N_("Gold trading"),
1621 N_("If turned off, trading gold in the diplomacy dialog "
1622 "is not allowed."), NULL, NULL,
1623 GAME_DEFAULT_TRADING_GOLD)
1625 GEN_BOOL("trading_city", game.info.trading_city,
1626 SSET_RULES, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1627 N_("City trading"),
1628 N_("If turned off, trading cities in the diplomacy dialog "
1629 "is not allowed."), NULL, NULL,
1630 GAME_DEFAULT_TRADING_CITY)
1632 GEN_INT("trademindist", game.info.trademindist,
1633 SSET_RULES, SSET_ECONOMICS, SSET_RARE, SSET_TO_CLIENT,
1634 N_("Minimum distance for trade routes"),
1635 N_("In order for two cities in the same civilization to establish "
1636 "a trade route, they must be at least this far apart on the "
1637 "map. For square grids, the distance is calculated as "
1638 "\"Manhattan distance\", that is, the sum of the displacements "
1639 "along the x and y directions."), NULL, NULL,
1640 GAME_MIN_TRADEMINDIST, GAME_MAX_TRADEMINDIST,
1641 GAME_DEFAULT_TRADEMINDIST)
1643 GEN_INT("rapturedelay", game.info.rapturedelay,
1644 SSET_RULES, SSET_SOCIOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1645 N_("Number of turns between rapture effect"),
1646 N_("Sets the number of turns between rapture growth of a city. "
1647 "If set to n a city will grow after celebrating for n+1 "
1648 "turns."),
1649 NULL, NULL,
1650 GAME_MIN_RAPTUREDELAY, GAME_MAX_RAPTUREDELAY,
1651 GAME_DEFAULT_RAPTUREDELAY)
1653 GEN_INT("disasters", game.info.disasters,
1654 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_VITAL, SSET_TO_CLIENT,
1655 N_("Frequency of disasters"),
1656 N_("Sets frequency of disasters occurring to cities."),
1657 NULL, NULL,
1658 GAME_MIN_DISASTERS, GAME_MAX_DISASTERS,
1659 GAME_DEFAULT_DISASTERS)
1661 GEN_INT("razechance", game.server.razechance,
1662 SSET_RULES, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1663 N_("Chance for conquered building destruction"),
1664 N_("When a player conquers a city, each city improvement has this "
1665 "percentage chance to be destroyed."), NULL, NULL,
1666 GAME_MIN_RAZECHANCE, GAME_MAX_RAZECHANCE, GAME_DEFAULT_RAZECHANCE)
1668 GEN_INT("occupychance", game.server.occupychance,
1669 SSET_RULES, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1670 N_("Chance of moving into tile after attack"),
1671 N_("If set to 0, combat is Civ1/2-style (when you attack, "
1672 "you remain in place). If set to 100, attacking units "
1673 "will always move into the tile they attacked when they win "
1674 "the combat (and no enemy units remain in the tile). If "
1675 "set to a value between 0 and 100, this will be used as "
1676 "the percent chance of \"occupying\" territory."), NULL, NULL,
1677 GAME_MIN_OCCUPYCHANCE, GAME_MAX_OCCUPYCHANCE,
1678 GAME_DEFAULT_OCCUPYCHANCE)
1680 GEN_BOOL("autoattack", game.server.autoattack, SSET_RULES_FLEXIBLE, SSET_MILITARY,
1681 SSET_SITUATIONAL, SSET_TO_CLIENT,
1682 N_("Turn on/off server-side autoattack"),
1683 N_("If set to on, units with moves left will automatically "
1684 "consider attacking enemy units that move adjacent to them."),
1685 NULL, NULL, GAME_DEFAULT_AUTOATTACK)
1687 GEN_BOOL("killstack", game.info.killstack, SSET_RULES, SSET_MILITARY,
1688 SSET_RARE, SSET_TO_CLIENT,
1689 N_("Do all units in tile die with defender"),
1690 N_("If this is enabled, each time a defender unit loses in combat, "
1691 "and is not inside a city or suitable base, all units in the same "
1692 "tile are destroyed along with the defender. If this is disabled, "
1693 "only the defender unit is destroyed."),
1694 NULL, NULL, GAME_DEFAULT_KILLSTACK)
1696 GEN_BOOL("killcitizen", game.info.killcitizen,
1697 SSET_RULES, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1698 N_("Reduce city population after attack"),
1699 N_("This flag indicates whether city population is reduced "
1700 "after successful attack of enemy unit. If this is disabled "
1701 "population is never reduced. Even when this is enabled "
1702 "only some units may kill citizens."),
1703 NULL, NULL, GAME_DEFAULT_KILLCITIZEN)
1705 GEN_INT("killunhomed", game.server.killunhomed,
1706 SSET_RULES, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1707 N_("Slowly kill units without home cities (e.g., starting units)"),
1708 N_("If greater than 0, then every unit without a homecity will "
1709 "lose hitpoints each turn. The number of hitpoints lost is "
1710 "given by 'killunhomed' percent of the hitpoints of the unit "
1711 "type. At least one hitpoint is lost every turn until the "
1712 "death of the unit."),
1713 NULL, NULL, GAME_MIN_KILLUNHOMED, GAME_MAX_KILLUNHOMED,
1714 GAME_DEFAULT_KILLUNHOMED)
1716 GEN_ENUM("borders", game.info.borders,
1717 SSET_RULES, SSET_MILITARY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1718 N_("National borders"),
1719 N_("If this is not disabled, then any land tiles around a "
1720 "fortress or city will be owned by that nation."),
1721 NULL, NULL, borders_name, GAME_DEFAULT_BORDERS)
1723 GEN_BOOL("happyborders", game.info.happyborders,
1724 SSET_RULES, SSET_MILITARY, SSET_SITUATIONAL,
1725 SSET_TO_CLIENT,
1726 N_("Units inside borders cause no unhappiness"),
1727 N_("If this is set, units will not cause unhappiness when "
1728 "inside your own borders."), NULL, NULL,
1729 GAME_DEFAULT_HAPPYBORDERS)
1731 GEN_ENUM("diplomacy", game.info.diplomacy,
1732 SSET_RULES, SSET_MILITARY, SSET_SITUATIONAL, SSET_TO_CLIENT,
1733 N_("Ability to do diplomacy with other players"),
1734 N_("This setting controls the ability to do diplomacy with "
1735 "other players."),
1736 NULL, NULL, diplomacy_name, GAME_DEFAULT_DIPLOMACY)
1738 GEN_ENUM("citynames", game.server.allowed_city_names,
1739 SSET_RULES, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1740 N_("Allowed city names"),
1741 /* TRANS: The strings between double quotes are also translated
1742 * separately (they must match!). The strings between parentheses
1743 * and in uppercase must not be translated. */
1744 N_("- \"No restrictions\" (NO_RESTRICTIONS): players can have "
1745 "multiple cities with the same names.\n"
1746 "- \"Unique to a player\" (PLAYER_UNIQUE): one player can't "
1747 "have multiple cities with the same name.\n"
1748 "- \"Globally unique\" (GLOBAL_UNIQUE): all cities in a game "
1749 "have to have different names.\n"
1750 "- \"No city name stealing\" (NO_STEALING): like "
1751 "\"Globally unique\", but a player isn't allowed to use a "
1752 "default city name of another nation unless it is a default "
1753 "for their nation also."),
1754 NULL, NULL, citynames_name, GAME_DEFAULT_ALLOWED_CITY_NAMES)
1756 GEN_ENUM("plrcolormode", game.server.plrcolormode,
1757 SSET_RULES, SSET_INTERNAL, SSET_RARE, SSET_TO_CLIENT,
1758 N_("How to pick player colors"),
1759 /* TRANS: The strings between double quotes are also translated
1760 * separately (they must match!). The strings between single quotes
1761 * are setting names and shouldn't be translated. The strings
1762 * between parentheses and in uppercase must not be translated. */
1763 N_("This setting determines how player colors are chosen. Player "
1764 "colors are used in the Nations report, for national borders on "
1765 "the map, and so on.\n"
1766 "- \"Per-player, in order\" (PLR_ORDER): colors are assigned to "
1767 "individual players in order from a list defined by the "
1768 "ruleset.\n"
1769 "- \"Per-player, random\" (PLR_RANDOM): colors are assigned "
1770 "to invididual players randomly from the set defined by the "
1771 "ruleset.\n"
1772 "- \"Set manually\" (PLR_SET): colors can be set with the "
1773 "'playercolor' command before the game starts; these are not "
1774 "restricted to the ruleset colors. Any players for which no "
1775 "color is set when the game starts get a random color from the "
1776 "ruleset.\n"
1777 "- \"Per-team, in order\" (TEAM_ORDER): colors are assigned to "
1778 "teams from the list in the ruleset. Every player on the same "
1779 "team gets the same color.\n"
1780 "- \"Per-nation, in order\" (NATION_ORDER): if the ruleset "
1781 "defines a color for a player's nation, the player takes that "
1782 "color. Any players whose nations don't have associated colors "
1783 "get a random color from the list in the ruleset.\n"
1784 "Regardless of this setting, individual player colors can be "
1785 "changed after the game starts with the 'playercolor' command."),
1786 plrcol_validate, plrcol_action, plrcol_name,
1787 GAME_DEFAULT_PLRCOLORMODE)
1789 /* Flexible rules: these can be changed after the game has started.
1791 * The distinction between "rules" and "flexible rules" is not always
1792 * clearcut, and some existing cases may be largely historical or
1793 * accidental. However some generalizations can be made:
1795 * -- Low-level game mechanics should not be flexible (eg, rulesets).
1796 * -- Options which would affect the game "state" (city production etc)
1797 * should not be flexible (eg, foodbox).
1798 * -- Options which are explicitly sent to the client (eg, in
1799 * packet_game_info) should probably not be flexible, or at
1800 * least need extra care to be flexible.
1802 GEN_ENUM("barbarians", game.server.barbarianrate,
1803 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_VITAL, SSET_TO_CLIENT,
1804 N_("Barbarian appearance frequency"),
1805 /* TRANS: The string between single quotes is a setting name and
1806 * should not be translated. */
1807 N_("This setting controls how frequently the barbarians appear "
1808 "in the game. See also the 'onsetbarbs' setting."),
1809 NULL, NULL, barbarians_name, GAME_DEFAULT_BARBARIANRATE)
1811 GEN_INT("onsetbarbs", game.server.onsetbarbarian,
1812 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_VITAL, SSET_TO_CLIENT,
1813 N_("Barbarian onset turn"),
1814 N_("Barbarians will not appear before this turn."), NULL, NULL,
1815 GAME_MIN_ONSETBARBARIAN, GAME_MAX_ONSETBARBARIAN,
1816 GAME_DEFAULT_ONSETBARBARIAN)
1818 GEN_INT("revolen", game.server.revolution_length,
1819 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1820 N_("Length in turns of revolution"),
1821 N_("When changing governments, a period of anarchy lasting this "
1822 "many turns will occur. "
1823 "Setting this value to 0 will give a random "
1824 "length of 1-5 turns."), NULL, NULL,
1825 GAME_MIN_REVOLUTION_LENGTH, GAME_MAX_REVOLUTION_LENGTH,
1826 GAME_DEFAULT_REVOLUTION_LENGTH)
1828 GEN_BOOL("fogofwar", game.info.fogofwar,
1829 SSET_RULES, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1830 N_("Whether to enable fog of war"),
1831 N_("If this is enabled, only those units and cities within "
1832 "the vision range of your own units and cities will be "
1833 "revealed to you. You will not see new cities or terrain "
1834 "changes in tiles not observed."),
1835 NULL, NULL, GAME_DEFAULT_FOGOFWAR)
1837 GEN_BOOL("foggedborders", game.server.foggedborders,
1838 SSET_RULES, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1839 N_("Whether fog of war applies to border changes"),
1840 N_("If this setting is enabled, players will not be able "
1841 "to see changes in tile ownership if they do not have "
1842 "direct sight of the affected tiles. Otherwise, players "
1843 "can see any or all changes to borders as long as they "
1844 "have previously seen the tiles."),
1845 NULL, NULL, GAME_DEFAULT_FOGGEDBORDERS)
1847 GEN_BITWISE("airliftingstyle", game.info.airlifting_style,
1848 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_SITUATIONAL,
1849 SSET_TO_CLIENT, N_("Airlifting style"),
1850 /* TRANS: The strings between double quotes are also
1851 * translated separately (they must match!). The strings
1852 * between parenthesis and in uppercase must not be
1853 * translated. */
1854 N_("This setting affects airlifting units between cities. It "
1855 "can be a set of the following values:\n"
1856 "- \"Allows units to be airlifted from allied cities\" "
1857 "(FROM_ALLIES).\n"
1858 "- \"Allows units to be airlifted to allied cities\" "
1859 "(TO_ALLIES).\n"
1860 "- \"Unlimited units from source city\" (SRC_UNLIMITED): "
1861 "note that airlifting from a city doesn't reduce the "
1862 "airlifted counter, but still needs at least 1.\n"
1863 "- \"Unlimited units to destination city\" "
1864 "(DEST_UNLIMITED): note that airlifting to a city doesn't "
1865 "reduce the airlifted counter, and doesn't need any."),
1866 NULL, NULL, airliftingstyle_name, GAME_DEFAULT_AIRLIFTINGSTYLE)
1868 GEN_INT("diplchance", game.server.diplchance,
1869 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_SITUATIONAL,
1870 SSET_TO_CLIENT,
1871 N_("Base chance for diplomats and spies to succeed"),
1872 N_("The base chance of a spy returning from a successful mission and "
1873 "the base chance of success for diplomats and spies."),
1874 NULL, NULL,
1875 GAME_MIN_DIPLCHANCE, GAME_MAX_DIPLCHANCE, GAME_DEFAULT_DIPLCHANCE)
1877 GEN_BOOL("spacerace", game.info.spacerace,
1878 SSET_RULES_FLEXIBLE, SSET_SCIENCE, SSET_VITAL, SSET_TO_CLIENT,
1879 N_("Whether to allow space race"),
1880 N_("If this option is enabled, players can build spaceships."),
1881 NULL, NULL, GAME_DEFAULT_SPACERACE)
1883 GEN_BOOL("endspaceship", game.server.endspaceship, SSET_RULES_FLEXIBLE,
1884 SSET_SCIENCE, SSET_VITAL, SSET_TO_CLIENT,
1885 N_("Should the game end if the spaceship arrives?"),
1886 N_("If this option is turned on, the game will end with the "
1887 "arrival of a spaceship at Alpha Centauri."),
1888 NULL, NULL, GAME_DEFAULT_END_SPACESHIP)
1890 GEN_INT("civilwarsize", game.server.civilwarsize,
1891 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1892 N_("Minimum number of cities for civil war"),
1893 N_("A civil war is triggered when a player has at least this "
1894 "many cities and the player's capital is captured. If "
1895 "this option is set to the maximum value, civil wars are "
1896 "turned off altogether."), NULL, NULL,
1897 GAME_MIN_CIVILWARSIZE, GAME_MAX_CIVILWARSIZE,
1898 GAME_DEFAULT_CIVILWARSIZE)
1900 GEN_BOOL("restrictinfra", game.info.restrictinfra,
1901 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1902 N_("Restrict the use of the infrastructure for enemy units"),
1903 N_("If this option is enabled, the use of roads and rails "
1904 "will be restricted for enemy units."), NULL, NULL,
1905 GAME_DEFAULT_RESTRICTINFRA)
1907 GEN_BOOL("unreachableprotects", game.info.unreachable_protects,
1908 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1909 N_("Does unreachable unit protect reachable ones"),
1910 N_("This option controls whether tiles with both unreachable "
1911 "and reachable units can be attacked. If disabled, any "
1912 "tile with reachable units can be attacked. If enabled, "
1913 "tiles with an unreachable unit in them cannot be attacked."),
1914 NULL, NULL, GAME_DEFAULT_UNRPROTECTS)
1916 GEN_INT("contactturns", game.server.contactturns,
1917 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1918 N_("Turns until player contact is lost"),
1919 N_("Players may meet for diplomacy this number of turns "
1920 "after their units have last met, even when they do not have "
1921 "an embassy. If set to zero, then players cannot meet unless "
1922 "they have an embassy."),
1923 NULL, NULL,
1924 GAME_MIN_CONTACTTURNS, GAME_MAX_CONTACTTURNS,
1925 GAME_DEFAULT_CONTACTTURNS)
1927 GEN_BOOL("savepalace", game.server.savepalace,
1928 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1929 N_("Rebuild palace whenever capital is conquered"),
1930 N_("If this is turned on, when the capital is conquered the "
1931 "palace is automatically rebuilt for free in another randomly "
1932 "chosen city. This is significant because the technology "
1933 "requirement for building a palace will be ignored. (In "
1934 "some rulesets, buildings other than the palace are affected "
1935 "by this setting.)"),
1936 NULL, NULL, GAME_DEFAULT_SAVEPALACE)
1938 GEN_BOOL("homecaughtunits", game.server.homecaughtunits,
1939 SSET_RULES_FLEXIBLE, SSET_MILITARY, SSET_RARE, SSET_TO_CLIENT,
1940 N_("Give caught units a homecity"),
1941 /* TRANS: The string between single quotes is a setting name and
1942 * should not be translated. */
1943 N_("If unset, caught units will have no homecity and will be "
1944 "subject to the 'killunhomed' option."),
1945 NULL, NULL, GAME_DEFAULT_HOMECAUGHTUNITS)
1947 GEN_BOOL("alliedvictory", game.server.allied_victory,
1948 SSET_RULES_FLEXIBLE, SSET_MILITARY,
1949 SSET_SITUATIONAL, SSET_TO_CLIENT,
1950 N_("Whether allied players can win together"),
1951 N_("If this option is turned on and a point is reached where "
1952 "all the players still able to win the game are allies, and "
1953 "at least one defeated player is not part of this alliance, "
1954 "then the game will end in an immediate shared victory for "
1955 "the allied players."),
1956 NULL, NULL, GAME_DEFAULT_ALLIED_VICTORY)
1958 GEN_BOOL("naturalcitynames", game.server.natural_city_names,
1959 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1960 N_("Whether to use natural city names"),
1961 N_("If enabled, the default city names will be determined based "
1962 "on the surrounding terrain."),
1963 NULL, NULL, GAME_DEFAULT_NATURALCITYNAMES)
1965 GEN_BOOL("migration", game.server.migration,
1966 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1967 N_("Whether to enable citizen migration"),
1968 /* TRANS: The strings between single quotes are setting names
1969 * and should not be translated. */
1970 N_("This is the master setting that controls whether citizen "
1971 "migration is active in the game. If enabled, citizens may "
1972 "automatically move from less desirable cities to more "
1973 "desirable ones. The \"desirability\" of a given city is "
1974 "calculated from a number of factors. In general larger "
1975 "cities with more income and improvements will be preferred. "
1976 "Citizens will never migrate out of the capital, or cause "
1977 "a wonder to be lost by disbanding a city. A number of other "
1978 "settings control how migration behaves:\n"
1979 " 'mgr_turninterval' - How often citizens try to migrate.\n"
1980 " 'mgr_foodneeded' - Whether destination food is checked.\n"
1981 " 'mgr_distance' - How far citizens will migrate.\n"
1982 " 'mgr_worldchance' - Chance for inter-nation migration.\n"
1983 " 'mgr_nationchance' - Chance for intra-nation migration."),
1984 NULL, NULL, GAME_DEFAULT_MIGRATION)
1986 GEN_INT("mgr_turninterval", game.server.mgr_turninterval,
1987 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
1988 N_("Number of turns between migrations from a city"),
1989 /* TRANS: Do not translate 'migration' setting name. */
1990 N_("This setting controls the number of turns between migration "
1991 "checks for a given city. The interval is calculated from "
1992 "the founding turn of the city. So for example if this "
1993 "setting is 5, citizens will look for a suitable migration "
1994 "destination every five turns from the founding of their "
1995 "current city. Migration will never occur the same turn "
1996 "that a city is built. This setting has no effect unless "
1997 "migration is enabled by the 'migration' setting."), NULL,
1998 NULL, GAME_MIN_MGR_TURNINTERVAL, GAME_MAX_MGR_TURNINTERVAL,
1999 GAME_DEFAULT_MGR_TURNINTERVAL)
2001 GEN_BOOL("mgr_foodneeded", game.server.mgr_foodneeded,
2002 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
2003 N_("Whether migration is limited by food"),
2004 /* TRANS: Do not translate 'migration' setting name. */
2005 N_("If this setting is enabled, citizens will not migrate to "
2006 "cities which would not have enough food to support them. "
2007 "This setting has no effect unless migration is enabled by "
2008 "the 'migration' setting."), NULL, NULL,
2009 GAME_DEFAULT_MGR_FOODNEEDED)
2011 GEN_INT("mgr_distance", game.server.mgr_distance,
2012 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
2013 N_("Maximum distance citizens may migrate"),
2014 /* TRANS: Do not translate 'migration' setting name. */
2015 N_("This setting controls how far citizens may look for a "
2016 "suitable migration destination when deciding which city "
2017 "to migrate to. The value is added to the current city radius "
2018 "and compared to the distance between the two cities. If "
2019 "the distance is lower or equal, migration is possible. This "
2020 "setting has no effect unless migration is activated by the "
2021 "'migration' setting."),
2022 NULL, NULL, GAME_MIN_MGR_DISTANCE, GAME_MAX_MGR_DISTANCE,
2023 GAME_DEFAULT_MGR_DISTANCE)
2025 GEN_INT("mgr_nationchance", game.server.mgr_nationchance,
2026 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
2027 N_("Percent probability for migration within the same nation"),
2028 /* TRANS: Do not translate 'migration' setting name. */
2029 N_("This setting controls how likely it is for citizens to "
2030 "migrate between cities owned by the same player. Zero "
2031 "indicates migration will never occur, 100 means that "
2032 "migration will always occur if the citizens find a suitable "
2033 "destination. This setting has no effect unless migration "
2034 "is activated by the 'migration' setting."), NULL, NULL,
2035 GAME_MIN_MGR_NATIONCHANCE, GAME_MAX_MGR_NATIONCHANCE,
2036 GAME_DEFAULT_MGR_NATIONCHANCE)
2038 GEN_INT("mgr_worldchance", game.server.mgr_worldchance,
2039 SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
2040 N_("Percent probability for migration between foreign cities"),
2041 /* TRANS: Do not translate 'migration' setting name. */
2042 N_("This setting controls how likely it is for migration "
2043 "to occur between cities owned by different players. "
2044 "Zero indicates migration will never occur, 100 means "
2045 "that citizens will always migrate if they find a suitable "
2046 "destination. This setting has no effect if migration is "
2047 "not enabled by the 'migration' setting."), NULL, NULL,
2048 GAME_MIN_MGR_WORLDCHANCE, GAME_MAX_MGR_WORLDCHANCE,
2049 GAME_DEFAULT_MGR_WORLDCHANCE)
2051 /* Meta options: these don't affect the internal rules of the game, but
2052 * do affect players. Also options which only produce extra server
2053 * "output" and don't affect the actual game.
2054 * ("endturn" is here, and not RULES_FLEXIBLE, because it doesn't
2055 * affect what happens in the game, it just determines when the
2056 * players stop playing and look at the score.)
2058 GEN_STRING("allowtake", game.server.allow_take,
2059 SSET_META, SSET_NETWORK, SSET_RARE, SSET_TO_CLIENT,
2060 N_("Players that users are allowed to take"),
2061 /* TRANS: the strings in double quotes are server command names
2062 * and should not be translated. */
2063 N_("This should be a string of characters, each of which "
2064 "specifies a type or status of a civilization (player).\n"
2065 "Clients will only be permitted to take or observe those "
2066 "players which match one of the specified letters. This "
2067 "only affects future uses of the \"take\" or \"observe\" "
2068 "commands; it is not retroactive. The characters and their "
2069 "meanings are:\n"
2070 " o,O = Global observer\n"
2071 " b = Barbarian players\n"
2072 " d = Dead players\n"
2073 " a,A = AI players\n"
2074 " h,H = Human players\n"
2075 "The first description on this list which matches a "
2076 "player is the one which applies. Thus 'd' does not "
2077 "include dead barbarians, 'a' does not include dead AI "
2078 "players, and so on. Upper case letters apply before "
2079 "the game has started, lower case letters afterwards.\n"
2080 "Each character above may be followed by one of the "
2081 "following numbers to allow or restrict the manner "
2082 "of connection:\n"
2083 "(none) = Controller allowed, observers allowed, "
2084 "can displace connections. (Displacing a connection means "
2085 "that you may take over a player, even when another user "
2086 "already controls that player.)\n"
2087 " 1 = Controller allowed, observers allowed, "
2088 "can't displace connections;\n"
2089 " 2 = Controller allowed, no observers allowed, "
2090 "can displace connections;\n"
2091 " 3 = Controller allowed, no observers allowed, "
2092 "can't displace connections;\n"
2093 " 4 = No controller allowed, observers allowed"),
2094 allowtake_callback, NULL, GAME_DEFAULT_ALLOW_TAKE)
2096 GEN_BOOL("autotoggle", game.server.auto_ai_toggle,
2097 SSET_META, SSET_NETWORK, SSET_SITUATIONAL, SSET_TO_CLIENT,
2098 N_("Whether AI-status toggles with connection"),
2099 N_("If enabled, AI status is turned off when a player "
2100 "connects, and on when a player disconnects."),
2101 NULL, autotoggle_action, GAME_DEFAULT_AUTO_AI_TOGGLE)
2103 GEN_INT("endturn", game.server.end_turn,
2104 SSET_META, SSET_SOCIOLOGY, SSET_VITAL, SSET_TO_CLIENT,
2105 N_("Turn the game ends"),
2106 N_("The game will end at the end of the given turn."),
2107 endturn_callback, NULL,
2108 GAME_MIN_END_TURN, GAME_MAX_END_TURN, GAME_DEFAULT_END_TURN)
2110 GEN_BITWISE("revealmap", game.server.revealmap, SSET_GAME_INIT,
2111 SSET_MILITARY, SSET_SITUATIONAL, SSET_TO_CLIENT,
2112 N_("Reveal the map"),
2113 /* TRANS: The strings between double quotes are also translated
2114 * separately (they must match!). The strings between single
2115 * quotes are setting names and shouldn't be translated. The
2116 * strings between parentheses and in uppercase must not be
2117 * translated. */
2118 N_("If \"Reveal map at game start\" (START) is set, the "
2119 "initial state of the entire map will be known to all "
2120 "players from the start of the game, although it may "
2121 "still be fogged (depending on the 'fogofwar' setting). "
2122 "If \"Unfog map for dead players\" (DEAD) is set, dead "
2123 "players can see the entire map, if they are alone in "
2124 "their team."),
2125 NULL, NULL, revealmap_name, GAME_DEFAULT_REVEALMAP)
2127 GEN_INT("timeout", game.info.timeout,
2128 SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_TO_CLIENT,
2129 N_("Maximum seconds per turn"),
2130 /* TRANS: \"Turn Done\" refers to the client button; it is also
2131 * translated separately, the translation should be the same.
2132 * \"timeoutincrease\" is a command name and must not to be
2133 * translated. */
2134 N_("If all players have not hit \"Turn Done\" before this "
2135 "time is up, then the turn ends automatically. Zero "
2136 "means there is no timeout. In servers compiled with "
2137 "debugging, a timeout of -1 sets the autogame test mode. "
2138 "Only connections with hack level access may set the "
2139 "timeout to lower than 30 seconds. Use this with the "
2140 "command \"timeoutincrease\" to have a dynamic timer. "
2141 "The first turn is treated as a special case and is controlled "
2142 "by the 'first_timeout' setting."),
2143 timeout_callback, timeout_action,
2144 GAME_MIN_TIMEOUT, GAME_MAX_TIMEOUT, GAME_DEFAULT_TIMEOUT)
2146 GEN_INT("first_timeout", game.server.first_timeout,
2147 SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_TO_CLIENT,
2148 N_("First turn timeout"),
2149 /* TRANS: The strings between single quotes are setting names and
2150 * should not be translated. */
2151 N_("If greater than 0, T0 will last for 'first_timeout' seconds.\n"
2152 "If set to 0, T0 will not have a timeout.\n"
2153 "If set to -1, the special treatment of T0 will be disabled.\n"
2154 "See also 'timeout'."),
2155 NULL, NULL, GAME_MIN_FIRST_TIMEOUT, GAME_MAX_FIRST_TIMEOUT,
2156 GAME_DEFAULT_FIRST_TIMEOUT)
2158 GEN_INT("timeaddenemymove", game.server.timeoutaddenemymove,
2159 SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_TO_CLIENT,
2160 N_("Timeout at least n seconds when enemy moved"),
2161 N_("Any time a unit moves while in sight of an enemy player, "
2162 "the remaining timeout is increased to this value."),
2163 NULL, NULL, 0, GAME_MAX_TIMEOUT, GAME_DEFAULT_TIMEOUTADDEMOVE)
2165 GEN_INT("unitwaittime", game.server.unitwaittime,
2166 SSET_RULES_FLEXIBLE, SSET_INTERNAL, SSET_VITAL, SSET_TO_CLIENT,
2167 N_("Time between unit moves over turn change"),
2168 /* TRANS: The string between single quotes is a setting name and
2169 * should not be translated. */
2170 N_("This setting gives the minimum amount of time in seconds "
2171 "between unit moves after a turn change occurs. For "
2172 "example, if this setting is set to 20 and a unit moves "
2173 "5 seconds before the turn change, it will not be able "
2174 "to move in the next turn for at least 15 seconds. Building "
2175 "cities is also affected by this setting, as well as units "
2176 "moving inside a transporter. This value is limited to "
2177 "a maximum value of 2/3 'timeout'."),
2178 unitwaittime_callback, NULL, GAME_MIN_UNITWAITTIME,
2179 GAME_MAX_UNITWAITTIME, GAME_DEFAULT_UNITWAITTIME)
2181 /* This setting points to the "stored" value; changing it won't have
2182 * an effect until the next synchronization point (i.e., the start of
2183 * the next turn). */
2184 GEN_ENUM("phasemode", game.server.phase_mode_stored,
2185 SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT,
2186 N_("Control of simultaneous player/team phases"),
2187 N_("This setting controls whether players may make "
2188 "moves at the same time during a turn. Change "
2189 "in setting takes effect next turn."),
2190 NULL, NULL, phasemode_name, GAME_DEFAULT_PHASE_MODE)
2192 GEN_INT("nettimeout", game.server.tcptimeout,
2193 SSET_META, SSET_NETWORK, SSET_RARE, SSET_TO_CLIENT,
2194 N_("Seconds to let a client's network connection block"),
2195 N_("If a network connection is blocking for a time greater than "
2196 "this value, then the connection is closed. Zero "
2197 "means there is no timeout (although connections will be "
2198 "automatically disconnected eventually)."),
2199 NULL, NULL,
2200 GAME_MIN_TCPTIMEOUT, GAME_MAX_TCPTIMEOUT, GAME_DEFAULT_TCPTIMEOUT)
2202 GEN_INT("netwait", game.server.netwait,
2203 SSET_META, SSET_NETWORK, SSET_RARE, SSET_TO_CLIENT,
2204 N_("Max seconds for network buffers to drain"),
2205 N_("The server will wait for up to the value of this "
2206 "parameter in seconds, for all client connection network "
2207 "buffers to unblock. Zero means the server will not "
2208 "wait at all."), NULL, NULL,
2209 GAME_MIN_NETWAIT, GAME_MAX_NETWAIT, GAME_DEFAULT_NETWAIT)
2211 GEN_INT("pingtime", game.server.pingtime,
2212 SSET_META, SSET_NETWORK, SSET_RARE, SSET_TO_CLIENT,
2213 N_("Seconds between PINGs"),
2214 N_("The server will poll the clients with a PING request "
2215 "each time this period elapses."), NULL, NULL,
2216 GAME_MIN_PINGTIME, GAME_MAX_PINGTIME, GAME_DEFAULT_PINGTIME)
2218 GEN_INT("pingtimeout", game.server.pingtimeout,
2219 SSET_META, SSET_NETWORK, SSET_RARE,
2220 SSET_TO_CLIENT,
2221 N_("Time to cut a client"),
2222 N_("If a client doesn't reply to a PING in this time the "
2223 "client is disconnected."), NULL, NULL,
2224 GAME_MIN_PINGTIMEOUT, GAME_MAX_PINGTIMEOUT, GAME_DEFAULT_PINGTIMEOUT)
2226 GEN_BOOL("turnblock", game.server.turnblock,
2227 SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT,
2228 N_("Turn-blocking game play mode"),
2229 N_("If this is turned on, the game turn is not advanced "
2230 "until all players have finished their turn, including "
2231 "disconnected players."),
2232 NULL, NULL, GAME_DEFAULT_TURNBLOCK)
2234 GEN_BOOL("fixedlength", game.server.fixedlength,
2235 SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT,
2236 N_("Fixed-length turns play mode"),
2237 /* TRANS: \"Turn Done\" refers to the client button; it is also
2238 * translated separately, the translation should be the same. */
2239 N_("If this is turned on the game turn will not advance "
2240 "until the timeout has expired, even after all players "
2241 "have clicked on \"Turn Done\"."),
2242 NULL, NULL, FALSE)
2244 GEN_STRING("demography", game.server.demography,
2245 SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT,
2246 N_("What is in the Demographics report"),
2247 /* TRANS: The strings between double quotes should be
2248 * translated. */
2249 N_("This should be a string of characters, each of which "
2250 "specifies the inclusion of a line of information "
2251 "in the Demographics report.\n"
2252 "The characters and their meanings are:\n"
2253 " N = include Population\n"
2254 " P = include Production\n"
2255 " A = include Land Area\n"
2256 " L = include Literacy\n"
2257 " R = include Research Speed\n"
2258 " S = include Settled Area\n"
2259 " E = include Economics\n"
2260 " M = include Military Service\n"
2261 " O = include Pollution\n"
2262 "Additionally, the following characters control whether "
2263 "or not certain columns are displayed in the report:\n"
2264 " q = display \"quantity\" column\n"
2265 " r = display \"rank\" column\n"
2266 " b = display \"best nation\" column\n"
2267 "The order of characters is not significant, but "
2268 "their capitalization is."),
2269 demography_callback, NULL, GAME_DEFAULT_DEMOGRAPHY)
2271 GEN_INT("saveturns", game.server.save_nturns,
2272 SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_SERVER_ONLY,
2273 N_("Turns per auto-save"),
2274 /* TRANS: The string between double quotes is also translated
2275 * separately (it must match!). The string between single
2276 * quotes is a setting name and shouldn't be translated. */
2277 N_("How many turns elapse between automatic game saves. This "
2278 "setting only has an effect when the 'autosaves' setting "
2279 "includes \"New turn\"."), NULL, NULL,
2280 GAME_MIN_SAVETURNS, GAME_MAX_SAVETURNS, GAME_DEFAULT_SAVETURNS)
2282 GEN_BITWISE("autosaves", game.server.autosaves,
2283 SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_SERVER_ONLY,
2284 N_("Which savegames are generated automatically"),
2285 /* TRANS: The strings between double quotes are also translated
2286 * separately (they must match!). The strings between single
2287 * quotes are setting names and shouldn't be translated. The
2288 * strings between parentheses and in uppercase must stay as
2289 * untranslated. */
2290 N_("This setting controls which autosave types get generated:\n"
2291 "- \"New turn\" (TURN): Save when turn begins, once every "
2292 "'saveturns' turns.\n"
2293 "- \"Game over\" (GAMEOVER): Final save when game ends.\n"
2294 "- \"No player connections\" (QUITIDLE): "
2295 "Save before server restarts due to lack of players.\n"
2296 "- \"Server interrupted\" (INTERRUPT): Save when server "
2297 "quits due to interrupt."),
2298 NULL, NULL, autosaves_name, GAME_DEFAULT_AUTOSAVES)
2300 GEN_INT("compress", game.server.save_compress_level,
2301 SSET_META, SSET_INTERNAL, SSET_RARE, SSET_SERVER_ONLY,
2302 N_("Savegame compression level"),
2303 /* TRANS: 'compresstype' setting name should not be translated. */
2304 N_("If non-zero, saved games will be compressed depending on the "
2305 "'compresstype' setting. Larger values will give better "
2306 "compression but take longer."),
2307 NULL, NULL, GAME_MIN_COMPRESS_LEVEL, GAME_MAX_COMPRESS_LEVEL,
2308 GAME_DEFAULT_COMPRESS_LEVEL)
2310 GEN_ENUM("compresstype", game.server.save_compress_type,
2311 SSET_META, SSET_INTERNAL, SSET_RARE, SSET_SERVER_ONLY,
2312 N_("Savegame compression algorithm"),
2313 N_("Compression library to use for savegames."),
2314 NULL, NULL, compresstype_name, GAME_DEFAULT_COMPRESS_TYPE)
2316 GEN_STRING("savename", game.server.save_name,
2317 SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_SERVER_ONLY,
2318 N_("Definition of the save file name"),
2319 /* TRANS: %R, %S, %T and %Y must not be translated. The
2320 * strings (examples and setting names) between single quotes
2321 * neither. The strings between <> should be translated.
2322 * xgettext:no-c-format */
2323 N_("Within the string the following custom formats are "
2324 "allowed:\n"
2325 " %R = <reason>\n"
2326 " %S = <suffix>\n"
2327 " %T = <turn-number>\n"
2328 " %Y = <game-year>\n"
2329 "\n"
2330 "Example: 'freeciv-T%04T-Y%+05Y-%R' => "
2331 "'freeciv-T0100-Y00001-manual'\n"
2332 "\n"
2333 "Be careful to use at least one of %T and %Y, else newer "
2334 "savegames will overwrite old ones. If none of the formats "
2335 "is used '-T%04T-Y%05Y-%R' is appended to the value of "
2336 "'savename'."),
2337 savename_validate, NULL, GAME_DEFAULT_SAVE_NAME)
2339 GEN_BOOL("scorelog", game.server.scorelog,
2340 SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_SERVER_ONLY,
2341 N_("Whether to log player statistics"),
2342 /* TRANS: The string between single quotes is a setting name and
2343 * should not be translated. */
2344 N_("If this is turned on, player statistics are appended to "
2345 "the file defined by the option 'scorefile' every turn. "
2346 "These statistics can be used to create power graphs after "
2347 "the game."), NULL, scorelog_action, GAME_DEFAULT_SCORELOG)
2349 GEN_STRING("scorefile", game.server.scorefile,
2350 SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_SERVER_ONLY,
2351 N_("Name for the score log file"),
2352 /* TRANS: Don't translate the string in single quotes. */
2353 N_("The default name for the score log file is "
2354 "'freeciv-score.log'."),
2355 scorefile_validate, NULL, GAME_DEFAULT_SCOREFILE)
2357 GEN_INT("maxconnectionsperhost", game.server.maxconnectionsperhost,
2358 SSET_RULES_FLEXIBLE, SSET_NETWORK, SSET_RARE, SSET_TO_CLIENT,
2359 N_("Maximum number of connections to the server per host"),
2360 N_("New connections from a given host will be rejected if "
2361 "the total number of connections from the very same host "
2362 "equals or exceeds this value. A value of 0 means that "
2363 "there is no limit, at least up to the maximum number of "
2364 "connections supported by the server."), NULL, NULL,
2365 GAME_MIN_MAXCONNECTIONSPERHOST, GAME_MAX_MAXCONNECTIONSPERHOST,
2366 GAME_DEFAULT_MAXCONNECTIONSPERHOST)
2368 GEN_INT("kicktime", game.server.kick_time,
2369 SSET_RULES_FLEXIBLE, SSET_NETWORK, SSET_RARE, SSET_SERVER_ONLY,
2370 N_("Time before a kicked user can reconnect"),
2371 /* TRANS: the string in double quotes is a server command name and
2372 * should not be translated */
2373 N_("Gives the time in seconds before a user kicked using the "
2374 "\"kick\" command may reconnect. Changing this setting will "
2375 "affect users kicked in the past."), NULL, NULL,
2376 GAME_MIN_KICK_TIME, GAME_MAX_KICK_TIME, GAME_DEFAULT_KICK_TIME)
2379 #undef GEN_BOOL
2380 #undef GEN_INT
2381 #undef GEN_STRING
2382 #undef GEN_ENUM
2383 #undef GEN_BITWISE
2385 /* The number of settings, not including the END. */
2386 static const int SETTINGS_NUM = ARRAY_SIZE(settings);
2388 /****************************************************************************
2389 Returns the setting to the given id.
2390 ****************************************************************************/
2391 struct setting *setting_by_number(int id)
2393 return (0 <= id && id < SETTINGS_NUM ? settings + id : NULL);
2396 /****************************************************************************
2397 Returns the setting to the given name.
2398 ****************************************************************************/
2399 struct setting *setting_by_name(const char *name)
2401 fc_assert_ret_val(name, NULL);
2403 settings_iterate(SSET_ALL, pset) {
2404 if (0 == strcmp(name, pset->name)) {
2405 return pset;
2407 } settings_iterate_end;
2408 return NULL;
2411 /****************************************************************************
2412 Returns the id to the given setting.
2413 ****************************************************************************/
2414 int setting_number(const struct setting *pset)
2416 fc_assert_ret_val(pset != NULL, -1);
2417 return pset - settings;
2420 /****************************************************************************
2421 Access function for the setting name.
2422 ****************************************************************************/
2423 const char *setting_name(const struct setting *pset)
2425 return pset->name;
2428 /****************************************************************************
2429 Access function for the short help (not translated yet) of the setting.
2430 ****************************************************************************/
2431 const char *setting_short_help(const struct setting *pset)
2433 return pset->short_help;
2436 /****************************************************************************
2437 Access function for the long (extra) help (not translated yet) of
2438 the setting.
2439 ****************************************************************************/
2440 const char *setting_extra_help(const struct setting *pset)
2442 return pset->extra_help;
2445 /****************************************************************************
2446 Access function for the setting type.
2447 ****************************************************************************/
2448 enum sset_type setting_type(const struct setting *pset)
2450 return pset->stype;
2453 /****************************************************************************
2454 Access function for the setting level (used by the /show command).
2455 ****************************************************************************/
2456 enum sset_level setting_level(const struct setting *pset)
2458 return pset->slevel;
2461 /****************************************************************************
2462 Access function for the setting category.
2463 ****************************************************************************/
2464 enum sset_category setting_category(const struct setting *pset)
2466 return pset->scategory;
2469 /****************************************************************************
2470 Returns whether the specified server setting (option) can currently
2471 be changed by the caller. If it returns FALSE, the reason of the failure
2472 is available by the function setting_error().
2473 ****************************************************************************/
2474 bool setting_is_changeable(const struct setting *pset,
2475 struct connection *caller, char *reject_msg,
2476 size_t reject_msg_len)
2478 if (caller
2479 && (caller->access_level < ALLOW_BASIC
2480 || (caller->access_level < ALLOW_HACK && !pset->to_client))) {
2481 settings_snprintf(reject_msg, reject_msg_len,
2482 _("You are not allowed to change the setting '%s'."),
2483 setting_name(pset));
2484 return FALSE;
2487 if (setting_locked(pset)) {
2488 /* setting is locked by the ruleset */
2489 settings_snprintf(reject_msg, reject_msg_len,
2490 _("The setting '%s' is locked by the ruleset."),
2491 setting_name(pset));
2492 return FALSE;
2495 switch (pset->sclass) {
2496 case SSET_MAP_SIZE:
2497 case SSET_MAP_GEN:
2498 /* Only change map options if we don't yet have a map: */
2499 if (map_is_empty()) {
2500 return TRUE;
2503 settings_snprintf(reject_msg, reject_msg_len,
2504 _("The setting '%s' can't be modified after the map "
2505 "is fixed."), setting_name(pset));
2506 return FALSE;
2508 case SSET_MAP_ADD:
2509 case SSET_PLAYERS:
2510 case SSET_GAME_INIT:
2511 case SSET_RULES:
2512 /* Only change start params and most rules if we don't yet have a map,
2513 * or if we do have a map but its a scenario one (ie, the game has
2514 * never actually been started).
2516 if (map_is_empty() || game.info.is_new_game) {
2517 return TRUE;
2520 settings_snprintf(reject_msg, reject_msg_len,
2521 _("The setting '%s' can't be modified after the game "
2522 "has started."), setting_name(pset));
2523 return FALSE;
2525 case SSET_RULES_FLEXIBLE:
2526 case SSET_META:
2527 /* These can always be changed: */
2528 return TRUE;
2531 log_error("Wrong class variant for setting %s (%d): %d.",
2532 setting_name(pset), setting_number(pset), pset->sclass);
2533 settings_snprintf(reject_msg, reject_msg_len, _("Internal error."));
2535 return FALSE;
2538 /****************************************************************************
2539 Returns whether the specified server setting (option) can be seen by the
2540 caller.
2541 ****************************************************************************/
2542 bool setting_is_visible(const struct setting *pset,
2543 struct connection *caller)
2545 return (!caller
2546 || pset->to_client
2547 || caller->access_level >= ALLOW_HACK);
2550 /****************************************************************************
2551 Convert the string prefix to an integer representation.
2552 NB: This function is used for SSET_ENUM *and* SSET_BITWISE.
2554 FIXME: this mostly duplicate match_prefix_full().
2555 ****************************************************************************/
2556 static enum m_pre_result
2557 setting_match_prefix_base(const val_name_func_t name_fn,
2558 const char *prefix, int *ind_result,
2559 const char **matches, size_t max_matches,
2560 size_t *pnum_matches)
2562 const struct sset_val_name *name;
2563 size_t len = strlen(prefix);
2564 size_t num_matches;
2565 int i;
2567 *pnum_matches = 0;
2569 if (0 == len) {
2570 return M_PRE_EMPTY;
2573 for (i = 0, num_matches = 0; (name = name_fn(i)); i++) {
2574 if (0 == fc_strncasecmp(name->support, prefix, len)) {
2575 if (strlen(name->support) == len) {
2576 *ind_result = i;
2577 return M_PRE_EXACT;
2579 if (num_matches < max_matches) {
2580 matches[num_matches] = name->support;
2581 (*pnum_matches)++;
2583 if (0 == num_matches++) {
2584 *ind_result = i;
2589 if (1 == num_matches) {
2590 return M_PRE_ONLY;
2591 } else if (1 < num_matches) {
2592 return M_PRE_AMBIGUOUS;
2593 } else {
2594 return M_PRE_FAIL;
2598 /****************************************************************************
2599 Convert the string prefix to an integer representation.
2600 NB: This function is used for SSET_ENUM *and* SSET_BITWISE.
2601 ****************************************************************************/
2602 static bool setting_match_prefix(const val_name_func_t name_fn,
2603 const char *prefix, int *pvalue,
2604 char *reject_msg,
2605 size_t reject_msg_len)
2607 const char *matches[16];
2608 size_t num_matches;
2610 switch (setting_match_prefix_base(name_fn, prefix, pvalue, matches,
2611 ARRAY_SIZE(matches), &num_matches)) {
2612 case M_PRE_EXACT:
2613 case M_PRE_ONLY:
2614 return TRUE; /* Ok. */
2615 case M_PRE_AMBIGUOUS:
2617 struct astring astr = ASTRING_INIT;
2619 fc_assert(2 <= num_matches);
2620 settings_snprintf(reject_msg, reject_msg_len,
2621 _("\"%s\" prefix is ambiguous. Candidates are: %s."),
2622 prefix,
2623 astr_build_and_list(&astr, matches, num_matches));
2624 astr_free(&astr);
2626 return FALSE;
2627 case M_PRE_EMPTY:
2628 settings_snprintf(reject_msg, reject_msg_len, _("Missing value."));
2629 return FALSE;
2630 case M_PRE_LONG:
2631 case M_PRE_FAIL:
2632 case M_PRE_LAST:
2633 break;
2636 settings_snprintf(reject_msg, reject_msg_len,
2637 _("No match for \"%s\"."), prefix);
2638 return FALSE;
2641 /****************************************************************************
2642 Compute the string representation of the value for this boolean setting.
2643 ****************************************************************************/
2644 static const char *setting_bool_to_str(const struct setting *pset,
2645 bool value, bool pretty,
2646 char *buf, size_t buf_len)
2648 const struct sset_val_name *name = pset->boolean.name(value);
2650 if (pretty) {
2651 fc_snprintf(buf, buf_len, "%s", Q_(name->pretty));
2652 } else {
2653 fc_strlcpy(buf, name->support, buf_len);
2655 return buf;
2658 /****************************************************************************
2659 Returns TRUE if 'val' is a valid value for this setting. If it's not,
2660 the reason of the failure is available in the optionnal parameter
2661 'reject_msg'.
2663 FIXME: also check the access level of pconn.
2664 ****************************************************************************/
2665 static bool setting_bool_validate_base(const struct setting *pset,
2666 const char *val, int *pint_val,
2667 struct connection *caller,
2668 char *reject_msg,
2669 size_t reject_msg_len)
2671 char buf[256];
2673 if (SSET_BOOL != pset->stype) {
2674 settings_snprintf(reject_msg, reject_msg_len,
2675 _("This setting is not a boolean."));
2676 return FALSE;
2679 sz_strlcpy(buf, val);
2680 remove_leading_trailing_spaces(buf);
2682 return (setting_match_prefix(pset->boolean.name, buf, pint_val,
2683 reject_msg, reject_msg_len)
2684 && (NULL == pset->boolean.validate
2685 || pset->boolean.validate(0 != *pint_val, caller, reject_msg,
2686 reject_msg_len)));
2689 /****************************************************************************
2690 Set the setting to 'val'. Returns TRUE on success. If it's not,
2691 the reason of the failure is available in the optionnal parameter
2692 'reject_msg'.
2693 ****************************************************************************/
2694 bool setting_bool_set(struct setting *pset, const char *val,
2695 struct connection *caller, char *reject_msg,
2696 size_t reject_msg_len)
2698 int int_val;
2700 if (!setting_is_changeable(pset, caller, reject_msg, reject_msg_len)
2701 || !setting_bool_validate_base(pset, val, &int_val, caller,
2702 reject_msg, reject_msg_len)) {
2703 return FALSE;
2706 *pset->boolean.pvalue = (0 != int_val);
2707 return TRUE;
2710 /****************************************************************************
2711 Returns TRUE if 'val' is a valid value for this setting. If it's not,
2712 the reason of the failure is available in the optionnal parameter
2713 'reject_msg'.
2714 ****************************************************************************/
2715 bool setting_bool_validate(const struct setting *pset, const char *val,
2716 struct connection *caller, char *reject_msg,
2717 size_t reject_msg_len)
2719 int int_val;
2721 return setting_bool_validate_base(pset, val, &int_val, caller,
2722 reject_msg, reject_msg_len);
2725 /****************************************************************************
2726 Convert the integer to the long support string representation of a boolean
2727 setting. This function must match the secfile_enum_name_data_fn_t type.
2728 ****************************************************************************/
2729 static const char *setting_bool_secfile_str(secfile_data_t data, int val)
2731 const struct sset_val_name *name =
2732 ((const struct setting *) data)->boolean.name(val);
2734 return (NULL != name ? name->support : NULL);
2737 /****************************************************************************
2738 Compute the string representation of the value for this integer setting.
2739 ****************************************************************************/
2740 static const char *setting_int_to_str(const struct setting *pset,
2741 int value, bool pretty,
2742 char *buf, size_t buf_len)
2744 fc_snprintf(buf, buf_len, "%d", value);
2745 return buf;
2748 /****************************************************************************
2749 Returns the minimal integer value for this setting.
2750 ****************************************************************************/
2751 int setting_int_min(const struct setting *pset)
2753 fc_assert_ret_val(pset->stype == SSET_INT, 0);
2754 return pset->integer.min_value;
2757 /****************************************************************************
2758 Returns the maximal integer value for this setting.
2759 ****************************************************************************/
2760 int setting_int_max(const struct setting *pset)
2762 fc_assert_ret_val(pset->stype == SSET_INT, 0);
2763 return pset->integer.max_value;
2766 /****************************************************************************
2767 Set the setting to 'val'. Returns TRUE on success. If it fails, the
2768 reason of the failure is available by the function setting_error().
2769 ****************************************************************************/
2770 bool setting_int_set(struct setting *pset, int val,
2771 struct connection *caller, char *reject_msg,
2772 size_t reject_msg_len)
2774 if (!setting_is_changeable(pset, caller, reject_msg, reject_msg_len)
2775 || !setting_int_validate(pset, val, caller, reject_msg,
2776 reject_msg_len)) {
2777 return FALSE;
2780 *pset->integer.pvalue = val;
2781 return TRUE;
2784 /****************************************************************************
2785 Returns TRUE if 'val' is a valid value for this setting. If it's not,
2786 the reason of the failure is available by the function setting_error().
2788 FIXME: also check the access level of pconn.
2789 ****************************************************************************/
2790 bool setting_int_validate(const struct setting *pset, int val,
2791 struct connection *caller, char *reject_msg,
2792 size_t reject_msg_len)
2794 if (SSET_INT != pset->stype) {
2795 settings_snprintf(reject_msg, reject_msg_len,
2796 _("This setting is not an integer."));
2797 return FALSE;
2800 if (val < pset->integer.min_value || val > pset->integer.max_value) {
2801 settings_snprintf(reject_msg, reject_msg_len,
2802 _("Value out of range: %d (min: %d; max: %d)."),
2803 val, pset->integer.min_value, pset->integer.max_value);
2804 return FALSE;
2807 return (!pset->integer.validate
2808 || pset->integer.validate(val, caller, reject_msg,
2809 reject_msg_len));
2812 /****************************************************************************
2813 Compute the string representation of the value for this string setting.
2814 ****************************************************************************/
2815 static const char *setting_str_to_str(const struct setting *pset,
2816 const char *value, bool pretty,
2817 char *buf, size_t buf_len)
2819 if (pretty) {
2820 fc_snprintf(buf, buf_len, "\"%s\"", value);
2821 } else {
2822 fc_strlcpy(buf, value, buf_len);
2824 return buf;
2827 /****************************************************************************
2828 Set the setting to 'val'. Returns TRUE on success. If it fails, the
2829 reason of the failure is available by the function setting_error().
2830 ****************************************************************************/
2831 bool setting_str_set(struct setting *pset, const char *val,
2832 struct connection *caller, char *reject_msg,
2833 size_t reject_msg_len)
2835 if (!setting_is_changeable(pset, caller, reject_msg, reject_msg_len)
2836 || !setting_str_validate(pset, val, caller, reject_msg,
2837 reject_msg_len)) {
2838 return FALSE;
2841 fc_strlcpy(pset->string.value, val, pset->string.value_size);
2842 return TRUE;
2845 /****************************************************************************
2846 Returns TRUE if 'val' is a valid value for this setting. If it's not,
2847 the reason of the failure is available by the function setting_error().
2849 FIXME: also check the access level of pconn.
2850 ****************************************************************************/
2851 bool setting_str_validate(const struct setting *pset, const char *val,
2852 struct connection *caller, char *reject_msg,
2853 size_t reject_msg_len)
2855 if (SSET_STRING != pset->stype) {
2856 settings_snprintf(reject_msg, reject_msg_len,
2857 _("This setting is not a string."));
2858 return FALSE;
2861 if (strlen(val) >= pset->string.value_size) {
2862 settings_snprintf(reject_msg, reject_msg_len,
2863 _("String value too long (max length: %lu)."),
2864 (unsigned long) pset->string.value_size);
2865 return FALSE;
2868 return (!pset->string.validate
2869 || pset->string.validate(val, caller, reject_msg,
2870 reject_msg_len));
2873 /****************************************************************************
2874 Convert the integer to the long support string representation of an
2875 enumerator. This function must match the secfile_enum_name_data_fn_t type.
2876 ****************************************************************************/
2877 static const char *setting_enum_secfile_str(secfile_data_t data, int val)
2879 const struct sset_val_name *name =
2880 ((const struct setting *) data)->enumerator.name(val);
2882 return (NULL != name ? name->support : NULL);
2885 /****************************************************************************
2886 Convert the integer to the string representation of an enumerator.
2887 Return NULL if 'val' is not a valid enumerator.
2888 ****************************************************************************/
2889 const char *setting_enum_val(const struct setting *pset, int val,
2890 bool pretty)
2892 const struct sset_val_name *name;
2894 fc_assert_ret_val(SSET_ENUM == pset->stype, NULL);
2895 name = pset->enumerator.name(val);
2896 if (NULL == name) {
2897 return NULL;
2898 } else if (pretty) {
2899 return _(name->pretty);
2900 } else {
2901 return name->support;
2905 /****************************************************************************
2906 Compute the string representation of the value for this enumerator
2907 setting.
2908 ****************************************************************************/
2909 static const char *setting_enum_to_str(const struct setting *pset,
2910 int value, bool pretty,
2911 char *buf, size_t buf_len)
2913 const struct sset_val_name *name = pset->enumerator.name(value);
2915 if (pretty) {
2916 fc_snprintf(buf, buf_len, "\"%s\" (%s)",
2917 Q_(name->pretty), name->support);
2918 } else {
2919 fc_strlcpy(buf, name->support, buf_len);
2921 return buf;
2924 /****************************************************************************
2925 Returns TRUE if 'val' is a valid value for this setting. If it's not,
2926 the reason of the failure is available in the optionnal parameter
2927 'reject_msg'.
2929 FIXME: also check the access level of pconn.
2930 ****************************************************************************/
2931 static bool setting_enum_validate_base(const struct setting *pset,
2932 const char *val, int *pint_val,
2933 struct connection *caller,
2934 char *reject_msg,
2935 size_t reject_msg_len)
2937 char buf[256];
2939 if (SSET_ENUM != pset->stype) {
2940 settings_snprintf(reject_msg, reject_msg_len,
2941 _("This setting is not an enumerator."));
2942 return FALSE;
2945 sz_strlcpy(buf, val);
2946 remove_leading_trailing_spaces(buf);
2948 return (setting_match_prefix(pset->enumerator.name, buf, pint_val,
2949 reject_msg, reject_msg_len)
2950 && (NULL == pset->enumerator.validate
2951 || pset->enumerator.validate(*pint_val, caller, reject_msg,
2952 reject_msg_len)));
2955 /****************************************************************************
2956 Helper function to write value to enumerator setting
2957 ****************************************************************************/
2958 static bool set_enum_value(struct setting *pset, int val)
2960 switch(pset->enumerator.store_size) {
2961 case sizeof(int):
2963 int *to_int = pset->enumerator.pvalue;
2965 *to_int = val;
2967 break;
2968 case sizeof(char):
2970 char *to_char = pset->enumerator.pvalue;
2972 *to_char = (char) val;
2974 break;
2975 case sizeof(short):
2977 short *to_short = pset->enumerator.pvalue;
2979 *to_short = (short) val;
2981 break;
2982 default:
2983 return FALSE;
2986 return TRUE;
2989 /****************************************************************************
2990 Helper function to read value from enumerator setting
2991 ****************************************************************************/
2992 static int read_enum_value(const struct setting *pset)
2994 int val;
2996 switch(pset->enumerator.store_size) {
2997 case sizeof(int):
2998 val = *((int *)pset->enumerator.pvalue);
2999 break;
3000 case sizeof(char):
3001 val = *((char *)pset->enumerator.pvalue);
3002 break;
3003 case sizeof(short):
3004 val = *((short *)pset->enumerator.pvalue);
3005 break;
3006 default:
3007 log_error("Illegal enum store size %d, can't read value", pset->enumerator.store_size);
3008 return 0;
3011 return val;
3014 /****************************************************************************
3015 Set the setting to 'val'. Returns TRUE on success. If it fails, the
3016 reason of the failure is available in the optionnal parameter
3017 'reject_msg'.
3018 ****************************************************************************/
3019 bool setting_enum_set(struct setting *pset, const char *val,
3020 struct connection *caller, char *reject_msg,
3021 size_t reject_msg_len)
3023 int int_val;
3025 if (!setting_is_changeable(pset, caller, reject_msg, reject_msg_len)) {
3026 return FALSE;
3029 if (!setting_enum_validate_base(pset, val, &int_val, caller,
3030 reject_msg, reject_msg_len)) {
3031 return FALSE;
3034 if (!set_enum_value(pset, int_val)) {
3035 log_error("Illegal enumerator value size %d for %s",
3036 pset->enumerator.store_size, val);
3037 return FALSE;
3040 return TRUE;
3043 /****************************************************************************
3044 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3045 the reason of the failure is available in the optionnal parameter
3046 'reject_msg'.
3047 ****************************************************************************/
3048 bool setting_enum_validate(const struct setting *pset, const char *val,
3049 struct connection *caller, char *reject_msg,
3050 size_t reject_msg_len)
3052 int int_val;
3054 return setting_enum_validate_base(pset, val, &int_val, caller,
3055 reject_msg, reject_msg_len);
3058 /****************************************************************************
3059 Convert the integer to the long support string representation of an
3060 enumerator. This function must match the secfile_enum_name_data_fn_t type.
3061 ****************************************************************************/
3062 static const char *setting_bitwise_secfile_str(secfile_data_t data, int bit)
3064 const struct sset_val_name *name =
3065 ((const struct setting *) data)->bitwise.name(bit);
3067 return (NULL != name ? name->support : NULL);
3070 /****************************************************************************
3071 Convert the bit number to its string representation.
3072 Return NULL if 'bit' is not a valid bit.
3073 ****************************************************************************/
3074 const char *setting_bitwise_bit(const struct setting *pset,
3075 int bit, bool pretty)
3077 const struct sset_val_name *name;
3079 fc_assert_ret_val(SSET_BITWISE == pset->stype, NULL);
3080 name = pset->bitwise.name(bit);
3081 if (NULL == name) {
3082 return NULL;
3083 } else if (pretty) {
3084 return _(name->pretty);
3085 } else {
3086 return name->support;
3090 /****************************************************************************
3091 Compute the string representation of the value for this bitwise setting.
3092 ****************************************************************************/
3093 static const char *setting_bitwise_to_str(const struct setting *pset,
3094 unsigned value, bool pretty,
3095 char *buf, size_t buf_len)
3097 const struct sset_val_name *name;
3098 char *old_buf = buf;
3099 int bit;
3101 if (pretty) {
3102 char buf2[64];
3103 struct astring astr = ASTRING_INIT;
3104 struct strvec *vec = strvec_new();
3105 size_t len;
3107 for (bit = 0; (name = pset->bitwise.name(bit)); bit++) {
3108 if ((1 << bit) & value) {
3109 /* TRANS: only emphasizing a string. */
3110 fc_snprintf(buf2, sizeof(buf2), _("\"%s\""), Q_(name->pretty));
3111 strvec_append(vec, buf2);
3115 if (0 == strvec_size(vec)) {
3116 /* No value. */
3117 fc_assert(0 == value);
3118 /* TRANS: Bitwise setting has no bits set. */
3119 fc_strlcpy(buf, _("empty value"), buf_len);
3120 strvec_destroy(vec);
3121 return buf;
3124 strvec_to_and_list(vec, &astr);
3125 strvec_destroy(vec);
3126 fc_strlcpy(buf, astr_str(&astr), buf_len);
3127 astr_free(&astr);
3128 fc_strlcat(buf, " (", buf_len);
3129 len = strlen(buf);
3130 buf += len;
3131 buf_len -= len;
3134 /* Long support part. */
3135 buf[0] = '\0';
3136 for (bit = 0; (name = pset->bitwise.name(bit)); bit++) {
3137 if ((1 << bit) & value) {
3138 if ('\0' != buf[0]) {
3139 fc_strlcat(buf, "|", buf_len);
3141 fc_strlcat(buf, name->support, buf_len);
3145 if (pretty) {
3146 fc_strlcat(buf, ")", buf_len);
3148 return old_buf;
3151 /****************************************************************************
3152 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3153 the reason of the failure is available in the optionnal parameter
3154 'reject_msg'.
3156 FIXME: also check the access level of pconn.
3157 ****************************************************************************/
3158 static bool setting_bitwise_validate_base(const struct setting *pset,
3159 const char *val,
3160 unsigned *pint_val,
3161 struct connection *caller,
3162 char *reject_msg,
3163 size_t reject_msg_len)
3165 char buf[256];
3166 const char *p;
3167 int bit;
3169 if (SSET_BITWISE != pset->stype) {
3170 settings_snprintf(reject_msg, reject_msg_len,
3171 _("This setting is not a bitwise."));
3172 return FALSE;
3175 *pint_val = 0;
3177 /* Value names are separated by '|'. */
3178 do {
3179 p = strchr(val, '|');
3180 if (NULL != p) {
3181 p++;
3182 fc_strlcpy(buf, val, MIN(p - val, sizeof(buf)));
3183 } else {
3184 /* Last segment, full copy. */
3185 sz_strlcpy(buf, val);
3187 remove_leading_trailing_spaces(buf);
3188 if (NULL == p && '\0' == buf[0] && 0 == *pint_val) {
3189 /* Empty string = value 0. */
3190 break;
3191 } else if (!setting_match_prefix(pset->bitwise.name, buf, &bit,
3192 reject_msg, reject_msg_len)) {
3193 return FALSE;
3195 *pint_val |= 1 << bit;
3196 val = p;
3197 } while (NULL != p);
3199 return (NULL == pset->bitwise.validate
3200 || pset->bitwise.validate(*pint_val, caller,
3201 reject_msg, reject_msg_len));
3204 /****************************************************************************
3205 Set the setting to 'val'. Returns TRUE on success. If it fails, the
3206 reason of the failure is available in the optionnal parameter
3207 'reject_msg'.
3208 ****************************************************************************/
3209 bool setting_bitwise_set(struct setting *pset, const char *val,
3210 struct connection *caller, char *reject_msg,
3211 size_t reject_msg_len)
3213 unsigned int_val;
3215 if (!setting_is_changeable(pset, caller, reject_msg, reject_msg_len)
3216 || !setting_bitwise_validate_base(pset, val, &int_val, caller,
3217 reject_msg, reject_msg_len)) {
3218 return FALSE;
3221 *pset->bitwise.pvalue = int_val;
3222 return TRUE;
3225 /****************************************************************************
3226 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3227 the reason of the failure is available in the optionnal parameter
3228 'reject_msg'.
3229 ****************************************************************************/
3230 bool setting_bitwise_validate(const struct setting *pset, const char *val,
3231 struct connection *caller, char *reject_msg,
3232 size_t reject_msg_len)
3234 unsigned int_val;
3236 return setting_bitwise_validate_base(pset, val, &int_val, caller,
3237 reject_msg, reject_msg_len);
3240 /****************************************************************************
3241 Compute the name of the current value of the setting.
3242 ****************************************************************************/
3243 const char *setting_value_name(const struct setting *pset, bool pretty,
3244 char *buf, size_t buf_len)
3246 fc_assert_ret_val(NULL != pset, NULL);
3247 fc_assert_ret_val(NULL != buf, NULL);
3248 fc_assert_ret_val(0 < buf_len, NULL);
3250 switch (pset->stype) {
3251 case SSET_BOOL:
3252 return setting_bool_to_str(pset, *pset->boolean.pvalue,
3253 pretty, buf, buf_len);
3254 case SSET_INT:
3255 return setting_int_to_str(pset, *pset->integer.pvalue,
3256 pretty, buf, buf_len);
3257 case SSET_STRING:
3258 return setting_str_to_str(pset, pset->string.value,
3259 pretty, buf, buf_len);
3260 case SSET_ENUM:
3261 return setting_enum_to_str(pset, read_enum_value(pset),
3262 pretty, buf, buf_len);
3263 case SSET_BITWISE:
3264 return setting_bitwise_to_str(pset, *pset->bitwise.pvalue,
3265 pretty, buf, buf_len);
3268 log_error("%s(): Setting \"%s\" (nb %d) not handled in switch statement.",
3269 __FUNCTION__, setting_name(pset), setting_number(pset));
3270 return NULL;
3273 /****************************************************************************
3274 Compute the name of the default value of the setting.
3275 ****************************************************************************/
3276 const char *setting_default_name(const struct setting *pset, bool pretty,
3277 char *buf, size_t buf_len)
3279 fc_assert_ret_val(NULL != pset, NULL);
3280 fc_assert_ret_val(NULL != buf, NULL);
3281 fc_assert_ret_val(0 < buf_len, NULL);
3283 switch (pset->stype) {
3284 case SSET_BOOL:
3285 return setting_bool_to_str(pset, pset->boolean.default_value,
3286 pretty, buf, buf_len);
3287 case SSET_INT:
3288 return setting_int_to_str(pset, pset->integer.default_value,
3289 pretty, buf, buf_len);
3290 case SSET_STRING:
3291 return setting_str_to_str(pset, pset->string.default_value,
3292 pretty, buf, buf_len);
3293 case SSET_ENUM:
3294 return setting_enum_to_str(pset, pset->enumerator.default_value,
3295 pretty, buf, buf_len);
3296 case SSET_BITWISE:
3297 return setting_bitwise_to_str(pset, pset->bitwise.default_value,
3298 pretty, buf, buf_len);
3301 log_error("%s(): Setting \"%s\" (nb %d) not handled in switch statement.",
3302 __FUNCTION__, setting_name(pset), setting_number(pset));
3303 return NULL;
3306 /****************************************************************************
3307 Update the setting to the default value
3308 ****************************************************************************/
3309 static void setting_set_to_default(struct setting *pset)
3311 switch (pset->stype) {
3312 case SSET_BOOL:
3313 (*pset->boolean.pvalue) = pset->boolean.default_value;
3314 break;
3315 case SSET_INT:
3316 (*pset->integer.pvalue) = pset->integer.default_value;
3317 break;
3318 case SSET_STRING:
3319 fc_strlcpy(pset->string.value, pset->string.default_value,
3320 pset->string.value_size);
3321 break;
3322 case SSET_ENUM:
3323 set_enum_value(pset, pset->enumerator.default_value);
3324 break;
3325 case SSET_BITWISE:
3326 (*pset->bitwise.pvalue) = pset->bitwise.default_value;
3327 break;
3331 /********************************************************************
3332 Execute the action callback if needed.
3333 *********************************************************************/
3334 void setting_action(const struct setting *pset)
3336 if (pset->action != NULL) {
3337 pset->action(pset);
3341 /**************************************************************************
3342 Load game settings from ruleset file 'game.ruleset'.
3343 **************************************************************************/
3344 bool settings_ruleset(struct section_file *file, const char *section,
3345 bool act)
3347 const char *name;
3348 int j;
3350 /* Unlock all settings. */
3351 settings_iterate(SSET_ALL, pset) {
3352 setting_lock_set(pset, FALSE);
3353 setting_set_to_default(pset);
3354 } settings_iterate_end;
3356 /* settings */
3357 if (NULL == secfile_section_by_name(file, section)) {
3358 /* no settings in ruleset file */
3359 log_verbose("no [%s] section for game settings in %s", section,
3360 secfile_name(file));
3361 return FALSE;
3364 for (j = 0; (name = secfile_lookup_str_default(file, NULL, "%s.set%d.name",
3365 section, j)); j++) {
3366 char path[256];
3367 fc_snprintf(path, sizeof(path), "%s.set%d", section, j);
3369 if (!setting_ruleset_one(file, name, path)) {
3370 log_error("unknown setting in '%s': %s", secfile_name(file), name);
3374 /* Execute all setting actions to consider actions due to the
3375 * default values. */
3376 if (act) {
3377 settings_iterate(SSET_ALL, pset) {
3378 setting_action(pset);
3379 } settings_iterate_end;
3382 /* send game settings */
3383 send_server_settings(NULL);
3385 return TRUE;
3388 /**************************************************************************
3389 Set one setting from the game.ruleset file.
3390 **************************************************************************/
3391 static bool setting_ruleset_one(struct section_file *file,
3392 const char *name, const char *path)
3394 struct setting *pset = NULL;
3395 char reject_msg[256], buf[256];
3396 bool lock;
3398 settings_iterate(SSET_ALL, pset_check) {
3399 if (0 == fc_strcasecmp(setting_name(pset_check), name)) {
3400 pset = pset_check;
3401 break;
3403 } settings_iterate_end;
3405 if (pset == NULL) {
3406 /* no setting found */
3407 return FALSE;
3410 switch (pset->stype) {
3411 case SSET_BOOL:
3413 int ival;
3414 bool val;
3416 /* Allow string with same boolean representation as accepted on
3417 * server command line */
3418 if (secfile_lookup_enum_data(file, &ival, FALSE,
3419 setting_bool_secfile_str, pset,
3420 "%s.value", path)) {
3421 val = (ival != 0);
3422 } else if (!secfile_lookup_bool(file, &val, "%s.value", path)) {
3423 log_error("Can't read value for setting '%s': %s", name,
3424 secfile_error());
3425 break;
3427 if (val != *pset->boolean.pvalue) {
3428 if (NULL == pset->boolean.validate
3429 || pset->boolean.validate(val, NULL, reject_msg,
3430 sizeof(reject_msg))) {
3431 *pset->boolean.pvalue = val;
3432 log_normal(_("Ruleset: '%s' has been set to %s."),
3433 setting_name(pset),
3434 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3435 } else {
3436 log_error("%s", reject_msg);
3440 break;
3442 case SSET_INT:
3444 int val;
3446 if (!secfile_lookup_int(file, &val, "%s.value", path)) {
3447 log_error("Can't read value for setting '%s': %s", name,
3448 secfile_error());
3449 } else if (val != *pset->integer.pvalue) {
3450 if (setting_int_set(pset, val, NULL, reject_msg,
3451 sizeof(reject_msg))) {
3452 log_normal(_("Ruleset: '%s' has been set to %s."),
3453 setting_name(pset),
3454 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3455 } else {
3456 log_error("%s", reject_msg);
3460 break;
3462 case SSET_STRING:
3464 const char *val = secfile_lookup_str(file, "%s.value", path);
3466 if (NULL == val) {
3467 log_error("Can't read value for setting '%s': %s", name,
3468 secfile_error());
3469 } else if (0 != strcmp(val, pset->string.value)) {
3470 if (setting_str_set(pset, val, NULL, reject_msg,
3471 sizeof(reject_msg))) {
3472 log_normal(_("Ruleset: '%s' has been set to %s."),
3473 setting_name(pset),
3474 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3475 } else {
3476 log_error("%s", reject_msg);
3480 break;
3482 case SSET_ENUM:
3484 int val;
3486 if (!secfile_lookup_enum_data(file, &val, FALSE,
3487 setting_enum_secfile_str, pset,
3488 "%s.value", path)) {
3489 log_error("Can't read value for setting '%s': %s",
3490 name, secfile_error());
3491 } else if (val != read_enum_value(pset)) {
3492 if (NULL == pset->enumerator.validate
3493 || pset->enumerator.validate(val, NULL, reject_msg,
3494 sizeof(reject_msg))) {
3495 set_enum_value(pset, val);
3496 log_normal(_("Ruleset: '%s' has been set to %s."),
3497 setting_name(pset),
3498 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3499 } else {
3500 log_error("%s", reject_msg);
3504 break;
3506 case SSET_BITWISE:
3508 int val;
3510 if (!secfile_lookup_enum_data(file, &val, TRUE,
3511 setting_bitwise_secfile_str, pset,
3512 "%s.value", path)) {
3513 log_error("Can't read value for setting '%s': %s",
3514 name, secfile_error());
3515 } else if (val != *pset->bitwise.pvalue) {
3516 if (NULL == pset->bitwise.validate
3517 || pset->bitwise.validate((unsigned) val, NULL,
3518 reject_msg, sizeof(reject_msg))) {
3519 *pset->bitwise.pvalue = val;
3520 log_normal(_("Ruleset: '%s' has been set to %s."),
3521 setting_name(pset),
3522 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3523 } else {
3524 log_error("%s", reject_msg);
3528 break;
3531 /* set lock */
3532 lock = secfile_lookup_bool_default(file, FALSE, "%s.lock", path);
3534 if (lock) {
3535 /* set lock */
3536 setting_lock_set(pset, lock);
3537 log_normal(_("Ruleset: '%s' has been locked by the ruleset."),
3538 setting_name(pset));
3541 return TRUE;
3544 /**************************************************************************
3545 Returns whether the setting has been changed (is not default).
3546 **************************************************************************/
3547 bool setting_changed(const struct setting *pset)
3549 switch (setting_type(pset)) {
3550 case SSET_BOOL:
3551 return (*pset->boolean.pvalue != pset->boolean.default_value);
3552 case SSET_INT:
3553 return (*pset->integer.pvalue != pset->integer.default_value);
3554 case SSET_STRING:
3555 return (0 != strcmp(pset->string.value, pset->string.default_value));
3556 case SSET_ENUM:
3557 return (read_enum_value(pset) != pset->enumerator.default_value);
3558 case SSET_BITWISE:
3559 return (*pset->bitwise.pvalue != pset->bitwise.default_value);
3562 log_error("%s(): Setting \"%s\" (nb %d) not handled in switch statement.",
3563 __FUNCTION__, setting_name(pset), setting_number(pset));
3564 return FALSE;
3567 /**************************************************************************
3568 Returns if the setting is locked by the ruleset.
3569 **************************************************************************/
3570 bool setting_locked(const struct setting *pset)
3572 return pset->locked;
3575 /**************************************************************************
3576 Set the value for the lock of a setting.
3577 **************************************************************************/
3578 void setting_lock_set(struct setting *pset, bool lock)
3580 pset->locked = lock;
3583 /**************************************************************************
3584 Save the setting value of the current game.
3585 **************************************************************************/
3586 static void setting_game_set(struct setting *pset, bool init)
3588 switch (setting_type(pset)) {
3589 case SSET_BOOL:
3590 pset->boolean.game_value = *pset->boolean.pvalue;
3591 break;
3593 case SSET_INT:
3594 pset->integer.game_value = *pset->integer.pvalue;
3595 break;
3597 case SSET_STRING:
3598 if (init) {
3599 pset->string.game_value
3600 = fc_calloc(1, pset->string.value_size
3601 * sizeof(pset->string.game_value));
3603 fc_strlcpy(pset->string.game_value, pset->string.value,
3604 pset->string.value_size);
3605 break;
3607 case SSET_ENUM:
3608 pset->enumerator.game_value = read_enum_value(pset);
3609 break;
3611 case SSET_BITWISE:
3612 pset->bitwise.game_value = *pset->bitwise.pvalue;
3613 break;
3617 /**************************************************************************
3618 Free the memory used for the settings at game start.
3619 **************************************************************************/
3620 static void setting_game_free(struct setting *pset)
3622 if (setting_type(pset) == SSET_STRING) {
3623 FC_FREE(pset->string.game_value);
3627 /**************************************************************************
3628 Restore the setting to the value used at the start of the current game.
3629 **************************************************************************/
3630 static void setting_game_restore(struct setting *pset)
3632 char reject_msg[256] = "", buf[256];
3633 bool res = FALSE;
3635 if (!setting_is_changeable(pset, NULL, reject_msg, sizeof(reject_msg))) {
3636 log_debug("Can't restore '%s': %s", setting_name(pset),
3637 reject_msg);
3638 return;
3641 switch (setting_type(pset)) {
3642 case SSET_BOOL:
3643 res = (NULL != setting_bool_to_str(pset, pset->boolean.game_value,
3644 FALSE, buf, sizeof(buf))
3645 && setting_bool_set(pset, buf, NULL, reject_msg,
3646 sizeof(reject_msg)));
3647 break;
3649 case SSET_INT:
3650 res = setting_int_set(pset, pset->integer.game_value, NULL, reject_msg,
3651 sizeof(reject_msg));
3652 break;
3654 case SSET_STRING:
3655 res = setting_str_set(pset, pset->string.game_value, NULL, reject_msg,
3656 sizeof(reject_msg));
3657 break;
3659 case SSET_ENUM:
3660 res = (NULL != setting_enum_to_str(pset, pset->enumerator.game_value,
3661 FALSE, buf, sizeof(buf))
3662 && setting_enum_set(pset, buf, NULL, reject_msg,
3663 sizeof(reject_msg)));
3664 break;
3666 case SSET_BITWISE:
3667 res = (NULL != setting_bitwise_to_str(pset, pset->bitwise.game_value,
3668 FALSE, buf, sizeof(buf))
3669 && setting_bitwise_set(pset, buf, NULL, reject_msg,
3670 sizeof(reject_msg)));
3671 break;
3674 if (!res) {
3675 log_error("Error restoring setting '%s' to the value from game start: "
3676 "%s", setting_name(pset), reject_msg);
3680 /**************************************************************************
3681 Save setting values at the start of the game.
3682 **************************************************************************/
3683 void settings_game_start(void)
3685 settings_iterate(SSET_ALL, pset) {
3686 setting_game_set(pset, FALSE);
3687 } settings_iterate_end;
3689 /* Settings from the start of the game are saved. */
3690 game.server.settings_gamestart_valid = TRUE;
3693 /********************************************************************
3694 Save game settings.
3695 *********************************************************************/
3696 void settings_game_save(struct section_file *file, const char *section)
3698 int set_count = 0;
3700 settings_iterate(SSET_ALL, pset) {
3701 secfile_insert_str(file, setting_name(pset),
3702 "%s.set%d.name", section, set_count);
3703 switch (setting_type(pset)) {
3704 case SSET_BOOL:
3705 secfile_insert_bool(file, *pset->boolean.pvalue,
3706 "%s.set%d.value", section, set_count);
3707 secfile_insert_bool(file, pset->boolean.game_value,
3708 "%s.set%d.gamestart", section, set_count);
3709 break;
3710 case SSET_INT:
3711 secfile_insert_int(file, *pset->integer.pvalue,
3712 "%s.set%d.value", section, set_count);
3713 secfile_insert_int(file, pset->integer.game_value,
3714 "%s.set%d.gamestart", section, set_count);
3715 break;
3716 case SSET_STRING:
3717 secfile_insert_str(file, pset->string.value,
3718 "%s.set%d.value", section, set_count);
3719 secfile_insert_str(file, pset->string.game_value,
3720 "%s.set%d.gamestart", section, set_count);
3721 break;
3722 case SSET_ENUM:
3723 secfile_insert_enum_data(file, read_enum_value(pset), FALSE,
3724 setting_enum_secfile_str, pset,
3725 "%s.set%d.value", section, set_count);
3726 secfile_insert_enum_data(file, pset->enumerator.game_value, FALSE,
3727 setting_enum_secfile_str, pset,
3728 "%s.set%d.gamestart", section, set_count);
3729 break;
3730 case SSET_BITWISE:
3731 secfile_insert_enum_data(file, *pset->bitwise.pvalue, TRUE,
3732 setting_bitwise_secfile_str, pset,
3733 "%s.set%d.value", section, set_count);
3734 secfile_insert_enum_data(file, pset->bitwise.game_value, TRUE,
3735 setting_bitwise_secfile_str, pset,
3736 "%s.set%d.gamestart", section, set_count);
3737 break;
3739 set_count++;
3740 } settings_iterate_end;
3742 secfile_insert_int(file, set_count, "%s.set_count", section);
3743 secfile_insert_bool(file, game.server.settings_gamestart_valid,
3744 "%s.gamestart_valid", section);
3747 /********************************************************************
3748 Restore all settings from a savegame.
3749 *********************************************************************/
3750 void settings_game_load(struct section_file *file, const char *section)
3752 const char *name;
3753 char reject_msg[256], buf[256];
3754 int i, set_count;
3755 int oldcitymindist = game.info.citymindist; /* backwards compat, see below */
3757 /* Compatibility with savegames created with older versions is usually
3758 * handled as conversions in savegame2.c compat_load_<version>() */
3760 if (!secfile_lookup_int(file, &set_count, "%s.set_count", section)) {
3761 /* Old savegames and scenarios doesn't contain this, not an error. */
3762 log_verbose("Can't read the number of settings in the save file.");
3763 return;
3766 /* Check if the saved settings are valid settings from game start. */
3767 game.server.settings_gamestart_valid
3768 = secfile_lookup_bool_default(file, FALSE, "%s.gamestart_valid",
3769 section);
3771 for (i = 0; i < set_count; i++) {
3772 name = secfile_lookup_str(file, "%s.set%d.name", section, i);
3774 settings_iterate(SSET_ALL, pset) {
3775 if (fc_strcasecmp(setting_name(pset), name) != 0) {
3776 continue;
3779 /* Load the current value of the setting. */
3780 switch (pset->stype) {
3781 case SSET_BOOL:
3783 bool val;
3785 if (!secfile_lookup_bool(file, &val, "%s.set%d.value", section,
3786 i)) {
3787 log_verbose("Option '%s' not defined in the savegame: %s", name,
3788 secfile_error());
3789 } else if (val != *pset->boolean.pvalue) {
3790 if (setting_is_changeable(pset, NULL, reject_msg,
3791 sizeof(reject_msg))
3792 && (NULL == pset->boolean.validate
3793 || pset->boolean.validate(val, NULL, reject_msg,
3794 sizeof(reject_msg)))) {
3795 *pset->boolean.pvalue = val;
3796 log_normal(_("Savegame: '%s' has been set to %s."),
3797 setting_name(pset),
3798 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3799 } else {
3800 log_error("Savegame: error restoring '%s' . (%s)",
3801 setting_name(pset), reject_msg);
3805 break;
3807 case SSET_INT:
3809 int val;
3811 if (!secfile_lookup_int(file, &val, "%s.set%d.value", section, i)) {
3812 log_verbose("Option '%s' not defined in the savegame: %s", name,
3813 secfile_error());
3814 } else if (val != *pset->integer.pvalue) {
3815 if (setting_is_changeable(pset, NULL, reject_msg,
3816 sizeof(reject_msg))
3817 && (NULL == pset->integer.validate
3818 || pset->integer.validate(val, NULL, reject_msg,
3819 sizeof(reject_msg)))) {
3820 *pset->integer.pvalue = val;
3821 log_normal(_("Savegame: '%s' has been set to %s."),
3822 setting_name(pset),
3823 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3824 } else {
3825 log_error("Savegame: error restoring '%s' . (%s)",
3826 setting_name(pset), reject_msg);
3830 break;
3832 case SSET_STRING:
3834 const char *val = secfile_lookup_str(file, "%s.set%d.value",
3835 section, i);
3837 if (NULL == val) {
3838 log_verbose("Option '%s' not defined in the savegame: %s", name,
3839 secfile_error());
3840 } else if (0 != strcmp(val, pset->string.value)) {
3841 if (setting_str_set(pset, val, NULL, reject_msg,
3842 sizeof(reject_msg))) {
3843 log_normal(_("Savegame: '%s' has been set to %s."),
3844 setting_name(pset),
3845 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3846 } else {
3847 log_error("Savegame: error restoring '%s' . (%s)",
3848 setting_name(pset), reject_msg);
3852 break;
3854 case SSET_ENUM:
3856 int val;
3858 if (!secfile_lookup_enum_data(file, &val, FALSE,
3859 setting_enum_secfile_str, pset,
3860 "%s.set%d.value", section, i)) {
3861 log_verbose("Option '%s' not defined in the savegame: %s", name,
3862 secfile_error());
3863 } else if (val != read_enum_value(pset)) {
3864 if (setting_is_changeable(pset, NULL, reject_msg,
3865 sizeof(reject_msg))
3866 && (NULL == pset->enumerator.validate
3867 || pset->enumerator.validate(val, NULL, reject_msg,
3868 sizeof(reject_msg)))) {
3869 set_enum_value(pset, val);
3870 log_normal(_("Savegame: '%s' has been set to %s."),
3871 setting_name(pset),
3872 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3873 } else {
3874 log_error("Savegame: error restoring '%s' . (%s)",
3875 setting_name(pset), reject_msg);
3879 break;
3881 case SSET_BITWISE:
3883 int val;
3885 if (!secfile_lookup_enum_data(file, &val, TRUE,
3886 setting_bitwise_secfile_str, pset,
3887 "%s.set%d.value", section, i)) {
3888 log_verbose("Option '%s' not defined in the savegame: %s", name,
3889 secfile_error());
3890 } else if (val != *pset->bitwise.pvalue) {
3891 if (setting_is_changeable(pset, NULL, reject_msg,
3892 sizeof(reject_msg))
3893 && (NULL == pset->bitwise.validate
3894 || pset->bitwise.validate(val, NULL, reject_msg,
3895 sizeof(reject_msg)))) {
3896 *pset->bitwise.pvalue = val;
3897 log_normal(_("Savegame: '%s' has been set to %s."),
3898 setting_name(pset),
3899 setting_value_name(pset, TRUE, buf, sizeof(buf)));
3900 } else {
3901 log_error("Savegame: error restoring '%s' . (%s)",
3902 setting_name(pset), reject_msg);
3906 break;
3909 if (game.server.settings_gamestart_valid) {
3910 /* Load the value of the setting at the start of the game. */
3911 switch (pset->stype) {
3912 case SSET_BOOL:
3913 pset->boolean.game_value =
3914 secfile_lookup_bool_default(file, *pset->boolean.pvalue,
3915 "%s.set%d.gamestart", section, i);
3916 break;
3918 case SSET_INT:
3919 pset->integer.game_value =
3920 secfile_lookup_int_default(file, *pset->integer.pvalue,
3921 "%s.set%d.gamestart", section, i);
3922 break;
3924 case SSET_STRING:
3925 fc_strlcpy(pset->string.game_value,
3926 secfile_lookup_str_default(file, pset->string.value,
3927 "%s.set%d.gamestart",
3928 section, i),
3929 pset->string.value_size);
3930 break;
3932 case SSET_ENUM:
3933 pset->enumerator.game_value =
3934 secfile_lookup_enum_default_data(file,
3935 read_enum_value(pset), FALSE, setting_enum_secfile_str,
3936 pset, "%s.set%d.gamestart", section, i);
3937 break;
3939 case SSET_BITWISE:
3940 pset->bitwise.game_value =
3941 secfile_lookup_enum_default_data(file,
3942 *pset->bitwise.pvalue, TRUE, setting_bitwise_secfile_str,
3943 pset, "%s.set%d.gamestart", section, i);
3944 break;
3947 } settings_iterate_end;
3950 /* Backwards compatibility for pre-2.4 savegames: citymindist=0 used to mean
3951 * take from ruleset min_dist_bw_cities, but that no longer exists.
3952 * This is here rather than in savegame2.c compat functions, as we need
3953 * to have loaded the relevant ruleset to know what to set it to (the
3954 * ruleset and any 'citymindist' setting it contains will have been loaded
3955 * before this function was called). */
3956 if (game.info.citymindist == 0) {
3957 game.info.citymindist = oldcitymindist;
3960 settings_iterate(SSET_ALL, pset) {
3961 /* Have to do this at the end due to dependencies ('aifill' and
3962 * 'maxplayer'). */
3963 setting_action(pset);
3964 } settings_iterate_end;
3967 /**************************************************************************
3968 Reset all settings to the values at game start.
3969 **************************************************************************/
3970 bool settings_game_reset(void)
3972 if (!game.server.settings_gamestart_valid) {
3973 log_debug("No saved settings from the game start available.");
3974 return FALSE;
3977 settings_iterate(SSET_ALL, pset) {
3978 setting_game_restore(pset);
3979 } settings_iterate_end;
3981 return TRUE;
3984 /**************************************************************************
3985 Initialize stuff related to this code module.
3986 **************************************************************************/
3987 void settings_init(bool act)
3989 settings_list_init();
3991 settings_iterate(SSET_ALL, pset) {
3992 setting_lock_set(pset, FALSE);
3993 setting_set_to_default(pset);
3994 setting_game_set(pset, TRUE);
3995 if (act) {
3996 setting_action(pset);
3998 } settings_iterate_end;
4000 settings_list_update();
4003 /********************************************************************
4004 Reset all settings iff they are changeable.
4005 *********************************************************************/
4006 void settings_reset(void)
4008 settings_iterate(SSET_ALL, pset) {
4009 if (setting_is_changeable(pset, NULL, NULL, 0)) {
4010 setting_set_to_default(pset);
4011 setting_action(pset);
4013 } settings_iterate_end;
4016 /**************************************************************************
4017 Update stuff every turn that is related to this code module. Run this
4018 on turn end.
4019 **************************************************************************/
4020 void settings_turn(void)
4022 /* Nothing at the moment. */
4025 /**************************************************************************
4026 Deinitialize stuff related to this code module.
4027 **************************************************************************/
4028 void settings_free(void)
4030 settings_iterate(SSET_ALL, pset) {
4031 setting_game_free(pset);
4032 } settings_iterate_end;
4034 settings_list_free();
4037 /****************************************************************************
4038 Returns the total number of settings.
4039 ****************************************************************************/
4040 int settings_number(void)
4042 return SETTINGS_NUM;
4045 /****************************************************************************
4046 Tell the client about just one server setting. Call this after a setting
4047 is saved.
4048 ****************************************************************************/
4049 void send_server_setting(struct conn_list *dest, const struct setting *pset)
4051 if (!dest) {
4052 dest = game.est_connections;
4055 #define PACKET_COMMON_INIT(packet, pset, pconn) \
4056 memset(&packet, 0, sizeof(packet)); \
4057 packet.id = setting_number(pset); \
4058 packet.is_visible = setting_is_visible(pset, pconn); \
4059 packet.is_changeable = setting_is_changeable(pset, pconn, NULL, 0); \
4060 packet.initial_setting = game.info.is_new_game;
4062 switch (setting_type(pset)) {
4063 case SSET_BOOL:
4065 struct packet_server_setting_bool packet;
4067 conn_list_iterate(dest, pconn) {
4068 PACKET_COMMON_INIT(packet, pset, pconn);
4069 if (packet.is_visible) {
4070 packet.val = *pset->boolean.pvalue;
4071 packet.default_val = pset->boolean.default_value;
4073 send_packet_server_setting_bool(pconn, &packet);
4074 } conn_list_iterate_end;
4076 break;
4077 case SSET_INT:
4079 struct packet_server_setting_int packet;
4081 conn_list_iterate(dest, pconn) {
4082 PACKET_COMMON_INIT(packet, pset, pconn);
4083 if (packet.is_visible) {
4084 packet.val = *pset->integer.pvalue;
4085 packet.default_val = pset->integer.default_value;
4086 packet.min_val = pset->integer.min_value;
4087 packet.max_val = pset->integer.max_value;
4089 send_packet_server_setting_int(pconn, &packet);
4090 } conn_list_iterate_end;
4092 break;
4093 case SSET_STRING:
4095 struct packet_server_setting_str packet;
4097 conn_list_iterate(dest, pconn) {
4098 PACKET_COMMON_INIT(packet, pset, pconn);
4099 if (packet.is_visible) {
4100 sz_strlcpy(packet.val, pset->string.value);
4101 sz_strlcpy(packet.default_val, pset->string.default_value);
4103 send_packet_server_setting_str(pconn, &packet);
4104 } conn_list_iterate_end;
4106 break;
4107 case SSET_ENUM:
4109 struct packet_server_setting_enum packet;
4110 const struct sset_val_name *val_name;
4111 int i;
4113 conn_list_iterate(dest, pconn) {
4114 PACKET_COMMON_INIT(packet, pset, pconn);
4115 if (packet.is_visible) {
4116 packet.val = read_enum_value(pset);
4117 packet.default_val = pset->enumerator.default_value;
4118 for (i = 0; (val_name = pset->enumerator.name(i)); i++) {
4119 sz_strlcpy(packet.support_names[i], val_name->support);
4120 /* Send untranslated string */
4121 sz_strlcpy(packet.pretty_names[i], val_name->pretty);
4123 packet.values_num = i;
4124 fc_assert(i <= ARRAY_SIZE(packet.support_names));
4125 fc_assert(i <= ARRAY_SIZE(packet.pretty_names));
4127 send_packet_server_setting_enum(pconn, &packet);
4128 } conn_list_iterate_end;
4130 break;
4131 case SSET_BITWISE:
4133 struct packet_server_setting_bitwise packet;
4134 const struct sset_val_name *val_name;
4135 int i;
4137 conn_list_iterate(dest, pconn) {
4138 PACKET_COMMON_INIT(packet, pset, pconn);
4139 if (packet.is_visible) {
4140 packet.val = *pset->bitwise.pvalue;
4141 packet.default_val = pset->bitwise.default_value;
4142 for (i = 0; (val_name = pset->bitwise.name(i)); i++) {
4143 sz_strlcpy(packet.support_names[i], val_name->support);
4144 /* Send untranslated string */
4145 sz_strlcpy(packet.pretty_names[i], val_name->pretty);
4147 packet.bits_num = i;
4148 fc_assert(i <= ARRAY_SIZE(packet.support_names));
4149 fc_assert(i <= ARRAY_SIZE(packet.pretty_names));
4151 send_packet_server_setting_bitwise(pconn, &packet);
4152 } conn_list_iterate_end;
4154 break;
4157 #undef PACKET_INIT
4160 /****************************************************************************
4161 Tell the client about all server settings.
4162 ****************************************************************************/
4163 void send_server_settings(struct conn_list *dest)
4165 settings_iterate(SSET_ALL, pset) {
4166 send_server_setting(dest, pset);
4167 } settings_iterate_end;
4170 /****************************************************************************
4171 Send the ALLOW_HACK server settings. Usually called when the access level
4172 of the user changes.
4173 ****************************************************************************/
4174 void send_server_hack_level_settings(struct conn_list *dest)
4176 settings_iterate(SSET_ALL, pset) {
4177 if (!pset->to_client) {
4178 send_server_setting(dest, pset);
4180 } settings_iterate_end;
4183 /****************************************************************************
4184 Tell the client about all server settings.
4185 ****************************************************************************/
4186 void send_server_setting_control(struct connection *pconn)
4188 struct packet_server_setting_control control;
4189 struct packet_server_setting_const setting;
4190 int i;
4192 control.settings_num = SETTINGS_NUM;
4194 /* Fill in the category strings. */
4195 fc_assert(SSET_NUM_CATEGORIES <= ARRAY_SIZE(control.category_names));
4196 control.categories_num = SSET_NUM_CATEGORIES;
4197 for (i = 0; i < SSET_NUM_CATEGORIES; i++) {
4198 /* Send untranslated name */
4199 sz_strlcpy(control.category_names[i], sset_category_name(i));
4202 /* Send off the control packet. */
4203 send_packet_server_setting_control(pconn, &control);
4205 /* Send the constant and common part of the settings. */
4206 settings_iterate(SSET_ALL, pset) {
4207 setting.id = setting_number(pset);
4208 sz_strlcpy(setting.name, setting_name(pset));
4209 /* Send untranslated strings to client */
4210 sz_strlcpy(setting.short_help, setting_short_help(pset));
4211 sz_strlcpy(setting.extra_help, setting_extra_help(pset));
4212 setting.category = pset->scategory;
4214 send_packet_server_setting_const(pconn, &setting);
4215 } settings_iterate_end;
4218 /*****************************************************************************
4219 Initialise sorted settings.
4220 *****************************************************************************/
4221 static void settings_list_init(void)
4223 struct setting *pset;
4224 int i;
4226 fc_assert_ret(setting_sorted.init == FALSE);
4228 /* Do it for all values of enum sset_level. */
4229 for (i = 0; i < OLEVELS_NUM; i++) {
4230 setting_sorted.level[i] = setting_list_new();
4233 for (i = 0; (pset = setting_by_number(i)); i++) {
4234 /* Add the setting to the list of all settings. */
4235 setting_list_append(setting_sorted.level[SSET_ALL], pset);
4237 switch (setting_level(pset)) {
4238 case SSET_NONE:
4239 /* No setting should be in this level. */
4240 fc_assert_msg(setting_level(pset) != SSET_NONE,
4241 "No setting level defined for '%s'.", setting_name(pset));
4242 break;
4243 case SSET_ALL:
4244 /* Done above - list of all settings. */
4245 break;
4246 case SSET_VITAL:
4247 setting_list_append(setting_sorted.level[SSET_VITAL], pset);
4248 break;
4249 case SSET_SITUATIONAL:
4250 setting_list_append(setting_sorted.level[SSET_SITUATIONAL], pset);
4251 break;
4252 case SSET_RARE:
4253 setting_list_append(setting_sorted.level[SSET_RARE], pset);
4254 break;
4255 case SSET_CHANGED:
4256 case SSET_LOCKED:
4257 /* This is done in settings_list_update. */
4258 break;
4259 case OLEVELS_NUM:
4260 /* No setting should be in this level. */
4261 fc_assert_msg(setting_level(pset) != OLEVELS_NUM,
4262 "Invalid setting level for '%s' (%s).",
4263 setting_name(pset), sset_level_name(setting_level(pset)));
4264 break;
4268 /* Sort the lists. */
4269 for (i = 0; i < OLEVELS_NUM; i++) {
4270 setting_list_sort(setting_sorted.level[i], settings_list_cmp);
4273 setting_sorted.init = TRUE;
4276 /*****************************************************************************
4277 Update sorted settings (changed and locked values).
4278 *****************************************************************************/
4279 void settings_list_update(void)
4281 struct setting *pset;
4282 int i;
4284 fc_assert_ret(setting_sorted.init == TRUE);
4286 /* Clear the lists for changed and locked values. */
4287 setting_list_clear(setting_sorted.level[SSET_CHANGED]);
4288 setting_list_clear(setting_sorted.level[SSET_LOCKED]);
4290 /* Refill them. */
4291 for (i = 0; (pset = setting_by_number(i)); i++) {
4292 if (setting_changed(pset)) {
4293 setting_list_append(setting_sorted.level[SSET_CHANGED], pset);
4295 if (setting_locked(pset)) {
4296 setting_list_append(setting_sorted.level[SSET_LOCKED], pset);
4300 /* Sort them. */
4301 setting_list_sort(setting_sorted.level[SSET_CHANGED], settings_list_cmp);
4302 setting_list_sort(setting_sorted.level[SSET_LOCKED], settings_list_cmp);
4305 /*****************************************************************************
4306 Update sorted settings (changed and locked values).
4307 *****************************************************************************/
4308 int settings_list_cmp(const struct setting *const *ppset1,
4309 const struct setting *const *ppset2)
4311 const struct setting *pset1 = *ppset1;
4312 const struct setting *pset2 = *ppset2;
4314 return fc_strcasecmp(setting_name(pset1), setting_name(pset2));
4317 /*****************************************************************************
4318 Get a settings list of a certain level. Call settings_list_update() before
4319 if something was changed.
4320 *****************************************************************************/
4321 struct setting_list *settings_list_get(enum sset_level level)
4323 fc_assert_ret_val(setting_sorted.init == TRUE, NULL);
4324 fc_assert_ret_val(setting_sorted.level[level] != NULL, NULL);
4325 fc_assert_ret_val(sset_level_is_valid(level), NULL);
4327 return setting_sorted.level[level];
4330 /*****************************************************************************
4331 Free sorted settings.
4332 *****************************************************************************/
4333 static void settings_list_free(void)
4335 int i;
4337 fc_assert_ret(setting_sorted.init == TRUE);
4339 /* Free the lists. */
4340 for (i = 0; i < OLEVELS_NUM; i++) {
4341 setting_list_destroy(setting_sorted.level[i]);
4344 setting_sorted.init = FALSE;