ConsoleWriter.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using HarmonyLib;
  7. namespace BepInEx.Unix
  8. {
  9. internal static class ConsoleWriter
  10. {
  11. private static Func<Stream, Encoding, bool, StreamWriter> cStreamWriterConstructor;
  12. private static Func<Stream, Encoding, bool, StreamWriter> CStreamWriterConstructor
  13. {
  14. get
  15. {
  16. if (cStreamWriterConstructor != null)
  17. return cStreamWriterConstructor;
  18. var cStreamWriter = AccessTools.TypeByName("System.IO.CStreamWriter");
  19. Func<Stream, Encoding, bool, StreamWriter> GetCtor(int[] perm)
  20. {
  21. var parameters = new[] { typeof(Stream), typeof(Encoding), typeof(bool) };
  22. var ctor = AccessTools.Constructor(cStreamWriter, perm.Select(i => parameters[i]).ToArray());
  23. if (ctor != null)
  24. {
  25. return (stream, encoding, l) =>
  26. {
  27. var vals = new object[] { stream, encoding, l };
  28. return (StreamWriter)ctor.Invoke(perm.Select(i => vals[i]).ToArray());
  29. };
  30. }
  31. return null;
  32. }
  33. var ctorParams = new []
  34. {
  35. new[] { 0, 1, 2 }, // Unity 5.x and up
  36. new[] { 0, 1 } // Unity 4.7 and older
  37. };
  38. cStreamWriterConstructor = ctorParams.Select(GetCtor).FirstOrDefault(f => f != null);
  39. if (cStreamWriterConstructor == null)
  40. throw new AmbiguousMatchException("Failed to find suitable constructor for CStreamWriter");
  41. return cStreamWriterConstructor;
  42. }
  43. }
  44. public static TextWriter CreateConsoleStreamWriter(Stream stream, Encoding encoding, bool leaveOpen)
  45. {
  46. var writer = CStreamWriterConstructor(stream, encoding, leaveOpen);
  47. writer.AutoFlush = true;
  48. return writer;
  49. }
  50. }
  51. }