diff options
Diffstat (limited to 'src/SMAPI')
-rw-r--r-- | src/SMAPI/Framework/ContentManagers/ModContentManager.cs | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs | 33 | ||||
-rw-r--r-- | src/SMAPI/Program.cs | 29 |
3 files changed, 49 insertions, 17 deletions
diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs index 4f6aa775..bc5a8b74 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -77,6 +77,8 @@ namespace StardewModdingAPI.Framework.ContentManagers /// <inheritdoc /> public override T Load<T>(string assetName, LanguageCode language, bool useCache) { + // normalize key + bool isXnbFile = Path.GetExtension(assetName).ToLower() == ".xnb"; assetName = this.AssertAndNormalizeAssetName(assetName); // disable caching @@ -108,7 +110,7 @@ namespace StardewModdingAPI.Framework.ContentManagers try { // get file - FileInfo file = this.GetModFile(assetName); + FileInfo file = this.GetModFile(isXnbFile ? $"{assetName}.xnb" : assetName); // .xnb extension is stripped from asset names passed to the content manager if (!file.Exists) throw GetContentError("the specified path doesn't exist."); diff --git a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs index 464367b6..8d1b6034 100644 --- a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs +++ b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs @@ -36,23 +36,26 @@ namespace StardewModdingAPI.Framework.Reflection public TInterface CreateProxy<TInterface>(object instance, string sourceModID, string targetModID) where TInterface : class { - // validate - if (instance == null) - throw new InvalidOperationException("Can't proxy access to a null API."); - if (!typeof(TInterface).IsInterface) - throw new InvalidOperationException("The proxy type must be an interface, not a class."); - - // get proxy type - Type targetType = instance.GetType(); - string proxyTypeName = $"StardewModdingAPI.Proxies.From<{sourceModID}_{typeof(TInterface).FullName}>_To<{targetModID}_{targetType.FullName}>"; - if (!this.Builders.TryGetValue(proxyTypeName, out InterfaceProxyBuilder builder)) + lock (this.Builders) { - builder = new InterfaceProxyBuilder(proxyTypeName, this.ModuleBuilder, typeof(TInterface), targetType); - this.Builders[proxyTypeName] = builder; - } + // validate + if (instance == null) + throw new InvalidOperationException("Can't proxy access to a null API."); + if (!typeof(TInterface).IsInterface) + throw new InvalidOperationException("The proxy type must be an interface, not a class."); - // create instance - return (TInterface)builder.CreateInstance(instance); + // get proxy type + Type targetType = instance.GetType(); + string proxyTypeName = $"StardewModdingAPI.Proxies.From<{sourceModID}_{typeof(TInterface).FullName}>_To<{targetModID}_{targetType.FullName}>"; + if (!this.Builders.TryGetValue(proxyTypeName, out InterfaceProxyBuilder builder)) + { + builder = new InterfaceProxyBuilder(proxyTypeName, this.ModuleBuilder, typeof(TInterface), targetType); + this.Builders[proxyTypeName] = builder; + } + + // create instance + return (TInterface)builder.CreateInstance(instance); + } } } } diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index e830f799..e6e51ac6 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Reflection; using System.Threading; using StardewModdingAPI.Framework; +using StardewModdingAPI.Toolkit.Framework; +using StardewModdingAPI.Toolkit.Serialization.Models; namespace StardewModdingAPI { @@ -31,6 +33,7 @@ namespace StardewModdingAPI AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve; Program.AssertGamePresent(); Program.AssertGameVersion(); + Program.AssertSmapiVersions(); Program.Start(args); } catch (BadImageFormatException ex) when (ex.FileName == "StardewValley" || ex.FileName == "Stardew Valley") // don't use EarlyConstants.GameAssemblyName, since we want to check both possible names @@ -107,8 +110,32 @@ namespace StardewModdingAPI } // max version - else if (Constants.MaximumGameVersion != null && Constants.GameVersion.IsNewerThan(Constants.MaximumGameVersion)) + if (Constants.MaximumGameVersion != null && Constants.GameVersion.IsNewerThan(Constants.MaximumGameVersion)) Program.PrintErrorAndExit($"Oops! You're running Stardew Valley {Constants.GameVersion}, but this version of SMAPI is only compatible up to Stardew Valley {Constants.MaximumGameVersion}. Please check for a newer version of SMAPI: https://smapi.io."); + + // bitness + bool is64BitGame = LowLevelEnvironmentUtility.Is64BitAssembly(Path.Combine(EarlyConstants.ExecutionPath, $"{EarlyConstants.GameAssemblyName}.exe")); +#if SMAPI_FOR_WINDOWS_64BIT_HACK + if (!is64bit) + Program.PrintErrorAndExit("Oops! This is the 64-bit version of SMAPI, but you have the 32-bit version of Stardew Valley. You can reinstall SMAPI using its installer to automatically install the correct version of SMAPI."); +#elif SMAPI_FOR_WINDOWS + if (is64BitGame) + Program.PrintErrorAndExit("Oops! This is the 32-bit version of SMAPI, but you have the 64-bit version of Stardew Valley. You can reinstall SMAPI using its installer to automatically install the correct version of SMAPI."); +#endif + } + + /// <summary>Assert that the versions of all SMAPI components are correct.</summary> + /// <remarks>Players sometimes have mismatched versions (particularly when installed through Vortex), which can cause some very confusing bugs without this check.</remarks> + private static void AssertSmapiVersions() + { + // SMAPI toolkit + foreach (var type in new[] { typeof(IManifest), typeof(Manifest) }) + { + Assembly assembly = type.Assembly; + var assemblyVersion = new SemanticVersion(assembly.GetName().Version); + if (!assemblyVersion.Equals(Constants.ApiVersion)) + Program.PrintErrorAndExit($"Oops! The 'smapi-internal/{assembly.GetName().Name}.dll' file is version {assemblyVersion} instead of the required {Constants.ApiVersion}. SMAPI doesn't seem to be installed correctly."); + } } /// <summary>Initialize SMAPI and launch the game.</summary> |