OpenTTD Source: src/settings.cpp Source File

OpenTTD Source 15.0-RC2

settings.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
24#include "stdafx.h"
25#include <charconv>
26#include "core/string_consumer.hpp"
27#include "settings_table.h"
28#include "debug.h"
29#include "currency.h"
30#include "network/network.h"
31#include "network/network_func.h"
32#include "network/core/config.h"
33#include "command_func.h"
34#include "console_func.h"
35#include "genworld.h"
36#include "string_func.h"
37#include "strings_func.h"
38#include "window_func.h"
39#include "company_func.h"
40#include "rev.h"
41#include "error.h"
42#include "gamelog.h"
43#include "settings_func.h"
44#include "ini_type.h"
45#include "ai/ai_config.hpp"
46#include "game/game_config.hpp"
47#include "newgrf_config.h"
48#include "picker_func.h"
49#include "newgrf_badge_config.h"
50#include "base_media_base.h"
51#include "base_media_graphics.h"
52#include "fios.h"
53#include "fileio_func.h"
54#include "settings_cmd.h"
55
56#include "table/strings.h"
57
58#include "safeguards.h"
59
60 ClientSettings _settings_client;
61 GameSettings _settings_game;
62 GameSettings _settings_newgame;
63 VehicleDefaultSettings _old_vds;
64std::string _config_file;
65std::string _private_file;
66std::string _secrets_file;
67std::string _favs_file;
68
69 static ErrorList _settings_error_list;
70
81 static auto &GenericSettingTables()
82{
83 static const SettingTable _generic_setting_tables[] = {
84 _difficulty_settings,
85 _economy_settings,
86 _game_settings,
87 _gui_settings,
88 _linkgraph_settings,
89 _locale_settings,
90 _multimedia_settings,
91 _network_settings,
92 _news_display_settings,
93 _pathfinding_settings,
94 _script_settings,
95 _world_settings,
96 };
97 return _generic_setting_tables;
98}
99
103 static auto &PrivateSettingTables()
104{
105 static const SettingTable _private_setting_tables[] = {
106 _network_private_settings,
107 };
108 return _private_setting_tables;
109}
110
114 static auto &SecretSettingTables()
115{
116 static const SettingTable _secrets_setting_tables[] = {
117 _network_secrets_settings,
118 };
119 return _secrets_setting_tables;
120}
121
122using SettingDescProc = void(IniFile &ini, const SettingTable &desc, std::string_view grpname, void *object, bool only_startup);
123using SettingDescProcList = void(IniFile &ini, std::string_view grpname, StringList &list);
124
125static bool IsSignedVarMemType(VarType vt)
126{
127 switch (GetVarMemType(vt)) {
128 case SLE_VAR_I8:
129 case SLE_VAR_I16:
130 case SLE_VAR_I32:
131 case SLE_VAR_I64:
132 return true;
133 }
134 return false;
135}
136
140 class ConfigIniFile : public IniFile {
141private:
142 static inline const IniGroupNameList list_group_names = {
143 "bans",
144 "newgrf",
145 "servers",
146 "server_bind_addresses",
147 "server_authorized_keys",
148 "rcon_authorized_keys",
149 "admin_authorized_keys"
150 };
151
152public:
153 ConfigIniFile(const std::string &filename) : IniFile(list_group_names)
154 {
155 this->LoadFromDisk(filename, NO_DIRECTORY);
156 }
157};
158
166 enum IniFileVersion : uint32_t {
167 IFV_0,
168 IFV_PRIVATE_SECRETS,
169 IFV_GAME_TYPE,
170 IFV_LINKGRAPH_SECONDS,
171 IFV_NETWORK_PRIVATE_SETTINGS,
172
173 IFV_AUTOSAVE_RENAME,
174 IFV_RIGHT_CLICK_CLOSE,
175 IFV_REMOVE_GENERATION_SEED,
176
177 IFV_MAX_VERSION,
178};
179
180 const uint16_t INIFILE_VERSION = (IniFileVersion)(IFV_MAX_VERSION - 1);
181
188std::optional<uint32_t> OneOfManySettingDesc::ParseSingleValue(std::string_view str, std::span<const std::string_view> many)
189{
190 StringConsumer consumer{str};
191 auto digit = consumer.TryReadIntegerBase<uint32_t>(10);
192 /* check if it's an integer */
193 if (digit.has_value()) return digit;
194
195 auto it = std::ranges::find(many, str);
196 if (it == many.end()) return std::nullopt;
197 return static_cast<uint32_t>(it - many.begin());
198}
199
206std::optional<bool> BoolSettingDesc::ParseSingleValue(std::string_view str)
207{
208 if (str == "true" || str == "on" || str == "1") return true;
209 if (str == "false" || str == "off" || str == "0") return false;
210
211 return std::nullopt;
212}
213
221 static std::optional<uint32_t> LookupManyOfMany(std::span<const std::string_view> many, std::string_view str)
222{
223 static const std::string_view separators{" \t|"};
224
225 uint32_t res = 0;
226 StringConsumer consumer{str};
227 while (consumer.AnyBytesLeft()) {
228 /* skip "whitespace" */
229 consumer.SkipUntilCharNotIn(separators);
230
231 std::string_view value = consumer.ReadUntilCharIn(separators);
232 if (value.empty()) break;
233
234 auto r = OneOfManySettingDesc::ParseSingleValue(value, many);
235 if (!r.has_value()) return r;
236
237 SetBit(res, *r); // value found, set it
238 }
239 return res;
240}
241
247 static std::optional<std::vector<uint32_t>> ParseIntList(std::string_view str)
248{
249 bool comma = false; // do we accept comma?
250 std::vector<uint32_t> result;
251
252 StringConsumer consumer{str};
253 for (;;) {
254 consumer.SkipUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE);
255 if (!consumer.AnyBytesLeft()) break;
256 if (comma && consumer.ReadIf(",")) {
257 /* commas are optional, but we only accept one between values */
258 comma = false;
259 continue;
260 }
261 auto v = consumer.TryReadIntegerBase<uint32_t>(10);
262 if (!v.has_value()) return std::nullopt;
263 result.push_back(*v);
264 comma = true;
265 }
266
267 /* If we have read comma but no number after it, fail.
268 * We have read comma when (n != 0) and comma is not allowed */
269 if (!result.empty() && !comma) return std::nullopt;
270
271 return result;
272}
273
282 static bool LoadIntList(std::optional<std::string_view> str, void *array, int nelems, VarType type)
283{
284 size_t elem_size = SlVarSize(type);
285 std::byte *p = static_cast<std::byte *>(array);
286 if (!str.has_value()) {
287 std::fill_n(p, nelems * elem_size, static_cast<std::byte>(0));
288 return true;
289 }
290
291 auto opt_items = ParseIntList(*str);
292 if (!opt_items.has_value() || opt_items->size() != (size_t)nelems) return false;
293
294 for (auto item : *opt_items) {
295 WriteValue(p, type, item);
296 p += elem_size;
297 }
298 return true;
299}
300
310std::string ListSettingDesc::FormatValue(const void *object) const
311{
312 const uint8_t *p = static_cast<const uint8_t *>(GetVariableAddress(object, this->save));
313
314 std::string result;
315 for (size_t i = 0; i != this->save.length; i++) {
316 int64_t v;
317 switch (GetVarMemType(this->save.conv)) {
318 case SLE_VAR_BL:
319 case SLE_VAR_I8: v = *(const int8_t *)p; p += 1; break;
320 case SLE_VAR_U8: v = *(const uint8_t *)p; p += 1; break;
321 case SLE_VAR_I16: v = *(const int16_t *)p; p += 2; break;
322 case SLE_VAR_U16: v = *(const uint16_t *)p; p += 2; break;
323 case SLE_VAR_I32: v = *(const int32_t *)p; p += 4; break;
324 case SLE_VAR_U32: v = *(const uint32_t *)p; p += 4; break;
325 default: NOT_REACHED();
326 }
327 if (i != 0) result += ',';
328 format_append(result, "{}", v);
329 }
330 return result;
331}
332
333std::string OneOfManySettingDesc::FormatSingleValue(uint id) const
334{
335 if (id >= this->many.size()) {
336 return fmt::format("{}", id);
337 }
338 return std::string{this->many[id]};
339}
340
341std::string OneOfManySettingDesc::FormatValue(const void *object) const
342{
343 uint id = (uint)this->Read(object);
344 return this->FormatSingleValue(id);
345}
346
347std::string ManyOfManySettingDesc::FormatValue(const void *object) const
348{
349 uint bitmask = (uint)this->Read(object);
350 if (bitmask == 0) {
351 return {};
352 }
353
354 std::string result;
355 for (uint id : SetBitIterator(bitmask)) {
356 if (!result.empty()) result += '|';
357 result += this->FormatSingleValue(id);
358 }
359 return result;
360}
361
367int32_t IntSettingDesc::ParseValue(std::string_view str) const
368{
369 StringConsumer consumer{str};
370 /* The actual settings value might be int32 or uint32. Read as int64 and just cast away the high bits. */
371 auto value = consumer.TryReadIntegerBase<int64_t>(10);
372 if (!value.has_value()) {
373 _settings_error_list.emplace_back(
374 GetEncodedString(STR_CONFIG_ERROR),
375 GetEncodedString(STR_CONFIG_ERROR_INVALID_VALUE, str, this->GetName()));
376 return this->GetDefaultValue();
377 }
378 if (consumer.AnyBytesLeft()) {
379 _settings_error_list.emplace_back(
380 GetEncodedString(STR_CONFIG_ERROR),
381 GetEncodedString(STR_CONFIG_ERROR_TRAILING_CHARACTERS, this->GetName()));
382 }
383 return static_cast<int32_t>(*value);
384}
385
386int32_t OneOfManySettingDesc::ParseValue(std::string_view str) const
387{
388 auto r = OneOfManySettingDesc::ParseSingleValue(str, this->many);
389 /* if the first attempt of conversion from string to the appropriate value fails,
390 * look if we have defined a converter from old value to new value. */
391 if (!r.has_value() && this->many_cnvt != nullptr) r = this->many_cnvt(str);
392 if (r.has_value()) return *r; // and here goes converted value
393
394 _settings_error_list.emplace_back(
395 GetEncodedString(STR_CONFIG_ERROR),
396 GetEncodedString(STR_CONFIG_ERROR_INVALID_VALUE, str, this->GetName()));
397 return this->GetDefaultValue();
398}
399
400int32_t ManyOfManySettingDesc::ParseValue(std::string_view str) const
401{
402 auto r = LookupManyOfMany(this->many, str);
403 if (r.has_value()) return *r;
404
405 _settings_error_list.emplace_back(
406 GetEncodedString(STR_CONFIG_ERROR),
407 GetEncodedString(STR_CONFIG_ERROR_INVALID_VALUE, str, this->GetName()));
408 return this->GetDefaultValue();
409}
410
411int32_t BoolSettingDesc::ParseValue(std::string_view str) const
412{
413 auto r = BoolSettingDesc::ParseSingleValue(str);
414 if (r.has_value()) return *r;
415
416 _settings_error_list.emplace_back(
417 GetEncodedString(STR_CONFIG_ERROR),
418 GetEncodedString(STR_CONFIG_ERROR_INVALID_VALUE, str, this->GetName()));
419 return this->GetDefaultValue();
420}
421
427 StringID IntSettingDesc::GetTitle() const
428{
429 return this->get_title_cb != nullptr ? this->get_title_cb(*this) : this->str;
430}
431
436 StringID IntSettingDesc::GetHelp() const
437{
438 return this->get_help_cb != nullptr ? this->get_help_cb(*this) : this->str_help;
439}
440
445std::pair<StringParameter, StringParameter> IntSettingDesc::GetValueParams(int32_t value) const
446{
447 if (this->get_value_params_cb != nullptr) {
448 return this->get_value_params_cb(*this, value);
449 }
450
451 if (this->IsBoolSetting()) {
452 return {value != 0 ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF, {}};
453 }
454
455 if (this->flags.Test(SettingFlag::GuiDropdown)) {
456 auto [min_val, _] = this->GetRange();
457 return {this->str_val - min_val + value, value};
458 }
459
460 return {this->str_val + ((value == 0 && this->flags.Test(SettingFlag::GuiZeroIsSpecial)) ? 1 : 0), value};
461}
462
467int32_t IntSettingDesc::GetDefaultValue() const
468{
469 return this->get_def_cb != nullptr ? this->get_def_cb(*this) : this->def;
470}
471
476std::tuple<int32_t, uint32_t> IntSettingDesc::GetRange() const
477{
478 return this->get_range_cb != nullptr ? this->get_range_cb(*this) : std::tuple(this->min, this->max);
479}
480
487 void IntSettingDesc::MakeValueValidAndWrite(const void *object, int32_t val) const
488{
489 this->MakeValueValid(val);
490 this->Write(object, val);
491}
492
502 void IntSettingDesc::MakeValueValid(int32_t &val) const
503{
504 auto [min_val, max_val] = this->GetRange();
505 /* We need to take special care of the uint32_t type as we receive from the function
506 * a signed integer. While here also bail out on 64-bit settings as those are not
507 * supported. Unsigned 8 and 16-bit variables are safe since they fit into a signed
508 * 32-bit variable
509 * TODO: Support 64-bit settings/variables; requires 64 bit over command protocol! */
510 switch (GetVarMemType(this->save.conv)) {
511 case SLE_VAR_NULL: return;
512 case SLE_VAR_BL:
513 case SLE_VAR_I8:
514 case SLE_VAR_U8:
515 case SLE_VAR_I16:
516 case SLE_VAR_U16:
517 case SLE_VAR_I32: {
518 /* Override the minimum value. No value below this->min, except special value 0 */
519 if (!this->flags.Test(SettingFlag::GuiZeroIsSpecial) || val != 0) {
520 if (!this->flags.Test(SettingFlag::GuiDropdown)) {
521 /* Clamp value-type setting to its valid range */
522 val = Clamp(val, min_val, max_val);
523 } else if (val < min_val || val > static_cast<int32_t>(max_val)) {
524 /* Reset invalid discrete setting (where different values change gameplay) to its default value */
525 val = this->GetDefaultValue();
526 }
527 }
528 break;
529 }
530 case SLE_VAR_U32: {
531 /* Override the minimum value. No value below this->min, except special value 0 */
532 uint32_t uval = static_cast<uint32_t>(val);
533 if (!this->flags.Test(SettingFlag::GuiZeroIsSpecial) || uval != 0) {
534 if (!this->flags.Test(SettingFlag::GuiDropdown)) {
535 /* Clamp value-type setting to its valid range */
536 uval = ClampU(uval, min_val, max_val);
537 } else if (uval < static_cast<uint32_t>(min_val) || uval > max_val) {
538 /* Reset invalid discrete setting to its default value */
539 uval = static_cast<uint32_t>(this->GetDefaultValue());
540 }
541 }
542 val = static_cast<int32_t>(uval);
543 return;
544 }
545 case SLE_VAR_I64:
546 case SLE_VAR_U64:
547 default: NOT_REACHED();
548 }
549}
550
556 void IntSettingDesc::Write(const void *object, int32_t val) const
557{
558 void *ptr = GetVariableAddress(object, this->save);
559 WriteValue(ptr, this->save.conv, (int64_t)val);
560}
561
567int32_t IntSettingDesc::Read(const void *object) const
568{
569 void *ptr = GetVariableAddress(object, this->save);
570 return (int32_t)ReadValue(ptr, this->save.conv);
571}
572
580 void StringSettingDesc::MakeValueValid(std::string &str) const
581{
582 if (this->max_length == 0 || str.size() < this->max_length) return;
583
584 /* In case a maximum length is imposed by the setting, the length
585 * includes the '\0' termination for network transfer purposes.
586 * Also ensure the string is valid after chopping of some bytes. */
587 str.erase(this->max_length - 1, std::string::npos);
588 StrMakeValidInPlace(str, {});
589}
590
596 void StringSettingDesc::Write(const void *object, std::string_view str) const
597{
598 reinterpret_cast<std::string *>(GetVariableAddress(object, this->save))->assign(str);
599}
600
606 const std::string &StringSettingDesc::Read(const void *object) const
607{
608 return *reinterpret_cast<std::string *>(GetVariableAddress(object, this->save));
609}
610
620 static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, std::string_view grpname, void *object, bool only_startup)
621{
622 const IniGroup *group;
623 const IniGroup *group_def = ini.GetGroup(grpname);
624
625 for (auto &desc : settings_table) {
626 const SettingDesc *sd = GetSettingDesc(desc);
627 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
628 if (sd->startup != only_startup) continue;
629
630 /* For settings.xx.yy load the settings from [xx] yy = ? */
631 std::string s{ sd->GetName() };
632 auto sc = s.find('.');
633 if (sc != std::string::npos) {
634 group = ini.GetGroup(s.substr(0, sc));
635 if (group == nullptr) group = group_def;
636 s = s.substr(sc + 1);
637 } else {
638 group = group_def;
639 }
640
641 const IniItem *item = nullptr;
642 if (group != nullptr) item = group->GetItem(s);
643 if (item == nullptr && group != group_def && group_def != nullptr) {
644 /* For settings.xx.yy load the settings from [settings] yy = ? in case the previous
645 * did not exist (e.g. loading old config files with a [settings] section */
646 item = group_def->GetItem(s);
647 }
648 if (item == nullptr) {
649 /* For settings.xx.zz.yy load the settings from [zz] yy = ? in case the previous
650 * did not exist (e.g. loading old config files with a [yapf] section */
651 sc = s.find('.');
652 if (sc != std::string::npos) {
653 if (group = ini.GetGroup(s.substr(0, sc)); group != nullptr) item = group->GetItem(s.substr(sc + 1));
654 }
655 }
656
657 sd->ParseValue(item, object);
658 }
659}
660
661 void IntSettingDesc::ParseValue(const IniItem *item, void *object) const
662{
663 int32_t val = (item != nullptr && item->value.has_value()) ? this->ParseValue(*item->value) : this->GetDefaultValue();
664 this->MakeValueValidAndWrite(object, val);
665}
666
667 void StringSettingDesc::ParseValue(const IniItem *item, void *object) const
668{
669 std::string str{(item == nullptr) ? this->def : item->value.value_or("")};
670 this->MakeValueValid(str);
671 this->Write(object, str);
672}
673
674 void ListSettingDesc::ParseValue(const IniItem *item, void *object) const
675{
676 std::optional<std::string_view> str;
677 if (item != nullptr) {
678 str = item->value;
679 } else if (!this->def.empty()) {
680 str = this->def;
681 }
682 void *ptr = GetVariableAddress(object, this->save);
683 if (!LoadIntList(str, ptr, this->save.length, GetVarMemType(this->save.conv))) {
684 _settings_error_list.emplace_back(
685 GetEncodedString(STR_CONFIG_ERROR),
686 GetEncodedString(STR_CONFIG_ERROR_ARRAY, this->GetName()));
687
688 /* Use default */
689 LoadIntList(this->def, ptr, this->save.length, GetVarMemType(this->save.conv));
690 }
691}
692
705 static void IniSaveSettings(IniFile &ini, const SettingTable &settings_table, std::string_view grpname, void *object, bool)
706{
707 IniGroup *group_def = nullptr, *group;
708
709 for (auto &desc : settings_table) {
710 const SettingDesc *sd = GetSettingDesc(desc);
711 /* If the setting is not saved to the configuration
712 * file, just continue with the next setting */
713 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
714 if (sd->flags.Test(SettingFlag::NotInConfig)) continue;
715
716 /* XXX - wtf is this?? (group override?) */
717 std::string s{ sd->GetName() };
718 auto sc = s.find('.');
719 if (sc != std::string::npos) {
720 group = &ini.GetOrCreateGroup(s.substr(0, sc));
721 s = s.substr(sc + 1);
722 } else {
723 if (group_def == nullptr) group_def = &ini.GetOrCreateGroup(grpname);
724 group = group_def;
725 }
726
727 IniItem &item = group->GetOrCreateItem(s);
728
729 if (!item.value.has_value() || !sd->IsSameValue(&item, object)) {
730 /* The value is different, that means we have to write it to the ini */
731 item.value.emplace(sd->FormatValue(object));
732 }
733 }
734}
735
736std::string IntSettingDesc::FormatValue(const void *object) const
737{
738 int64_t i;
739 if (IsSignedVarMemType(this->save.conv)) {
740 i = this->Read(object);
741 } else {
742 i = (uint32_t)this->Read(object);
743 }
744 return fmt::format("{}", i);
745}
746
747std::string BoolSettingDesc::FormatValue(const void *object) const
748{
749 bool val = this->Read(object) != 0;
750 return val ? "true" : "false";
751}
752
753 bool IntSettingDesc::IsSameValue(const IniItem *item, void *object) const
754{
755 int32_t item_value = static_cast<int32_t>(this->ParseValue(*item->value));
756 int32_t object_value = this->Read(object);
757 return item_value == object_value;
758}
759
760 bool IntSettingDesc::IsDefaultValue(void *object) const
761{
762 int32_t object_value = this->Read(object);
763 return this->GetDefaultValue() == object_value;
764}
765
766 void IntSettingDesc::ResetToDefault(void *object) const
767{
768 this->Write(object, this->GetDefaultValue());
769}
770
771std::string StringSettingDesc::FormatValue(const void *object) const
772{
773 const std::string &str = this->Read(object);
774 switch (GetVarMemType(this->save.conv)) {
775 case SLE_VAR_STR: return str;
776
777 case SLE_VAR_STRQ:
778 if (str.empty()) {
779 return str;
780 }
781 return fmt::format("\"{}\"", str);
782
783 default: NOT_REACHED();
784 }
785}
786
787 bool StringSettingDesc::IsSameValue(const IniItem *item, void *object) const
788{
789 /* The ini parsing removes the quotes, which are needed to retain the spaces in STRQs,
790 * so those values are always different in the parsed ini item than they should be. */
791 if (GetVarMemType(this->save.conv) == SLE_VAR_STRQ) return false;
792
793 const std::string &str = this->Read(object);
794 return item->value->compare(str) == 0;
795}
796
797 bool StringSettingDesc::IsDefaultValue(void *object) const
798{
799 const std::string &str = this->Read(object);
800 return this->def == str;
801}
802
803 void StringSettingDesc::ResetToDefault(void *object) const
804{
805 this->Write(object, this->def);
806}
807
808 bool ListSettingDesc::IsSameValue(const IniItem *, void *) const
809{
810 /* Checking for equality is way more expensive than just writing the value. */
811 return false;
812}
813
814 bool ListSettingDesc::IsDefaultValue(void *) const
815{
816 /* Defaults of lists are often complicated, and hard to compare. */
817 return false;
818}
819
820 void ListSettingDesc::ResetToDefault(void *) const
821{
822 /* Resetting a list to default is not supported. */
823 NOT_REACHED();
824}
825
835 static void IniLoadSettingList(IniFile &ini, std::string_view grpname, StringList &list)
836{
837 const IniGroup *group = ini.GetGroup(grpname);
838
839 if (group == nullptr) return;
840
841 list.clear();
842
843 for (const IniItem &item : group->items) {
844 if (!item.name.empty()) list.push_back(item.name);
845 }
846}
847
857 static void IniSaveSettingList(IniFile &ini, std::string_view grpname, StringList &list)
858{
859 IniGroup &group = ini.GetOrCreateGroup(grpname);
860 group.Clear();
861
862 for (const auto &iter : list) {
863 group.GetOrCreateItem(iter).SetValue("");
864 }
865}
866
873 void IniLoadWindowSettings(IniFile &ini, std::string_view grpname, WindowDesc *desc)
874{
875 IniLoadSettings(ini, _window_settings, grpname, desc, false);
876}
877
884 void IniSaveWindowSettings(IniFile &ini, std::string_view grpname, WindowDesc *desc)
885{
886 IniSaveSettings(ini, _window_settings, grpname, desc, false);
887}
888
894 bool SettingDesc::IsEditable(bool do_command) const
895{
896 if (!do_command && !this->flags.Test(SettingFlag::NoNetworkSync) && _networking && !_network_server && !this->flags.Test(SettingFlag::PerCompany)) return false;
897 if (do_command && this->flags.Test(SettingFlag::NoNetworkSync)) return false;
898 if (this->flags.Test(SettingFlag::NetworkOnly) && !_networking && _game_mode != GM_MENU) return false;
899 if (this->flags.Test(SettingFlag::NoNetwork) && _networking) return false;
900 if (this->flags.Test(SettingFlag::NewgameOnly) &&
901 (_game_mode == GM_NORMAL ||
902 (_game_mode == GM_EDITOR && !this->flags.Test(SettingFlag::SceneditToo)))) return false;
903 if (this->flags.Test(SettingFlag::SceneditOnly) && _game_mode != GM_EDITOR) return false;
904 return true;
905}
906
911 SettingType SettingDesc::GetType() const
912{
913 if (this->flags.Test(SettingFlag::PerCompany)) return ST_COMPANY;
914 return this->flags.Test(SettingFlag::NotInSave) ? ST_CLIENT : ST_GAME;
915}
916
921 const IntSettingDesc *SettingDesc::AsIntSetting() const
922{
923 assert(this->IsIntSetting());
924 return static_cast<const IntSettingDesc *>(this);
925}
926
931 const StringSettingDesc *SettingDesc::AsStringSetting() const
932{
933 assert(this->IsStringSetting());
934 return static_cast<const StringSettingDesc *>(this);
935}
936
937void PrepareOldDiffCustom();
938void HandleOldDiffCustom(bool savegame);
939
940
942 static void ValidateSettings()
943{
944 /* Do not allow a custom sea level with the original land generator. */
945 if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL &&
946 _settings_newgame.difficulty.quantity_sea_lakes == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
947 _settings_newgame.difficulty.quantity_sea_lakes = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE;
948 }
949}
950
951static void AILoadConfig(const IniFile &ini, std::string_view grpname)
952{
953 const IniGroup *group = ini.GetGroup(grpname);
954
955 /* Clean any configured AI */
956 for (CompanyID c = CompanyID::Begin(); c < MAX_COMPANIES; ++c) {
957 AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME)->Change(std::nullopt);
958 }
959
960 /* If no group exists, return */
961 if (group == nullptr) return;
962
963 CompanyID c = CompanyID::Begin();
964 for (const IniItem &item : group->items) {
965 AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME);
966
967 config->Change(item.name);
968 if (!config->HasScript()) {
969 if (item.name != "none") {
970 Debug(script, 0, "The AI by the name '{}' was no longer found, and removed from the list.", item.name);
971 continue;
972 }
973 }
974 if (item.value.has_value()) config->StringToSettings(*item.value);
975 ++c;
976 if (c >= MAX_COMPANIES) break;
977 }
978}
979
980static void GameLoadConfig(const IniFile &ini, std::string_view grpname)
981{
982 const IniGroup *group = ini.GetGroup(grpname);
983
984 /* Clean any configured GameScript */
985 GameConfig::GetConfig(GameConfig::SSS_FORCE_NEWGAME)->Change(std::nullopt);
986
987 /* If no group exists, return */
988 if (group == nullptr || group->items.empty()) return;
989
990 const IniItem &item = group->items.front();
991
992 GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME);
993
994 config->Change(item.name);
995 if (!config->HasScript()) {
996 if (item.name != "none") {
997 Debug(script, 0, "The GameScript by the name '{}' was no longer found, and removed from the list.", item.name);
998 return;
999 }
1000 }
1001 if (item.value.has_value()) config->StringToSettings(*item.value);
1002}
1003
1007 static void GraphicsSetLoadConfig(IniFile &ini)
1008{
1009 if (const IniGroup *group = ini.GetGroup("misc"); group != nullptr) {
1010 /* Load old setting first. */
1011 if (const IniItem *item = group->GetItem("graphicsset"); item != nullptr && item->value) BaseGraphics::ini_data.name = *item->value;
1012 }
1013
1014 if (const IniGroup *group = ini.GetGroup("graphicsset"); group != nullptr) {
1015 /* Load new settings. */
1016 if (const IniItem *item = group->GetItem("name"); item != nullptr && item->value) BaseGraphics::ini_data.name = *item->value;
1017
1018 if (const IniItem *item = group->GetItem("shortname"); item != nullptr && item->value && item->value->size() == 8) {
1019 auto val = ParseInteger<uint32_t>(*item->value, 16);
1020 if (val.has_value()) {
1021 BaseGraphics::ini_data.shortname = std::byteswap<uint32_t>(*val);
1022 } else {
1023 ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR),
1024 GetEncodedString(STR_CONFIG_ERROR_INVALID_VALUE, *item->value, BaseGraphics::ini_data.name),
1025 WL_CRITICAL);
1026 }
1027 }
1028
1029 if (const IniItem *item = group->GetItem("extra_version"); item != nullptr && item->value) {
1030 auto val = ParseInteger<uint32_t>(*item->value);
1031 if (val.has_value()) {
1032 BaseGraphics::ini_data.extra_version = *val;
1033 } else {
1034 ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR),
1035 GetEncodedString(STR_CONFIG_ERROR_INVALID_VALUE, *item->value, BaseGraphics::ini_data.name),
1036 WL_CRITICAL);
1037 }
1038 }
1039
1040 if (const IniItem *item = group->GetItem("extra_params"); item != nullptr && item->value) {
1041 auto params = ParseIntList(*item->value);
1042 if (params.has_value()) {
1043 BaseGraphics::ini_data.extra_params = params.value();
1044 } else {
1045 ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR),
1046 GetEncodedString(STR_CONFIG_ERROR_ARRAY, BaseGraphics::ini_data.name),
1047 WL_CRITICAL);
1048 }
1049 }
1050 }
1051}
1052
1059 static GRFConfigList GRFLoadConfig(const IniFile &ini, std::string_view grpname, bool is_static)
1060{
1061 const IniGroup *group = ini.GetGroup(grpname);
1062 GRFConfigList list;
1063
1064 if (group == nullptr) return list;
1065
1066 uint num_grfs = 0;
1067 for (const IniItem &item : group->items) {
1068 std::unique_ptr<GRFConfig> c{};
1069
1070 std::array<uint8_t, 4> grfid_buf;
1071 MD5Hash md5sum;
1072 std::string_view item_name = item.name;
1073 bool has_md5sum = false;
1074
1075 /* Try reading "<grfid>|" and on success, "<md5sum>|". */
1076 auto grfid_pos = item_name.find("|");
1077 if (grfid_pos != std::string_view::npos) {
1078 std::string_view grfid_str = item_name.substr(0, grfid_pos);
1079
1080 if (ConvertHexToBytes(grfid_str, grfid_buf)) {
1081 item_name = item_name.substr(grfid_pos + 1);
1082
1083 auto md5sum_pos = item_name.find("|");
1084 if (md5sum_pos != std::string_view::npos) {
1085 std::string_view md5sum_str = item_name.substr(0, md5sum_pos);
1086
1087 has_md5sum = ConvertHexToBytes(md5sum_str, md5sum);
1088 if (has_md5sum) item_name = item_name.substr(md5sum_pos + 1);
1089 }
1090
1091 uint32_t grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
1092 if (has_md5sum) {
1093 const GRFConfig *s = FindGRFConfig(grfid, FGCM_EXACT, &md5sum);
1094 if (s != nullptr) c = std::make_unique<GRFConfig>(*s);
1095 }
1096 if (c == nullptr && !FioCheckFileExists(std::string(item_name), NEWGRF_DIR)) {
1097 const GRFConfig *s = FindGRFConfig(grfid, FGCM_NEWEST_VALID);
1098 if (s != nullptr) c = std::make_unique<GRFConfig>(*s);
1099 }
1100 }
1101 }
1102 std::string filename = std::string(item_name);
1103
1104 if (c == nullptr) c = std::make_unique<GRFConfig>(filename);
1105
1106 /* Parse parameters */
1107 if (item.value.has_value() && !item.value->empty()) {
1108 auto params = ParseIntList(*item.value);
1109 if (params.has_value()) {
1110 c->SetParams(params.value());
1111 } else {
1112 ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR),
1113 GetEncodedString(STR_CONFIG_ERROR_ARRAY, filename),
1114 WL_CRITICAL);
1115 }
1116 }
1117
1118 /* Check if item is valid */
1119 if (!FillGRFDetails(*c, is_static) || c->flags.Test(GRFConfigFlag::Invalid)) {
1120 StringID reason;
1121 if (c->status == GCS_NOT_FOUND) {
1122 reason = STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND;
1123 } else if (c->flags.Test(GRFConfigFlag::Unsafe)) {
1124 reason = STR_CONFIG_ERROR_INVALID_GRF_UNSAFE;
1125 } else if (c->flags.Test(GRFConfigFlag::System)) {
1126 reason = STR_CONFIG_ERROR_INVALID_GRF_SYSTEM;
1127 } else if (c->flags.Test(GRFConfigFlag::Invalid)) {
1128 reason = STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE;
1129 } else {
1130 reason = STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN;
1131 }
1132
1133 ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR),
1134 GetEncodedString(STR_CONFIG_ERROR_INVALID_GRF, filename.empty() ? item.name : filename, reason),
1135 WL_CRITICAL);
1136 continue;
1137 }
1138
1139 /* Check for duplicate GRFID (will also check for duplicate filenames) */
1140 auto found = std::ranges::find_if(list, [&c](const auto &gc) { return gc->ident.grfid == c->ident.grfid; });
1141 if (found != std::end(list)) {
1142 ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR),
1143 GetEncodedString(STR_CONFIG_ERROR_DUPLICATE_GRFID, c->filename, (*found)->filename),
1144 WL_CRITICAL);
1145 continue;
1146 }
1147
1148 if (is_static) {
1149 /* Mark file as static to avoid saving in savegame. */
1150 c->flags.Set(GRFConfigFlag::Static);
1151 } else if (++num_grfs > NETWORK_MAX_GRF_COUNT) {
1152 /* Check we will not load more non-static NewGRFs than allowed. This could trigger issues for game servers. */
1153 ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR),
1154 GetEncodedString(STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED), WL_CRITICAL);
1155 break;
1156 }
1157
1158 /* Add item to list */
1159 list.push_back(std::move(c));
1160 }
1161
1162 return list;
1163}
1164
1165static IniFileVersion LoadVersionFromConfig(const IniFile &ini)
1166{
1167 const IniGroup *group = ini.GetGroup("version");
1168 if (group == nullptr) return IFV_0;
1169
1170 auto version_number = group->GetItem("ini_version");
1171 /* Older ini-file versions don't have this key yet. */
1172 if (version_number == nullptr || !version_number->value.has_value()) return IFV_0;
1173
1174 uint32_t version = 0;
1175 std::from_chars(version_number->value->data(), version_number->value->data() + version_number->value->size(), version);
1176
1177 return static_cast<IniFileVersion>(version);
1178}
1179
1180static void AISaveConfig(IniFile &ini, std::string_view grpname)
1181{
1182 IniGroup &group = ini.GetOrCreateGroup(grpname);
1183 group.Clear();
1184
1185 for (CompanyID c = CompanyID::Begin(); c < MAX_COMPANIES; ++c) {
1186 AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME);
1187 std::string name;
1188 std::string value = config->SettingsToString();
1189
1190 if (config->HasScript()) {
1191 name = config->GetName();
1192 } else {
1193 name = "none";
1194 }
1195
1196 group.CreateItem(name).SetValue(value);
1197 }
1198}
1199
1200static void GameSaveConfig(IniFile &ini, std::string_view grpname)
1201{
1202 IniGroup &group = ini.GetOrCreateGroup(grpname);
1203 group.Clear();
1204
1205 GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME);
1206 std::string name;
1207 std::string value = config->SettingsToString();
1208
1209 if (config->HasScript()) {
1210 name = config->GetName();
1211 } else {
1212 name = "none";
1213 }
1214
1215 group.CreateItem(name).SetValue(value);
1216}
1217
1222 static void SaveVersionInConfig(IniFile &ini)
1223{
1224 IniGroup &group = ini.GetOrCreateGroup("version");
1225 group.GetOrCreateItem("version_string").SetValue(_openttd_revision);
1226 group.GetOrCreateItem("version_number").SetValue(fmt::format("{:08X}", _openttd_newgrf_version));
1227 group.GetOrCreateItem("ini_version").SetValue(fmt::format("{}", INIFILE_VERSION));
1228}
1229
1233 static void GraphicsSetSaveConfig(IniFile &ini)
1234{
1235 const GraphicsSet *used_set = BaseGraphics::GetUsedSet();
1236 if (used_set == nullptr) return;
1237
1238 IniGroup &group = ini.GetOrCreateGroup("graphicsset");
1239 group.Clear();
1240
1241 group.GetOrCreateItem("name").SetValue(used_set->name);
1242 group.GetOrCreateItem("shortname").SetValue(fmt::format("{:08X}", std::byteswap(used_set->shortname)));
1243
1244 const GRFConfig *extra_cfg = used_set->GetExtraConfig();
1245 if (extra_cfg != nullptr && !extra_cfg->param.empty()) {
1246 group.GetOrCreateItem("extra_version").SetValue(fmt::format("{}", extra_cfg->version));
1247 group.GetOrCreateItem("extra_params").SetValue(GRFBuildParamList(*extra_cfg));
1248 }
1249}
1250
1251/* Save a GRF configuration to the given group name */
1252static void GRFSaveConfig(IniFile &ini, std::string_view grpname, const GRFConfigList &list)
1253{
1254 IniGroup &group = ini.GetOrCreateGroup(grpname);
1255 group.Clear();
1256
1257 for (const auto &c : list) {
1258 std::string key = fmt::format("{:08X}|{}|{}", std::byteswap(c->ident.grfid),
1259 FormatArrayAsHex(c->ident.md5sum), c->filename);
1260 group.GetOrCreateItem(key).SetValue(GRFBuildParamList(*c));
1261 }
1262}
1263
1264/* Common handler for saving/loading variables to the configuration file */
1265static void HandleSettingDescs(IniFile &generic_ini, IniFile &private_ini, IniFile &secrets_ini, SettingDescProc *proc, SettingDescProcList *proc_list, bool only_startup = false)
1266{
1267 proc(generic_ini, _misc_settings, "misc", nullptr, only_startup);
1268#if defined(_WIN32) && !defined(DEDICATED)
1269 proc(generic_ini, _win32_settings, "win32", nullptr, only_startup);
1270#endif /* _WIN32 */
1271
1272 /* The name "patches" is a fallback, as every setting should sets its own group. */
1273
1274 for (auto &table : GenericSettingTables()) {
1275 proc(generic_ini, table, "patches", &_settings_newgame, only_startup);
1276 }
1277 for (auto &table : PrivateSettingTables()) {
1278 proc(private_ini, table, "patches", &_settings_newgame, only_startup);
1279 }
1280 for (auto &table : SecretSettingTables()) {
1281 proc(secrets_ini, table, "patches", &_settings_newgame, only_startup);
1282 }
1283
1284 proc(generic_ini, _currency_settings, "currency", &GetCustomCurrency(), only_startup);
1285 proc(generic_ini, _company_settings, "company", &_settings_client.company, only_startup);
1286
1287 if (!only_startup) {
1288 proc_list(private_ini, "server_bind_addresses", _network_bind_list);
1289 proc_list(private_ini, "servers", _network_host_list);
1290 proc_list(private_ini, "bans", _network_ban_list);
1291 proc_list(private_ini, "server_authorized_keys", _settings_client.network.server_authorized_keys);
1292 proc_list(private_ini, "rcon_authorized_keys", _settings_client.network.rcon_authorized_keys);
1293 proc_list(private_ini, "admin_authorized_keys", _settings_client.network.admin_authorized_keys);
1294 }
1295}
1296
1306 static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table)
1307{
1308 for (auto &desc : table) {
1309 const SettingDesc *sd = GetSettingDesc(desc);
1310
1311 /* For settings.xx.yy load the settings from [xx] yy = ? */
1312 std::string s{ sd->GetName() };
1313 auto sc = s.find('.');
1314 if (sc == std::string::npos) continue;
1315
1316 IniGroup *group = ini.GetGroup(s.substr(0, sc));
1317 if (group == nullptr) continue;
1318 s = s.substr(sc + 1);
1319
1320 group->RemoveItem(s);
1321 }
1322}
1323
1347 bool IsConversionNeeded(const ConfigIniFile &ini, const std::string &group, const std::string &old_var, const std::string &new_var, const IniItem **old_item)
1348{
1349 *old_item = nullptr;
1350
1351 const IniGroup *igroup = ini.GetGroup(group);
1352 /* If the group doesn't exist, there is nothing to convert. */
1353 if (igroup == nullptr) return false;
1354
1355 const IniItem *tmp_old_item = igroup->GetItem(old_var);
1356 const IniItem *new_item = igroup->GetItem(new_var);
1357
1358 /* If the old item doesn't exist, there is nothing to convert. */
1359 if (tmp_old_item == nullptr) return false;
1360
1361 /* If the new item exists, it means conversion was already done. We only
1362 * do the conversion the first time, and after that these settings are
1363 * independent. This allows users to freely change between older and
1364 * newer clients without breaking anything. */
1365 if (new_item != nullptr) return false;
1366
1367 *old_item = tmp_old_item;
1368 return true;
1369}
1370
1375 void LoadFromConfig(bool startup)
1376{
1377 ConfigIniFile generic_ini(_config_file);
1378 ConfigIniFile private_ini(_private_file);
1379 ConfigIniFile secrets_ini(_secrets_file);
1380 ConfigIniFile favs_ini(_favs_file);
1381
1382 if (!startup) ResetCurrencies(false); // Initialize the array of currencies, without preserving the custom one
1383
1384 IniFileVersion generic_version = LoadVersionFromConfig(generic_ini);
1385
1386 if (startup) {
1387 GraphicsSetLoadConfig(generic_ini);
1388 }
1389
1390 /* Before the split of private/secrets, we have to look in the generic for these settings. */
1391 if (generic_version < IFV_PRIVATE_SECRETS) {
1392 HandleSettingDescs(generic_ini, generic_ini, generic_ini, IniLoadSettings, IniLoadSettingList, startup);
1393 } else {
1394 HandleSettingDescs(generic_ini, private_ini, secrets_ini, IniLoadSettings, IniLoadSettingList, startup);
1395 }
1396
1397 /* Load basic settings only during bootstrap, load other settings not during bootstrap */
1398 if (!startup) {
1399 if (generic_version < IFV_LINKGRAPH_SECONDS) {
1400 _settings_newgame.linkgraph.recalc_interval *= CalendarTime::SECONDS_PER_DAY;
1401 _settings_newgame.linkgraph.recalc_time *= CalendarTime::SECONDS_PER_DAY;
1402 }
1403
1404 /* Move use_relay_service from generic_ini to private_ini. */
1405 if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) {
1406 const IniGroup *network = generic_ini.GetGroup("network");
1407 if (network != nullptr) {
1408 const IniItem *use_relay_service = network->GetItem("use_relay_service");
1409 if (use_relay_service != nullptr) {
1410 if (use_relay_service->value == "never") {
1411 _settings_client.network.use_relay_service = UseRelayService::URS_NEVER;
1412 } else if (use_relay_service->value == "ask") {
1413 _settings_client.network.use_relay_service = UseRelayService::URS_ASK;
1414 } else if (use_relay_service->value == "allow") {
1415 _settings_client.network.use_relay_service = UseRelayService::URS_ALLOW;
1416 }
1417 }
1418 }
1419 }
1420
1421 const IniItem *old_item;
1422
1423 if (generic_version < IFV_GAME_TYPE && IsConversionNeeded(generic_ini, "network", "server_advertise", "server_game_type", &old_item)) {
1424 auto old_value = BoolSettingDesc::ParseSingleValue(*old_item->value);
1425 _settings_client.network.server_game_type = old_value.value_or(false) ? SERVER_GAME_TYPE_PUBLIC : SERVER_GAME_TYPE_LOCAL;
1426 }
1427
1428 if (generic_version < IFV_AUTOSAVE_RENAME && IsConversionNeeded(generic_ini, "gui", "autosave", "autosave_interval", &old_item)) {
1429 static constexpr std::initializer_list<std::string_view> _old_autosave_interval{"off"sv, "monthly"sv, "quarterly"sv, "half year"sv, "yearly"sv};
1430 auto old_value = OneOfManySettingDesc::ParseSingleValue(*old_item->value, _old_autosave_interval).value_or(-1);
1431
1432 switch (old_value) {
1433 case 0: _settings_client.gui.autosave_interval = 0; break;
1434 case 1: _settings_client.gui.autosave_interval = 10; break;
1435 case 2: _settings_client.gui.autosave_interval = 30; break;
1436 case 3: _settings_client.gui.autosave_interval = 60; break;
1437 case 4: _settings_client.gui.autosave_interval = 120; break;
1438 default: break;
1439 }
1440 }
1441
1442 /* Persist the right click close option from older versions. */
1443 if (generic_version < IFV_RIGHT_CLICK_CLOSE && IsConversionNeeded(generic_ini, "gui", "right_mouse_wnd_close", "right_click_wnd_close", &old_item)) {
1444 auto old_value = BoolSettingDesc::ParseSingleValue(*old_item->value);
1445 _settings_client.gui.right_click_wnd_close = old_value.value_or(false) ? RCC_YES : RCC_NO;
1446 }
1447
1448 _grfconfig_newgame = GRFLoadConfig(generic_ini, "newgrf", false);
1449 _grfconfig_static = GRFLoadConfig(generic_ini, "newgrf-static", true);
1450 AILoadConfig(generic_ini, "ai_players");
1451 GameLoadConfig(generic_ini, "game_scripts");
1452 PickerLoadConfig(favs_ini);
1453 BadgeClassLoadConfig(favs_ini);
1454
1455 PrepareOldDiffCustom();
1456 IniLoadSettings(generic_ini, _old_gameopt_settings, "gameopt", &_settings_newgame, false);
1457 HandleOldDiffCustom(false);
1458
1459 ValidateSettings();
1460 DebugReconsiderSendRemoteMessages();
1461
1462 /* Display scheduled errors */
1463 ScheduleErrorMessage(_settings_error_list);
1464 if (FindWindowById(WC_ERRMSG, 0) == nullptr) ShowFirstError();
1465 }
1466}
1467
1469 void SaveToConfig()
1470{
1471 ConfigIniFile generic_ini(_config_file);
1472 ConfigIniFile private_ini(_private_file);
1473 ConfigIniFile secrets_ini(_secrets_file);
1474 ConfigIniFile favs_ini(_favs_file);
1475
1476 IniFileVersion generic_version = LoadVersionFromConfig(generic_ini);
1477
1478 /* If we newly create the private/secrets file, add a dummy group on top
1479 * just so we can add a comment before it (that is how IniFile works).
1480 * This to explain what the file is about. After doing it once, never touch
1481 * it again, as otherwise we might be reverting user changes. */
1482 if (IniGroup *group = private_ini.GetGroup("private"); group != nullptr) group->comment = "; This file possibly contains private information which can identify you as person.\n";
1483 if (IniGroup *group = secrets_ini.GetGroup("secrets"); group != nullptr) group->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n";
1484
1485 if (generic_version == IFV_0) {
1486 /* Remove some obsolete groups. These have all been loaded into other groups. */
1487 generic_ini.RemoveGroup("patches");
1488 generic_ini.RemoveGroup("yapf");
1489 generic_ini.RemoveGroup("gameopt");
1490
1491 /* Remove all settings from the generic ini that are now in the private ini. */
1492 generic_ini.RemoveGroup("server_bind_addresses");
1493 generic_ini.RemoveGroup("servers");
1494 generic_ini.RemoveGroup("bans");
1495 for (auto &table : PrivateSettingTables()) {
1496 RemoveEntriesFromIni(generic_ini, table);
1497 }
1498
1499 /* Remove all settings from the generic ini that are now in the secrets ini. */
1500 for (auto &table : SecretSettingTables()) {
1501 RemoveEntriesFromIni(generic_ini, table);
1502 }
1503 }
1504
1505 if (generic_version < IFV_REMOVE_GENERATION_SEED) {
1506 IniGroup *game_creation = generic_ini.GetGroup("game_creation");
1507 if (game_creation != nullptr) {
1508 game_creation->RemoveItem("generation_seed");
1509 }
1510 }
1511
1512 /* These variables are migrated from generic ini to private ini now. */
1513 if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) {
1514 IniGroup *network = generic_ini.GetGroup("network");
1515 if (network != nullptr) {
1516 network->RemoveItem("use_relay_service");
1517 }
1518 }
1519
1520 HandleSettingDescs(generic_ini, private_ini, secrets_ini, IniSaveSettings, IniSaveSettingList);
1521 GraphicsSetSaveConfig(generic_ini);
1522 GRFSaveConfig(generic_ini, "newgrf", _grfconfig_newgame);
1523 GRFSaveConfig(generic_ini, "newgrf-static", _grfconfig_static);
1524 AISaveConfig(generic_ini, "ai_players");
1525 GameSaveConfig(generic_ini, "game_scripts");
1526 PickerSaveConfig(favs_ini);
1527 BadgeClassSaveConfig(favs_ini);
1528
1529 SaveVersionInConfig(generic_ini);
1530 SaveVersionInConfig(private_ini);
1531 SaveVersionInConfig(secrets_ini);
1532 SaveVersionInConfig(favs_ini);
1533
1534 generic_ini.SaveToDisk(_config_file);
1535 private_ini.SaveToDisk(_private_file);
1536 secrets_ini.SaveToDisk(_secrets_file);
1537 favs_ini.SaveToDisk(_favs_file);
1538}
1539
1544 StringList GetGRFPresetList()
1545{
1546 StringList list;
1547
1548 ConfigIniFile ini(_config_file);
1549 for (const IniGroup &group : ini.groups) {
1550 if (group.name.starts_with("preset-")) {
1551 list.push_back(group.name.substr(7));
1552 }
1553 }
1554
1555 return list;
1556}
1557
1564GRFConfigList LoadGRFPresetFromConfig(std::string_view config_name)
1565{
1566 std::string section("preset-");
1567 section += config_name;
1568
1569 ConfigIniFile ini(_config_file);
1570 GRFConfigList config = GRFLoadConfig(ini, section, false);
1571
1572 return config;
1573}
1574
1581 void SaveGRFPresetToConfig(std::string_view config_name, GRFConfigList &config)
1582{
1583 std::string section("preset-");
1584 section += config_name;
1585
1586 ConfigIniFile ini(_config_file);
1587 GRFSaveConfig(ini, section, config);
1588 ini.SaveToDisk(_config_file);
1589}
1590
1595 void DeleteGRFPresetFromConfig(std::string_view config_name)
1596{
1597 std::string section("preset-");
1598 section += config_name;
1599
1600 ConfigIniFile ini(_config_file);
1601 ini.RemoveGroup(section);
1602 ini.SaveToDisk(_config_file);
1603}
1604
1611 void IntSettingDesc::ChangeValue(const void *object, int32_t newval) const
1612{
1613 int32_t oldval = this->Read(object);
1614 this->MakeValueValid(newval);
1615 if (this->pre_check != nullptr && !this->pre_check(newval)) return;
1616 if (oldval == newval) return;
1617
1618 this->Write(object, newval);
1619 if (this->post_callback != nullptr) this->post_callback(newval);
1620
1621 if (this->flags.Test(SettingFlag::NoNetwork) || this->flags.Test(SettingFlag::Sandbox)) {
1622 _gamelog.StartAction(GLAT_SETTING);
1623 _gamelog.Setting(this->GetName(), oldval, newval);
1624 _gamelog.StopAction();
1625 }
1626
1627 SetWindowClassesDirty(WC_GAME_OPTIONS);
1628 if (this->flags.Test(SettingFlag::Sandbox)) SetWindowClassesDirty(WC_CHEATS);
1629
1630 if (_save_config) SaveToConfig();
1631}
1632
1640 static const SettingDesc *GetSettingFromName(std::string_view name, const SettingTable &settings)
1641{
1642 /* First check all full names */
1643 for (auto &desc : settings) {
1644 const SettingDesc *sd = GetSettingDesc(desc);
1645 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
1646 if (sd->GetName() == name) return sd;
1647 }
1648
1649 /* Then check the shortcut variant of the name. */
1650 std::string short_name_suffix = std::string{ "." }.append(name);
1651 for (auto &desc : settings) {
1652 const SettingDesc *sd = GetSettingDesc(desc);
1653 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
1654 if (sd->GetName().ends_with(short_name_suffix)) return sd;
1655 }
1656
1657 return nullptr;
1658}
1659
1665 void GetSaveLoadFromSettingTable(SettingTable settings, std::vector<SaveLoad> &saveloads)
1666{
1667 for (auto &desc : settings) {
1668 const SettingDesc *sd = GetSettingDesc(desc);
1669 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
1670 saveloads.push_back(sd->save);
1671 }
1672}
1673
1678SettingTable GetSaveLoadSettingTable()
1679{
1680 static const SettingTable saveload_settings_tables[] = {
1681 _difficulty_settings,
1682 _economy_settings,
1683 _game_settings,
1684 _linkgraph_settings,
1685 _locale_settings,
1686 _pathfinding_settings,
1687 _script_settings,
1688 _world_settings,
1689 };
1690 static std::vector<SettingVariant> settings_table;
1691
1692 if (settings_table.empty()) {
1693 for (auto &saveload_settings_table : saveload_settings_tables) {
1694 for (auto &saveload_setting : saveload_settings_table) {
1695 settings_table.push_back(saveload_setting);
1696 }
1697 }
1698 }
1699
1700 return settings_table;
1701}
1702
1709 static const SettingDesc *GetCompanySettingFromName(std::string_view name)
1710{
1711 static const std::string_view company_prefix = "company.";
1712 if (name.starts_with(company_prefix)) name.remove_prefix(company_prefix.size());
1713 return GetSettingFromName(name, _company_settings);
1714}
1715
1722 const SettingDesc *GetSettingFromName(std::string_view name)
1723{
1724 for (auto &table : GenericSettingTables()) {
1725 auto sd = GetSettingFromName(name, table);
1726 if (sd != nullptr) return sd;
1727 }
1728 for (auto &table : PrivateSettingTables()) {
1729 auto sd = GetSettingFromName(name, table);
1730 if (sd != nullptr) return sd;
1731 }
1732 for (auto &table : SecretSettingTables()) {
1733 auto sd = GetSettingFromName(name, table);
1734 if (sd != nullptr) return sd;
1735 }
1736
1737 return GetCompanySettingFromName(name);
1738}
1739
1745std::vector<const SettingDesc *> GetFilteredSettingCollection(std::function<bool(const SettingDesc &desc)> func)
1746{
1747 std::vector<const SettingDesc *> collection;
1748
1749 for (const auto &table : GenericSettingTables()) {
1750 for (const auto &desc : table) {
1751 const auto sd = GetSettingDesc(desc);
1752 if (!func(*sd)) continue;
1753
1754 collection.push_back(sd);
1755 }
1756 }
1757
1758 return collection;
1759}
1760
1770 CommandCost CmdChangeSetting(DoCommandFlags flags, const std::string &name, int32_t value)
1771{
1772 if (name.empty()) return CMD_ERROR;
1773 const SettingDesc *sd = GetSettingFromName(name);
1774
1775 if (sd == nullptr) return CMD_ERROR;
1776 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR;
1777 if (!sd->IsIntSetting()) return CMD_ERROR;
1778
1779 if (!sd->IsEditable(true)) return CMD_ERROR;
1780
1781 if (flags.Test(DoCommandFlag::Execute)) {
1782 sd->AsIntSetting()->ChangeValue(&GetGameSettings(), value);
1783 }
1784
1785 return CommandCost();
1786}
1787
1796 CommandCost CmdChangeCompanySetting(DoCommandFlags flags, const std::string &name, int32_t value)
1797{
1798 if (name.empty()) return CMD_ERROR;
1799 const SettingDesc *sd = GetCompanySettingFromName(name);
1800
1801 if (sd == nullptr) return CMD_ERROR;
1802 if (!sd->IsIntSetting()) return CMD_ERROR;
1803
1804 if (flags.Test(DoCommandFlag::Execute)) {
1805 sd->AsIntSetting()->ChangeValue(&Company::Get(_current_company)->settings, value);
1806 }
1807
1808 return CommandCost();
1809}
1810
1818 bool SetSettingValue(const IntSettingDesc *sd, int32_t value, bool force_newgame)
1819{
1820 const IntSettingDesc *setting = sd->AsIntSetting();
1821 if (setting->flags.Test(SettingFlag::PerCompany)) {
1822 if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) {
1823 return Command<CMD_CHANGE_COMPANY_SETTING>::Post(setting->GetName(), value);
1824 }
1825
1826 setting->ChangeValue(&_settings_client.company, value);
1827 return true;
1828 }
1829
1830 /* If an item is company-based, we do not send it over the network
1831 * (if any) to change. Also *hack*hack* we update the _newgame version
1832 * of settings because changing a company-based setting in a game also
1833 * changes its defaults. At least that is the convention we have chosen */
1834 if (setting->flags.Test(SettingFlag::NoNetworkSync)) {
1835 if (_game_mode != GM_MENU) {
1836 setting->ChangeValue(&_settings_newgame, value);
1837 }
1838 setting->ChangeValue(&GetGameSettings(), value);
1839 return true;
1840 }
1841
1842 if (force_newgame) {
1843 setting->ChangeValue(&_settings_newgame, value);
1844 return true;
1845 }
1846
1847 /* send non-company-based settings over the network */
1848 if (!_networking || (_networking && _network_server)) {
1849 return Command<CMD_CHANGE_SETTING>::Post(setting->GetName(), value);
1850 }
1851 return false;
1852}
1853
1857 void SetDefaultCompanySettings(CompanyID cid)
1858{
1859 Company *c = Company::Get(cid);
1860 AutoRestoreBackup backup(_current_company, cid);
1861 for (auto &desc : _company_settings) {
1862 const IntSettingDesc *int_setting = GetSettingDesc(desc)->AsIntSetting();
1863 int_setting->MakeValueValidAndWrite(&c->settings, int_setting->GetDefaultValue());
1864 }
1865}
1866
1870 void SyncCompanySettings()
1871{
1872 const void *old_object = &Company::Get(_current_company)->settings;
1873 const void *new_object = &_settings_client.company;
1874 for (auto &desc : _company_settings) {
1875 const SettingDesc *sd = GetSettingDesc(desc);
1876 uint32_t old_value = (uint32_t)sd->AsIntSetting()->Read(old_object);
1877 uint32_t new_value = (uint32_t)sd->AsIntSetting()->Read(new_object);
1878 /*
1879 * This is called from a command, and since it contains local configuration information
1880 * that the rest of the clients do not know about, we need to circumvent the normal ::Post
1881 * local command validation and immediately send the command to the server.
1882 */
1883 if (old_value != new_value) Command<CMD_CHANGE_COMPANY_SETTING>::SendNet(STR_NULL, _local_company, sd->GetName(), new_value);
1884 }
1885}
1886
1894 bool SetSettingValue(const StringSettingDesc *sd, std::string_view value, bool force_newgame)
1895{
1896 assert(sd->flags.Test(SettingFlag::NoNetworkSync));
1897
1898 if (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ && value == "(null)") {
1899 value = {};
1900 }
1901
1902 const void *object = (_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game;
1903 sd->AsStringSetting()->ChangeValue(object, std::string{value});
1904 return true;
1905}
1906
1913 void StringSettingDesc::ChangeValue(const void *object, std::string &&newval) const
1914{
1915 this->MakeValueValid(newval);
1916 if (this->pre_check != nullptr && !this->pre_check(newval)) return;
1917
1918 this->Write(object, newval);
1919 if (this->post_callback != nullptr) this->post_callback(newval);
1920
1921 if (_save_config) SaveToConfig();
1922}
1923
1924/* Those 2 functions need to be here, else we have to make some stuff non-static
1925 * and besides, it is also better to keep stuff like this at the same place */
1926void IConsoleSetSetting(std::string_view name, std::string_view value, bool force_newgame)
1927{
1928 const SettingDesc *sd = GetSettingFromName(name);
1929 /* Company settings are not in "list_settings", so don't try to modify them. */
1930 if (sd == nullptr || sd->flags.Test(SettingFlag::PerCompany)) {
1931 IConsolePrint(CC_ERROR, "'{}' is an unknown setting.", name);
1932 return;
1933 }
1934
1935 bool success = true;
1936 if (sd->IsStringSetting()) {
1937 success = SetSettingValue(sd->AsStringSetting(), value, force_newgame);
1938 } else if (sd->IsIntSetting()) {
1939 const IntSettingDesc *isd = sd->AsIntSetting();
1940 size_t val = isd->ParseValue(value);
1941 if (!_settings_error_list.empty()) {
1942 IConsolePrint(CC_ERROR, "'{}' is not a valid value for this setting.", value);
1943 _settings_error_list.clear();
1944 return;
1945 }
1946 success = SetSettingValue(isd, (int32_t)val, force_newgame);
1947 }
1948
1949 if (!success) {
1950 if (_network_server) {
1951 IConsolePrint(CC_ERROR, "This command/variable is not available during network games.");
1952 } else {
1953 IConsolePrint(CC_ERROR, "This command/variable is only available to a network server.");
1954 }
1955 }
1956}
1957
1958void IConsoleSetSetting(std::string_view name, int value)
1959{
1960 const SettingDesc *sd = GetSettingFromName(name);
1961 assert(sd != nullptr);
1962 SetSettingValue(sd->AsIntSetting(), value);
1963}
1964
1970 void IConsoleGetSetting(std::string_view name, bool force_newgame)
1971{
1972 const SettingDesc *sd = GetSettingFromName(name);
1973 /* Company settings are not in "list_settings", so don't try to read them. */
1974 if (sd == nullptr || sd->flags.Test(SettingFlag::PerCompany)) {
1975 IConsolePrint(CC_ERROR, "'{}' is an unknown setting.", name);
1976 return;
1977 }
1978
1979 const void *object = (_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game;
1980
1981 if (sd->IsStringSetting()) {
1982 IConsolePrint(CC_INFO, "Current value for '{}' is '{}'.", sd->GetName(), sd->AsStringSetting()->Read(object));
1983 } else if (sd->IsIntSetting()) {
1984 std::string value = sd->FormatValue(object);
1985 const IntSettingDesc *int_setting = sd->AsIntSetting();
1986 auto [min_val, max_val] = int_setting->GetRange();
1987 auto def_val = int_setting->GetDefaultValue();
1988 IConsolePrint(CC_INFO, "Current value for '{}' is '{}' (min: {}{}, max: {}, def: {}).",
1989 sd->GetName(), value, sd->flags.Test(SettingFlag::GuiZeroIsSpecial) ? "(0) " : "", min_val, max_val, def_val);
1990 }
1991}
1992
1993static void IConsoleListSettingsTable(const SettingTable &table, std::string_view prefilter)
1994{
1995 for (auto &desc : table) {
1996 const SettingDesc *sd = GetSettingDesc(desc);
1997 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
1998 if (!prefilter.empty() && sd->GetName().find(prefilter) == std::string::npos) continue;
1999 IConsolePrint(CC_DEFAULT, "{} = {}", sd->GetName(), sd->FormatValue(&GetGameSettings()));
2000 }
2001}
2002
2008 void IConsoleListSettings(std::string_view prefilter)
2009{
2010 IConsolePrint(CC_HELP, "All settings with their current value:");
2011
2012 for (auto &table : GenericSettingTables()) {
2013 IConsoleListSettingsTable(table, prefilter);
2014 }
2015 for (auto &table : PrivateSettingTables()) {
2016 IConsoleListSettingsTable(table, prefilter);
2017 }
2018 for (auto &table : SecretSettingTables()) {
2019 IConsoleListSettingsTable(table, prefilter);
2020 }
2021
2022 IConsolePrint(CC_HELP, "Use 'setting' command to change a value.");
2023}
2024
2025ScriptConfigSettings::ScriptConfigSettings()
2026{
2027 /* Instantiate here, because unique_ptr needs a complete type. */
2028}
2029
2030ScriptConfigSettings::~ScriptConfigSettings()
2031{
2032 /* Instantiate here, because unique_ptr needs a complete type. */
2033}
2034
2035ScriptConfigSettings::ScriptConfigSettings(const ScriptConfigSettings &other)
2036{
2037 *this = other;
2038}
2039
2040 ScriptConfigSettings &ScriptConfigSettings::operator=(const ScriptConfigSettings &other)
2041{
2042 for (CompanyID c = CompanyID::Begin(); c < MAX_COMPANIES; ++c) {
2043 if (other.ai[c] != nullptr) {
2044 this->ai[c] = std::make_unique<AIConfig>(*other.ai[c]);
2045 }
2046 }
2047 if (other.game != nullptr) {
2048 this->game = std::make_unique<GameConfig>(*other.game);
2049 }
2050 return *this;
2051}
ai_config.hpp
AIConfig stores the configuration settings of every AI.
base_media_base.h
Generic functions for replacing base data (graphics, sounds).
base_media_graphics.h
Generic functions for replacing base graphics data.
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition bitmath_func.hpp:121
AIConfig
Definition ai_config.hpp:16
AIConfig::GetConfig
static AIConfig * GetConfig(CompanyID company, ScriptSettingSource source=SSS_DEFAULT)
Get the config of a company.
Definition ai_config.cpp:20
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseMedia< GraphicsSet >::GetUsedSet
static const GraphicsSet * GetUsedSet()
Return the used set.
Definition base_media_func.h:400
CommandCost
Common return value for all commands.
Definition command_type.h:24
ConfigIniFile
IniFile to store a configuration.
Definition settings.cpp:140
EnumBitSet
Enum-as-bit-set wrapper.
Definition enum_type.hpp:177
GameConfig
Definition game_config.hpp:15
GameConfig::GetConfig
static GameConfig * GetConfig(ScriptSettingSource source=SSS_DEFAULT)
Get the config of a company.
Definition game_config.cpp:18
Gamelog::StartAction
void StartAction(GamelogActionType at)
Stores information about new action, but doesn't allocate it Action is allocated only when there is a...
Definition gamelog.cpp:65
Gamelog::StopAction
void StopAction()
Stops logging of any changes.
Definition gamelog.cpp:74
Gamelog::Setting
void Setting(const std::string &name, int32_t oldval, int32_t newval)
Logs change in game settings.
Definition gamelog.cpp:413
ScriptConfig::SSS_FORCE_NEWGAME
@ SSS_FORCE_NEWGAME
Get the newgame Script config.
Definition script_config.hpp:99
ScriptConfig::HasScript
bool HasScript() const
Is this config attached to an Script? In other words, is there a Script that is assigned to this slot...
Definition script_config.cpp:127
ScriptConfig::Change
void Change(std::optional< std::string_view > name, int version=-1, bool force_exact_match=false)
Set another Script to be loaded in this slot.
Definition script_config.cpp:22
ScriptConfig::StringToSettings
void StringToSettings(std::string_view value)
Convert a string which is stored in the config file or savegames to custom settings of this Script.
Definition script_config.cpp:142
ScriptConfig::GetName
const std::string & GetName() const
Get the name of the Script.
Definition script_config.cpp:132
ScriptConfig::SettingsToString
std::string SettingsToString() const
Convert the custom settings to a string that can be stored in the config file or savegames.
Definition script_config.cpp:164
StringConsumer
Parse data from a string / buffer.
Definition string_consumer.hpp:27
StringConsumer::TryReadIntegerBase
std::optional< T > TryReadIntegerBase(int base, bool clamp=false)
Try to read and parse an integer in number 'base', and then advance the reader.
Definition string_consumer.hpp:874
StringConsumer::WHITESPACE_NO_NEWLINE
static const std::string_view WHITESPACE_NO_NEWLINE
ASCII whitespace characters, excluding new-line.
Definition string_consumer.hpp:40
StringConsumer::SkipUntilCharNotIn
void SkipUntilCharNotIn(std::string_view chars)
Skip 8-bit chars, while they are in 'chars', until they are not.
Definition string_consumer.hpp:683
TimerGameConst< struct Calendar >::SECONDS_PER_DAY
static constexpr int SECONDS_PER_DAY
approximate seconds per day, not for precise calculations
Definition timer_game_common.h:153
command_func.h
Functions related to commands.
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition command_func.h:28
DoCommandFlag::Execute
@ Execute
execute the given command
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:55
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
company_func.h
Functions related to companies.
config.h
Configuration options of the network stuff.
NETWORK_MAX_GRF_COUNT
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition config.h:90
IConsolePrint
void IConsolePrint(TextColour colour_code, const std::string &string)
Handle the printing of text entered into the console or redirected there by any other means.
Definition console.cpp:90
console_func.h
Console functions used outside of the console code.
CC_HELP
static const TextColour CC_HELP
Colour for help lines.
Definition console_type.h:26
CC_INFO
static const TextColour CC_INFO
Colour for information lines.
Definition console_type.h:27
CC_DEFAULT
static const TextColour CC_DEFAULT
Default colour of the console.
Definition console_type.h:23
CC_ERROR
static const TextColour CC_ERROR
Colour for error lines.
Definition console_type.h:24
ResetCurrencies
void ResetCurrencies(bool preserve_custom)
Will fill _currency_specs array with default values from origin_currency_specs Called only from newgr...
Definition currency.cpp:163
currency.h
Functions to handle different currencies.
GetCustomCurrency
CurrencySpec & GetCustomCurrency()
Get the custom currency.
Definition currency.h:110
DebugReconsiderSendRemoteMessages
void DebugReconsiderSendRemoteMessages()
Reconsider whether we need to send debug messages to either NetworkAdminConsole or IConsolePrint.
Definition debug.cpp:259
debug.h
Functions related to debugging.
Debug
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
error.h
Functions related to errors.
ErrorList
std::list< ErrorMessageData > ErrorList
Define a queue with errors.
Definition error.h:48
ScheduleErrorMessage
void ScheduleErrorMessage(ErrorList &datas)
Schedule a list of errors.
Definition error_gui.cpp:368
WL_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
ShowErrorMessage
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Definition error_gui.cpp:290
ShowFirstError
void ShowFirstError()
Show the first error of the queue.
Definition error_gui.cpp:258
FioCheckFileExists
bool FioCheckFileExists(std::string_view filename, Subdirectory subdir)
Check whether the given file exists.
Definition fileio.cpp:121
fileio_func.h
Functions for Standard In/Out file operations.
NO_DIRECTORY
@ NO_DIRECTORY
A path without any base directory.
Definition fileio_type.h:107
NEWGRF_DIR
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition fileio_type.h:97
fios.h
Declarations for savegames operations.
settings
fluid_settings_t * settings
FluidSynth settings handle.
Definition fluidsynth.cpp:25
game_config.hpp
GameConfig stores the configuration settings of every Game.
_gamelog
Gamelog _gamelog
Gamelog instance.
Definition gamelog.cpp:31
gamelog.h
Functions to be called to log fundamental changes to the game.
GLAT_SETTING
@ GLAT_SETTING
Setting changed.
Definition gamelog.h:21
genworld.h
Functions related to world/map generation.
LG_ORIGINAL
@ LG_ORIGINAL
The original landscape generator.
Definition genworld.h:21
CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY
static const uint CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY
Value for custom sea level in difficulty settings.
Definition genworld.h:48
CUSTOM_SEA_LEVEL_MIN_PERCENTAGE
static const uint CUSTOM_SEA_LEVEL_MIN_PERCENTAGE
Minimum percentage a user can specify for custom sea level.
Definition genworld.h:49
ini_type.h
Types related to reading/writing '*.ini' files.
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
ClampU
constexpr uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition math_func.hpp:150
_network_host_list
StringList _network_host_list
The servers we know.
Definition network.cpp:75
_networking
bool _networking
are we in networking mode?
Definition network.cpp:66
_network_ban_list
StringList _network_ban_list
The banned clients.
Definition network.cpp:76
_network_server
bool _network_server
network-server is active
Definition network.cpp:67
_network_bind_list
StringList _network_bind_list
The addresses to bind on.
Definition network.cpp:74
network.h
Basic functions/variables used all over the place.
network_func.h
Network functions used by other parts of OpenTTD.
BadgeClassSaveConfig
void BadgeClassSaveConfig(IniFile &ini)
Save badge column preferences.
Definition newgrf_badge_config.cpp:198
BadgeClassLoadConfig
void BadgeClassLoadConfig(const IniFile &ini)
Load badge column preferences.
Definition newgrf_badge_config.cpp:169
newgrf_badge_config.h
Functions related to NewGRF badge configuration.
_grfconfig_static
GRFConfigList _grfconfig_static
First item in list of static GRF set up.
Definition newgrf_config.cpp:156
GRFBuildParamList
std::string GRFBuildParamList(const GRFConfig &c)
Build a string containing space separated parameter values, and terminate.
Definition newgrf_config.cpp:632
FindGRFConfig
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
Definition newgrf_config.cpp:596
_grfconfig_newgame
GRFConfigList _grfconfig_newgame
First item in list of default GRF set up.
Definition newgrf_config.cpp:155
FillGRFDetails
bool FillGRFDetails(GRFConfig &config, bool is_static, Subdirectory subdir)
Find the GRFID of a given grf, and calculate its md5sum.
Definition newgrf_config.cpp:292
newgrf_config.h
Functions to find and configure NewGRFs.
GCS_NOT_FOUND
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition newgrf_config.h:36
System
@ System
GRF file is an openttd-internal system grf.
Definition newgrf_config.h:21
Static
@ Static
GRF file is used statically (can be used in any MP game)
Definition newgrf_config.h:23
Unsafe
@ Unsafe
GRF file is unsafe for static usage.
Definition newgrf_config.h:22
Invalid
@ Invalid
GRF is unusable with this version of OpenTTD.
Definition newgrf_config.h:28
FGCM_NEWEST_VALID
@ FGCM_NEWEST_VALID
Find newest Grf, ignoring Grfs with GRFConfigFlag::Invalid set.
Definition newgrf_config.h:211
FGCM_EXACT
@ FGCM_EXACT
Only find Grfs matching md5sum.
Definition newgrf_config.h:208
picker_func.h
Functions/types etc.
PickerSaveConfig
void PickerSaveConfig(IniFile &ini)
Save favourites of all registered Pickers to config.
Definition picker_gui.cpp:123
PickerLoadConfig
void PickerLoadConfig(const IniFile &ini)
Load favourites of all registered Pickers from config.
Definition picker_gui.cpp:114
rev.h
declaration of OTTD revision dependent variables
safeguards.h
A number of safeguards to prevent using unsafe methods.
WriteValue
void WriteValue(void *ptr, VarType conv, int64_t val)
Write the value of a setting.
Definition saveload.cpp:836
ReadValue
int64_t ReadValue(const void *ptr, VarType conv)
Return a signed-long version of the value of a setting.
Definition saveload.cpp:812
SLE_VAR_NULL
@ SLE_VAR_NULL
useful to write zeros in savegame.
Definition saveload.h:667
SLE_VAR_STR
@ SLE_VAR_STR
string pointer
Definition saveload.h:668
SLE_VAR_STRQ
@ SLE_VAR_STRQ
string pointer enclosed in quotes
Definition saveload.h:669
SlVarSize
constexpr size_t SlVarSize(VarType type)
Return expect size in bytes of a VarType.
Definition saveload.h:797
GetVariableAddress
void * GetVariableAddress(const void *object, const SaveLoad &sld)
Get the address of the variable.
Definition saveload.h:1316
SlIsObjectCurrentlyValid
bool SlIsObjectCurrentlyValid(SaveLoadVersion version_from, SaveLoadVersion version_to)
Checks if some version from/to combination falls within the range of the active savegame version.
Definition saveload.h:1305
GetVarMemType
constexpr VarType GetVarMemType(VarType type)
Get the NumberType of a setting.
Definition saveload.h:766
GraphicsSetLoadConfig
static void GraphicsSetLoadConfig(IniFile &ini)
Load BaseGraphics set selection and configuration.
Definition settings.cpp:1007
HandleOldDiffCustom
void HandleOldDiffCustom(bool savegame)
Reading of the old diff_custom array and transforming it to the new format.
Definition settings_sl.cpp:37
SyncCompanySettings
void SyncCompanySettings()
Sync all company settings in a multiplayer game.
Definition settings.cpp:1870
IniLoadWindowSettings
void IniLoadWindowSettings(IniFile &ini, std::string_view grpname, WindowDesc *desc)
Load a WindowDesc from config.
Definition settings.cpp:873
RemoveEntriesFromIni
static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table)
Remove all entries from a settings table from an ini-file.
Definition settings.cpp:1306
SaveGRFPresetToConfig
void SaveGRFPresetToConfig(std::string_view config_name, GRFConfigList &config)
Save a NewGRF configuration with a preset name.
Definition settings.cpp:1581
GetGRFPresetList
StringList GetGRFPresetList()
Get the list of known NewGrf presets.
Definition settings.cpp:1544
ValidateSettings
static void ValidateSettings()
Checks if any settings are set to incorrect values, and sets them to correct values in that case.
Definition settings.cpp:942
IsConversionNeeded
bool IsConversionNeeded(const ConfigIniFile &ini, const std::string &group, const std::string &old_var, const std::string &new_var, const IniItem **old_item)
Check whether a conversion should be done, and based on what old setting information.
Definition settings.cpp:1347
IConsoleGetSetting
void IConsoleGetSetting(std::string_view name, bool force_newgame)
Output value of a specific setting to the console.
Definition settings.cpp:1970
_secrets_file
std::string _secrets_file
Secrets configuration file of OpenTTD.
Definition settings.cpp:66
GRFLoadConfig
static GRFConfigList GRFLoadConfig(const IniFile &ini, std::string_view grpname, bool is_static)
Load a GRF configuration.
Definition settings.cpp:1059
_favs_file
std::string _favs_file
Picker favourites configuration file of OpenTTD.
Definition settings.cpp:67
_settings_error_list
static ErrorList _settings_error_list
Errors while loading minimal settings.
Definition settings.cpp:69
DeleteGRFPresetFromConfig
void DeleteGRFPresetFromConfig(std::string_view config_name)
Delete a NewGRF configuration by preset name.
Definition settings.cpp:1595
SetDefaultCompanySettings
void SetDefaultCompanySettings(CompanyID cid)
Set the company settings for a new company to their default values.
Definition settings.cpp:1857
IniLoadSettingList
static void IniLoadSettingList(IniFile &ini, std::string_view grpname, StringList &list)
Loads all items from a 'grpname' section into a list The list parameter can be a nullptr pointer,...
Definition settings.cpp:835
GetFilteredSettingCollection
std::vector< const SettingDesc * > GetFilteredSettingCollection(std::function< bool(const SettingDesc &desc)> func)
Get a collection of settings matching a custom filter.
Definition settings.cpp:1745
LoadFromConfig
void LoadFromConfig(bool startup)
Load the values from the configuration files.
Definition settings.cpp:1375
LoadGRFPresetFromConfig
GRFConfigList LoadGRFPresetFromConfig(std::string_view config_name)
Load a NewGRF configuration by preset-name.
Definition settings.cpp:1564
SetSettingValue
bool SetSettingValue(const IntSettingDesc *sd, int32_t value, bool force_newgame)
Top function to save the new value of an element of the Settings struct.
Definition settings.cpp:1818
SaveToConfig
void SaveToConfig()
Save the values to the configuration file.
Definition settings.cpp:1469
_old_vds
VehicleDefaultSettings _old_vds
Used for loading default vehicles settings from old savegames.
Definition settings.cpp:63
PrepareOldDiffCustom
void PrepareOldDiffCustom()
Prepare for reading and old diff_custom by zero-ing the memory.
Definition settings_sl.cpp:26
IniLoadSettings
static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, std::string_view grpname, void *object, bool only_startup)
Load values from a group of an IniFile structure into the internal representation.
Definition settings.cpp:620
GetSaveLoadFromSettingTable
void GetSaveLoadFromSettingTable(SettingTable settings, std::vector< SaveLoad > &saveloads)
Get the SaveLoad for all settings in the settings table.
Definition settings.cpp:1665
GraphicsSetSaveConfig
static void GraphicsSetSaveConfig(IniFile &ini)
Save BaseGraphics set selection and configuration.
Definition settings.cpp:1233
LoadIntList
static bool LoadIntList(std::optional< std::string_view > str, void *array, int nelems, VarType type)
Load parsed string-values into an integer-array (intlist)
Definition settings.cpp:282
ParseIntList
static std::optional< std::vector< uint32_t > > ParseIntList(std::string_view str)
Parse a string into a vector of uint32s.
Definition settings.cpp:247
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
CmdChangeCompanySetting
CommandCost CmdChangeCompanySetting(DoCommandFlags flags, const std::string &name, int32_t value)
Change one of the per-company settings.
Definition settings.cpp:1796
IniFileVersion
IniFileVersion
Ini-file versions.
Definition settings.cpp:166
IFV_0
@ IFV_0
0 All versions prior to introduction.
Definition settings.cpp:167
IFV_AUTOSAVE_RENAME
@ IFV_AUTOSAVE_RENAME
5 PR#11143 Renamed values of autosave to be in minutes.
Definition settings.cpp:173
IFV_LINKGRAPH_SECONDS
@ IFV_LINKGRAPH_SECONDS
3 PR#10610 Store linkgraph update intervals in seconds instead of days.
Definition settings.cpp:170
IFV_REMOVE_GENERATION_SEED
@ IFV_REMOVE_GENERATION_SEED
7 PR#11927 Remove "generation_seed" from configuration.
Definition settings.cpp:175
IFV_MAX_VERSION
@ IFV_MAX_VERSION
Highest possible ini-file version.
Definition settings.cpp:177
IFV_NETWORK_PRIVATE_SETTINGS
@ IFV_NETWORK_PRIVATE_SETTINGS
4 PR#10762 Move use_relay_service to private settings.
Definition settings.cpp:171
IFV_GAME_TYPE
@ IFV_GAME_TYPE
2 PR#9515 Convert server_advertise to server_game_type.
Definition settings.cpp:169
IFV_RIGHT_CLICK_CLOSE
@ IFV_RIGHT_CLICK_CLOSE
6 PR#10204 Add alternative right click to close windows setting.
Definition settings.cpp:174
IFV_PRIVATE_SECRETS
@ IFV_PRIVATE_SECRETS
1 PR#9298 Moving of settings from openttd.cfg to private.cfg / secrets.cfg.
Definition settings.cpp:168
GetSaveLoadSettingTable
SettingTable GetSaveLoadSettingTable()
Create a single table with all settings that should be stored/loaded in the savegame.
Definition settings.cpp:1678
IConsoleListSettings
void IConsoleListSettings(std::string_view prefilter)
List all settings and their value to the console.
Definition settings.cpp:2008
IniSaveSettingList
static void IniSaveSettingList(IniFile &ini, std::string_view grpname, StringList &list)
Saves all items from a list into the 'grpname' section The list parameter can be a nullptr pointer,...
Definition settings.cpp:857
INIFILE_VERSION
const uint16_t INIFILE_VERSION
Current ini-file version of OpenTTD.
Definition settings.cpp:180
IniSaveSettings
static void IniSaveSettings(IniFile &ini, const SettingTable &settings_table, std::string_view grpname, void *object, bool)
Save the values of settings to the inifile.
Definition settings.cpp:705
SecretSettingTables
static auto & SecretSettingTables()
List of all the secrets setting tables.
Definition settings.cpp:114
_private_file
std::string _private_file
Private configuration file of OpenTTD.
Definition settings.cpp:65
_settings_newgame
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
PrivateSettingTables
static auto & PrivateSettingTables()
List of all the private setting tables.
Definition settings.cpp:103
SaveVersionInConfig
static void SaveVersionInConfig(IniFile &ini)
Save the version of OpenTTD to the ini file.
Definition settings.cpp:1222
_config_file
std::string _config_file
Configuration file of OpenTTD.
Definition settings.cpp:64
LookupManyOfMany
static std::optional< uint32_t > LookupManyOfMany(std::span< const std::string_view > many, std::string_view str)
Find the set-integer value MANYofMANY type in a string.
Definition settings.cpp:221
GetSettingFromName
static const SettingDesc * GetSettingFromName(std::string_view name, const SettingTable &settings)
Given a name of setting, return a setting description from the table.
Definition settings.cpp:1640
GenericSettingTables
static auto & GenericSettingTables()
List of all the generic setting tables.
Definition settings.cpp:81
IniSaveWindowSettings
void IniSaveWindowSettings(IniFile &ini, std::string_view grpname, WindowDesc *desc)
Save a WindowDesc to config.
Definition settings.cpp:884
GetCompanySettingFromName
static const SettingDesc * GetCompanySettingFromName(std::string_view name)
Given a name of setting, return a company setting description of it.
Definition settings.cpp:1709
CmdChangeSetting
CommandCost CmdChangeSetting(DoCommandFlags flags, const std::string &name, int32_t value)
Network-safe changing of settings (server-only).
Definition settings.cpp:1770
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
settings_cmd.h
Command definitions related to settings.
settings_func.h
Functions related to setting/changing the settings.
SettingFlag::NotInSave
@ NotInSave
Do not save with savegame, basically client-based.
SettingFlag::Sandbox
@ Sandbox
This setting is a sandbox setting.
SettingFlag::SceneditOnly
@ SceneditOnly
This setting can only be changed in the scenario editor.
SettingFlag::PerCompany
@ PerCompany
This setting can be different for each company (saved in company struct).
SettingFlag::NewgameOnly
@ NewgameOnly
This setting cannot be changed in a game.
SettingFlag::GuiZeroIsSpecial
@ GuiZeroIsSpecial
A value of zero is possible and has a custom string (the one after "strval").
SettingFlag::NoNetwork
@ NoNetwork
This setting does not apply to network games; it may not be changed during the game.
SettingFlag::NotInConfig
@ NotInConfig
Do not save to config file.
SettingFlag::GuiDropdown
@ GuiDropdown
The value represents a limited number of string-options (internally integer) presented as dropdown.
SettingFlag::SceneditToo
@ SceneditToo
This setting can be changed in the scenario editor (only makes sense when SettingFlag::NewgameOnly is...
SettingFlag::NoNetworkSync
@ NoNetworkSync
Do not synchronize over network (but it is saved if SettingFlag::NotInSave is not set).
SettingFlag::NetworkOnly
@ NetworkOnly
This setting only applies to network games.
SettingType
SettingType
Type of settings for filtering.
Definition settings_internal.h:60
ST_CLIENT
@ ST_CLIENT
Client setting.
Definition settings_internal.h:63
ST_GAME
@ ST_GAME
Game setting.
Definition settings_internal.h:61
ST_COMPANY
@ ST_COMPANY
Company setting.
Definition settings_internal.h:62
GetSettingDesc
static constexpr const SettingDesc * GetSettingDesc(const SettingVariant &desc)
Helper to convert the type of the iterated settings description to a pointer to it.
Definition settings_internal.h:384
settings_table.h
Definition of the configuration tables of the settings.
GetGameSettings
GameSettings & GetGameSettings()
Get the settings-object applicable for the current situation: the newgame settings when we're in the ...
Definition settings_type.h:674
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
ConvertHexToBytes
bool ConvertHexToBytes(std::string_view hex, std::span< uint8_t > bytes)
Convert a hex-string to a byte-array, while validating it was actually hex.
Definition string.cpp:570
StrMakeValidInPlace
void StrMakeValidInPlace(char *str, StringValidationSettings settings)
Scans the string for invalid characters and replaces them with a question mark '?' (if not ignored).
Definition string.cpp:157
FormatArrayAsHex
std::string FormatArrayAsHex(std::span< const uint8_t > data)
Format a byte array into a continuous hex string.
Definition string.cpp:77
string_consumer.hpp
Parse strings.
string_func.h
Functions related to low-level strings.
StringList
std::vector< std::string > StringList
Type for a list of strings.
Definition string_type.h:60
GetEncodedString
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
strings_func.h
Functions related to OTTD's strings.
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:19
AutoRestoreBackup
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Definition backup_type.hpp:150
BaseGraphics::Ini::extra_version
uint32_t extra_version
version of the extra GRF
Definition base_media_graphics.h:67
BaseGraphics::Ini::extra_params
std::vector< uint32_t > extra_params
parameters for the extra GRF
Definition base_media_graphics.h:68
BaseGraphics::Ini::shortname
uint32_t shortname
unique key for base set
Definition base_media_graphics.h:66
BaseSet::name
std::string name
The name of the base set.
Definition base_media_base.h:62
BaseSet::shortname
uint32_t shortname
Four letter short variant of the name.
Definition base_media_base.h:65
BoolSettingDesc::FormatValue
std::string FormatValue(const void *object) const override
Format the value of the setting associated with this object.
Definition settings.cpp:747
BoolSettingDesc::ParseSingleValue
static std::optional< bool > ParseSingleValue(std::string_view str)
Find whether a string was a boolean true or a boolean false.
Definition settings.cpp:206
BoolSettingDesc::ParseValue
int32_t ParseValue(std::string_view str) const override
Convert a string representation (external) of an integer-like setting to an integer.
Definition settings.cpp:411
ClientSettings
All settings that are only important for the local client.
Definition settings_type.h:649
ClientSettings::company
CompanySettings company
default values for per-company settings
Definition settings_type.h:652
ClientSettings::network
NetworkSettings network
settings related to the network
Definition settings_type.h:651
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:650
CommandHelper
Definition command_func.h:83
CompanyProperties::settings
CompanySettings settings
settings specific for each company
Definition company_base.h:124
Company
Definition company_base.h:127
DifficultySettings::quantity_sea_lakes
uint8_t quantity_sea_lakes
the amount of seas/lakes
Definition settings_type.h:138
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition newgrf_config.h:158
GRFConfig::version
uint32_t version
NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown.
Definition newgrf_config.h:176
GRFConfig::param
std::vector< uint32_t > param
GRF parameters.
Definition newgrf_config.h:185
GUISettings::autosave_interval
uint32_t autosave_interval
how often should we do autosaves?
Definition settings_type.h:194
GUISettings::right_click_wnd_close
RightClickClose right_click_wnd_close
close window with right click
Definition settings_type.h:206
GameCreationSettings::land_generator
uint8_t land_generator
the landscape generator
Definition settings_type.h:384
GameSettings
All settings together for the game.
Definition settings_type.h:632
GameSettings::difficulty
DifficultySettings difficulty
settings related to the difficulty
Definition settings_type.h:633
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
GameSettings::linkgraph
LinkGraphSettings linkgraph
settings for link graph calculations
Definition settings_type.h:643
GraphicsSet
All data of a graphics set.
Definition base_media_graphics.h:41
IniFile
Ini file that supports both loading and saving.
Definition ini_type.h:86
IniFile::SaveToDisk
bool SaveToDisk(const std::string &filename)
Save the Ini file's data to the disk.
Definition ini.cpp:42
IniGroup
A group within an ini file.
Definition ini_type.h:34
IniGroup::GetItem
const IniItem * GetItem(std::string_view name) const
Get the item with the given name.
Definition ini_load.cpp:51
IniGroup::comment
std::string comment
comment for group
Definition ini_type.h:38
IniGroup::Clear
void Clear()
Clear all items in the group.
Definition ini_load.cpp:97
IniGroup::RemoveItem
void RemoveItem(std::string_view name)
Remove the item with the given name.
Definition ini_load.cpp:89
IniGroup::name
std::string name
name of group
Definition ini_type.h:37
IniGroup::CreateItem
IniItem & CreateItem(std::string_view name)
Create an item with the given name.
Definition ini_load.cpp:80
IniGroup::GetOrCreateItem
IniItem & GetOrCreateItem(std::string_view name)
Get the item with the given name, and if it doesn't exist create a new item.
Definition ini_load.cpp:65
IniGroup::items
std::list< IniItem > items
all items in the group
Definition ini_type.h:35
IniItem
A single "line" in an ini file.
Definition ini_type.h:23
IniItem::value
std::optional< std::string > value
The value of this item.
Definition ini_type.h:25
IniItem::name
std::string name
The name of this item.
Definition ini_type.h:24
IniItem::SetValue
void SetValue(std::string_view value)
Replace the current value with another value.
Definition ini_load.cpp:31
IniLoadFile::groups
std::list< IniGroup > groups
all groups in the ini
Definition ini_type.h:53
IniLoadFile::RemoveGroup
void RemoveGroup(std::string_view name)
Remove the group with the given name.
Definition ini_load.cpp:174
IniLoadFile::GetGroup
const IniGroup * GetGroup(std::string_view name) const
Get the group with the given name.
Definition ini_load.cpp:118
IniLoadFile::LoadFromDisk
void LoadFromDisk(std::string_view filename, Subdirectory subdir)
Load the Ini file's data from the disk.
Definition ini_load.cpp:185
IniLoadFile::GetOrCreateGroup
IniGroup & GetOrCreateGroup(std::string_view name)
Get the group with the given name, and if it doesn't exist create a new group.
Definition ini_load.cpp:146
IntSettingDesc
Base integer type, including boolean, settings.
Definition settings_internal.h:148
IntSettingDesc::str_help
StringID str_help
(Translated) string with help text; gui only.
Definition settings_internal.h:211
IntSettingDesc::str_val
StringID str_val
(Translated) first string describing the value.
Definition settings_internal.h:212
IntSettingDesc::MakeValueValid
void MakeValueValid(int32_t &value) const
Make the value valid given the limitations of this setting.
Definition settings.cpp:502
IntSettingDesc::ResetToDefault
void ResetToDefault(void *object) const override
Reset the setting to its default value.
Definition settings.cpp:766
IntSettingDesc::FormatValue
std::string FormatValue(const void *object) const override
Format the value of the setting associated with this object.
Definition settings.cpp:736
IntSettingDesc::def
int32_t def
default value given when none is present
Definition settings_internal.h:206
IntSettingDesc::GetRange
std::tuple< int32_t, uint32_t > GetRange() const
Get the min/max range for the setting.
Definition settings.cpp:476
IntSettingDesc::GetTitle
StringID GetTitle() const
Get the title of the setting.
Definition settings.cpp:427
IntSettingDesc::ChangeValue
void ChangeValue(const void *object, int32_t newvalue) const
Handle changing a value.
Definition settings.cpp:1611
IntSettingDesc::max
uint32_t max
maximum values
Definition settings_internal.h:208
IntSettingDesc::get_def_cb
GetDefaultValueCallback * get_def_cb
Callback to set the correct default value.
Definition settings_internal.h:219
IntSettingDesc::IsSameValue
bool IsSameValue(const IniItem *item, void *object) const override
Check whether the value in the Ini item is the same as is saved in this setting in the object.
Definition settings.cpp:753
IntSettingDesc::min
int32_t min
minimum values
Definition settings_internal.h:207
IntSettingDesc::pre_check
PreChangeCheck * pre_check
Callback to check for the validity of the setting.
Definition settings_internal.h:214
IntSettingDesc::GetDefaultValue
int32_t GetDefaultValue() const
Get the default value of the setting.
Definition settings.cpp:467
IntSettingDesc::Write
void Write(const void *object, int32_t value) const
Set the value of a setting.
Definition settings.cpp:556
IntSettingDesc::GetHelp
StringID GetHelp() const
Get the help text of the setting.
Definition settings.cpp:436
IntSettingDesc::IsBoolSetting
virtual bool IsBoolSetting() const
Check whether this setting is a boolean type setting.
Definition settings_internal.h:232
IntSettingDesc::post_callback
PostChangeCallback * post_callback
Callback when the setting has been changed.
Definition settings_internal.h:215
IntSettingDesc::str
StringID str
(translated) string with descriptive text; gui and console
Definition settings_internal.h:210
IntSettingDesc::MakeValueValidAndWrite
void MakeValueValidAndWrite(const void *object, int32_t value) const
Make the value valid and then write it to the setting.
Definition settings.cpp:487
IntSettingDesc::GetValueParams
std::pair< StringParameter, StringParameter > GetValueParams(int32_t value) const
Get parameters for drawing the value of the setting.
Definition settings.cpp:445
IntSettingDesc::Read
int32_t Read(const void *object) const
Read the integer from the the actual setting.
Definition settings.cpp:567
IntSettingDesc::ParseValue
virtual int32_t ParseValue(std::string_view str) const
Convert a string representation (external) of an integer-like setting to an integer.
Definition settings.cpp:367
IntSettingDesc::IsDefaultValue
bool IsDefaultValue(void *object) const override
Check whether the value is the same as the default value.
Definition settings.cpp:760
LinkGraphSettings::recalc_time
uint16_t recalc_time
time (in days) for recalculating each link graph component.
Definition settings_type.h:571
LinkGraphSettings::recalc_interval
uint16_t recalc_interval
time (in days) between subsequent checks for link graphs to be calculated.
Definition settings_type.h:572
ListSettingDesc::ParseValue
void ParseValue(const IniItem *item, void *object) const override
Parse/read the value from the Ini item into the setting associated with this object.
Definition settings.cpp:674
ListSettingDesc::ResetToDefault
void ResetToDefault(void *object) const override
Reset the setting to its default value.
Definition settings.cpp:820
ListSettingDesc::IsSameValue
bool IsSameValue(const IniItem *item, void *object) const override
Check whether the value in the Ini item is the same as is saved in this setting in the object.
Definition settings.cpp:808
ListSettingDesc::def
std::string_view def
default value given when none is present
Definition settings_internal.h:356
ListSettingDesc::FormatValue
std::string FormatValue(const void *object) const override
Convert an integer-array (intlist) to a string representation.
Definition settings.cpp:310
ListSettingDesc::IsDefaultValue
bool IsDefaultValue(void *object) const override
Check whether the value is the same as the default value.
Definition settings.cpp:814
ManyOfManySettingDesc::ParseValue
int32_t ParseValue(std::string_view str) const override
Convert a string representation (external) of an integer-like setting to an integer.
Definition settings.cpp:400
ManyOfManySettingDesc::FormatValue
std::string FormatValue(const void *object) const override
Format the value of the setting associated with this object.
Definition settings.cpp:347
NetworkSettings::admin_authorized_keys
NetworkAuthorizedKeys admin_authorized_keys
Public keys of clients that are authorized to use the admin network.
Definition settings_type.h:356
NetworkSettings::server_game_type
ServerGameType server_game_type
Server type: local / public / invite-only.
Definition settings_type.h:346
NetworkSettings::rcon_authorized_keys
NetworkAuthorizedKeys rcon_authorized_keys
Public keys of clients that are authorized to use the rconsole (server side).
Definition settings_type.h:353
NetworkSettings::use_relay_service
UseRelayService use_relay_service
Use relay service?
Definition settings_type.h:371
NetworkSettings::server_authorized_keys
NetworkAuthorizedKeys server_authorized_keys
Public keys of clients that are authorized to connect to the game.
Definition settings_type.h:351
OneOfManySettingDesc::many_cnvt
OnConvert * many_cnvt
callback procedure when loading value mechanism fails
Definition settings_internal.h:285
OneOfManySettingDesc::FormatValue
std::string FormatValue(const void *object) const override
Format the value of the setting associated with this object.
Definition settings.cpp:341
OneOfManySettingDesc::ParseSingleValue
static std::optional< uint32_t > ParseSingleValue(std::string_view str, std::span< const std::string_view > many)
Find the index value of a ONEofMANY type in a string.
Definition settings.cpp:188
OneOfManySettingDesc::many
std::vector< std::string_view > many
possible values for this type
Definition settings_internal.h:284
OneOfManySettingDesc::ParseValue
int32_t ParseValue(std::string_view str) const override
Convert a string representation (external) of an integer-like setting to an integer.
Definition settings.cpp:386
PoolID< uint8_t, struct CompanyIDTag, 0xF, 0xFF >
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition pool_type.hpp:376
SaveLoad::length
uint16_t length
(Conditional) length of the variable (eg. arrays) (max array size is 65536 elements).
Definition saveload.h:736
SaveLoad::version_to
SaveLoadVersion version_to
Save/load the variable before this savegame version.
Definition saveload.h:738
SaveLoad::conv
VarType conv
Type of the variable to be saved; this field combines both FileVarType and MemVarType.
Definition saveload.h:735
SaveLoad::version_from
SaveLoadVersion version_from
Save/load the variable starting from this savegame version.
Definition saveload.h:737
ScriptConfigSettings
Container for AI and Game script configuration.
Definition settings_type.h:620
ScriptConfigSettings::game
std::unique_ptr< class GameConfig > game
settings for gamescript
Definition settings_type.h:622
ScriptConfigSettings::ai
TypedIndexContainer< std::array< std::unique_ptr< class AIConfig >, MAX_COMPANIES >, CompanyID > ai
settings per company
Definition settings_type.h:621
SetBitIterator
Iterable ensemble of each set bit in a value.
Definition bitmath_func.hpp:277
SettingDesc
Properties of config file settings.
Definition settings_internal.h:71
SettingDesc::ParseValue
virtual void ParseValue(const IniItem *item, void *object) const =0
Parse/read the value from the Ini item into the setting associated with this object.
SettingDesc::IsEditable
bool IsEditable(bool do_command=false) const
Check whether the setting is editable in the current gamemode.
Definition settings.cpp:894
SettingDesc::flags
SettingFlags flags
Handles how a setting would show up in the GUI (text/currency, etc.).
Definition settings_internal.h:76
SettingDesc::IsStringSetting
virtual bool IsStringSetting() const
Check whether this setting is an string type setting.
Definition settings_internal.h:102
SettingDesc::GetType
SettingType GetType() const
Return the type of the setting.
Definition settings.cpp:911
SettingDesc::GetName
constexpr const std::string & GetName() const
Get the name of this setting.
Definition settings_internal.h:87
SettingDesc::startup
bool startup
Setting has to be loaded directly at startup?.
Definition settings_internal.h:77
SettingDesc::FormatValue
virtual std::string FormatValue(const void *object) const =0
Format the value of the setting associated with this object.
SettingDesc::AsStringSetting
const struct StringSettingDesc * AsStringSetting() const
Get the setting description of this setting as a string setting.
Definition settings.cpp:931
SettingDesc::IsSameValue
virtual bool IsSameValue(const IniItem *item, void *object) const =0
Check whether the value in the Ini item is the same as is saved in this setting in the object.
SettingDesc::save
SaveLoad save
Internal structure (going to savegame, parts to config).
Definition settings_internal.h:78
SettingDesc::IsIntSetting
virtual bool IsIntSetting() const
Check whether this setting is an integer type setting.
Definition settings_internal.h:96
SettingDesc::AsIntSetting
const struct IntSettingDesc * AsIntSetting() const
Get the setting description of this setting as an integer setting.
Definition settings.cpp:921
StringSettingDesc
String settings.
Definition settings_internal.h:310
StringSettingDesc::Read
const std::string & Read(const void *object) const
Read the string from the the actual setting.
Definition settings.cpp:606
StringSettingDesc::def
std::string_view def
Default value given when none is present.
Definition settings_internal.h:331
StringSettingDesc::Write
void Write(const void *object, std::string_view str) const
Write a string to the actual setting.
Definition settings.cpp:596
StringSettingDesc::max_length
uint32_t max_length
Maximum length of the string, 0 means no maximum length.
Definition settings_internal.h:332
StringSettingDesc::pre_check
PreChangeCheck * pre_check
Callback to check for the validity of the setting.
Definition settings_internal.h:333
StringSettingDesc::ChangeValue
void ChangeValue(const void *object, std::string &&newval) const
Handle changing a string value.
Definition settings.cpp:1913
StringSettingDesc::MakeValueValid
void MakeValueValid(std::string &str) const
Make the value valid given the limitations of this setting.
Definition settings.cpp:580
StringSettingDesc::IsSameValue
bool IsSameValue(const IniItem *item, void *object) const override
Check whether the value in the Ini item is the same as is saved in this setting in the object.
Definition settings.cpp:787
StringSettingDesc::IsDefaultValue
bool IsDefaultValue(void *object) const override
Check whether the value is the same as the default value.
Definition settings.cpp:797
StringSettingDesc::post_callback
PostChangeCallback * post_callback
Callback when the setting has been changed.
Definition settings_internal.h:334
StringSettingDesc::ResetToDefault
void ResetToDefault(void *object) const override
Reset the setting to its default value.
Definition settings.cpp:803
StringSettingDesc::FormatValue
std::string FormatValue(const void *object) const override
Format the value of the setting associated with this object.
Definition settings.cpp:771
StringSettingDesc::ParseValue
void ParseValue(const IniItem *item, void *object) const override
Parse/read the value from the Ini item into the setting associated with this object.
Definition settings.cpp:667
VehicleDefaultSettings
Default settings for vehicles.
Definition settings_type.h:601
WindowDesc
High level window description.
Definition window_gui.h:168
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3202
FindWindowById
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1151
window_func.h
Window functions not directly related to making/drawing windows.
WC_ERRMSG
@ WC_ERRMSG
Error message; Window numbers:
Definition window_type.h:115
WC_CHEATS
@ WC_CHEATS
Cheat window; Window numbers:
Definition window_type.h:647
WC_GAME_OPTIONS
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition window_type.h:635