diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index c3bdbff5..0dc5d1f6 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -431,7 +431,9 @@ namespace StardewModdingAPI // ignore invalid path } } - +#if SMAPI_FOR_MOBILE + if (folder != null && rawSaveName.Length > 0) folder.Create(); +#endif // if save doesn't exist yet, return the default one we expect to be created return folder; } diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/Game1Methods.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/Game1Methods.cs index e15756e1..478c7d91 100644 --- a/src/SMAPI/Framework/ModLoading/RewriteFacades/Game1Methods.cs +++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/Game1Methods.cs @@ -17,7 +17,7 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades public static new IList LocationsGetter() { - return Game1.game1._locations; + return Game1.locations; } #if SMAPI_LEGACY_PATCH diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/ModuleReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/ModuleReferenceRewriter.cs index f9c1782c..d0e55556 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/ModuleReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/ModuleReferenceRewriter.cs @@ -22,23 +22,20 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// public ISet Phrases { get; } = new HashSet(StringComparer.OrdinalIgnoreCase); - private readonly string AssemblyName; - - private readonly Version Version; + private readonly Dictionary AssemblyRules; private readonly Dictionary TargetMap = new(); - public ModuleReferenceRewriter(string phrase, string assemblyName, Version version, Assembly[] assemblies) + public ModuleReferenceRewriter(string phrase, Dictionary assemblyRules, Assembly[] assemblies) { this.DefaultPhrase = $"{phrase} assembly ref"; - this.AssemblyName = assemblyName; - this.Version = version; + this.AssemblyRules = assemblyRules; foreach (var assembly in assemblies) { AssemblyNameReference target = AssemblyNameReference.Parse(assembly.FullName); var map = assembly.GetTypes().ToDictionary(p => p.FullName, p => target); - foreach (KeyValuePair pair in map) + foreach (KeyValuePair pair in map) { this.TargetMap.TryAdd(pair.Key, pair.Value); } @@ -47,15 +44,18 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters private bool IsMatch(AssemblyNameReference reference) { - if (this.AssemblyName.EndsWith('.')) + foreach ((string assemblyName, Version version) in this.AssemblyRules) { - if (reference.Name.Equals(this.AssemblyName) || reference.Name.StartsWith(this.AssemblyName)) - return reference.Version.CompareTo(this.Version) >= 0; - } - else - { - if (reference.Name.Equals(this.AssemblyName)) - return reference.Version.CompareTo(this.Version) >= 0; + if (assemblyName.EndsWith('.')) + { + if (reference.Name.Equals(assemblyName) || reference.Name.StartsWith(assemblyName)) + return reference.Version.CompareTo(version) >= 0; + } + else + { + if (reference.Name.Equals(assemblyName)) + return reference.Version.CompareTo(version) >= 0; + } } return false; @@ -63,13 +63,22 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters private bool IsMatch(TypeReference reference) { - if (this.AssemblyName.EndsWith('.')) { - if(reference.Scope.Name.Equals(this.AssemblyName) || reference.Scope.Name.StartsWith(this.AssemblyName)) + foreach ((string assemblyName, Version _) in this.AssemblyRules) + { + if (assemblyName.EndsWith('.')) + { + if (reference.Scope.Name.Equals(assemblyName) || reference.Scope.Name.StartsWith(assemblyName)) + { + return this.TargetMap.ContainsKey(reference.FullName.Split('/')[0]); + } + } + else if(reference.Scope.Name.Equals(assemblyName)) { return this.TargetMap.ContainsKey(reference.FullName.Split('/')[0]); } } - return reference.Scope.Name.Equals(this.AssemblyName) && this.TargetMap.ContainsKey(reference.FullName.Split('/')[0]); + + return false; } public bool Handle(ModuleDefinition module) @@ -93,6 +102,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters module.AssemblyReferences.Add(target); assembliesAdded.Add(target.FullName); } + type.Scope = target; } @@ -113,6 +123,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters module.AssemblyReferences.Add(target); assembliesAdded.Add(target.FullName); } + type.Scope = target; } } @@ -121,7 +132,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters for (int i = module.AssemblyReferences.Count - 1; i >= 0; i--) { - if(this.IsMatch(module.AssemblyReferences[i])) + if (this.IsMatch(module.AssemblyReferences[i])) { module.AssemblyReferences.RemoveAt(i); } diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypePropertyToAnotherTypeMethodRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypePropertyToAnotherTypeMethodRewriter.cs index b532fe9e..8a39fa1b 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypePropertyToAnotherTypeMethodRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypePropertyToAnotherTypeMethodRewriter.cs @@ -52,14 +52,12 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters if (this.GetterName != null && methodRef.Name == "get_" + this.PropertyName) { methodRef = module.ImportReference(this.ToType.GetMethod(this.GetterName)); - instruction.OpCode = OpCodes.Callvirt; instruction.Operand = methodRef; return true; } if(this.SetterName != null && methodRef.Name == "set_" + this.PropertyName) { methodRef = module.ImportReference(this.ToType.GetMethod(this.SetterName)); - instruction.OpCode = OpCodes.Callvirt; instruction.Operand = methodRef; return true; } diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 39a6e0e6..d6b34ef8 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -399,7 +399,8 @@ namespace StardewModdingAPI.Metadata foreach (DayTimeMoneyBox menu in Game1.onScreenMenus.OfType()) { foreach (ClickableTextureComponent button in new[] { menu.questButton, menu.zoomInButton, menu.zoomOutButton }) - button.texture = Game1.mouseCursors; + if(button != null) + button.texture = Game1.mouseCursors; } if (!ignoreWorld) diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index b545a421..e130ee10 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -58,7 +58,27 @@ namespace StardewModdingAPI.Metadata #if SMAPI_FOR_MOBILE // module rewrite for .Net 5 runtime assemblies - yield return new ModuleReferenceRewriter("System.*", "System.", new Version(4,0), new[] + yield return new ModuleReferenceRewriter("System.*", new() + { + { "System.Collections", new Version(4, 0) }, + { "System.Runtime.InteropServices", new Version(4, 0) }, + { "System.IO", new Version(4, 0) }, + { "System.Reflection", new Version(4, 0) }, + { "System.Text.Encoding", new Version(4, 0) }, + { "System.IO.FileSystem.Primitives", new Version(4, 0) }, + { "System.Linq.Expressions", new Version(4, 0) }, + { "System.Text.RegularExpressions", new Version(4, 0) }, + { "System.Runtime.Extensions", new Version(4, 0) }, + { "System.Linq", new Version(4, 0) }, + { "System.Reflection.Extensions", new Version(4, 0) }, + { "System.Globalization", new Version(4, 0) }, + { "System.IO.FileSystem", new Version(4, 0) }, + { "System.Console", new Version(4, 0) }, + { "System.Threading", new Version(4, 0) }, + { "System.Threading.Tasks", new Version(4, 0) }, + { "System.Text.Encoding.Extensions", new Version(4, 0) }, + { "System.", new Version(5, 0) } + }, new[] { typeof(System.Collections.CollectionBase).Assembly, typeof(System.Collections.Generic.ISet<>).Assembly, @@ -81,8 +101,8 @@ namespace StardewModdingAPI.Metadata yield return new TypePropertyToAnotherTypeMethodRewriter(typeof(TextBox), typeof(TextBoxMethods), "Selected", null, "SelectedSetter"); // Game1.location fix - yield return new TypePropertyToAnotherTypeMethodRewriter(typeof(Game1), typeof(Game1Methods), "locations", "LocationsGetter", null); - yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "rainDrops", "RainDropsProp"); + yield return new TypePropertyToAnotherTypeMethodRewriter(typeof(Game1), typeof(Game1Methods), "locations", nameof(Game1Methods.LocationsGetter), null); + yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "rainDrops", nameof(Game1Methods.RainDropsProp)); // Rewrite Missing Type yield return new TypeReferenceRewriter("StardewValley.Menus.CraftingPage", typeof(CraftingPageMobile));