using System; using System.IO; using System.Linq; using System.Reflection; using System.Text; using HarmonyLib; namespace BepInEx.Unix { internal static class ConsoleWriter { private static Func cStreamWriterConstructor; private static Func CStreamWriterConstructor { get { if (cStreamWriterConstructor != null) return cStreamWriterConstructor; var cStreamWriter = AccessTools.TypeByName("System.IO.CStreamWriter"); Func 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 = CStreamWriterConstructor(stream, encoding, leaveOpen); writer.AutoFlush = true; return writer; } } }