diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-05-26 00:57:13 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-06-10 00:04:23 -0400 |
commit | db578c389e35ee026ed4ea12dfdcef99f8bc3b28 (patch) | |
tree | b2192a475beb3383356689ef0953c37d5c5da4a8 /src/SMAPI/Framework | |
parent | 769475166ab3b92cd3763bb86e364a8b2c7d914f (diff) | |
download | SMAPI-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.cs | 6 | ||||
-rw-r--r-- | src/SMAPI/Framework/Reflection/OriginalInterfaceProxyBuilder.cs | 118 | ||||
-rw-r--r-- | src/SMAPI/Framework/Reflection/OriginalInterfaceProxyFactory.cs | 57 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 4 |
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) |