summaryrefslogtreecommitdiff
path: root/src/SMAPI
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI')
-rw-r--r--src/SMAPI/Framework/ContentManagers/ModContentManager.cs4
-rw-r--r--src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs33
-rw-r--r--src/SMAPI/Program.cs29
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>