UnityLogSource.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using BepInEx.Logging;
  2. using System;
  3. using System.Reflection;
  4. using UnityEngine;
  5. namespace BepInEx.Unity.Logging
  6. {
  7. /// <summary>
  8. /// Logs entries using Unity specific outputs.
  9. /// </summary>
  10. public class UnityLogSource : ILogSource
  11. {
  12. public string SourceName { get; } = "Unity Log";
  13. public event EventHandler<LogEventArgs> LogEvent;
  14. public UnityLogSource()
  15. {
  16. InternalUnityLogMessage += unityLogMessageHandler;
  17. }
  18. private void unityLogMessageHandler(object sender, LogEventArgs eventArgs)
  19. {
  20. var newEventArgs = new LogEventArgs(eventArgs.Data, eventArgs.Level, this);
  21. LogEvent?.Invoke(this, newEventArgs);
  22. }
  23. private bool disposed = false;
  24. public void Dispose()
  25. {
  26. if (!disposed)
  27. {
  28. InternalUnityLogMessage -= unityLogMessageHandler;
  29. disposed = true;
  30. }
  31. }
  32. #region Static Unity handler
  33. private static event EventHandler<LogEventArgs> InternalUnityLogMessage;
  34. static UnityLogSource()
  35. {
  36. var callback = new Application.LogCallback(OnUnityLogMessageReceived);
  37. EventInfo logEvent = typeof(Application).GetEvent("logMessageReceived", BindingFlags.Public | BindingFlags.Static);
  38. if (logEvent != null)
  39. {
  40. logEvent.AddEventHandler(null, callback);
  41. //UnsubscribeAction = () => logEvent.RemoveEventHandler(null, callback);
  42. }
  43. else
  44. {
  45. MethodInfo registerLogCallback = typeof(Application).GetMethod("RegisterLogCallback", BindingFlags.Public | BindingFlags.Static);
  46. registerLogCallback.Invoke(null, new object[] { callback });
  47. //UnsubscribeAction = () => registerLogCallback.Invoke(null, new object[] { null });
  48. }
  49. }
  50. private static void OnUnityLogMessageReceived(string message, string stackTrace, LogType type)
  51. {
  52. LogLevel logLevel;
  53. switch (type)
  54. {
  55. case LogType.Error:
  56. case LogType.Assert:
  57. case LogType.Exception:
  58. logLevel = LogLevel.Error;
  59. break;
  60. case LogType.Warning:
  61. logLevel = LogLevel.Warning;
  62. break;
  63. case LogType.Log:
  64. default:
  65. logLevel = LogLevel.Info;
  66. break;
  67. }
  68. if (type == LogType.Exception)
  69. message += $"\nStack trace:\n{stackTrace}";
  70. InternalUnityLogMessage?.Invoke(null, new LogEventArgs(message, logLevel, null));
  71. }
  72. #endregion
  73. }
  74. }