public TextArea2DComponentManipulator()
        {
            var textDataField = UnityTypes.AdvPage.ClrType.GetField("textData", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            set_textData = CustomFastReflectionHelper.CreateFastFieldSetter <object, object>(textDataField);

            var statusField = UnityTypes.AdvPage.ClrType.GetField("status", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            set_status = CustomFastReflectionHelper.CreateFastFieldSetter <object, object>(statusField);

            var isInputSendMessageField = UnityTypes.AdvPage.ClrType.GetField("isInputSendMessage", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            set_isInputSendMessage = CustomFastReflectionHelper.CreateFastFieldSetter <object, bool>(isInputSendMessageField);

            var nameTextField = UnityTypes.AdvPage.ClrType.GetField("nameText", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            set_nameText = CustomFastReflectionHelper.CreateFastFieldSetter <object, object>(nameTextField);

            _text     = UnityTypes.TextArea2D.ClrType.CachedProperty("text");
            _TextData = UnityTypes.TextArea2D.ClrType.CachedProperty("TextData");
        }
        public BepInExLogger(string source)
            : base(source)
        {
            var staticFlags   = BindingFlags.Static | BindingFlags.Public;
            var instanceFlags = BindingFlags.Instance | BindingFlags.Public;

            var logLevelType = Type.GetType("BepInEx.Logging.LogLevel, BepInEx", false);

            if (logLevelType == null)
            {
                throw new Exception("BepInEx is not loaded!");
            }

            var manualLogSourceType = Type.GetType("BepInEx.Logging.ManualLogSource, BepInEx", false);

            if (manualLogSourceType != null)
            {
                var loggerType            = Type.GetType("BepInEx.Logging.Logger, BepInEx", false);
                var createLogSourceMethod = loggerType.GetMethod("CreateLogSource", staticFlags, null, new[] { typeof(string) }, null);
                _logObject = createLogSourceMethod.Invoke(null, new object[] { Source });
                var logMethod = _logObject.GetType().GetMethod("Log", instanceFlags, null, new[] { logLevelType, typeof(object) }, null);
                _logMethod = CustomFastReflectionHelper.CreateFastDelegate(logMethod);
            }
            else
            {
                var loggerType = Type.GetType("BepInEx.Logger, BepInEx", false);
                _logObject = loggerType.GetProperty("CurrentLogger", staticFlags).GetValue(null, null);
                var logMethod = _logObject.GetType().GetMethod("Log", instanceFlags, null, new[] { logLevelType, typeof(object) }, null);
                _logMethod = CustomFastReflectionHelper.CreateFastDelegate(logMethod);
            }

            if (_logMethod == null)
            {
                throw new Exception("BepInEx is not loaded!");
            }
        }
        public ModLoaderSpecificLogger(string source)
            : base(source)
        {
            if (_logMethod != null)
            {
                return;
            }

            var staticFlags   = BindingFlags.Static | BindingFlags.Public;
            var instanceFlags = BindingFlags.Instance | BindingFlags.Public;

            var logLevelType = Type.GetType("BepInEx.Logging.LogLevel, BepInEx", false) ?? Type.GetType("BepInEx.Logging.LogLevel, BepInEx.Core", false);

            if (logLevelType != null)
            {
                var manualLogSourceType = Type.GetType("BepInEx.Logging.ManualLogSource, BepInEx", false) ?? Type.GetType("BepInEx.Logging.ManualLogSource, BepInEx.Core", false);
                if (manualLogSourceType != null)
                {
                    var loggerType            = Type.GetType("BepInEx.Logging.Logger, BepInEx", false) ?? Type.GetType("BepInEx.Logging.Logger, BepInEx.Core", false);
                    var createLogSourceMethod = loggerType.GetMethod("CreateLogSource", staticFlags, null, new[] { typeof(string) }, null);
                    var logInstance           = createLogSourceMethod.Invoke(null, new object[] { Source });
                    var logMethod             = logInstance.GetType().GetMethod("Log", instanceFlags, null, new[] { logLevelType, typeof(object) }, null);
                    var log = CustomFastReflectionHelper.CreateFastDelegate(logMethod);

                    _logMethod = (level, msg) =>
                    {
                        var bepinexLevel = Convert(level);
                        log(logInstance, new object[] { bepinexLevel, msg });
                    };
                }
                else
                {
                    var loggerType  = Type.GetType("BepInEx.Logger, BepInEx", false);
                    var logInstance = loggerType.GetProperty("CurrentLogger", staticFlags).GetValue(null, null);
                    var logMethod   = logInstance.GetType().GetMethod("Log", instanceFlags, null, new[] { logLevelType, typeof(object) }, null);
                    var log         = CustomFastReflectionHelper.CreateFastDelegate(logMethod);

                    _logMethod = (level, msg) =>
                    {
                        var bepinexLevel = Convert(level);
                        log(logInstance, new object[] { bepinexLevel, msg });
                    };
                }
            }
            else
            {
                var melonModLogger = Type.GetType("MelonLoader.MelonLogger, MelonLoader.ModHandler", false);
                if (melonModLogger != null)
                {
                    var logDebugMethod   = melonModLogger.GetMethod("Log", staticFlags, null, new Type[] { typeof(ConsoleColor), typeof(string) }, null);
                    var logInfoMethod    = melonModLogger.GetMethod("Log", staticFlags, null, new Type[] { typeof(string) }, null);
                    var logWarningMethod = melonModLogger.GetMethod("LogWarning", staticFlags, null, new Type[] { typeof(string) }, null);
                    var logErrorMethod   = melonModLogger.GetMethod("LogError", staticFlags, null, new Type[] { typeof(string) }, null);

                    var logDebug   = CustomFastReflectionHelper.CreateFastDelegate(logDebugMethod);
                    var logInfo    = CustomFastReflectionHelper.CreateFastDelegate(logInfoMethod);
                    var logWarning = CustomFastReflectionHelper.CreateFastDelegate(logWarningMethod);
                    var logError   = CustomFastReflectionHelper.CreateFastDelegate(logErrorMethod);

                    _logMethod = (level, msg) =>
                    {
                        switch (level)
                        {
                        case LogLevel.Debug:
                            logDebug(null, ConsoleColor.Gray, msg);
                            break;

                        case LogLevel.Info:
                            logInfo(null, msg);
                            break;

                        case LogLevel.Warn:
                            logWarning(null, msg);
                            break;

                        case LogLevel.Error:
                            logError(null, msg);
                            break;

                        default:
                            throw new ArgumentException("level");
                        }
                    };
                }
            }

            if (_logMethod == null)
            {
                throw new Exception("Did not recognize any mod loader!");
            }
        }