From ad9cb482d0f6a00eafca5cbf1c5bdfffdb598c51 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 25 Jan 2026 00:00:01 -0500 Subject: [PATCH] add integration with Generic Mod Config Menu --- docs/README.md | 32 +- docs/release-notes.md | 1 + .../ConsoleWriting/ColorfulConsoleWriter.cs | 21 +- src/SMAPI/Framework/Logging/LogManager.cs | 60 ++- src/SMAPI/Framework/Models/SConfig.cs | 39 +- src/SMAPI/Framework/Monitor.cs | 21 +- src/SMAPI/Framework/SCore.cs | 66 +++- .../GenericModConfigMenuIntegration.cs | 343 ++++++++++++++++++ .../IGenericModConfigMenuApi.cs | 55 +++ .../JsonSettingsWrapper.cs | 195 ++++++++++ src/SMAPI/SMAPI.config.json | 5 +- src/SMAPI/i18n/de.json | 51 ++- src/SMAPI/i18n/default.json | 50 ++- src/SMAPI/i18n/es.json | 51 ++- src/SMAPI/i18n/fr.json | 51 ++- src/SMAPI/i18n/hu.json | 51 ++- src/SMAPI/i18n/id.json | 51 ++- src/SMAPI/i18n/it.json | 51 ++- src/SMAPI/i18n/ja.json | 51 ++- src/SMAPI/i18n/ko.json | 51 ++- src/SMAPI/i18n/pl.json | 51 ++- src/SMAPI/i18n/pt.json | 51 ++- src/SMAPI/i18n/ru.json | 51 ++- src/SMAPI/i18n/th.json | 51 ++- src/SMAPI/i18n/tr.json | 51 ++- src/SMAPI/i18n/uk.json | 51 ++- src/SMAPI/i18n/zh.json | 51 ++- 27 files changed, 1566 insertions(+), 87 deletions(-) create mode 100644 src/SMAPI/Integrations/GenericModConfigMenu/GenericModConfigMenuIntegration.cs create mode 100644 src/SMAPI/Integrations/GenericModConfigMenu/IGenericModConfigMenuApi.cs create mode 100644 src/SMAPI/Integrations/GenericModConfigMenu/JsonSettingsWrapper.cs diff --git a/docs/README.md b/docs/README.md index 95cb9848..f4245146 100644 --- a/docs/README.md +++ b/docs/README.md @@ -58,22 +58,22 @@ contributing translations. locale | status ----------- | :---------------- -default | ✓ [fully translated](../src/SMAPI/i18n/default.json) -Chinese | ✓ [fully translated](../src/SMAPI/i18n/zh.json) -French | ✓ [fully translated](../src/SMAPI/i18n/fr.json) -German | ✓ [fully translated](../src/SMAPI/i18n/de.json) -Hungarian | ✓ [fully translated](../src/SMAPI/i18n/hu.json) -Indonesian | ✓ [fully translated](../src/SMAPI/i18n/id.json) -Italian | ✓ [fully translated](../src/SMAPI/i18n/it.json) -Japanese | ✓ [fully translated](../src/SMAPI/i18n/ja.json) -Korean | ✓ [fully translated](../src/SMAPI/i18n/ko.json) -[Polish] | ✓ [fully translated](../src/SMAPI/i18n/pl.json) -Portuguese | ✓ [fully translated](../src/SMAPI/i18n/pt.json) -Russian | ✓ [fully translated](../src/SMAPI/i18n/ru.json) -Spanish | ✓ [fully translated](../src/SMAPI/i18n/es.json) -[Thai] | ✓ [fully translated](../src/SMAPI/i18n/th.json) -Turkish | ✓ [fully translated](../src/SMAPI/i18n/tr.json) -[Ukrainian] | ✓ [fully translated](../src/SMAPI/i18n/uk.json) +default | ↻ [partly translated](../src/SMAPI/i18n/default.json) +Chinese | ↻ [partly translated](../src/SMAPI/i18n/zh.json) +French | ↻ [partly translated](../src/SMAPI/i18n/fr.json) +German | ↻ [partly translated](../src/SMAPI/i18n/de.json) +Hungarian | ↻ [partly translated](../src/SMAPI/i18n/hu.json) +Indonesian | ↻ [partly translated](../src/SMAPI/i18n/id.json) +Italian | ↻ [partly translated](../src/SMAPI/i18n/it.json) +Japanese | ↻ [partly translated](../src/SMAPI/i18n/ja.json) +Korean | ↻ [partly translated](../src/SMAPI/i18n/ko.json) +[Polish] | ↻ [partly translated](../src/SMAPI/i18n/pl.json) +Portuguese | ↻ [partly translated](../src/SMAPI/i18n/pt.json) +Russian | ↻ [partly translated](../src/SMAPI/i18n/ru.json) +Spanish | ↻ [partly translated](../src/SMAPI/i18n/es.json) +[Thai] | ↻ [partly translated](../src/SMAPI/i18n/th.json) +Turkish | ↻ [partly translated](../src/SMAPI/i18n/tr.json) +[Ukrainian] | ↻ [partly translated](../src/SMAPI/i18n/uk.json) [Polish]: https://www.nexusmods.com/stardewvalley/mods/3616 [Thai]: https://www.nexusmods.com/stardewvalley/mods/7052 diff --git a/docs/release-notes.md b/docs/release-notes.md index 39e4b91d..241ce635 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,6 +3,7 @@ # Release notes ## Upcoming release * For players: + * Added in-game config UI via [Generic Mod Config Menu](). * SMAPI now uses [automated and attested builds](https://www.patreon.com/posts/automated-builds-148417912) (thanks to DecidedlyHuman)! _This improves the security and transparency of SMAPI builds. Every step to build SMAPI from the public source code is now public and verifiable, with file signatures to let players and tools confirm the build hasn't been tampered with._ * SMAPI can now detect known malicious loose files in the `Mods` folder. diff --git a/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs b/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs index 4fdfc3b7..aaea200e 100644 --- a/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs +++ b/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs @@ -11,12 +11,15 @@ internal class ColorfulConsoleWriter : IConsoleWriter /********* ** Fields *********/ + /// The target platform. + private readonly Platform Platform; + /// The console text color for each log level. - private readonly IDictionary? Colors; + private IDictionary? Colors; /// Whether the current console supports color formatting. [MemberNotNullWhen(true, nameof(ColorfulConsoleWriter.Colors))] - private bool SupportsColor { get; } + private bool SupportsColor { get; set; } /********* @@ -32,6 +35,16 @@ internal class ColorfulConsoleWriter : IConsoleWriter /// The color scheme ID in to use, or to select one automatically. /// The colors to use for text written to the SMAPI console. public ColorfulConsoleWriter(Platform platform, MonitorColorScheme colorSchemeId, Dictionary> colorConfig) + { + this.Platform = platform; + + this.SetColors(colorSchemeId, colorConfig); + } + + /// Set the color scheme to apply. + /// The color scheme ID in to use, or to select one automatically. + /// The colors to use for text written to the SMAPI console. + public void SetColors(MonitorColorScheme colorSchemeId, Dictionary> colorSchemes) { if (colorSchemeId == MonitorColorScheme.None) { @@ -41,7 +54,7 @@ internal class ColorfulConsoleWriter : IConsoleWriter else { this.SupportsColor = this.TestColorSupport(); - this.Colors = this.GetConsoleColorScheme(platform, colorSchemeId, colorConfig); + this.Colors = ColorfulConsoleWriter.GetConsoleColorScheme(this.Platform, colorSchemeId, colorSchemes); } } @@ -123,7 +136,7 @@ internal class ColorfulConsoleWriter : IConsoleWriter /// The target platform. /// The color scheme ID in to use, or to select one automatically. /// The colors to use for text written to the SMAPI console. - private IDictionary GetConsoleColorScheme(Platform platform, MonitorColorScheme colorSchemeId, Dictionary> colorConfig) + private static IDictionary GetConsoleColorScheme(Platform platform, MonitorColorScheme colorSchemeId, Dictionary> colorConfig) { // get color scheme ID if (colorSchemeId == MonitorColorScheme.AutoDetect) diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 573d9185..59edad26 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -28,6 +28,12 @@ internal class LogManager : IDisposable /// Create a monitor instance given the ID and name. private readonly Func GetMonitorImpl; + /// The console writer which sends color-coded text to the console. + private readonly ColorfulConsoleWriter ConsoleWriter; + + /// The monitors managed by SMAPI. + private readonly List Monitors = []; + /********* ** Accessors @@ -59,12 +65,9 @@ internal class LogManager : IDisposable this.LogFile = new LogFileManager(logPath); // init monitor - this.GetMonitorImpl = (id, name) => new Monitor(id, name, this.LogFile, colorSchemeId, colorConfig, verboseLogging.Contains("*") || verboseLogging.Contains(id), getScreenIdForLog) - { - WriteToConsole = writeToConsole, - ShowTraceInConsole = isDeveloperMode, - ShowFullStampInConsole = isDeveloperMode - }; + this.ConsoleWriter = new ColorfulConsoleWriter(Constants.Platform, colorSchemeId, colorConfig); + this.GetMonitorImpl = (id, name) => this.CreateAndRegisterMonitor(id, name, verboseLogging, getScreenIdForLog, writeToConsole, isDeveloperMode); + this.Monitor = this.GetMonitor("SMAPI", "SMAPI"); this.MonitorForGame = this.GetMonitor("game", "game"); @@ -91,6 +94,19 @@ internal class LogManager : IDisposable Console.Title = title; } + /// Apply the SMAPI settings to the log manager and its managed monitors. + /// The color scheme ID in to use, or to select one automatically. + /// The colors to use for text written to the SMAPI console. + /// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting. + /// Whether to enable full console output for developers. + public void ApplySettings(MonitorColorScheme colorSchemeId, Dictionary> colorSchemes, HashSet verboseLogging, bool isDeveloperMode) + { + foreach (Monitor monitor in this.Monitors) + this.ApplySettings(monitor, verboseLogging, isDeveloperMode); + + this.ConsoleWriter.SetColors(colorSchemeId, colorSchemes); + } + /**** ** Console input ****/ @@ -333,6 +349,38 @@ internal class LogManager : IDisposable /********* ** Protected methods *********/ + /// Create and register a monitor instance. + /// The mod ID, if applicable. + /// The name of the module which logs messages using this instance. + /// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting. + /// Get the screen ID that should be logged to distinguish between players in split-screen mode, if any. + /// Whether to write anything to the console. This should be disabled if no console is available. + /// Whether to enable full console output for developers. + private Monitor CreateAndRegisterMonitor(string modId, string source, HashSet verboseLogging, Func getScreenIdForLog, bool writeToConsole, bool isDeveloperMode) + { + Monitor monitor = new(modId, source, this.LogFile, this.ConsoleWriter, getScreenIdForLog) + { + WriteToConsole = writeToConsole + }; + + this.ApplySettings(monitor, verboseLogging, isDeveloperMode); + + this.Monitors.Add(monitor); + + return monitor; + } + + /// Apply the SMAPI settings to a managed monitor. + /// The monitor to update. + /// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting. + /// Whether to enable full console output for developers. + private void ApplySettings(Monitor monitor, HashSet verboseLogging, bool isDeveloperMode) + { + monitor.IsVerbose = verboseLogging.Contains("*") || verboseLogging.Contains(monitor.ModId); + monitor.ShowTraceInConsole = isDeveloperMode; + monitor.ShowFullStampInConsole = isDeveloperMode; + } + /// Write a summary of mod warnings to the console and log. /// The loaded mods. /// The mods which could not be loaded. diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs index b8b80cee..febb71f5 100644 --- a/src/SMAPI/Framework/Models/SConfig.cs +++ b/src/SMAPI/Framework/Models/SConfig.cs @@ -15,20 +15,21 @@ internal class SConfig /// The default config values, for fields that should be logged if different. private static readonly IDictionary DefaultValues = new Dictionary { - [nameof(CheckForUpdates)] = true, - [nameof(CheckForBlacklistUpdates)] = true, - [nameof(CheckContentIntegrity)] = true, - [nameof(ListenForConsoleInput)] = true, - [nameof(ParanoidWarnings)] = Constants.IsDebugBuild, - [nameof(UseBetaChannel)] = Constants.ApiVersion.IsPrerelease(), - [nameof(GitHubProjectName)] = "Pathoschild/SMAPI", - [nameof(WebApiBaseUrl)] = "https://smapi.io/api/", - [nameof(LogNetworkTraffic)] = false, - [nameof(LogTechnicalDetailsForBrokenMods)] = false, - [nameof(RewriteMods)] = true, - [nameof(FixHarmony)] = true, - [nameof(UseCaseInsensitivePaths)] = Constants.Platform is Platform.Android or Platform.Linux, - [nameof(SuppressHarmonyDebugMode)] = true + [nameof(SConfig.CheckForUpdates)] = true, + [nameof(SConfig.CheckForBlacklistUpdates)] = true, + [nameof(SConfig.CheckContentIntegrity)] = true, + [nameof(SConfig.ListenForConsoleInput)] = true, + [nameof(SConfig.ParanoidWarnings)] = Constants.IsDebugBuild, + [nameof(SConfig.UseBetaChannel)] = Constants.ApiVersion.IsPrerelease(), + [nameof(SConfig.GitHubProjectName)] = "Pathoschild/SMAPI", + [nameof(SConfig.WebApiBaseUrl)] = "https://smapi.io/api/", + [nameof(SConfig.LogNetworkTraffic)] = false, + [nameof(SConfig.LogTechnicalDetailsForBrokenMods)] = false, + [nameof(SConfig.RewriteMods)] = true, + [nameof(SConfig.EnableConfigMenu)] = true, + [nameof(SConfig.FixHarmony)] = true, + [nameof(SConfig.UseCaseInsensitivePaths)] = Constants.Platform is Platform.Android or Platform.Linux, + [nameof(SConfig.SuppressHarmonyDebugMode)] = true }; /// The default values for , to log changes if different. @@ -46,7 +47,7 @@ internal class SConfig // Note: properties must be writable to support merging config.user.json into it. // - /// Whether to enable development features. + /// Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players. public bool DeveloperMode { get; set; } /// Whether to check for newer versions of SMAPI and mods on startup. @@ -61,7 +62,7 @@ internal class SConfig /// Whether SMAPI should listen for console input to support console commands. public bool ListenForConsoleInput { 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. + /// Whether to add a section to the 'mod issues' list for mods 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. @@ -83,6 +84,9 @@ internal class SConfig /// Whether SMAPI should rewrite mods for compatibility. public bool RewriteMods { get; set; } + /// Whether SMAPI should add an in-game config menu through Generic Mod Config Menu. + public bool EnableConfigMenu { get; set; } + /// Whether to apply fixes to Harmony so it works with Stardew Valley. public bool FixHarmony { get; set; } @@ -130,6 +134,7 @@ internal class SConfig /// /// /// + /// /// /// /// @@ -153,6 +158,7 @@ internal class SConfig string blacklistUrl, string[]? verboseLogging, bool? rewriteMods, + bool? enableConfigMenu, bool? fixHarmony, bool? useCaseInsensitivePaths, bool? logNetworkTraffic, @@ -177,6 +183,7 @@ internal class SConfig this.BlacklistUrl = blacklistUrl; this.VerboseLogging = new HashSet(verboseLogging ?? [], StringComparer.OrdinalIgnoreCase); this.RewriteMods = rewriteMods ?? (bool)SConfig.DefaultValues[nameof(this.RewriteMods)]; + this.EnableConfigMenu = enableConfigMenu ?? (bool)SConfig.DefaultValues[nameof(this.EnableConfigMenu)]; this.FixHarmony = fixHarmony ?? (bool)SConfig.DefaultValues[nameof(this.FixHarmony)]; this.UseCaseInsensitivePaths = useCaseInsensitivePaths ?? (bool)SConfig.DefaultValues[nameof(this.UseCaseInsensitivePaths)]; this.LogNetworkTraffic = logNetworkTraffic ?? (bool)SConfig.DefaultValues[nameof(this.LogNetworkTraffic)]; diff --git a/src/SMAPI/Framework/Monitor.cs b/src/SMAPI/Framework/Monitor.cs index 031500e2..8e13ab1d 100644 --- a/src/SMAPI/Framework/Monitor.cs +++ b/src/SMAPI/Framework/Monitor.cs @@ -13,9 +13,6 @@ internal class Monitor : IMonitor /********* ** Fields *********/ - /// The mod ID, if applicable. - private readonly string ModId; - /// The name of the module which logs messages using this instance. private readonly string Source; @@ -41,6 +38,9 @@ internal class Monitor : IMonitor /********* ** Accessors *********/ + /// The mod ID, if applicable. + public string ModId { get; } + /// Whether to log basic contextual info (like buttons pressed and menus opened) even if is disabled. public static bool ForceLogContext { get; set; } @@ -54,7 +54,11 @@ internal class Monitor : IMonitor public static LogLevel ContextLogLevel => Monitor.ForceLogContext ? LogLevel.Info : LogLevel.Trace; /// - public bool IsVerbose => field || Monitor.ForceVerboseLoggingForAll || Monitor.ForceVerboseLogging.Contains(this.ModId); + public bool IsVerbose + { + get => field || Monitor.ForceVerboseLoggingForAll || Monitor.ForceVerboseLogging.Contains(this.ModId); + set => field = value; + } /// Whether to show the full log stamps (with time/level/logger) in the console. If false, shows a simplified stamp with only the logger. internal bool ShowFullStampInConsole { get; set; } @@ -73,11 +77,9 @@ internal class Monitor : IMonitor /// The mod ID, if applicable. /// The name of the module which logs messages using this instance. /// The log file to which to write messages. - /// The color scheme ID in to use, or to select one automatically. - /// The colors to use for text written to the SMAPI console. - /// Whether verbose logging is enabled. This enables more detailed diagnostic messages than are normally needed. + /// Handles writing text to the console. /// Get the screen ID that should be logged to distinguish between players in split-screen mode, if any. - public Monitor(string modId, string source, LogFileManager logFile, MonitorColorScheme colorSchemeId, Dictionary> colorConfig, bool isVerbose, Func getScreenIdForLog) + public Monitor(string modId, string source, LogFileManager logFile, IConsoleWriter consoleWriter, Func getScreenIdForLog) { // validate if (string.IsNullOrWhiteSpace(source)) @@ -87,8 +89,7 @@ internal class Monitor : IMonitor this.ModId = modId; this.Source = source; this.LogFile = logFile ?? throw new ArgumentNullException(nameof(logFile), "The log file manager cannot be null."); - this.ConsoleWriter = new ColorfulConsoleWriter(Constants.Platform, colorSchemeId, colorConfig); - this.IsVerbose = isVerbose; + this.ConsoleWriter = consoleWriter ?? throw new ArgumentNullException(nameof(consoleWriter), "The console writer cannot be null."); this.GetScreenIdForLog = getScreenIdForLog; } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 517c6a51..036ec76c 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -37,6 +37,7 @@ using StardewModdingAPI.Framework.Rendering; using StardewModdingAPI.Framework.Serialization; using StardewModdingAPI.Framework.StateTracking.Snapshots; using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Integrations.GenericModConfigMenu; using StardewModdingAPI.Internal; using StardewModdingAPI.Toolkit; using StardewModdingAPI.Toolkit.Framework.Clients.WebApi; @@ -85,12 +86,12 @@ internal class SCore : IDisposable /// Encapsulates access to SMAPI core translations. private readonly Translator Translator = new(); - /// The SMAPI configuration settings. - private readonly SConfig Settings; - /// The mod toolkit used for generic mod interactions. private readonly ModToolkit Toolkit = new(); + /// The SMAPI configuration settings. + private SConfig Settings; + /**** ** Higher-level components ****/ @@ -113,13 +114,15 @@ internal class SCore : IDisposable /// Manages SMAPI events for mods. private readonly EventManager EventManager; - /**** ** State ****/ /// The path to search for mods. private string ModsPath => Constants.ModsPath; + /// The override to apply for , or null to use the value from the settings file. + private readonly bool? OverrideDeveloperMode; + /// Whether the game is currently running. private bool IsGameRunning; @@ -178,8 +181,8 @@ internal class SCore : IDisposable /// Construct an instance. /// The path to search for mods. /// Whether to output log messages to the console. - /// Whether to enable development features, or null to use the value from the settings file. - public SCore(string modsPath, bool writeToConsole, bool? developerMode) + /// The override to apply for , or null to use the value from the settings file. + public SCore(string modsPath, bool writeToConsole, bool? overrideDeveloperMode) { SCore.Instance = this; @@ -193,17 +196,8 @@ internal class SCore : IDisposable string logPath = this.GetLogPath(); // init settings - { - var deserializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; - - this.Settings = JsonConvert.DeserializeObject(File.ReadAllText(Constants.ApiConfigPath)) ?? throw new InvalidOperationException("The 'smapi-internal/config.json' file is missing or invalid. You can reinstall SMAPI to fix this."); - if (File.Exists(Constants.ApiUserConfigPath)) - JsonConvert.PopulateObject(File.ReadAllText(Constants.ApiUserConfigPath), this.Settings, deserializerSettings); - if (File.Exists(Constants.ApiModGroupConfigPath)) - JsonConvert.PopulateObject(File.ReadAllText(Constants.ApiModGroupConfigPath), this.Settings, deserializerSettings); - if (developerMode.HasValue) - this.Settings.OverrideDeveloperMode(developerMode.Value); - } + this.OverrideDeveloperMode = overrideDeveloperMode; + this.ReloadSettings(); // init basics this.LogManager = new LogManager(logPath: logPath, colorSchemeId: this.Settings.ConsoleColorScheme, colorConfig: this.Settings.ConsoleColorSchemes, writeToConsole: writeToConsole, verboseLogging: this.Settings.VerboseLogging, isDeveloperMode: this.Settings.DeveloperMode, getScreenIdForLog: this.GetScreenIdForLog); @@ -521,6 +515,10 @@ internal class SCore : IDisposable // check for updates _ = this.CheckForUpdatesAsync(mods); // ignore task since the main thread doesn't need to wait for it + + // register config menu with Generic Mod Config Menu + if (this.Settings.EnableConfigMenu) + new GenericModConfigMenuIntegration(this.Monitor, this.Translator, () => this.Settings, this.ReloadSettings).Register(this.ModRegistry); } // update window titles @@ -1406,6 +1404,40 @@ internal class SCore : IDisposable this.EventManager.AssetsInvalidated.Raise(new AssetsInvalidatedEventArgs(assetNames, assetNames.Select(p => p.GetBaseAssetName()))); } + /// Reload the SMAPI settings. + /// The intern + [MemberNotNull(nameof(SCore.Settings))] + private void ReloadSettings() + { + JsonSerializerSettings deserializerSettings = new() { NullValueHandling = NullValueHandling.Ignore }; + + // load default settings + SConfig? settings = JsonConvert.DeserializeObject(File.ReadAllText(Constants.ApiConfigPath)); + if (settings is null) + { + if (this.Settings is null) + throw new InvalidOperationException("The 'smapi-internal/config.json' file is missing or invalid. You can reinstall SMAPI to fix this."); + + this.Monitor.Log("Could not load updated settings from the 'smapi-internal/config.json' file. Keeping the settings as-is.", LogLevel.Warn); + return; + } + + // load user settings + if (File.Exists(Constants.ApiUserConfigPath)) + JsonConvert.PopulateObject(File.ReadAllText(Constants.ApiUserConfigPath), settings, deserializerSettings); + if (File.Exists(Constants.ApiModGroupConfigPath)) + JsonConvert.PopulateObject(File.ReadAllText(Constants.ApiModGroupConfigPath), settings, deserializerSettings); + if (this.OverrideDeveloperMode.HasValue) + settings.OverrideDeveloperMode(this.OverrideDeveloperMode.Value); + + // apply + this.Settings = settings; + + // update log manager if already initialized + // ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract + this.LogManager?.ApplySettings(settings.ConsoleColorScheme, settings.ConsoleColorSchemes, settings.VerboseLogging, this.OverrideDeveloperMode ?? settings.DeveloperMode); + } + /// Get the load/edit operations to apply to an asset by querying registered event handlers. /// The asset info being requested. private AssetOperationGroup? RequestAssetOperations(IAssetInfo asset) diff --git a/src/SMAPI/Integrations/GenericModConfigMenu/GenericModConfigMenuIntegration.cs b/src/SMAPI/Integrations/GenericModConfigMenu/GenericModConfigMenuIntegration.cs new file mode 100644 index 00000000..1c257d5c --- /dev/null +++ b/src/SMAPI/Integrations/GenericModConfigMenu/GenericModConfigMenuIntegration.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using StardewModdingAPI.Framework; +using StardewModdingAPI.Framework.Models; +using StardewModdingAPI.Framework.ModHelpers; +using StardewModdingAPI.Framework.ModLoading; +using StardewModdingAPI.Framework.Reflection; +using StardewModdingAPI.Internal.ConsoleWriting; +using StardewModdingAPI.Toolkit.Serialization.Models; +using StardewModdingAPI.Toolkit.Utilities; +using StardewValley.Extensions; + +namespace StardewModdingAPI.Integrations.GenericModConfigMenu +{ + /// Registers the SMAPI configuration with Generic Mod Config Menu. + internal class GenericModConfigMenuIntegration + { + /********* + ** Fields + *********/ + /// The unique mod ID for Generic Mod Config Menu. + private const string GenericModConfigMenuModId = "spacechase0.GenericModConfigMenu"; + + /// The minimum version of Generic Mod Config Menu supported by this integration. + private const string MinVersion = "1.9.6"; + + /// Encapsulates monitoring and logging. + private readonly IMonitor Monitor; + + /// The core SMAPI translations. + private readonly Translator Translations; + + /// Get the current SMAPI settings. + private readonly Func GetConfig; + + /// Reload the SMAPI settings when they're changed through the config menu. + private readonly Action ReloadConfig; + + /// The custom setting values which haven't been saved yet. + private readonly Dictionary StagedSettings = []; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// + /// + /// + /// + public GenericModConfigMenuIntegration(IMonitor monitor, Translator translations, Func getConfig, Action reloadConfig) + { + this.Monitor = monitor; + this.Translations = translations; + this.GetConfig = getConfig; + this.ReloadConfig = reloadConfig; + } + + /// Register the mod config. + /// An API for fetching metadata about loaded mods. + public void Register(ModRegistry internalModRegistry) + { + try + { + // init + ModMetadata smapiMod = this.CreateFakeMod(); + IModRegistry modRegistry = this.CreateModRegistryHelper(internalModRegistry, this.Monitor, smapiMod); + IGenericModConfigMenuApi? api = this.GetGenericModConfigMenuApi(modRegistry, this.Monitor); + if (api is null) + return; + + // register config + api.Register(smapiMod.Manifest, this.OnReset, this.Save); + var getConfig = this.GetConfig; + + // add 'SMAPI features' section + api.AddSectionTitle(smapiMod.Manifest, () => this.Translations.Get("config.section.features")); + api.AddBoolOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.check-for-updates.name"), + tooltip: () => this.Translations.Get("config.check-for-updates.desc"), + getValue: () => getConfig().CheckForUpdates, + setValue: value => this.StageOption(nameof(SConfig.CheckForUpdates), value) + ); + api.AddBoolOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.check-content-integrity.name"), + tooltip: () => this.Translations.Get("config.check-content-integrity.desc"), + getValue: () => getConfig().CheckContentIntegrity, + setValue: value => this.StageOption(nameof(SConfig.CheckContentIntegrity), value) + ); + api.AddBoolOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.read-console-input.name"), + tooltip: () => this.Translations.Get("config.read-console-input.desc"), + getValue: () => getConfig().ListenForConsoleInput, + setValue: value => this.StageOption(nameof(SConfig.ListenForConsoleInput), value) + ); + + // add 'console window' section + api.AddSectionTitle(smapiMod.Manifest, () => this.Translations.Get("config.section.console-window")); + api.AddBoolOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.developer-mode.name"), + tooltip: () => this.Translations.Get("config.developer-mode.desc"), + getValue: () => getConfig().DeveloperMode, + setValue: value => this.StageOption(nameof(SConfig.DeveloperMode), value) + ); + api.AddTextOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.color-scheme.name"), + tooltip: () => this.Translations.Get("config.color-scheme.desc"), + getValue: () => getConfig().ConsoleColorScheme.ToString(), + setValue: value => this.StageOption(nameof(SConfig.ConsoleColorScheme), value), + allowedValues: Enum.GetValues().Select(p => p.ToString()).ToArray(), + formatAllowedValue: value => this.Translations.Get( + value is nameof(MonitorColorScheme.AutoDetect) && Constants.Platform == Platform.Windows + ? $"config.color-scheme.options.{value}.on-windows" + : $"config.color-scheme.options.{value}" + )); + + // add 'verbose logging' section + api.AddSectionTitle(smapiMod.Manifest, () => this.Translations.Get("config.section.verbose-logs")); + api.AddParagraph(smapiMod.Manifest, () => this.Translations.Get("config.section.verbose-logs.explanation")); + api.AddTextOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.enable-for.name"), + tooltip: () => this.Translations.Get("config.enable-for.desc"), + getValue: () => getConfig().VerboseLogging.Contains("*").ToString(), + setValue: value => this.StageVerboseLoggingOption("*", value == bool.TrueString), + allowedValues: [bool.TrueString, bool.FalseString], + formatAllowedValue: value => this.Translations.Get($"config.enable-for.options.{(value == bool.TrueString ? "all" : "selected")}") + ); + api.AddBoolOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.enable-for-smapi.name"), + tooltip: () => this.Translations.Get("config.enable-for-smapi.desc"), + getValue: () => getConfig().VerboseLogging.Contains("SMAPI"), + setValue: value => this.StageVerboseLoggingOption("SMAPI", value) + ); + foreach (IModInfo mod in modRegistry.GetAll().OrderBy(p => p.Manifest.Name, StringComparer.OrdinalIgnoreCase)) + { + if (mod.IsContentPack) + continue; + + api.AddBoolOption( + mod: smapiMod.Manifest, + name: () => this.Translations.Get("config.enable-for-mod.name", new { modName = mod.Manifest.Name }), + tooltip: () => this.Translations.Get("config.enable-for-mod.desc", new { modName = mod.Manifest.Name }), + getValue: () => getConfig().VerboseLogging.Contains(mod.Manifest.UniqueID), + setValue: value => this.StageVerboseLoggingOption(mod.Manifest.UniqueID, value) + ); + } + } + catch (Exception ex) + { + this.Monitor.Log("Couldn't register the SMAPI settings with Generic Mod Config Menu. This has no effect on SMAPI, but the in-game config menu won't be available.", LogLevel.Warn); + this.Monitor.Log(ex.ToString()); + } + } + + + /********* + ** Private methods + *********/ + /**** + ** Save events + ****/ + /// Reset the SMAPI configuration to the default values. + private void OnReset() + { + try + { + foreach (string customPath in new[] { Constants.ApiUserConfigPath, Constants.ApiModGroupConfigPath }) + { + if (File.Exists(customPath)) + File.Delete(customPath); + } + + this.ReloadConfig(); + } + catch (Exception ex) + { + this.Monitor.Log($"Couldn't reset SMAPI to the default settings from the Generic Mod Config Menu UI.\n\nTechnical details:\n{ex}", LogLevel.Error); + } + } + + /// Save the mod configuration. + private void Save() + { + try + { + // load settings + JsonSettingsWrapper? defaultSettings = JsonSettingsWrapper.TryLoadFile(Constants.ApiConfigPath, this.Monitor); + JsonSettingsWrapper? userSettings = JsonSettingsWrapper.TryLoadFile(Constants.ApiUserConfigPath, this.Monitor); + JsonSettingsWrapper? modGroupSettings = JsonSettingsWrapper.TryLoadFile(Constants.ApiModGroupConfigPath, this.Monitor); + + // skip if invalid + if (defaultSettings is null) + { + this.Monitor.Log("Couldn't save the SMAPI settings from the Generic Mod Config Menu UI. The default settings could not be loaded.", LogLevel.Error); + return; + } + + // apply edited options + if (this.StagedSettings.Count > 0) + { + // create settings file if needed + if (userSettings is null && modGroupSettings is null) + userSettings = new JsonSettingsWrapper(Constants.ApiUserConfigPath); + + // save simple options + foreach ((string fieldName, object newValue) in this.StagedSettings) + { + // replace existing property if possible + if (modGroupSettings?.SetUserOption(fieldName, newValue, defaultSettings, overwriteOnly: true) is true) + continue; + if (userSettings?.SetUserOption(fieldName, newValue, defaultSettings, overwriteOnly: true) is true) + continue; + + // else add new property + (modGroupSettings ?? userSettings)?.SetUserOption(fieldName, newValue, defaultSettings, overwriteOnly: false); + } + } + + // save to files + if (modGroupSettings?.Changed is true) + modGroupSettings.SaveOrDeleteFile(); + if (userSettings?.Changed is true) + userSettings.SaveOrDeleteFile(); + + // reload settings + this.StagedSettings.Clear(); + this.ReloadConfig(); + } + catch (Exception ex) + { + this.Monitor.Log($"Couldn't save the SMAPI settings from the Generic Mod Config Menu UI.\n\nTechnical details:\n{ex}", LogLevel.Error); + } + } + + /**** + ** Config option staging + ****/ + /// Store a value set by the player before it's saved to the config files. + /// The name of the field to change. + /// The value to stage. + private void StageOption(string fieldName, object value) + { + this.StagedSettings[fieldName] = value; + } + + /// Store a custom option before it's saved to the config files. + /// The mod ID, 'SMAPI', or '*' (all) for which to toggle verbose logging. + /// Whether verbose logging is enabled. + private void StageVerboseLoggingOption(string id, bool enable) + { + const string fieldName = nameof(SConfig.VerboseLogging); + + if (this.StagedSettings.TryGetValue(fieldName, out object? rawValue) && rawValue is HashSet set) + set.Toggle(id, enable); + else + { + HashSet newSet = new HashSet(this.GetConfig().VerboseLogging, StringComparer.OrdinalIgnoreCase); + newSet.Toggle(id, enable); + this.StagedSettings[fieldName] = newSet; + } + } + + /**** + ** Initialization + ****/ + /// Get the public API for Generic Mod Config Menu, if it's available. + /// The mod registry to query. + /// The monitor with which to log issues loading the API. + /// Returns the API if it's available, else null. + private IGenericModConfigMenuApi? GetGenericModConfigMenuApi(IModRegistry modRegistry, IMonitor monitor) + { + // check mod is installed + if (modRegistry.Get(GenericModConfigMenuIntegration.GenericModConfigMenuModId) is not { } configMod) + return null; + + // check min version + if (configMod.Manifest.Version.IsOlderThan(GenericModConfigMenuIntegration.MinVersion)) + { + monitor.Log("Can't register the SMAPI settings with Generic Mod Config Menu, because you need version 1.9.6 or later of that mod.", LogLevel.Debug); + return null; + } + + // check API + if (modRegistry.GetApi(GenericModConfigMenuIntegration.GenericModConfigMenuModId) is not { } api) + { + monitor.Log("Can't register the SMAPI settings with Generic Mod Config Menu, because it unexpectedly had no API.", LogLevel.Debug); + return null; + } + + return api; + } + + /// Create a fake mod entry to represent SMAPI itself. + private ModMetadata CreateFakeMod() + { + IManifest manifest = new Manifest( + uniqueId: "SMAPI", + name: "SMAPI", + author: "Pathoschild", + description: string.Empty, + version: Constants.ApiVersion, + minimumApiVersion: Constants.ApiVersion, + minimumGameVersion: Constants.MinimumGameVersion, + entryDll: "StardewModdingAPI.exe", + contentPackFor: null, + dependencies: [], + updateKeys: [] + ); + + return new ModMetadata( + displayName: "SMAPI", + directoryPath: Constants.GamePath, + rootPath: Constants.ModsPath, + manifest: manifest, + dataRecord: null, + isIgnored: false + ); + } + + /// Create a mod registry helper. + /// The internal mod registry. + /// Encapsulates monitoring and logging. + /// The fake mod entry representing SMAPI itself. + private IModRegistry CreateModRegistryHelper(ModRegistry internalRegistry, IMonitor monitor, ModMetadata smapiMod) + { + return new ModRegistryHelper( + mod: smapiMod, + registry: internalRegistry, + proxyFactory: new InterfaceProxyFactory(), + monitor: monitor + ); + } + } +} diff --git a/src/SMAPI/Integrations/GenericModConfigMenu/IGenericModConfigMenuApi.cs b/src/SMAPI/Integrations/GenericModConfigMenu/IGenericModConfigMenuApi.cs new file mode 100644 index 00000000..ff6e9ddc --- /dev/null +++ b/src/SMAPI/Integrations/GenericModConfigMenu/IGenericModConfigMenuApi.cs @@ -0,0 +1,55 @@ +using System; + +namespace StardewModdingAPI.Integrations.GenericModConfigMenu; + +/// The API provided by the Generic Mod Config Menu mod. +public interface IGenericModConfigMenuApi +{ + /********* + ** Methods + *********/ + /**** + ** Must be called first + ****/ + /// Register a mod whose config can be edited through the UI. + /// The mod's manifest. + /// Reset the mod's config to its default values. + /// Save the mod's current config to the config.json file. + /// Whether the options can only be edited from the title screen. + void Register(IManifest mod, Action reset, Action save, bool titleScreenOnly = false); + + + /**** + ** Basic options + ****/ + /// Add a section title at the current position in the form. + /// The mod's manifest. + /// The title text shown in the form. + /// The tooltip text shown when the cursor hovers on the title, or null to disable the tooltip. + void AddSectionTitle(IManifest mod, Func text, Func? tooltip = null); + + /// Add a paragraph of text at the current position in the form. + /// The mod's manifest. + /// The paragraph text to display. + void AddParagraph(IManifest mod, Func text); + + /// Add a boolean option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with OnFieldChanged, or null to auto-generate a randomized ID. + void AddBoolOption(IManifest mod, Func getValue, Action setValue, Func name, Func? tooltip = null, string? fieldId = null); + + /// Add a string option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The values that can be selected, or null to allow any. + /// Get the display text to show for a value from , or null to show the values as-is. + /// The unique field ID for use with OnFieldChanged, or null to auto-generate a randomized ID. + void AddTextOption(IManifest mod, Func getValue, Action setValue, Func name, Func? tooltip = null, string[]? allowedValues = null, Func? formatAllowedValue = null, string? fieldId = null); +} diff --git a/src/SMAPI/Integrations/GenericModConfigMenu/JsonSettingsWrapper.cs b/src/SMAPI/Integrations/GenericModConfigMenu/JsonSettingsWrapper.cs new file mode 100644 index 00000000..f2302c55 --- /dev/null +++ b/src/SMAPI/Integrations/GenericModConfigMenu/JsonSettingsWrapper.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Framework.Models; + +namespace StardewModdingAPI.Integrations.GenericModConfigMenu; + +/// Wraps access to a JSON file which stores fields. +internal class JsonSettingsWrapper +{ + /********* + ** Accessors + *********/ + /// The full path to the underlying file. + public string FilePath { get; } + + /// The loaded option properties. + public Dictionary Properties { get; } + + /// Whether the saved values have changed. + public bool Changed { get; private set; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// + public JsonSettingsWrapper(string filePath) + : this(filePath, new Dictionary(StringComparer.OrdinalIgnoreCase)) { } + + /// Set the value for a user settings field. + /// The name of the field to set. + /// The new value to set. + /// The default settings. + /// Whether to only set the value if it's already set in this file. + /// Returns whether the value changed. + public bool SetUserOption(string fieldName, object newValue, JsonSettingsWrapper defaultSettings, bool overwriteOnly) + { + return fieldName == nameof(SConfig.VerboseLogging) + ? this.SetVerboseLoggingUserOption(fieldName, (HashSet)newValue, defaultSettings, overwriteOnly) + : this.SetScalarUserOption(fieldName, newValue, defaultSettings, overwriteOnly); + } + + /// Remove a user settings field. + /// The name of the field to set. + /// Returns whether the value was found and removed. + public bool RemoveUserOption(string fieldName) + { + bool changed = this.Properties.Remove(fieldName); + this.Changed = this.Changed || changed; + return changed; + } + + /// Save the user settings to the file on disk, or delete the files if it's empty. + public void SaveOrDeleteFile() + { + if (this.Properties.Count == 0) + File.Delete(Constants.ApiUserConfigPath); + else + { + string json = JsonConvert.SerializeObject(this.Properties, Formatting.Indented); + File.WriteAllText(this.FilePath, json, Encoding.UTF8); + } + + this.Changed = false; + } + + /// Read a raw JSON settings file. + /// The full path for the file to read. + /// The monitor with which to log errors. + /// Returns the loaded JSON wrapper, or null if the file doesn't exist or couldn't be loaded. + public static JsonSettingsWrapper? TryLoadFile(string path, IMonitor monitor) + { + try + { + if (!File.Exists(path)) + return null; + + string rawJson = File.ReadAllText(path); + JObject? json = JsonConvert.DeserializeObject(rawJson); + if (json is null) + return null; + + Dictionary properties = new(StringComparer.OrdinalIgnoreCase); + foreach (JProperty property in json.Properties()) + properties[property.Name] = property.Value; + + return new JsonSettingsWrapper(path, properties); + } + catch (Exception ex) + { + monitor.Log($"Can't read settings file at {path}.\n\nTechnical details:\n{ex}", LogLevel.Error); + return null; + } + } + + + /********* + ** Private methods + *********/ + /// Construct an instance. + /// + /// + private JsonSettingsWrapper(string filePath, Dictionary properties) + { + this.FilePath = filePath; + this.Properties = properties; + } + + /// Set the value for a scalar user settings field. + /// The name of the field to set. + /// The new value to set. + /// The default settings. + /// Whether to only set the value if it's already set in this file. + /// Returns whether the value changed. + public bool SetScalarUserOption(string fieldName, object newValue, JsonSettingsWrapper defaultSettings, bool overwriteOnly) + { + // remove default + if (defaultSettings.Properties.TryGetValue(fieldName, out JToken? rawDefaultValue) && this.TokenHasValue(rawDefaultValue, newValue)) + return this.RemoveUserOption(fieldName); + + // else overwrite value + if (this.Properties.TryGetValue(fieldName, out JToken? oldValue)) + { + if (this.TokenHasValue(oldValue, newValue)) + return false; + + this.Properties[fieldName] = JToken.FromObject(newValue); + this.Changed = true; + return true; + } + + // else add value + if (!overwriteOnly) + { + this.Properties[fieldName] = JToken.FromObject(newValue); + this.Changed = true; + return true; + } + + return false; + } + + /// Set the value for the verbose logging field. + /// The name of the field to set. + /// The new value to set. + /// The default settings. + /// Whether to only set the value if it's already set in this file. + /// Returns whether the value changed. + public bool SetVerboseLoggingUserOption(string fieldName, HashSet newValue, JsonSettingsWrapper defaultSettings, bool overwriteOnly) + { + // remove default + if (newValue.Count == 0) + return this.RemoveUserOption(fieldName); + + // else overwrite value + if (this.Properties.GetValueOrDefault(fieldName)?.ToObject>() is { } oldSet) + { + oldSet = new HashSet(oldSet, StringComparer.OrdinalIgnoreCase); + + bool changed = newValue.Count != oldSet.Count || !oldSet.All(newValue.Contains); + if (changed) + { + this.Properties[fieldName] = JToken.FromObject(newValue); + this.Changed = true; + } + + return changed; + } + + // else add value + if (!overwriteOnly) + { + this.Properties[fieldName] = JToken.FromObject(newValue); + this.Changed = true; + return true; + } + + return false; + } + + /// Get whether a token has the expected value. + /// The token whose value to check. + /// The value to match. + private bool TokenHasValue(JToken token, object expectedValue) + { + object? actualValue = token.Value()?.Value; + return expectedValue.Equals(actualValue); + } +} diff --git a/src/SMAPI/SMAPI.config.json b/src/SMAPI/SMAPI.config.json index 8b92f354..3b999ad0 100644 --- a/src/SMAPI/SMAPI.config.json +++ b/src/SMAPI/SMAPI.config.json @@ -45,8 +45,9 @@ in future SMAPI versions. "CheckContentIntegrity": true, /** - * Whether to enable features intended for mod developers. Currently this only makes TRACE-level - * messages appear in the console. + * Whether to show much more info in the SMAPI consoler window, intended for mod developers. + * + * Not recommended for most players. */ "DeveloperMode": true, diff --git a/src/SMAPI/i18n/de.json b/src/SMAPI/i18n/de.json index 595c3eff..b417c337 100644 --- a/src/SMAPI/i18n/de.json +++ b/src/SMAPI/i18n/de.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}} {{day}}", - "generic.date-with-year": "{{season}} {{day}} im Jahr {{year}}" + "generic.date-with-year": "{{season}} {{day}} im Jahr {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/default.json b/src/SMAPI/i18n/default.json index 7e1f9c4d..356fee76 100644 --- a/src/SMAPI/i18n/default.json +++ b/src/SMAPI/i18n/default.json @@ -1,6 +1,54 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}} {{day}}", - "generic.date-with-year": "{{season}} {{day}} in year {{year}}" + "generic.date-with-year": "{{season}} {{day}} in year {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/es.json b/src/SMAPI/i18n/es.json index 76228d7d..0aa48179 100644 --- a/src/SMAPI/i18n/es.json +++ b/src/SMAPI/i18n/es.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{seasonLowercase}} {{day}}", - "generic.date-with-year": "{{seasonLowercase}} {{day}} del año {{year}}" + "generic.date-with-year": "{{seasonLowercase}} {{day}} del año {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/fr.json b/src/SMAPI/i18n/fr.json index e32ee712..7fa876e4 100644 --- a/src/SMAPI/i18n/fr.json +++ b/src/SMAPI/i18n/fr.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{day}} {{seasonLowercase}}", - "generic.date-with-year": "{{day}} {{seasonLowercase}} de l'année {{year}}" + "generic.date-with-year": "{{day}} {{seasonLowercase}} de l'année {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/hu.json b/src/SMAPI/i18n/hu.json index 2e3b7264..cc1f8544 100644 --- a/src/SMAPI/i18n/hu.json +++ b/src/SMAPI/i18n/hu.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}} {{day}}", - "generic.date-with-year": "{{year}}. év {{season}} {{day}}" + "generic.date-with-year": "{{year}}. év {{season}} {{day}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/id.json b/src/SMAPI/i18n/id.json index 4616e7c0..18a78da2 100644 --- a/src/SMAPI/i18n/id.json +++ b/src/SMAPI/i18n/id.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "Tanggal {{day}} di {{season}}", - "generic.date-with-year": "Tanggal {{day}} di {{season}} tahun ke-{{year}}" + "generic.date-with-year": "Tanggal {{day}} di {{season}} tahun ke-{{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/it.json b/src/SMAPI/i18n/it.json index 7ada11f0..24b61771 100644 --- a/src/SMAPI/i18n/it.json +++ b/src/SMAPI/i18n/it.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{day}} {{season}}", - "generic.date-with-year": "{{day}} {{season}} dell'anno {{year}}" + "generic.date-with-year": "{{day}} {{season}} dell'anno {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/ja.json b/src/SMAPI/i18n/ja.json index c95ac1b1..bf675425 100644 --- a/src/SMAPI/i18n/ja.json +++ b/src/SMAPI/i18n/ja.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}} {{day}}日", - "generic.date-with-year": "{{year}}年目 {{season}} {{day}}日" + "generic.date-with-year": "{{year}}年目 {{season}} {{day}}日", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/ko.json b/src/SMAPI/i18n/ko.json index 8122a9e2..c590ba97 100644 --- a/src/SMAPI/i18n/ko.json +++ b/src/SMAPI/i18n/ko.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}} {{day}}일", - "generic.date-with-year": "{{year}}년차 {{season}} {{day}}일" + "generic.date-with-year": "{{year}}년차 {{season}} {{day}}일", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/pl.json b/src/SMAPI/i18n/pl.json index fa4650a2..c8ade848 100644 --- a/src/SMAPI/i18n/pl.json +++ b/src/SMAPI/i18n/pl.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{day}} {{seasonLowercase}}", - "generic.date-with-year": "{{day}} {{seasonLowercase}} w roku {{year}}" + "generic.date-with-year": "{{day}} {{seasonLowercase}} w roku {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/pt.json b/src/SMAPI/i18n/pt.json index 7a08b08f..dff8e0c7 100644 --- a/src/SMAPI/i18n/pt.json +++ b/src/SMAPI/i18n/pt.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}} {{day}}", - "generic.date-with-year": "{{season}} {{day}} no ano {{year}}" + "generic.date-with-year": "{{season}} {{day}} no ano {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/ru.json b/src/SMAPI/i18n/ru.json index b8ff55c4..1ac64673 100644 --- a/src/SMAPI/i18n/ru.json +++ b/src/SMAPI/i18n/ru.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}}, {{day}}-е число", - "generic.date-with-year": "{{season}}, {{day}}-е число, {{year}}-й год" + "generic.date-with-year": "{{season}}, {{day}}-е число, {{year}}-й год", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/th.json b/src/SMAPI/i18n/th.json index 361b7aa7..0c87c6cd 100644 --- a/src/SMAPI/i18n/th.json +++ b/src/SMAPI/i18n/th.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "วันที่ {{day}} {{season}}", - "generic.date-with-year": "วันที่ {{day}} {{season}} ปีที่ {{year}}" + "generic.date-with-year": "วันที่ {{day}} {{season}} ปีที่ {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/tr.json b/src/SMAPI/i18n/tr.json index ba0c33c9..99f6ea7f 100644 --- a/src/SMAPI/i18n/tr.json +++ b/src/SMAPI/i18n/tr.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{day}} {{season}}", - "generic.date-with-year": "{{day}} {{season}} Yıl {{year}}" + "generic.date-with-year": "{{day}} {{season}} Yıl {{year}}", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/uk.json b/src/SMAPI/i18n/uk.json index a4286363..bc98490c 100644 --- a/src/SMAPI/i18n/uk.json +++ b/src/SMAPI/i18n/uk.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}}, {{day}}-й день", - "generic.date-with-year": "{{season}}, {{day}}-й день, {{year}} рік" + "generic.date-with-year": "{{season}}, {{day}}-й день, {{year}} рік", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." } diff --git a/src/SMAPI/i18n/zh.json b/src/SMAPI/i18n/zh.json index 36d459de..49c3f392 100644 --- a/src/SMAPI/i18n/zh.json +++ b/src/SMAPI/i18n/zh.json @@ -1,6 +1,55 @@ { + /********* + ** Date formatting + *********/ // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) "generic.date": "{{season}}{{day}}日", - "generic.date-with-year": "第{{year}}年{{season}}{{day}}日" + "generic.date-with-year": "第{{year}}年{{season}}{{day}}日", + + + /********* + ** Generic Mod Config Menu UI + *********/ + // TODO + // 'SMAPI features' section + "config.section.features": "SMAPI features", + + "config.check-for-updates.name": "Check for updates", + "config.check-for-updates.desc": "Whether to automatically check for newer versions of SMAPI and mods when you load the game. If new versions are available, an alert will be shown in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.", + + "config.check-content-integrity.name": "Check content integrity", + "config.check-content-integrity.desc": "Whether SMAPI should check whether the game's content files are present and unmodified. This should nearly always be enabled. If disabled, SMAPI will log a warning for visibility when someone helps you troubleshoot game issues.", + + "config.read-console-input.name": "Read console input", + "config.read-console-input.desc": "Whether SMAPI should listen for console input. Disabling this will prevent you from using console commands. On some specific Linux systems, disabling this may reduce CPU usage.", + + // 'Console window' section + "config.section.console-window": "Console window", + + "config.developer-mode.name": "Developer mode", + "config.developer-mode.desc": "Whether to show much more info in the SMAPI consoler window, intended for mod developers. Not recommended for most players.", + + "config.color-scheme.name": "Color scheme", + "config.color-scheme.desc": "The color scheme to apply to text in the SMAPI console window. This has no effect on the game, mods, or SMAPI log file.", + "config.color-scheme.options.AutoDetect": "Auto-detect", + "config.color-scheme.options.AutoDetect.on-windows": "Auto-detect (recommended)", + "config.color-scheme.options.DarkBackground": "Lighter text (for dark backgrounds)", + "config.color-scheme.options.LightBackground": "Darker text (for light backgrounds)", + "config.color-scheme.options.None": "No colors", + + // 'Verbose logging' section + "config.section.verbose-logs": "Verbose logs", + "config.section.verbose-logs.explanation": "To help troubleshoot, SMAPI and many mods can send extra info to the SMAPI log (called 'verbose logging'). This may cause performance issues, and should usually be disabled.", + + "config.enable-for.name": "Enable for", + "config.enable-for.desc": "Choose which mods have verbose logging enabled.", + "config.enable-for.options.all": "All (not recommended)", + "config.enable-for.options.selected": "Mods selected below", + + "config.enable-for-smapi.name": "SMAPI", + "config.enable-for-smapi.desc": "Whether to enable verbose logs for SMAPI itself.", + + "config.enable-for-mod.name": "{{modName}}", + "config.enable-for-mod.desc": "Whether to enable verbose logs for the '{{modName}}' mod." }