diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 0d945c8593..2d9a2d7db4 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -495,7 +495,7 @@ DEF_CONSOLE_CMD(ConSaveConfig) return true; } - SaveToConfig(); + SaveToConfig(STCF_ALL); IConsolePrint(CC_DEFAULT, "Saved config."); return true; } diff --git a/src/fontcache.cpp b/src/fontcache.cpp index 6d1bb597b8..39493948dc 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -121,7 +121,7 @@ void SetFont(FontSize fontsize, const std::string& font, uint size, bool aa) UpdateAllVirtCoords(); ReInitAllWindows(true); - if (_save_config) SaveToConfig(); + if (_save_config) SaveToConfig(STCF_GENERIC); } #ifdef WITH_FREETYPE diff --git a/src/openttd.cpp b/src/openttd.cpp index 67c1a9e0c5..32d3f6f6d8 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1041,7 +1041,7 @@ int openttd_main(int argc, char *argv[]) /* only save config if we have to */ if (_save_config) { - SaveToConfig(); + SaveToConfig(STCF_ALL); SaveHotkeysToConfig(); WindowDesc::SaveToConfig(); SaveToHighScore(); diff --git a/src/settings.cpp b/src/settings.cpp index ad2c637351..8fac35bc03 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -2425,23 +2425,44 @@ void LoadFromConfig(bool startup) } /** Save the values to the configuration file */ -void SaveToConfig() +void SaveToConfig(SaveToConfigFlags flags) { + if (flags & STCF_PRIVATE) { + ConfigIniFile private_ini(_private_file); + + /* If we newly create the private/secrets file, add a dummy group on top + * just so we can add a comment before it (that is how IniFile works). + * This to explain what the file is about. After doing it once, never touch + * it again, as otherwise we might be reverting user changes. */ + if (!private_ini.GetGroup("private", false)) private_ini.GetGroup("private")->comment = "; This file possibly contains private information which can identify you as person.\n"; + + HandlePrivateSettingDescs(private_ini, IniSaveSettings, IniSaveSettingList); + SaveVersionInConfig(private_ini); + private_ini.SaveToDisk(_private_file); + } + + if (flags & STCF_SECRETS) { + ConfigIniFile secrets_ini(_secrets_file); + + /* If we newly create the private/secrets file, add a dummy group on top + * just so we can add a comment before it (that is how IniFile works). + * This to explain what the file is about. After doing it once, never touch + * it again, as otherwise we might be reverting user changes. */ + if (!secrets_ini.GetGroup("secrets", false)) secrets_ini.GetGroup("secrets")->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"; + + HandleSecretsSettingDescs(secrets_ini, IniSaveSettings, IniSaveSettingList); + SaveVersionInConfig(secrets_ini); + secrets_ini.SaveToDisk(_secrets_file); + } + + if ((flags & STCF_GENERIC) == 0) return; + PreTransparencyOptionSave(); ConfigIniFile generic_ini(_config_file); - ConfigIniFile private_ini(_private_file); - ConfigIniFile secrets_ini(_secrets_file); IniFileVersion generic_version = LoadVersionFromConfig(generic_ini); - /* If we newly create the private/secrets file, add a dummy group on top - * just so we can add a comment before it (that is how IniFile works). - * This to explain what the file is about. After doing it once, never touch - * it again, as otherwise we might be reverting user changes. */ - if (!private_ini.GetGroup("private", false)) private_ini.GetGroup("private")->comment = "; This file possibly contains private information which can identify you as person.\n"; - if (!secrets_ini.GetGroup("secrets", false)) secrets_ini.GetGroup("secrets")->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"; - if (generic_version == IFV_0) { /* Remove some obsolete groups. These have all been loaded into other groups. */ generic_ini.RemoveGroup("patches"); @@ -2478,20 +2499,14 @@ void SaveToConfig() } HandleSettingDescs(generic_ini, IniSaveSettings, IniSaveSettingList); - HandlePrivateSettingDescs(private_ini, IniSaveSettings, IniSaveSettingList); - HandleSecretsSettingDescs(secrets_ini, IniSaveSettings, IniSaveSettingList); + GRFSaveConfig(generic_ini, "newgrf", _grfconfig_newgame); GRFSaveConfig(generic_ini, "newgrf-static", _grfconfig_static); AISaveConfig(generic_ini, "ai_players"); GameSaveConfig(generic_ini, "game_scripts"); SaveVersionInConfig(generic_ini); - SaveVersionInConfig(private_ini); - SaveVersionInConfig(secrets_ini); - generic_ini.SaveToDisk(_config_file); - private_ini.SaveToDisk(_private_file); - secrets_ini.SaveToDisk(_secrets_file); } /** @@ -2568,7 +2583,7 @@ void DeleteGRFPresetFromConfig(const char *config_name) * @param object The object the setting is in. * @param newval The new value for the setting. */ -void IntSettingDesc::ChangeValue(const void *object, int32 newval) const +void IntSettingDesc::ChangeValue(const void *object, int32 newval, SaveToConfigFlags ini_save_flags) const { int32 oldval = this->Read(object); this->MakeValueValid(newval); @@ -2586,7 +2601,7 @@ void IntSettingDesc::ChangeValue(const void *object, int32 newval) const SetWindowClassesDirty(WC_GAME_OPTIONS); - if (_save_config) SaveToConfig(); + if (_save_config) SaveToConfig(ini_save_flags); } /** @@ -2653,6 +2668,20 @@ const SettingDesc *GetSettingFromName(const char *name) return GetCompanySettingFromName(name); } +SaveToConfigFlags ConfigSaveFlagsFor(const SettingDesc *sd) +{ + if (sd->flags & SF_PRIVATE) return STCF_PRIVATE; + if (sd->flags & SF_SECRET) return STCF_SECRETS; + return STCF_GENERIC; +} + +SaveToConfigFlags ConfigSaveFlagsUsingGameSettingsFor(const SettingDesc *sd) +{ + SaveToConfigFlags flags = ConfigSaveFlagsFor(sd); + if (_game_mode != GM_MENU && !sd->save.global) flags &= ~STCF_GENERIC; + return flags; +} + /** * Network-safe changing of settings (server-only). * @param tile unused @@ -2678,7 +2707,7 @@ CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (flags & DC_EXEC) { SCOPE_INFO_FMT([=], "CmdChangeSetting: %s -> %d", sd->name, p2); - sd->AsIntSetting()->ChangeValue(&GetGameSettings(), p2); + sd->AsIntSetting()->ChangeValue(&GetGameSettings(), p2, ConfigSaveFlagsUsingGameSettingsFor(sd)); } return CommandCost(); @@ -2713,7 +2742,7 @@ CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 if (flags & DC_EXEC) { SCOPE_INFO_FMT([=], "CmdChangeCompanySetting: %s -> %d", sd->name, p2); - sd->AsIntSetting()->ChangeValue(&Company::Get(_current_company)->settings, p2); + sd->AsIntSetting()->ChangeValue(&Company::Get(_current_company)->settings, p2, STCF_NONE); } return CommandCost(); @@ -2743,7 +2772,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) return false; } - setting->ChangeValue(&_settings_client.company, value); + setting->ChangeValue(&_settings_client.company, value, ConfigSaveFlagsFor(setting)); return true; } @@ -2755,14 +2784,14 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) if (no_newgame && _game_mode == GM_MENU) return false; if (setting->flags & SF_NO_NETWORK_SYNC) { if (_game_mode != GM_MENU && !no_newgame) { - setting->ChangeValue(&_settings_newgame, value); + setting->ChangeValue(&_settings_newgame, value, ConfigSaveFlagsFor(setting)); } - setting->ChangeValue(&GetGameSettings(), value); + setting->ChangeValue(&GetGameSettings(), value, ConfigSaveFlagsUsingGameSettingsFor(setting)); return true; } if (force_newgame && !no_newgame) { - setting->ChangeValue(&_settings_newgame, value); + setting->ChangeValue(&_settings_newgame, value, ConfigSaveFlagsFor(setting)); return true; } @@ -2819,7 +2848,7 @@ bool SetSettingValue(const StringSettingDesc *sd, std::string value, bool force_ } const void *object = (_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game; - sd->AsStringSetting()->ChangeValue(object, value); + sd->AsStringSetting()->ChangeValue(object, value, object == &_settings_newgame ? ConfigSaveFlagsFor(sd) : STCF_NONE); return true; } @@ -2829,7 +2858,7 @@ bool SetSettingValue(const StringSettingDesc *sd, std::string value, bool force_ * @param object The object the setting is in. * @param newval The new value for the setting. */ -void StringSettingDesc::ChangeValue(const void *object, std::string &newval) const +void StringSettingDesc::ChangeValue(const void *object, std::string &newval, SaveToConfigFlags ini_save_flags) const { this->MakeValueValid(newval); if (this->pre_check != nullptr && !this->pre_check(newval)) return; @@ -2837,7 +2866,7 @@ void StringSettingDesc::ChangeValue(const void *object, std::string &newval) con this->Write(object, newval); if (this->post_callback != nullptr) this->post_callback(newval); - if (_save_config) SaveToConfig(); + if (_save_config) SaveToConfig(ini_save_flags); } uint GetSettingIndexByFullName(const char *name) diff --git a/src/settings_func.h b/src/settings_func.h index f8ec87060c..c2298cc61a 100644 --- a/src/settings_func.h +++ b/src/settings_func.h @@ -21,7 +21,17 @@ void IConsoleGetSetting(const char *name, bool force_newgame = false); void IConsoleListSettings(const char *prefilter, bool show_defaults); void LoadFromConfig(bool minimal = false); -void SaveToConfig(); + +enum SaveToConfigFlags : uint32 { + STCF_NONE = 0, + STCF_GENERIC = 1 << 0, + STCF_PRIVATE = 1 << 1, + STCF_SECRETS = 1 << 2, + STCF_ALL = STCF_GENERIC | STCF_PRIVATE | STCF_SECRETS, +}; +DECLARE_ENUM_AS_BIT_SET(SaveToConfigFlags) + +void SaveToConfig(SaveToConfigFlags flags); void IniLoadWindowSettings(IniFile &ini, const char *grpname, void *desc); void IniSaveWindowSettings(IniFile &ini, const char *grpname, void *desc); diff --git a/src/settings_internal.h b/src/settings_internal.h index 465556803b..63b7b6ab5a 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -15,6 +15,8 @@ #include #include +enum SaveToConfigFlags : uint32; + enum SettingFlag : uint32 { SF_NONE = 0, SF_GUI_0_IS_SPECIAL = 1 << 0, ///< A value of zero is possible and has a custom string (the one after "strval"). @@ -40,6 +42,8 @@ enum SettingFlag : uint32 { SF_ENUM_PRE_CB_VALIDATE = 1 << 20, ///< Call the pre_check callback for enum incoming value validation SF_CONVERT_BOOL_TO_INT = 1 << 21, ///< Accept a boolean value when loading an int-type setting from the config file SF_ENABLE_UPSTREAM_LOAD = 1 << 22, ///< Enable loading from upstream mode savegames even when patx_name is set + SF_PRIVATE = 1 << 23, ///< Setting is in private ini + SF_SECRET = 1 << 24, ///< Setting is in secrets ini }; DECLARE_ENUM_AS_BIT_SET(SettingFlag) @@ -217,7 +221,7 @@ struct IntSettingDesc : SettingDesc { virtual bool IsBoolSetting() const { return false; } bool IsIntSetting() const override { return true; } - void ChangeValue(const void *object, int32 newvalue) const; + void ChangeValue(const void *object, int32 newvalue, SaveToConfigFlags ini_save_flags) const; void MakeValueValidAndWrite(const void *object, int32 value) const; virtual size_t ParseValue(const char *str) const; @@ -308,7 +312,7 @@ struct StringSettingDesc : SettingDesc { PostChangeCallback *post_callback; ///< Callback when the setting has been changed. bool IsStringSetting() const override { return true; } - void ChangeValue(const void *object, std::string &newval) const; + void ChangeValue(const void *object, std::string &newval, SaveToConfigFlags ini_save_flags) const; void FormatValue(char *buf, const char *last, const void *object) const override; void ParseValue(const IniItem *item, void *object) const override; diff --git a/src/table/settings/network_private_settings.ini b/src/table/settings/network_private_settings.ini index 85fda03eaa..bc2957b25b 100644 --- a/src/table/settings/network_private_settings.ini +++ b/src/table/settings/network_private_settings.ini @@ -14,9 +14,9 @@ static const SettingTable _network_private_settings = { [post-amble] }; [templates] -SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), -SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), -SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), +SDTC_BOOL = SDTC_BOOL( $var, $flags | SF_PRIVATE, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), +SDTC_OMANY = SDTC_OMANY( $var, $type, $flags | SF_PRIVATE, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), +SDTC_SSTR = SDTC_SSTR( $var, $type, $flags | SF_PRIVATE, $def, $length, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), [validation] SDTC_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); diff --git a/src/table/settings/network_secrets_settings.ini b/src/table/settings/network_secrets_settings.ini index aba8c14a4b..0c718a94ae 100644 --- a/src/table/settings/network_secrets_settings.ini +++ b/src/table/settings/network_secrets_settings.ini @@ -17,7 +17,7 @@ static const SettingTable _network_secrets_settings = { [post-amble] }; [templates] -SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), +SDTC_SSTR = SDTC_SSTR( $var, $type, $flags | SF_SECRET, $def, $length, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr), [validation]