UnityLogSource.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. /// <inheritdoc />
  13. public string SourceName { get; } = "Unity Log";
  14. /// <inheritdoc />
  15. public event EventHandler<LogEventArgs> LogEvent;
  16. /// <summary>
  17. /// Creates a new Unity log source.
  18. /// </summary>
  19. public UnityLogSource()
  20. {
  21. InternalUnityLogMessage += UnityLogMessageHandler;
  22. }
  23. private void UnityLogMessageHandler(object sender, LogEventArgs eventArgs)
  24. {
  25. var newEventArgs = new LogEventArgs(eventArgs.Data, eventArgs.Level, this);
  26. LogEvent?.Invoke(this, newEventArgs);
  27. }
  28. private bool disposed = false;
  29. /// <inheritdoc />
  30. public void Dispose()
  31. {
  32. if (!disposed)
  33. {
  34. InternalUnityLogMessage -= UnityLogMessageHandler;
  35. disposed = true;
  36. }
  37. }
  38. #region Static Unity handler
  39. private static event EventHandler<LogEventArgs> InternalUnityLogMessage;
  40. static UnityLogSource()
  41. {
  42. var callback = new Application.LogCallback(OnUnityLogMessageReceived);
  43. EventInfo logEvent = typeof(Application).GetEvent("logMessageReceived", BindingFlags.Public | BindingFlags.Static);
  44. if (logEvent != null)
  45. {
  46. logEvent.AddEventHandler(null, callback);
  47. //UnsubscribeAction = () => logEvent.RemoveEventHandler(null, callback);
  48. }
  49. else
  50. {
  51. MethodInfo registerLogCallback = typeof(Application).GetMethod("RegisterLogCallback", BindingFlags.Public | BindingFlags.Static);
  52. registerLogCallback.Invoke(null, new object[] { callback });
  53. //UnsubscribeAction = () => registerLogCallback.Invoke(null, new object[] { null });
  54. }
  55. }
  56. private static void OnUnityLogMessageReceived(string message, string stackTrace, LogType type)
  57. {
  58. LogLevel logLevel;
  59. switch (type)
  60. {
  61. case LogType.Error:
  62. case LogType.Assert:
  63. case LogType.Exception:
  64. logLevel = LogLevel.Error;
  65. break;
  66. case LogType.Warning:
  67. logLevel = LogLevel.Warning;
  68. break;
  69. case LogType.Log:
  70. default:
  71. logLevel = LogLevel.Info;
  72. break;
  73. }
  74. if (type == LogType.Exception)
  75. message += $"\nStack trace:\n{stackTrace}";
  76. InternalUnityLogMessage?.Invoke(null, new LogEventArgs(message, logLevel, null));
  77. }
  78. #endregion
  79. }
  80. }