Parcourir la source

Support alternative CStreamWriter ctor args

ghorsington il y a 4 ans
Parent
commit
a53d4d5c21
1 fichiers modifiés avec 42 ajouts et 5 suppressions
  1. 42 5
      BepInEx/Console/Unix/ConsoleWriter.cs

+ 42 - 5
BepInEx/Console/Unix/ConsoleWriter.cs

@@ -1,4 +1,6 @@
-using System.IO;
+using System;
+using System.IO;
+using System.Linq;
 using System.Reflection;
 using System.Text;
 using HarmonyLib;
@@ -7,13 +9,48 @@ namespace BepInEx.Unix
 {
 	internal static class ConsoleWriter
 	{
-		private static ConstructorInfo cStreamWriterConstructor = AccessTools.Constructor(AccessTools.TypeByName("System.IO.CStreamWriter"), new []{ typeof(Stream), typeof(Encoding), typeof(bool) });
+		private static Func<Stream, Encoding, bool, StreamWriter> cStreamWriterConstructor = null;//AccessTools.Constructor(AccessTools.TypeByName("System.IO.CStreamWriter"), new []{ typeof(Stream), typeof(Encoding), typeof(bool) });
+		
+		private static Func<Stream, Encoding, bool, StreamWriter> CStreamWriterConstructor
+		{
+			get
+			{
+				if (cStreamWriterConstructor != null)
+					return cStreamWriterConstructor;
+
+				var cStreamWriter = AccessTools.TypeByName("System.IO.CStreamWriter");
+				Func<Stream, Encoding, bool, StreamWriter> GetCtor(int[] perm)
+				{
+					var parameters = new[] { typeof(Stream), typeof(Encoding), typeof(bool) };
+					var ctor = AccessTools.Constructor(cStreamWriter, perm.Select(i => parameters[i]).ToArray());
+					if (ctor != null)
+					{
+						return (stream, encoding, l) =>
+						{
+							var vals = new object[] { stream, encoding, l };
+							return (StreamWriter)ctor.Invoke(perm.Select(i => vals[i]).ToArray());
+						};
+					}
+					return null;
+				}
+
+				var ctorParams = new []
+				{
+					new[] { 0, 1, 2 }, // Unity 5.x and up
+					new[] { 0, 1 }     // Unity 4.7 and older
+				};
+				
+				cStreamWriterConstructor = ctorParams.Select(GetCtor).FirstOrDefault(f => f != null);
+				if (cStreamWriterConstructor == null)
+					throw new AmbiguousMatchException("Failed to find suitable constructor for CStreamWriter");
+				return cStreamWriterConstructor;
+			}
+		}
+
 		public static TextWriter CreateConsoleStreamWriter(Stream stream, Encoding encoding, bool leaveOpen)
 		{
-			var writer = (StreamWriter)cStreamWriterConstructor.Invoke(new object[] { stream, encoding, leaveOpen, });
-			
+			var writer = CStreamWriterConstructor(stream, encoding, leaveOpen);
 			writer.AutoFlush = true;
-
 			return writer;
 		}
 	}