From e89de6316d8a8b2e0169790b2a14427892828be5 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 30 Oct 2021 19:53:28 -0400 Subject: add set_farm_type console command --- .../Commands/Player/SetFarmTypeCommand.cs | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs (limited to 'src') diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs new file mode 100644 index 00000000..0bebd2b7 --- /dev/null +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using System.Linq; +using StardewValley; + +namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player +{ + /// A command which changes the player's farm type. + internal class SetFarmTypeCommand : ConsoleCommand + { + /********* + ** Fields + *********/ + /// The vanilla farm type IDs. + private static readonly ISet VanillaFarmTypes = new HashSet( + Enumerable.Range(0, Farm.layout_max + 1) + ); + + + /********* + ** Public methods + *********/ + /// Construct an instance. + public SetFarmTypeCommand() + : base("set_farm_type", $"Sets the current player's farm type.\n\nUsage: set_farm_type \n- farm type: one of {string.Join(", ", SetFarmTypeCommand.VanillaFarmTypes.Select(id => $"{id} ({SetFarmTypeCommand.GetFarmLabel(id)})"))}.") { } + + /// Handle the command. + /// Writes messages to the console and log file. + /// The command name. + /// The command arguments. + public override void Handle(IMonitor monitor, string command, ArgumentParser args) + { + // validation checks + if (!Context.IsWorldReady) + { + monitor.Log("You must load a save to use this command.", LogLevel.Error); + return; + } + + // parse argument + if (!args.TryGetInt(0, "farm type", out int farmType, min: 0, max: Farm.layout_max)) + return; + + // handle + if (Game1.whichFarm == farmType) + { + monitor.Log($"Your current farm is already set to {farmType} ({SetFarmTypeCommand.GetFarmLabel(farmType)}).", LogLevel.Info); + return; + } + + this.SetFarmType(farmType); + monitor.Log($"Your current farm has been converted to {farmType} ({SetFarmTypeCommand.GetFarmLabel(farmType)}).", LogLevel.Warn); + monitor.Log("Saving and reloading is recommended to make sure everything is updated for the change.", LogLevel.Warn); + } + + + /********* + ** Private methods + *********/ + /// Change the farm type to the given value. + /// The farm type ID. + private void SetFarmType(int type) + { + Game1.whichFarm = type; + + Farm farm = Game1.getFarm(); + farm.mapPath.Value = $@"Maps\{Farm.getMapNameFromTypeInt(Game1.whichFarm)}"; + farm.reloadMap(); + } + + /// Get the display name for a vanilla farm type. + /// The farm type. + private static string GetFarmLabel(int type) + { + string translationKey = type switch + { + Farm.default_layout => "Character_FarmStandard", + Farm.riverlands_layout => "Character_FarmFishing", + Farm.forest_layout => "Character_FarmForaging", + Farm.mountains_layout => "Character_FarmMining", + Farm.combat_layout => "Character_FarmCombat", + Farm.fourCorners_layout => "Character_FarmFourCorners", + Farm.beach_layout => "Character_FarmBeach", + _ => null + }; + + return translationKey != null + ? Game1.content.LoadString(@$"Strings\UI:{translationKey}").Split('_')[0] + : type.ToString(); + } + } +} -- cgit From 96db1d931552ef8973cdf07e3f1d4a4618992276 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 31 Oct 2021 14:14:21 -0400 Subject: update Content Patcher schema for 1.24.0 --- src/SMAPI.Web/wwwroot/schemas/content-patcher.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json index aac4ff0f..d39574ef 100644 --- a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json +++ b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json @@ -12,11 +12,11 @@ "properties": { "Format": { "title": "Format version", - "description": "The format version. You should always use the latest version to enable the latest features and avoid obsolete behavior.", + "description": "The format version. You should always use the latest version to enable the latest features, avoid obsolete behavior, and reduce load times.", "type": "string", - "const": "1.23.0", + "const": "1.24.0", "@errorMessages": { - "const": "Incorrect value '@value'. This should be set to the latest format version, currently '1.23.0'." + "const": "Incorrect value '@value'. You should always use the latest format version (currently 1.24.0) to enable the latest features, avoid obsolete behavior, and reduce load times." } }, "ConfigSchema": { -- cgit From 01f59000e96357ec5288c4cc86348c90ce272ba4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 31 Oct 2021 14:37:51 -0400 Subject: ignore WebDeploy files --- src/SMAPI.Web/SMAPI.Web.csproj | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/SMAPI.Web/SMAPI.Web.csproj b/src/SMAPI.Web/SMAPI.Web.csproj index 4c8465a6..c1ba3ddc 100644 --- a/src/SMAPI.Web/SMAPI.Web.csproj +++ b/src/SMAPI.Web/SMAPI.Web.csproj @@ -9,6 +9,8 @@ + + -- cgit From 12e0c1519663b7106c5672ce75c6e94d8ab7638f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 27 Nov 2021 22:37:21 -0500 Subject: migrate web project to .NET 6, update web & unit test packages --- .../SMAPI.ModBuildConfig.Analyzer.Tests.csproj | 4 ++-- src/SMAPI.Web/SMAPI.Web.csproj | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj index 8cc61f44..dc3d8320 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj @@ -7,9 +7,9 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/SMAPI.Web/SMAPI.Web.csproj b/src/SMAPI.Web/SMAPI.Web.csproj index c1ba3ddc..f1400e62 100644 --- a/src/SMAPI.Web/SMAPI.Web.csproj +++ b/src/SMAPI.Web/SMAPI.Web.csproj @@ -2,7 +2,7 @@ SMAPI.Web StardewModdingAPI.Web - net5.0 + net6.0 latest @@ -15,16 +15,16 @@ - - + + - - - - + + + + - + -- cgit From b64cec918d1511b6b71c9d2e30f987e9b5cc24fd Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 27 Nov 2021 22:45:14 -0500 Subject: remove direct download for beta versions With this change, only the main version has a direct download. Showing beta info here caused a few issues: * The vast majority of players don't use the game beta, so they were often confused about which version to download. * Beta versions typically have much longer release info (e.g. detailed summary, release notes, caveats and warnings, etc), and the extra download button made the player guide button under it less prominent and visible. Those both contributed to information overload and the above confusion. * Unlike main versions, beta versions aren't permanently archived on GitHub (since the beta branch is routinely rebased onto the latest stable update). That makes it messy to manage beta releases through GitHub. Instead there's now a message under the download button which clearly links to where the beta version can be downloaded. --- src/SMAPI.Web/Controllers/IndexController.cs | 52 +++++--------------- src/SMAPI.Web/Framework/ConfigModels/SiteConfig.cs | 7 +-- src/SMAPI.Web/ViewModels/IndexModel.cs | 15 ++---- src/SMAPI.Web/Views/Index/Index.cshtml | 57 +++++----------------- src/SMAPI.Web/appsettings.json | 3 +- src/SMAPI.Web/wwwroot/Content/css/index.css | 4 ++ 6 files changed, 35 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/SMAPI.Web/Controllers/IndexController.cs b/src/SMAPI.Web/Controllers/IndexController.cs index 080285ab..f2f4c342 100644 --- a/src/SMAPI.Web/Controllers/IndexController.cs +++ b/src/SMAPI.Web/Controllers/IndexController.cs @@ -57,21 +57,16 @@ namespace StardewModdingAPI.Web.Controllers { // choose versions ReleaseVersion[] versions = await this.GetReleaseVersionsAsync(); - ReleaseVersion stableVersion = versions.LastOrDefault(version => !version.IsBeta && !version.IsForDevs); - ReleaseVersion stableVersionForDevs = versions.LastOrDefault(version => !version.IsBeta && version.IsForDevs); - ReleaseVersion betaVersion = versions.LastOrDefault(version => version.IsBeta && !version.IsForDevs); - ReleaseVersion betaVersionForDevs = versions.LastOrDefault(version => version.IsBeta && version.IsForDevs); + ReleaseVersion stableVersion = versions.LastOrDefault(version => !version.IsForDevs); + ReleaseVersion stableVersionForDevs = versions.LastOrDefault(version => version.IsForDevs); // render view IndexVersionModel stableVersionModel = stableVersion != null ? new IndexVersionModel(stableVersion.Version.ToString(), stableVersion.Release.Body, stableVersion.Asset.DownloadUrl, stableVersionForDevs?.Asset.DownloadUrl) - : new IndexVersionModel("unknown", "", "https://github.com/Pathoschild/SMAPI/releases", null); // just in case something goes wrong) - IndexVersionModel betaVersionModel = betaVersion != null && this.SiteConfig.BetaEnabled - ? new IndexVersionModel(betaVersion.Version.ToString(), betaVersion.Release.Body, betaVersion.Asset.DownloadUrl, betaVersionForDevs?.Asset.DownloadUrl) - : null; + : new IndexVersionModel("unknown", "", "https://github.com/Pathoschild/SMAPI/releases", null); // just in case something goes wrong // render view - var model = new IndexModel(stableVersionModel, betaVersionModel, this.SiteConfig.BetaBlurb, this.SiteConfig.SupporterList); + var model = new IndexModel(stableVersionModel, this.SiteConfig.OtherBlurb, this.SiteConfig.SupporterList); return this.View(model); } @@ -93,27 +88,12 @@ namespace StardewModdingAPI.Web.Controllers { entry.AbsoluteExpiration = DateTimeOffset.UtcNow.Add(this.CacheTime); - // get latest release (whether preview or stable) - GitRelease stableRelease = await this.GitHub.GetLatestReleaseAsync(this.RepositoryName, includePrerelease: true); + // get latest stable release + GitRelease release = await this.GitHub.GetLatestReleaseAsync(this.RepositoryName, includePrerelease: false); - // split stable/prerelease if applicable - GitRelease betaRelease = null; - if (stableRelease.IsPrerelease) + // strip 'noinclude' blocks from release description + if (release != null) { - GitRelease result = await this.GitHub.GetLatestReleaseAsync(this.RepositoryName, includePrerelease: false); - if (result != null) - { - betaRelease = stableRelease; - stableRelease = result; - } - } - - // strip 'noinclude' blocks from release descriptions - foreach (GitRelease release in new[] { stableRelease, betaRelease }) - { - if (release == null) - continue; - HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(release.Body); foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//*[@class='noinclude']")?.ToArray() ?? new HtmlNode[0]) @@ -122,10 +102,8 @@ namespace StardewModdingAPI.Web.Controllers } // get versions - ReleaseVersion[] stableVersions = this.ParseReleaseVersions(stableRelease).ToArray(); - ReleaseVersion[] betaVersions = this.ParseReleaseVersions(betaRelease).ToArray(); - return stableVersions - .Concat(betaVersions) + return this + .ParseReleaseVersions(release) .OrderBy(p => p.Version) .ToArray(); }); @@ -146,10 +124,9 @@ namespace StardewModdingAPI.Web.Controllers Match match = Regex.Match(asset.FileName, @"SMAPI-(?[\d\.]+(?:-.+)?)-installer(?-for-developers)?.zip"); if (!match.Success || !SemanticVersion.TryParse(match.Groups["version"].Value, out ISemanticVersion version)) continue; - bool isBeta = version.IsPrerelease(); bool isForDevs = match.Groups["forDevs"].Success; - yield return new ReleaseVersion(release, asset, version, isBeta, isForDevs); + yield return new ReleaseVersion(release, asset, version, isForDevs); } } @@ -168,9 +145,6 @@ namespace StardewModdingAPI.Web.Controllers /// The SMAPI version. public ISemanticVersion Version { get; } - /// Whether this is a beta download. - public bool IsBeta { get; } - /// Whether this is a 'for developers' download. public bool IsForDevs { get; } @@ -182,14 +156,12 @@ namespace StardewModdingAPI.Web.Controllers /// The underlying GitHub release. /// The underlying download asset. /// The SMAPI version. - /// Whether this is a beta download. /// Whether this is a 'for developers' download. - public ReleaseVersion(GitRelease release, GitAsset asset, ISemanticVersion version, bool isBeta, bool isForDevs) + public ReleaseVersion(GitRelease release, GitAsset asset, ISemanticVersion version, bool isForDevs) { this.Release = release; this.Asset = asset; this.Version = version; - this.IsBeta = isBeta; this.IsForDevs = isForDevs; } } diff --git a/src/SMAPI.Web/Framework/ConfigModels/SiteConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/SiteConfig.cs index 43969f51..664dbef3 100644 --- a/src/SMAPI.Web/Framework/ConfigModels/SiteConfig.cs +++ b/src/SMAPI.Web/Framework/ConfigModels/SiteConfig.cs @@ -6,11 +6,8 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels /********* ** Accessors *********/ - /// Whether to show SMAPI beta versions on the main page, if any. - public bool BetaEnabled { get; set; } - - /// A short sentence shown under the beta download button, if any. - public string BetaBlurb { get; set; } + /// A message to show below the download button (e.g. for details on downloading a beta version), in Markdown format. + public string OtherBlurb { get; set; } /// A list of supports to credit on the main page, in Markdown format. public string SupporterList { get; set; } diff --git a/src/SMAPI.Web/ViewModels/IndexModel.cs b/src/SMAPI.Web/ViewModels/IndexModel.cs index 450fdc0e..d8d2d27f 100644 --- a/src/SMAPI.Web/ViewModels/IndexModel.cs +++ b/src/SMAPI.Web/ViewModels/IndexModel.cs @@ -9,11 +9,8 @@ namespace StardewModdingAPI.Web.ViewModels /// The latest stable SMAPI version. public IndexVersionModel StableVersion { get; set; } - /// The latest prerelease SMAPI version (if newer than ). - public IndexVersionModel BetaVersion { get; set; } - - /// A short sentence shown under the beta download button, if any. - public string BetaBlurb { get; set; } + /// A message to show below the download button (e.g. for details on downloading a beta version), in Markdown format. + public string OtherBlurb { get; set; } /// A list of supports to credit on the main page, in Markdown format. public string SupporterList { get; set; } @@ -27,14 +24,12 @@ namespace StardewModdingAPI.Web.ViewModels /// Construct an instance. /// The latest stable SMAPI version. - /// The latest prerelease SMAPI version (if newer than ). - /// A short sentence shown under the beta download button, if any. + /// A message to show below the download button (e.g. for details on downloading a beta version), in Markdown format. /// A list of supports to credit on the main page, in Markdown format. - internal IndexModel(IndexVersionModel stableVersion, IndexVersionModel betaVersion, string betaBlurb, string supporterList) + internal IndexModel(IndexVersionModel stableVersion, string otherBlurb, string supporterList) { this.StableVersion = stableVersion; - this.BetaVersion = betaVersion; - this.BetaBlurb = betaBlurb; + this.OtherBlurb = otherBlurb; this.SupporterList = supporterList; } } diff --git a/src/SMAPI.Web/Views/Index/Index.cshtml b/src/SMAPI.Web/Views/Index/Index.cshtml index 9d6e4bed..669cfd99 100644 --- a/src/SMAPI.Web/Views/Index/Index.cshtml +++ b/src/SMAPI.Web/Views/Index/Index.cshtml @@ -8,9 +8,9 @@ ViewData["ViewTitle"] = string.Empty; } @section Head { - + - + }

@@ -29,25 +29,12 @@ Download from Nexus Direct download -
- - @if (Model.BetaVersion != null) + + + @if (Model.OtherBlurb != null) { -
+
@Html.Raw(Markdig.Markdown.ToHtml(Model.OtherBlurb))
} -
@@ -61,29 +48,11 @@
- @if (Model.BetaVersion == null) - { -

What's new

-
- @Html.Raw(Markdig.Markdown.ToHtml(Model.StableVersion.Description)) -
-

See the release notes and mod compatibility list for more info.

- } - else - { -

What's new in...

-

SMAPI @Model.StableVersion.Version?

-
- @Html.Raw(Markdig.Markdown.ToHtml(Model.StableVersion.Description)) -
-

See the release notes and mod compatibility list for more info.

- -

SMAPI @Model.BetaVersion.Version?

-
- @Html.Raw(Markdig.Markdown.ToHtml(Model.BetaVersion.Description)) -
-

See the release notes and mod compatibility list for more info.

- } +

What's new

+
+ @Html.Raw(Markdig.Markdown.ToHtml(Model.StableVersion.Description)) +
+

See the release notes and mod compatibility list for more info.

@@ -122,10 +91,6 @@

For mod creators

diff --git a/src/SMAPI.Web/appsettings.json b/src/SMAPI.Web/appsettings.json index 22fd7396..1837170b 100644 --- a/src/SMAPI.Web/appsettings.json +++ b/src/SMAPI.Web/appsettings.json @@ -17,8 +17,7 @@ "Site": { "BetaEnabled": false, - "BetaBlurb": null, - "SupporterList": null + "OtherBlurb": null }, "ApiClients": { diff --git a/src/SMAPI.Web/wwwroot/Content/css/index.css b/src/SMAPI.Web/wwwroot/Content/css/index.css index 1cf8d261..150ccc0a 100644 --- a/src/SMAPI.Web/wwwroot/Content/css/index.css +++ b/src/SMAPI.Web/wwwroot/Content/css/index.css @@ -97,6 +97,10 @@ h1 { display: block; } +.cta-blurb { + font-size: 0.85em; +} + .sublinks { font-size: 0.9em; margin-bottom: 1em; -- cgit From 3ca6fb562417748c87567d6bb6915d56b2c1b57c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 27 Nov 2021 23:59:13 -0500 Subject: automatically include beta versions on Nexus for SMAPI update checks --- src/SMAPI.Web/Controllers/ModsApiController.cs | 7 +++++++ .../Framework/ConfigModels/ModUpdateCheckConfig.cs | 3 +++ src/SMAPI.Web/Framework/ConfigModels/SmapiInfoConfig.cs | 15 +++++++++++++++ src/SMAPI.Web/appsettings.json | 7 ++++++- 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/SMAPI.Web/Framework/ConfigModels/SmapiInfoConfig.cs (limited to 'src') diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs index dcddaf10..37d763cc 100644 --- a/src/SMAPI.Web/Controllers/ModsApiController.cs +++ b/src/SMAPI.Web/Controllers/ModsApiController.cs @@ -81,6 +81,8 @@ namespace StardewModdingAPI.Web.Controllers if (model?.Mods == null) return new ModEntryModel[0]; + ModUpdateCheckConfig config = this.Config.Value; + // fetch wiki data WikiModEntry[] wikiData = this.WikiCache.GetWikiMods().Select(p => p.Data).ToArray(); IDictionary mods = new Dictionary(StringComparer.CurrentCultureIgnoreCase); @@ -89,6 +91,11 @@ namespace StardewModdingAPI.Web.Controllers if (string.IsNullOrWhiteSpace(mod.ID)) continue; + // special case: if this is an update check for the official SMAPI repo, check the Nexus mod page for beta versions + if (mod.ID == config.SmapiInfo.ID && mod.UpdateKeys?.Any(key => key == config.SmapiInfo.DefaultUpdateKey) == true && mod.InstalledVersion?.IsPrerelease() == true) + mod.UpdateKeys = mod.UpdateKeys.Concat(config.SmapiInfo.AddBetaUpdateKeys).ToArray(); + + // fetch result ModEntryModel result = await this.GetModData(mod, wikiData, model.IncludeExtendedMetadata, model.ApiVersion); if (!model.IncludeExtendedMetadata && (model.ApiVersion == null || mod.InstalledVersion == null)) { diff --git a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs index bd58dba0..aea695b8 100644 --- a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs +++ b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs @@ -14,5 +14,8 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels /// Update-check metadata to override. public ModOverrideConfig[] ModOverrides { get; set; } + + /// The update-check config for SMAPI's own update checks. + public SmapiInfoConfig SmapiInfo { get; set; } } } diff --git a/src/SMAPI.Web/Framework/ConfigModels/SmapiInfoConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/SmapiInfoConfig.cs new file mode 100644 index 00000000..d69fabb3 --- /dev/null +++ b/src/SMAPI.Web/Framework/ConfigModels/SmapiInfoConfig.cs @@ -0,0 +1,15 @@ +namespace StardewModdingAPI.Web.Framework.ConfigModels +{ + /// The update-check config for SMAPI's own update checks. + internal class SmapiInfoConfig + { + /// The mod ID used for SMAPI update checks. + public string ID { get; set; } + + /// The default update key used for SMAPI update checks. + public string DefaultUpdateKey { get; set; } + + /// The update keys to add for SMAPI update checks when the player has a beta version installed. + public string[] AddBetaUpdateKeys { get; set; } + } +} diff --git a/src/SMAPI.Web/appsettings.json b/src/SMAPI.Web/appsettings.json index 1837170b..0265a928 100644 --- a/src/SMAPI.Web/appsettings.json +++ b/src/SMAPI.Web/appsettings.json @@ -75,6 +75,11 @@ "ID": "MartyrPher.SMAPI-Android-Installer", "AllowNonStandardVersions": true } - ] + ], + "SmapiInfo": { + "ID": "Pathoschild.SMAPI", + "DefaultUpdateKey": "GitHub:Pathoschild/SMAPI", + "AddBetaUpdateKeys": [ "Nexus:2400" ] + } } } -- cgit From c8c6b3897cd080ef3261f5642d31d8a51971981b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 2 Sep 2021 19:31:22 -0400 Subject: update versions for Stardew Valley 1.5.5 and remove 1.5.4-specific checks --- src/SMAPI.Installer/InteractiveInstaller.cs | 20 -------------------- src/SMAPI/Constants.cs | 4 ++-- src/SMAPI/Program.cs | 13 ------------- 3 files changed, 2 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 9f49137f..79c3b891 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -277,18 +277,6 @@ namespace StardewModdingApi.Installer /********* ** Step 4: validate assumptions *********/ - // not 64-bit on Windows - if (context.Platform == Platform.Windows) - { - FileInfo linuxExecutable = new FileInfo(Path.Combine(paths.GamePath, "StardewValley.exe")); - if (linuxExecutable.Exists && this.Is64Bit(linuxExecutable.FullName)) - { - this.PrintError("Oops! The detected game install path seems to be unofficial 64-bit mode, which is no longer supported. You can update to Stardew Valley 1.5.5 or later instead. See https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows for more info."); - Console.ReadLine(); - return; - } - } - // executable exists if (!File.Exists(paths.ExecutablePath)) { @@ -297,14 +285,6 @@ namespace StardewModdingApi.Installer return; } - // not Stardew Valley 1.5.5+ - if (File.Exists(Path.Combine(paths.GamePath, "Stardew Valley.dll"))) - { - this.PrintError("Oops! The detected game install path seems to be Stardew Valley 1.5.5 or later, but this version of SMAPI is only compatible up to Stardew Valley 1.5.4. Please check for a newer version of SMAPI: https://smapi.io."); - Console.ReadLine(); - return; - } - // game folder doesn't contain paths beyond the max limit { string[] tooLongPaths = PathUtilities.GetTooLongPaths(Path.Combine(paths.GamePath, "Mods")).ToArray(); diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 42c3b21b..4d6a2a0b 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -70,10 +70,10 @@ namespace StardewModdingAPI public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion(EarlyConstants.RawApiVersion); /// The minimum supported version of Stardew Valley. - public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.5.4"); + public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.5.5"); /// The maximum supported version of Stardew Valley. - public static ISemanticVersion MaximumGameVersion { get; } = new GameVersion("1.5.4"); + public static ISemanticVersion MaximumGameVersion { get; } = null; /// The target game platform. public static GamePlatform TargetPlatform { get; } = EarlyConstants.Platform; diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 3f97e531..574e781d 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Reflection; using System.Threading; using StardewModdingAPI.Framework; -using StardewModdingAPI.Toolkit.Framework; using StardewModdingAPI.Toolkit.Serialization.Models; namespace StardewModdingAPI @@ -84,22 +83,10 @@ namespace StardewModdingAPI } catch (Exception ex) { - // unofficial 64-bit - if (EarlyConstants.Platform == GamePlatform.Windows) - { - FileInfo linuxExecutable = new FileInfo(Path.Combine(EarlyConstants.ExecutionPath, "StardewValley.exe")); - if (linuxExecutable.Exists && LowLevelEnvironmentUtility.Is64BitAssembly(linuxExecutable.FullName)) - Program.PrintErrorAndExit("Oops! You're running Stardew Valley in unofficial 64-bit mode, which is no longer supported. You can update to Stardew Valley 1.5.5 or later instead. See https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows for more info."); - } - // file doesn't exist if (!File.Exists(Path.Combine(EarlyConstants.ExecutionPath, $"{EarlyConstants.GameAssemblyName}.exe"))) Program.PrintErrorAndExit("Oops! SMAPI can't find the game. Make sure you're running StardewModdingAPI.exe in your game folder."); - // Stardew Valley 1.5.5+ - if (File.Exists(Path.Combine(EarlyConstants.ExecutionPath, "Stardew Valley.dll"))) - Program.PrintErrorAndExit("Oops! You're running Stardew Valley 1.5.5 or later, but this version of SMAPI is only compatible up to Stardew Valley 1.5.4. Please check for a newer version of SMAPI: https://smapi.io."); - // can't load file Program.PrintErrorAndExit( message: "Oops! SMAPI couldn't load the game executable. The technical details below may have more info.", -- cgit From 6efaa651cb2b026b7bace55ffeba9d7c5a3d0567 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 12 Aug 2021 21:26:01 -0400 Subject: drop support for XNA Framework Stardew Valley 1.5.5 migrates to MonoGame on all platforms. --- src/SMAPI.ModBuildConfig/build/smapi.targets | 32 +++------ .../SMAPI.Mods.ConsoleCommands.csproj | 18 +---- .../Patches/SpriteBatchPatcher.cs | 9 +-- .../SMAPI.Mods.ErrorHandler.csproj | 18 +---- src/SMAPI/Constants.cs | 82 +++++++--------------- src/SMAPI/Framework/Content/ContentCache.cs | 9 +-- src/SMAPI/Framework/Input/GamePadStateBuilder.cs | 19 ++--- src/SMAPI/Framework/InternalExtensions.cs | 7 +- src/SMAPI/Framework/Logging/LogManager.cs | 8 +-- .../ModLoading/RewriteFacades/SpriteBatchFacade.cs | 10 +-- src/SMAPI/Framework/SCore.cs | 8 +-- src/SMAPI/GameFramework.cs | 7 +- src/SMAPI/Metadata/InstructionMetadata.cs | 8 +-- src/SMAPI/SMAPI.csproj | 19 +---- 14 files changed, 60 insertions(+), 194 deletions(-) (limited to 'src') diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 698765ad..664ba7df 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -43,38 +43,24 @@ - + + + + + - + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs index 6860a4ec..f243c6d1 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs @@ -19,9 +19,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: Constants.GameFramework == GameFramework.Xna - ? this.RequireMethod("InternalDraw") - : this.RequireMethod("CheckValid", new[] { typeof(Texture2D) }), + original: this.RequireMethod("CheckValid", new[] { typeof(Texture2D) }), postfix: this.GetHarmonyMethod(nameof(SpriteBatchPatcher.After_CheckValid)) ); } @@ -30,13 +28,8 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /********* ** Private methods *********/ -#if SMAPI_FOR_XNA - /// The method to call after . - /// The texture to validate. -#else /// The method to call after . /// The texture to validate. -#endif private static void After_CheckValid(Texture2D texture) { if (texture?.IsDisposed == true) diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 182a978e..27b9144f 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -15,6 +15,7 @@ + @@ -24,23 +25,6 @@ - - - - - - - - - - - - - - - - - diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 4d6a2a0b..72456ae4 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -40,12 +40,7 @@ namespace StardewModdingAPI internal static GamePlatform Platform { get; } = (GamePlatform)Enum.Parse(typeof(GamePlatform), LowLevelEnvironmentUtility.DetectPlatform()); /// The game framework running the game. - internal static GameFramework GameFramework { get; } = -#if SMAPI_FOR_XNA - GameFramework.Xna; -#else - GameFramework.MonoGame; -#endif + internal static GameFramework GameFramework { get; } = GameFramework.MonoGame; /// The game's assembly name. internal static string GameAssemblyName => EarlyConstants.Platform == GamePlatform.Windows ? "Stardew Valley" : "StardewValley"; @@ -260,61 +255,32 @@ namespace StardewModdingAPI removeAssemblyReferences.Add("StardewModdingAPI.Toolkit.CoreInterfaces"); targetAssemblies.Add(typeof(StardewModdingAPI.IManifest).Assembly); - // get changes for platform - if (Constants.Platform != Platform.Windows) + // XNA Framework before Stardew Valley 1.5.5 + removeAssemblyReferences.AddRange(new[] { - removeAssemblyReferences.AddRange(new[] - { - "Netcode", - "Stardew Valley" - }); - targetAssemblies.Add( - typeof(StardewValley.Game1).Assembly // note: includes Netcode types on Linux/macOS - ); - } - else - { - removeAssemblyReferences.Add( - "StardewValley" - ); - targetAssemblies.AddRange(new[] - { - typeof(Netcode.NetBool).Assembly, - typeof(StardewValley.Game1).Assembly - }); - } + "Microsoft.Xna.Framework", + "Microsoft.Xna.Framework.Game", + "Microsoft.Xna.Framework.Graphics", + "Microsoft.Xna.Framework.Xact" + }); + targetAssemblies.Add( + typeof(Microsoft.Xna.Framework.Vector2).Assembly + ); - // get changes for game framework - switch (framework) - { - case GameFramework.MonoGame: - removeAssemblyReferences.AddRange(new[] - { - "Microsoft.Xna.Framework", - "Microsoft.Xna.Framework.Game", - "Microsoft.Xna.Framework.Graphics", - "Microsoft.Xna.Framework.Xact" - }); - targetAssemblies.Add( - typeof(Microsoft.Xna.Framework.Vector2).Assembly - ); - break; - - case GameFramework.Xna: - removeAssemblyReferences.Add( - "MonoGame.Framework" - ); - targetAssemblies.AddRange(new[] - { - typeof(Microsoft.Xna.Framework.Vector2).Assembly, - typeof(Microsoft.Xna.Framework.Game).Assembly, - typeof(Microsoft.Xna.Framework.Graphics.SpriteBatch).Assembly - }); - break; + // `Netcode.dll` merged into the game assembly in Stardew Valley 1.5.5 + removeAssemblyReferences.Add( + "Netcode" + ); - default: - throw new InvalidOperationException($"Unknown game framework '{framework}'."); - } + // Stardew Valley reference + removeAssemblyReferences.Add( + Constants.Platform == Platform.Windows + ? "StardewValley" + : "Stardew Valley" + ); + targetAssemblies.Add( + typeof(StardewValley.Game1).Assembly + ); return new PlatformAssemblyMap(targetPlatform, removeAssemblyReferences.ToArray(), targetAssemblies.ToArray()); } diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs index 7edc9ab9..87d15e32 100644 --- a/src/SMAPI/Framework/Content/ContentCache.cs +++ b/src/SMAPI/Framework/Content/ContentCache.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; -using Microsoft.Xna.Framework; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Toolkit.Utilities; using StardewValley; @@ -52,13 +51,7 @@ namespace StardewModdingAPI.Framework.Content this.Cache = reflection.GetField>(contentManager, "loadedAssets").GetValue(); // get key normalization logic - if (Constants.GameFramework == GameFramework.Xna) - { - IReflectedMethod method = reflection.GetMethod(typeof(TitleContainer), "GetCleanPath"); - this.NormalizeAssetNameForPlatform = path => method.Invoke(path); - } - else - this.NormalizeAssetNameForPlatform = key => key.Replace('\\', '/'); // based on MonoGame's ContentManager.Load logic + this.NormalizeAssetNameForPlatform = PathUtilities.NormalizePath; //this.NormalizeAssetNameForPlatform = key => key.Replace('\\', '/'); // based on MonoGame's ContentManager.Load logic } /**** diff --git a/src/SMAPI/Framework/Input/GamePadStateBuilder.cs b/src/SMAPI/Framework/Input/GamePadStateBuilder.cs index f5f2d916..b0bb7f80 100644 --- a/src/SMAPI/Framework/Input/GamePadStateBuilder.cs +++ b/src/SMAPI/Framework/Input/GamePadStateBuilder.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -157,11 +158,8 @@ namespace StardewModdingAPI.Framework.Input yield break; // buttons - foreach (var pair in this.ButtonStates) - { - if (pair.Value == ButtonState.Pressed && pair.Key.TryGetController(out Buttons button)) - yield return button.ToSButton(); - } + foreach (Buttons button in this.GetPressedGamePadButtons()) + yield return button.ToSButton(); // triggers if (this.LeftTrigger > 0.2f) @@ -201,7 +199,7 @@ namespace StardewModdingAPI.Framework.Input rightThumbStick: this.RightStickPos, leftTrigger: this.LeftTrigger, rightTrigger: this.RightTrigger, - buttons: this.GetButtonBitmask() // MonoGame requires one bitmask here; don't specify multiple values + buttons: this.GetPressedGamePadButtons().ToArray() ); return this.State.Value; @@ -211,17 +209,14 @@ namespace StardewModdingAPI.Framework.Input /********* ** Private methods *********/ - /// Get a bitmask representing the pressed buttons. - private Buttons GetButtonBitmask() + /// Get the pressed gamepad buttons. + private IEnumerable GetPressedGamePadButtons() { - Buttons flag = 0; foreach (var pair in this.ButtonStates) { if (pair.Value == ButtonState.Pressed && pair.Key.TryGetController(out Buttons button)) - flag |= button; + yield return button; } - - return flag; } } } diff --git a/src/SMAPI/Framework/InternalExtensions.cs b/src/SMAPI/Framework/InternalExtensions.cs index 6c9a5f3b..4cb77a45 100644 --- a/src/SMAPI/Framework/InternalExtensions.cs +++ b/src/SMAPI/Framework/InternalExtensions.cs @@ -6,7 +6,6 @@ using System.Threading; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.Events; using StardewModdingAPI.Framework.Reflection; -using StardewValley; using StardewValley.Menus; namespace StardewModdingAPI.Framework @@ -150,11 +149,7 @@ namespace StardewModdingAPI.Framework /// The reflection helper with which to access private fields. public static bool IsOpen(this SpriteBatch spriteBatch, Reflector reflection) { - string fieldName = Constants.GameFramework == GameFramework.Xna - ? "inBeginEndPair" - : "_beginCalled"; - - return reflection.GetField(Game1.spriteBatch, fieldName).GetValue(); + return reflection.GetField(spriteBatch, "_beginCalled").GetValue(); } } } diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index f2876146..2e25a94a 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -253,10 +253,10 @@ namespace StardewModdingAPI.Framework.Logging switch (exception) { // audio crash - case InvalidOperationException ex when ex.Source == "Microsoft.Xna.Framework.Xact" && ex.StackTrace.Contains("Microsoft.Xna.Framework.Audio.AudioEngine..ctor"): - this.Monitor.Log("The game couldn't load audio. Do you have speakers or headphones plugged in?", LogLevel.Error); - this.Monitor.Log($"Technical details: {ex.GetLogSummary()}"); - break; + //case InvalidOperationException ex when ex.Source == "Microsoft.Xna.Framework.Xact" && ex.StackTrace.Contains("Microsoft.Xna.Framework.Audio.AudioEngine..ctor"): + // this.Monitor.Log("The game couldn't load audio. Do you have speakers or headphones plugged in?", LogLevel.Error); + // this.Monitor.Log($"Technical details: {ex.GetLogSummary()}"); + // break; // missing content folder exception case FileNotFoundException ex when ex.Message == "Couldn't find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs index aefd1c20..a064f503 100644 --- a/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs +++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs @@ -4,7 +4,7 @@ using Microsoft.Xna.Framework.Graphics; namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades { - /// Provides method signatures that can be injected into mod code for compatibility between Linux/macOS or Windows. + /// Provides method signatures that can be injected into mod code for compatibility with mods written for XNA Framework before Stardew Valley 1.5.5. /// This is public to support SMAPI rewriting and should not be referenced directly by mods. [SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "Used via assembly rewriting")] [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Linux/macOS.")] @@ -18,14 +18,6 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades public SpriteBatchFacade(GraphicsDevice graphicsDevice) : base(graphicsDevice) { } - /**** - ** MonoGame signatures - ****/ - public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix? matrix) - { - base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, matrix ?? Matrix.Identity); - } - /**** ** XNA signatures ****/ diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 6dffb1de..b049e868 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -16,9 +16,7 @@ using Microsoft.Xna.Framework; #if SMAPI_FOR_WINDOWS using Microsoft.Win32; #endif -#if SMAPI_FOR_XNA -using System.Windows.Forms; -#endif +using Microsoft.Xna.Framework; using Newtonsoft.Json; using StardewModdingAPI.Enums; using StardewModdingAPI.Events; @@ -224,10 +222,6 @@ namespace StardewModdingAPI.Framework this.Toolkit.JsonHelper.JsonSettings.Converters.Add(converter); // add error handlers -#if SMAPI_FOR_XNA - Application.ThreadException += (sender, e) => this.Monitor.Log($"Critical thread exception: {e.Exception.GetLogSummary()}", LogLevel.Error); - Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); -#endif AppDomain.CurrentDomain.UnhandledException += (sender, e) => this.Monitor.Log($"Critical app domain exception: {e.ExceptionObject}", LogLevel.Error); // add more lenient assembly resolver diff --git a/src/SMAPI/GameFramework.cs b/src/SMAPI/GameFramework.cs index 7670ce8f..a0154329 100644 --- a/src/SMAPI/GameFramework.cs +++ b/src/SMAPI/GameFramework.cs @@ -1,12 +1,15 @@ +using System; + namespace StardewModdingAPI { /// The game framework running the game. public enum GameFramework { - /// The XNA Framework on Windows. + /// The XNA Framework, previously used on Windows. + [Obsolete("Stardew Valley no longer uses XNA Framework on any supported platform.")] Xna, - /// The MonoGame framework, usually on non-Windows platforms. + /// The MonoGame framework. MonoGame } } diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 76371e50..368306a1 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -36,9 +36,6 @@ namespace StardewModdingAPI.Metadata // rewrite for crossplatform compatibility if (rewriteMods) { - if (platformChanged) - yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade)); - // rewrite for Stardew Valley 1.5 yield return new FieldReplaceRewriter(typeof(DecoratableLocation), "furniture", typeof(GameLocation), nameof(GameLocation.furniture)); yield return new FieldReplaceRewriter(typeof(Farm), "resourceClumps", typeof(GameLocation), nameof(GameLocation.resourceClumps)); @@ -48,8 +45,9 @@ namespace StardewModdingAPI.Metadata yield return new HeuristicFieldRewriter(this.ValidateReferencesToAssemblies); yield return new HeuristicMethodRewriter(this.ValidateReferencesToAssemblies); - // rewrite for 64-bit mode - // re-enable in Stardew Valley 1.5.5 + // rewrite for Stardew Valley 1.5.5 + if (platformChanged) + yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade)); //yield return new ArchitectureAssemblyRewriter(); // detect Harmony & rewrite for SMAPI 3.12 (Harmony 1.x => 2.0 update) diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index c147e7dc..7fb40722 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -30,32 +30,15 @@ + - - - - - - - - - - - -