diff options
Diffstat (limited to 'src')
40 files changed, 553 insertions, 241 deletions
diff --git a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj index e25da168..cded6f65 100644 --- a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj +++ b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj @@ -10,7 +10,7 @@ <!--NuGet package--> <PackageId>Pathoschild.Stardew.ModBuildConfig</PackageId> <Title>Build package for SMAPI mods</Title> - <Version>4.0.1</Version> + <Version>4.0.2</Version> <Authors>Pathoschild</Authors> <Description>Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.13.0 or later.</Description> <PackageLicenseExpression>MIT</PackageLicenseExpression> diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 12619439..b4fd312e 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -27,8 +27,12 @@ <EnableGameDebugging Condition="'$(EnableGameDebugging)' == ''">true</EnableGameDebugging> <BundleExtraAssemblies Condition="'$(BundleExtraAssemblies)' == ''"></BundleExtraAssemblies> + <!-- simplify conditions --> + <_BundleExtraAssembliesForGame>$([System.Text.RegularExpressions.Regex]::IsMatch('$(BundleExtraAssemblies)', '\bGame|All\b', RegexOptions.IgnoreCase))</_BundleExtraAssembliesForGame> + <_BundleExtraAssembliesForAny>$([System.Text.RegularExpressions.Regex]::IsMatch('$(BundleExtraAssemblies)', '\bGame|System|ThirdParty|All\b', RegexOptions.IgnoreCase))</_BundleExtraAssembliesForAny> + <!-- coppy referenced DLLs into build output --> - <CopyLocalLockFileAssemblies Condition="$(BundleExtraAssemblies.Contains('ThirdParty')) OR $(BundleExtraAssemblies.Contains('Game')) OR $(BundleExtraAssemblies.Contains('System')) OR $(BundleExtraAssemblies.Contains('All'))">true</CopyLocalLockFileAssemblies> + <CopyLocalLockFileAssemblies Condition="$(_BundleExtraAssembliesForAny)">true</CopyLocalLockFileAssemblies> </PropertyGroup> <PropertyGroup Condition="'$(OS)' == 'Windows_NT' AND '$(EnableGameDebugging)' == 'true'"> @@ -44,17 +48,17 @@ **********************************************--> <ItemGroup> <!-- game --> - <Reference Include="Stardew Valley" HintPath="$(GamePath)\Stardew Valley.dll" Private="$(BundleExtraAssemblies.Contains('Game'))" /> - <Reference Include="StardewValley.GameData" HintPath="$(GamePath)\StardewValley.GameData.dll" Private="$(BundleExtraAssemblies.Contains('Game'))" /> - <Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="$(BundleExtraAssemblies.Contains('Game'))" /> - <Reference Include="xTile" HintPath="$(GamePath)\xTile.dll" Private="$(BundleExtraAssemblies.Contains('Game'))" /> + <Reference Include="Stardew Valley" HintPath="$(GamePath)\Stardew Valley.dll" Private="$(_BundleExtraAssembliesForGame)" /> + <Reference Include="StardewValley.GameData" HintPath="$(GamePath)\StardewValley.GameData.dll" Private="$(_BundleExtraAssembliesForGame)" /> + <Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="$(_BundleExtraAssembliesForGame)" /> + <Reference Include="xTile" HintPath="$(GamePath)\xTile.dll" Private="$(_BundleExtraAssembliesForGame)" /> <!-- SMAPI --> - <Reference Include="StardewModdingAPI" HintPath="$(GamePath)\StardewModdingAPI.dll" Private="$(BundleExtraAssemblies.Contains('Game'))" /> - <Reference Include="SMAPI.Toolkit.CoreInterfaces" HintPath="$(GamePath)\smapi-internal\SMAPI.Toolkit.CoreInterfaces.dll" Private="$(BundleExtraAssemblies.Contains('Game'))" /> + <Reference Include="StardewModdingAPI" HintPath="$(GamePath)\StardewModdingAPI.dll" Private="$(_BundleExtraAssembliesForGame)" /> + <Reference Include="SMAPI.Toolkit.CoreInterfaces" HintPath="$(GamePath)\smapi-internal\SMAPI.Toolkit.CoreInterfaces.dll" Private="$(_BundleExtraAssembliesForGame)" /> <!-- Harmony --> - <Reference Include="0Harmony" Condition="'$(EnableHarmony)' == 'true'" HintPath="$(GamePath)\smapi-internal\0Harmony.dll" Private="$(BundleExtraAssemblies.Contains('Game'))" /> + <Reference Include="0Harmony" Condition="'$(EnableHarmony)' == 'true'" HintPath="$(GamePath)\smapi-internal\0Harmony.dll" Private="$(_BundleExtraAssembliesForGame)" /> </ItemGroup> diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs index 12a51bc9..ea9f1d82 100644 --- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs @@ -63,7 +63,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player /// <param name="color">The color to set.</param> private bool TryParseColor(string input, out Color color) { - string[] colorHexes = input.Split(new[] { ',' }, 3); + string[] colorHexes = input.Split(',', 3); if (int.TryParse(colorHexes[0], out int r) && int.TryParse(colorHexes[1], out int g) && int.TryParse(colorHexes[2], out int b)) { color = new Color(r, g, b); diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index abe8b334..754e543a 100644 --- a/src/SMAPI.Mods.ConsoleCommands/manifest.json +++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json @@ -1,9 +1,9 @@ { "Name": "Console Commands", "Author": "SMAPI", - "Version": "3.16.2", + "Version": "3.17.0", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll", - "MinimumApiVersion": "3.16.2" + "MinimumApiVersion": "3.17.0" } diff --git a/src/SMAPI.Mods.ErrorHandler/manifest.json b/src/SMAPI.Mods.ErrorHandler/manifest.json index b6764bc0..8f94e5ab 100644 --- a/src/SMAPI.Mods.ErrorHandler/manifest.json +++ b/src/SMAPI.Mods.ErrorHandler/manifest.json @@ -1,9 +1,9 @@ { "Name": "Error Handler", "Author": "SMAPI", - "Version": "3.16.2", + "Version": "3.17.0", "Description": "Handles some common vanilla errors to log more useful info or avoid breaking the game.", "UniqueID": "SMAPI.ErrorHandler", "EntryDll": "ErrorHandler.dll", - "MinimumApiVersion": "3.16.2" + "MinimumApiVersion": "3.17.0" } diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json index a2657168..a9401fc3 100644 --- a/src/SMAPI.Mods.SaveBackup/manifest.json +++ b/src/SMAPI.Mods.SaveBackup/manifest.json @@ -1,9 +1,9 @@ { "Name": "Save Backup", "Author": "SMAPI", - "Version": "3.16.2", + "Version": "3.17.0", "Description": "Automatically backs up all your saves once per day into its folder.", "UniqueID": "SMAPI.SaveBackup", "EntryDll": "SaveBackup.dll", - "MinimumApiVersion": "3.16.2" + "MinimumApiVersion": "3.17.0" } diff --git a/src/SMAPI.Tests/Utilities/KeybindListTests.cs b/src/SMAPI.Tests/Utilities/KeybindListTests.cs index c4c086de..c5fd5daf 100644 --- a/src/SMAPI.Tests/Utilities/KeybindListTests.cs +++ b/src/SMAPI.Tests/Utilities/KeybindListTests.cs @@ -136,11 +136,11 @@ namespace SMAPI.Tests.Utilities foreach (string rawPair in stateMap.Split(',')) { // parse values - string[] parts = rawPair.Split(new[] { ':' }, 2); + string[] parts = rawPair.Split(':', 2, StringSplitOptions.TrimEntries); if (!Enum.TryParse(parts[0], ignoreCase: true, out SButton curButton)) - Assert.Fail($"The state map is invalid: unknown button value '{parts[0].Trim()}'"); + Assert.Fail($"The state map is invalid: unknown button value '{parts[0]}'"); if (!Enum.TryParse(parts[1], ignoreCase: true, out SButtonState state)) - Assert.Fail($"The state map is invalid: unknown state value '{parts[1].Trim()}'"); + Assert.Fail($"The state map is invalid: unknown state value '{parts[1]}'"); // get state if (curButton == button) diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index fedadba6..77c0da5f 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -382,11 +382,11 @@ namespace SMAPI.Tests.Utilities { // act string json = JsonConvert.SerializeObject(new SemanticVersion(versionStr)); - SemanticVersion after = JsonConvert.DeserializeObject<SemanticVersion>(json); + SemanticVersion? after = JsonConvert.DeserializeObject<SemanticVersion>(json); // assert Assert.IsNotNull(after, "The semantic version after deserialization is unexpectedly null."); - Assert.AreEqual(versionStr, after.ToString(), "The semantic version after deserialization doesn't match the input version."); + Assert.AreEqual(versionStr, after!.ToString(), "The semantic version after deserialization doesn't match the input version."); } diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index 8e1538a5..66465ffe 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -9,6 +9,7 @@ using StardewModdingAPI.Toolkit.Utilities; using System.Reflection; #if SMAPI_FOR_WINDOWS using Microsoft.Win32; +using VdfParser; #endif namespace StardewModdingAPI.Toolkit.Framework.GameScanning @@ -23,6 +24,9 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning /// <summary>The current OS.</summary> private readonly Platform Platform; + /// <summary>The Steam app ID for Stardew Valley.</summary> + private const string SteamAppId = "413150"; + /********* ** Public methods @@ -145,7 +149,7 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning #if SMAPI_FOR_WINDOWS IDictionary<string, string> registryKeys = new Dictionary<string, string> { - [@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150"] = "InstallLocation", // Steam + [@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App " + GameScanner.SteamAppId] = "InstallLocation", // Steam [@"SOFTWARE\WOW6432Node\GOG.com\Games\1453375253"] = "PATH", // GOG on 64-bit Windows }; foreach (var pair in registryKeys) @@ -158,7 +162,15 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning // via Steam library path string? steamPath = this.GetCurrentUserRegistryValue(@"Software\Valve\Steam", "SteamPath"); if (steamPath != null) + { + // conventional path yield return Path.Combine(steamPath.Replace('/', '\\'), @"steamapps\common\Stardew Valley"); + + // from Steam's .vdf file + string? path = this.GetPathFromSteamLibrary(steamPath); + if (!string.IsNullOrWhiteSpace(path)) + yield return path; + } #endif // default GOG/Steam paths @@ -243,6 +255,42 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning using (openKey) return (string?)openKey.GetValue(name); } + + /// <summary>Get the game directory path from alternative Steam library locations.</summary> + /// <param name="steamPath">The full path to the directory containing steam.exe.</param> + /// <returns>The game directory, if found.</returns> + private string? GetPathFromSteamLibrary(string? steamPath) + { + if (steamPath == null) + return null; + + // get raw .vdf data + string libraryFoldersPath = Path.Combine(steamPath.Replace('/', '\\'), "steamapps\\libraryfolders.vdf"); + using FileStream fileStream = File.OpenRead(libraryFoldersPath); + VdfDeserializer deserializer = new(); + dynamic libraries = deserializer.Deserialize(fileStream); + if (libraries?.libraryfolders is null) + return null; + + // get path from Stardew Valley app (if any) + foreach (dynamic pair in libraries.libraryfolders) + { + dynamic library = pair.Value; + + foreach (dynamic app in library.apps) + { + string key = app.Key; + if (key == GameScanner.SteamAppId) + { + string path = library.path; + + return Path.Combine(path.Replace("\\\\", "\\"), "steamapps", "common", "Stardew Valley"); + } + } + } + + return null; + } #endif } } diff --git a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs index a85ef109..5e9e3c35 100644 --- a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs +++ b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs @@ -45,10 +45,14 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning ".png", ".psd", ".tif", + ".xcf", // gimp files // archives ".rar", ".zip", + ".7z", + ".tar", + ".tar.gz", // backup files ".backup", diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj index 7b79105f..10f1df70 100644 --- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj +++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj @@ -11,9 +11,10 @@ <ItemGroup> <PackageReference Include="HtmlAgilityPack" Version="1.11.43" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> - <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.1.1" /> + <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.2.0" /> <PackageReference Include="System.Management" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" /> <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" /> + <PackageReference Include="VdfConverter" Version="1.0.3" Condition="'$(OS)' == 'Windows_NT'" Private="False" /> </ItemGroup> <ItemGroup> diff --git a/src/SMAPI.Toolkit/Serialization/Models/Manifest.cs b/src/SMAPI.Toolkit/Serialization/Models/Manifest.cs index da3ad608..8a449f0a 100644 --- a/src/SMAPI.Toolkit/Serialization/Models/Manifest.cs +++ b/src/SMAPI.Toolkit/Serialization/Models/Manifest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Text; using Newtonsoft.Json; using StardewModdingAPI.Toolkit.Serialization.Converters; @@ -90,13 +91,13 @@ namespace StardewModdingAPI.Toolkit.Serialization.Models [JsonConstructor] public Manifest(string uniqueId, string name, string author, string description, ISemanticVersion version, ISemanticVersion? minimumApiVersion, string? entryDll, IManifestContentPackFor? contentPackFor, IManifestDependency[]? dependencies, string[]? updateKeys) { - this.UniqueID = this.NormalizeWhitespace(uniqueId); - this.Name = this.NormalizeWhitespace(name); - this.Author = this.NormalizeWhitespace(author); - this.Description = this.NormalizeWhitespace(description); + this.UniqueID = this.NormalizeField(uniqueId); + this.Name = this.NormalizeField(name, replaceSquareBrackets: true); + this.Author = this.NormalizeField(author); + this.Description = this.NormalizeField(description); this.Version = version; this.MinimumApiVersion = minimumApiVersion; - this.EntryDll = this.NormalizeWhitespace(entryDll); + this.EntryDll = this.NormalizeField(entryDll); this.ContentPackFor = contentPackFor; this.Dependencies = dependencies ?? Array.Empty<IManifestDependency>(); this.UpdateKeys = updateKeys ?? Array.Empty<string>(); @@ -113,17 +114,47 @@ namespace StardewModdingAPI.Toolkit.Serialization.Models /********* ** Private methods *********/ - /// <summary>Normalize whitespace in a raw string.</summary> + /// <summary>Normalize a manifest field to strip newlines, trim whitespace, and optionally strip square brackets.</summary> /// <param name="input">The input to strip.</param> + /// <param name="replaceSquareBrackets">Whether to replace square brackets with round ones. This is used in the mod name to avoid breaking the log format.</param> #if NET5_0_OR_GREATER [return: NotNullIfNotNull("input")] #endif - private string? NormalizeWhitespace(string? input) + private string? NormalizeField(string? input, bool replaceSquareBrackets = false) { - return input - ?.Trim() - .Replace("\r", "") - .Replace("\n", ""); + input = input?.Trim(); + + if (!string.IsNullOrEmpty(input)) + { + StringBuilder? builder = null; + + for (int i = 0; i < input.Length; i++) + { + switch (input[i]) + { + case '\r': + case '\n': + builder ??= new StringBuilder(input); + builder[i] = ' '; + break; + + case '[' when replaceSquareBrackets: + builder ??= new StringBuilder(input); + builder[i] = '('; + break; + + case ']' when replaceSquareBrackets: + builder ??= new StringBuilder(input); + builder[i] = ')'; + break; + } + } + + if (builder != null) + input = builder.ToString(); + } + + return input; } } } diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs index 401bba4f..71fb42c2 100644 --- a/src/SMAPI.Web/Controllers/ModsApiController.cs +++ b/src/SMAPI.Web/Controllers/ModsApiController.cs @@ -159,11 +159,20 @@ namespace StardewModdingAPI.Web.Controllers continue; } + // if there's only a prerelease version (e.g. from GitHub), don't override the main version + ISemanticVersion? curMain = data.Version; + ISemanticVersion? curPreview = data.PreviewVersion; + if (curPreview == null && curMain?.IsPrerelease() == true) + { + curPreview = curMain; + curMain = null; + } + // handle versions - if (this.IsNewer(data.Version, main?.Version)) - main = new ModEntryVersionModel(data.Version, data.Url!); - if (this.IsNewer(data.PreviewVersion, optional?.Version)) - optional = new ModEntryVersionModel(data.PreviewVersion, data.Url!); + if (this.IsNewer(curMain, main?.Version)) + main = new ModEntryVersionModel(curMain, data.Url!); + if (this.IsNewer(curPreview, optional?.Version)) + optional = new ModEntryVersionModel(curPreview, data.Url!); } // get unofficial version diff --git a/src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs b/src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs index 23b25f95..46c3092c 100644 --- a/src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs +++ b/src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs @@ -121,10 +121,10 @@ namespace StardewModdingAPI.Web.Framework.Clients.Nexus HtmlNode? node = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'site-notice')][contains(@class, 'warning')]"); if (node != null) { - string[] errorParts = node.InnerText.Trim().Split(new[] { '\n' }, 2, System.StringSplitOptions.RemoveEmptyEntries); + string[] errorParts = node.InnerText.Trim().Split('\n', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); string errorCode = errorParts[0]; string? errorText = errorParts.Length > 1 ? errorParts[1] : null; - switch (errorCode.Trim().ToLower()) + switch (errorCode.ToLower()) { case "not found": return null; diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs index 18ba754c..5e0dedf3 100644 --- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs +++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs @@ -199,8 +199,15 @@ namespace StardewModdingAPI.Web.Framework.LogParsing log.ApiVersion = match.Groups["apiVersion"].Value; log.GameVersion = match.Groups["gameVersion"].Value; log.OperatingSystem = match.Groups["os"].Value; - smapiMod.OverrideVersion(log.ApiVersion); + const string strictModeSuffix = " (strict mode)"; + if (log.ApiVersion.EndsWith(strictModeSuffix)) + { + log.IsStrictMode = true; + log.ApiVersion = log.ApiVersion[..^strictModeSuffix.Length]; + } + + smapiMod.OverrideVersion(log.ApiVersion); log.ApiVersionParsed = smapiMod.GetParsedVersion(); } diff --git a/src/SMAPI.Web/Framework/LogParsing/Models/ParsedLog.cs b/src/SMAPI.Web/Framework/LogParsing/Models/ParsedLog.cs index 3f649199..cda0f653 100644 --- a/src/SMAPI.Web/Framework/LogParsing/Models/ParsedLog.cs +++ b/src/SMAPI.Web/Framework/LogParsing/Models/ParsedLog.cs @@ -25,6 +25,9 @@ namespace StardewModdingAPI.Web.Framework.LogParsing.Models /**** ** Log data ****/ + /// <summary>Whether SMAPI is running in strict mode, which disables all deprecated APIs.</summary> + public bool IsStrictMode { get; set; } + /// <summary>The SMAPI version.</summary> public string? ApiVersion { get; set; } diff --git a/src/SMAPI.Web/SMAPI.Web.csproj b/src/SMAPI.Web/SMAPI.Web.csproj index d26cb6f8..81b187fe 100644 --- a/src/SMAPI.Web/SMAPI.Web.csproj +++ b/src/SMAPI.Web/SMAPI.Web.csproj @@ -25,7 +25,7 @@ <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.5" /> <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14" /> <PackageReference Include="Pathoschild.FluentNexus" Version="1.0.5" /> - <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.1.1" /> + <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.2.0" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" /> diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index 24fe5fa2..28127903 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -40,7 +40,7 @@ <meta name="robots" content="noindex" /> } <link rel="stylesheet" href="~/Content/css/file-upload.css" /> - <link rel="stylesheet" href="~/Content/css/log-parser.css" /> + <link rel="stylesheet" href="~/Content/css/log-parser.css?r=20221009" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tabbyjs@12.0.3/dist/css/tabby-ui-vertical.min.css" /> <script src="https://cdn.jsdelivr.net/npm/tabbyjs@12.0.3" crossorigin="anonymous"></script> @@ -243,7 +243,7 @@ else if (log?.IsValid == true) @if (log?.IsValid == true) { <div id="output"> - @if (outdatedMods.Any() || errorHandler is null || hasOlderErrorHandler || isPyTkCompatibilityMode) + @if (outdatedMods.Any() || errorHandler is null || hasOlderErrorHandler || isPyTkCompatibilityMode || log.IsStrictMode) { <h2>Suggested fixes</h2> <ul id="fix-list"> @@ -257,7 +257,14 @@ else if (log?.IsValid == true) } @if (isPyTkCompatibilityMode) { - <li>PyTK 1.23.* or earlier |
