using System;
using System.Collections.Generic;
using System.Linq;
using StardewModdingAPI.Internal.ConsoleWriting;
using StardewModdingAPI.Toolkit.Utilities;
namespace StardewModdingAPI.Framework.Models
{
/// The SMAPI configuration settings.
internal class SConfig
{
/********
** Fields
********/
/// The default config values, for fields that should be logged if different.
private static readonly IDictionary DefaultValues = new Dictionary
{
[nameof(CheckForUpdates)] = true,
[nameof(ParanoidWarnings)] = Constants.IsDebugBuild,
[nameof(UseBetaChannel)] = Constants.ApiVersion.IsPrerelease(),
[nameof(GitHubProjectName)] = "Pathoschild/SMAPI",
[nameof(WebApiBaseUrl)] = "https://smapi.io/api/",
[nameof(LogNetworkTraffic)] = false,
[nameof(RewriteMods)] = true,
[nameof(UseCaseInsensitivePaths)] = Constants.Platform is Platform.Android or Platform.Linux,
[nameof(SuppressHarmonyDebugMode)] = true
};
/// The default values for , to log changes if different.
private static readonly HashSet DefaultSuppressUpdateChecks = new(StringComparer.OrdinalIgnoreCase)
{
"SMAPI.ConsoleCommands",
"SMAPI.ErrorHandler",
"SMAPI.SaveBackup"
};
/********
** Accessors
********/
//
// Note: properties must be writable to support merging config.user.json into it.
//
/// Whether to enable development features.
public bool DeveloperMode { get; set; }
/// Whether to check for newer versions of SMAPI and mods on startup.
public bool CheckForUpdates { get; set; }
/// Whether to add a section to the 'mod issues' list for mods which which directly use potentially sensitive .NET APIs like file or shell access.
public bool ParanoidWarnings { get; set; }
/// Whether to show beta versions as valid updates.
public bool UseBetaChannel { get; set; }
/// SMAPI's GitHub project name, used to perform update checks.
public string GitHubProjectName { get; set; }
/// The base URL for SMAPI's web API, used to perform update checks.
public string WebApiBaseUrl { get; set; }
/// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.
/// The possible values are "*" (everything is verbose), "SMAPI", (SMAPI itself), or mod IDs.
public HashSet VerboseLogging { get; set; }
/// Whether SMAPI should rewrite mods for compatibility.
public bool RewriteMods { get; set; }
/// Whether to make SMAPI file APIs case-insensitive, even on Linux.
public bool UseCaseInsensitivePaths { get; set; }
/// Whether SMAPI should log network traffic. Best combined with , which includes network metadata.
public bool LogNetworkTraffic { get; set; }
/// The colors to use for text written to the SMAPI console.
public ColorSchemeConfig ConsoleColors { get; set; }
/// Whether to prevent mods from enabling Harmony's debug mode, which impacts performance and creates a file on your desktop. Debug mode should never be enabled by a released mod.
public bool SuppressHarmonyDebugMode { get; set; }
/// The mod IDs SMAPI should ignore when performing update checks or validating update keys.
public HashSet SuppressUpdateChecks { get; set; }
/// The mod IDs SMAPI should try to load early, before any other mods not included in this list.
public List ModsToLoadEarly { get; set; }
/// The mod IDs SMAPI should try to load late, after all other mods not included in this list.
public List ModsToLoadLate { get; set; }
/********
** Public methods
********/
/// Construct an instance.
/// Whether to enable development features.
/// Whether to check for newer versions of SMAPI and mods on startup.
/// Whether to add a section to the 'mod issues' list for mods which which directly use potentially sensitive .NET APIs like file or shell access.
/// Whether to show beta versions as valid updates.
/// SMAPI's GitHub project name, used to perform update checks.
/// The base URL for SMAPI's web API, used to perform update checks.
/// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.
/// Whether SMAPI should rewrite mods for compatibility.
/// >Whether to make SMAPI file APIs case-insensitive, even on Linux.
/// Whether SMAPI should log network traffic.
/// The colors to use for text written to the SMAPI console.
/// Whether to prevent mods from enabling Harmony's debug mode, which impacts performance and creates a file on your desktop. Debug mode should never be enabled by a released mod.
/// The mod IDs SMAPI should ignore when performing update checks or validating update keys.
/// The mod IDs SMAPI should try to load early, before any other mods not included in this list.
/// The mod IDs SMAPI should try to load late, after all other mods not included in this list.
public SConfig(bool developerMode, bool? checkForUpdates, bool? paranoidWarnings, bool? useBetaChannel, string gitHubProjectName, string webApiBaseUrl, string[]? verboseLogging, bool? rewriteMods, bool? useCaseInsensitivePaths, bool? logNetworkTraffic, ColorSchemeConfig consoleColors, bool? suppressHarmonyDebugMode, string[]? suppressUpdateChecks, string[]? modsToLoadEarly, string[]? modsToLoadLate)
{
this.DeveloperMode = developerMode;
this.CheckForUpdates = checkForUpdates ?? (bool)SConfig.DefaultValues[nameof(this.CheckForUpdates)];
this.ParanoidWarnings = paranoidWarnings ?? (bool)SConfig.DefaultValues[nameof(this.ParanoidWarnings)];
this.UseBetaChannel = useBetaChannel ?? (bool)SConfig.DefaultValues[nameof(this.UseBetaChannel)];
this.GitHubProjectName = gitHubProjectName;
this.WebApiBaseUrl = webApiBaseUrl;
this.VerboseLogging = new HashSet(verboseLogging ?? Array.Empty(), StringComparer.OrdinalIgnoreCase);
this.RewriteMods = rewriteMods ?? (bool)SConfig.DefaultValues[nameof(this.RewriteMods)];
this.UseCaseInsensitivePaths = useCaseInsensitivePaths ?? (bool)SConfig.DefaultValues[nameof(this.UseCaseInsensitivePaths)];
this.LogNetworkTraffic = logNetworkTraffic ?? (bool)SConfig.DefaultValues[nameof(this.LogNetworkTraffic)];
this.ConsoleColors = consoleColors;
this.SuppressHarmonyDebugMode = suppressHarmonyDebugMode ?? (bool)SConfig.DefaultValues[nameof(this.SuppressHarmonyDebugMode)];
this.SuppressUpdateChecks = new HashSet(suppressUpdateChecks ?? Array.Empty(), StringComparer.OrdinalIgnoreCase);
this.ModsToLoadEarly = new List(modsToLoadEarly ?? Array.Empty());
this.ModsToLoadLate = new List(modsToLoadLate ?? Array.Empty());
}
/// Override the value of .
/// The value to set.
public void OverrideDeveloperMode(bool value)
{
this.DeveloperMode = value;
}
/// Get the settings which have been customized by the player.
public IDictionary GetCustomSettings()
{
Dictionary custom = new();
foreach ((string? name, object defaultValue) in SConfig.DefaultValues)
{
object? value = typeof(SConfig).GetProperty(name)?.GetValue(this);
if (!defaultValue.Equals(value))
custom[name] = value;
}
if (!this.SuppressUpdateChecks.SetEquals(SConfig.DefaultSuppressUpdateChecks))
custom[nameof(this.SuppressUpdateChecks)] = $"[{string.Join(", ", this.SuppressUpdateChecks)}]";
if (this.VerboseLogging.Any())
custom[nameof(this.VerboseLogging)] = $"[{string.Join(", ", this.VerboseLogging)}]";
return custom;
}
}
}