summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-05-26 00:57:13 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-06-10 00:04:23 -0400
commitdb578c389e35ee026ed4ea12dfdcef99f8bc3b28 (patch)
treeb2192a475beb3383356689ef0953c37d5c5da4a8 /src/SMAPI/Framework
parent769475166ab3b92cd3763bb86e364a8b2c7d914f (diff)
downloadSMAPI-db578c389e35ee026ed4ea12dfdcef99f8bc3b28.tar.gz
SMAPI-db578c389e35ee026ed4ea12dfdcef99f8bc3b28.tar.bz2
SMAPI-db578c389e35ee026ed4ea12dfdcef99f8bc3b28.zip
drop support for pre-Pintail proxying
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r--src/SMAPI/Framework/Models/SConfig.cs6
-rw-r--r--src/SMAPI/Framework/Reflection/OriginalInterfaceProxyBuilder.cs118
-rw-r--r--src/SMAPI/Framework/Reflection/OriginalInterfaceProxyFactory.cs57
-rw-r--r--src/SMAPI/Framework/SCore.cs4
4 files changed, 1 insertions, 184 deletions
diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs
index 6edaa818..baef6144 100644
--- a/src/SMAPI/Framework/Models/SConfig.cs
+++ b/src/SMAPI/Framework/Models/SConfig.cs
@@ -22,7 +22,6 @@ namespace StardewModdingAPI.Framework.Models
[nameof(WebApiBaseUrl)] = "https://smapi.io/api/",
[nameof(LogNetworkTraffic)] = false,
[nameof(RewriteMods)] = true,
- [nameof(UsePintail)] = true,
[nameof(UseRawImageLoading)] = true,
[nameof(UseCaseInsensitivePaths)] = Constants.Platform is Platform.Android or Platform.Linux
};
@@ -64,9 +63,6 @@ namespace StardewModdingAPI.Framework.Models
/// <summary>Whether SMAPI should rewrite mods for compatibility.</summary>
public bool RewriteMods { get; }
- /// <summary>Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</summary>
- public bool UsePintail { get; }
-
/// <summary>Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</summary>
public bool UseRawImageLoading { get; }
@@ -95,7 +91,6 @@ namespace StardewModdingAPI.Framework.Models
/// <param name="webApiBaseUrl">The base URL for SMAPI's web API, used to perform update checks.</param>
/// <param name="verboseLogging">The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.</param>
/// <param name="rewriteMods">Whether SMAPI should rewrite mods for compatibility.</param>
- /// <param name="usePintail">Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</param>
/// <param name="useRawImageLoading">Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</param>
/// <param name="useCaseInsensitivePaths">>Whether to make SMAPI file APIs case-insensitive, even on Linux.</param>
/// <param name="logNetworkTraffic">Whether SMAPI should log network traffic.</param>
@@ -111,7 +106,6 @@ namespace StardewModdingAPI.Framework.Models
this.WebApiBaseUrl = webApiBaseUrl;
this.VerboseLogging = new HashSet<string>(verboseLogging ?? Array.Empty<string>(), StringComparer.OrdinalIgnoreCase);
this.RewriteMods = rewriteMods ?? (bool)SConfig.DefaultValues[nameof(this.RewriteMods)];
- this.UsePintail = usePintail ?? (bool)SConfig.DefaultValues[nameof(this.UsePintail)];
this.UseRawImageLoading = useRawImageLoading ?? (bool)SConfig.DefaultValues[nameof(this.UseRawImageLoading)];
this.UseCaseInsensitivePaths = useCaseInsensitivePaths ?? (bool)SConfig.DefaultValues[nameof(this.UseCaseInsensitivePaths)];
this.LogNetworkTraffic = logNetworkTraffic ?? (bool)SConfig.DefaultValues[nameof(this.LogNetworkTraffic)];
diff --git a/src/SMAPI/Framework/Reflection/OriginalInterfaceProxyBuilder.cs b/src/SMAPI/Framework/Reflection/OriginalInterfaceProxyBuilder.cs
deleted file mode 100644
index 9576f768..00000000
--- a/src/SMAPI/Framework/Reflection/OriginalInterfaceProxyBuilder.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-using System;
-using System.Linq;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace StardewModdingAPI.Framework.Reflection
-{
- /// <summary>Generates a proxy class to access a mod API through an arbitrary interface.</summary>
- internal class OriginalInterfaceProxyBuilder
- {
- /*********
- ** Fields
- *********/
- /// <summary>The target class type.</summary>
- private readonly Type TargetType;
-
- /// <summary>The generated proxy type.</summary>
- private readonly Type ProxyType;
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Construct an instance.</summary>
- /// <param name="name">The type name to generate.</param>
- /// <param name="moduleBuilder">The CLR module in which to create proxy classes.</param>
- /// <param name="interfaceType">The interface type to implement.</param>
- /// <param name="targetType">The target type.</param>
- public OriginalInterfaceProxyBuilder(string name, ModuleBuilder moduleBuilder, Type interfaceType, Type targetType)
- {
- // validate
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (targetType == null)
- throw new ArgumentNullException(nameof(targetType));
-
- // define proxy type
- TypeBuilder proxyBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Class);
- proxyBuilder.AddInterfaceImplementation(interfaceType);
-
- // create field to store target instance
- FieldBuilder targetField = proxyBuilder.DefineField("__Target", targetType, FieldAttributes.Private);
-
- // create constructor which accepts target instance and sets field
- {
- ConstructorBuilder constructor = proxyBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard | CallingConventions.HasThis, new[] { targetType });
- ILGenerator il = constructor.GetILGenerator();
-
- il.Emit(OpCodes.Ldarg_0); // this
- // ReSharper disable once AssignNullToNotNullAttribute -- never null
- il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)!); // call base constructor
- il.Emit(OpCodes.Ldarg_0); // this
- il.Emit(OpCodes.Ldarg_1); // load argument
- il.Emit(OpCodes.Stfld, targetField); // set field to loaded argument
- il.Emit(OpCodes.Ret);
- }
-
- // proxy methods
- foreach (MethodInfo proxyMethod in interfaceType.GetMethods())
- {
- var targetMethod = targetType.GetMethod(proxyMethod.Name, proxyMethod.GetParameters().Select(a => a.ParameterType).ToArray());
- if (targetMethod == null)
- throw new InvalidOperationException($"The {interfaceType.FullName} interface defines method {proxyMethod.Name} which doesn't exist in the API.");
-
- this.ProxyMethod(proxyBuilder, targetMethod, targetField);
- }
-
- // save info
- this.TargetType = targetType;
- this.ProxyType = proxyBuilder.CreateType()!;
- }
-
- /// <summary>Create an instance of the proxy for a target instance.</summary>
- /// <param name="targetInstance">The target instance.</param>
- public object CreateInstance(object targetInstance)
- {
- ConstructorInfo? constructor = this.ProxyType.GetConstructor(new[] { this.TargetType });
- if (constructor == null)
- throw new InvalidOperationException($"Couldn't find the constructor for generated proxy type '{this.ProxyType.Name}'."); // should never happen
- return constructor.Invoke(new[] { targetInstance });
- }
-
-
- /*********
- ** Private methods
- *********/
- /// <summary>Define a method which proxies access to a method on the target.</summary>
- /// <param name="proxyBuilder">The proxy type being generated.</param>
- /// <param name="target">The target method.</param>
- /// <param name="instanceField">The proxy field containing the API instance.</param>
- private void ProxyMethod(TypeBuilder proxyBuilder, MethodInfo target, FieldBuilder instanceField)
- {
- Type[] argTypes = target.GetParameters().Select(a => a.ParameterType).ToArray();
-
- // create method
- MethodBuilder methodBuilder = proxyBuilder.DefineMethod(target.Name, MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual);
- methodBuilder.SetParameters(argTypes);
- methodBuilder.SetReturnType(target.ReturnType);
-
- // create method body
- {
- ILGenerator il = methodBuilder.GetILGenerator();
-
- // load target instance
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, instanceField);
-
- // invoke target method on instance
- for (int i = 0; i < argTypes.Length; i++)
- il.Emit(OpCodes.Ldarg, i + 1);
- il.Emit(OpCodes.Call, target);
-
- // return result
- il.Emit(OpCodes.Ret);
- }
- }
- }
-}
diff --git a/src/SMAPI/Framework/Reflection/OriginalInterfaceProxyFactory.cs b/src/SMAPI/Framework/Reflection/OriginalInterfaceProxyFactory.cs
deleted file mode 100644
index d6966978..00000000
--- a/src/SMAPI/Framework/Reflection/OriginalInterfaceProxyFactory.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace StardewModdingAPI.Framework.Reflection
-{
- /// <inheritdoc />
- internal class OriginalInterfaceProxyFactory : IInterfaceProxyFactory
- {
- /*********
- ** Fields
- *********/
- /// <summary>The CLR module in which to create proxy classes.</summary>
- private readonly ModuleBuilder ModuleBuilder;
-
- /// <summary>The generated proxy types.</summary>
- private readonly IDictionary<string, OriginalInterfaceProxyBuilder> Builders = new Dictionary<string, OriginalInterfaceProxyBuilder>();
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Construct an instance.</summary>
- public OriginalInterfaceProxyFactory()
- {
- AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run);
- this.ModuleBuilder = assemblyBuilder.DefineDynamicModule("StardewModdingAPI.Proxies");
- }
-
- /// <inheritdoc />
- public TInterface CreateProxy<TInterface>(object instance, string sourceModID, string targetModID)
- where TInterface : class
- {
- lock (this.Builders)
- {
- // 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 OriginalInterfaceProxyBuilder? builder))
- {
- builder = new OriginalInterfaceProxyBuilder(proxyTypeName, this.ModuleBuilder, typeof(TInterface), targetType);
- this.Builders[proxyTypeName] = builder;
- }
-
- // create instance
- return (TInterface)builder.CreateInstance(instance);
- }
- }
- }
-}
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index f018acad..fa3f8778 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -1610,9 +1610,7 @@ namespace StardewModdingAPI.Framework
{
// init
HashSet<string> suppressUpdateChecks = this.Settings.SuppressUpdateChecks;
- IInterfaceProxyFactory proxyFactory = this.Settings.UsePintail
- ? new InterfaceProxyFactory()
- : new OriginalInterfaceProxyFactory();
+ IInterfaceProxyFactory proxyFactory = new InterfaceProxyFactory();
// load mods
foreach (IModMetadata mod in mods)