Decompiled source of SafetyStatus v1.2.1

SafetyStatus.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using SafetyStatus.Extensions;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SafetyStatus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SafetyStatus")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.2.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.0")]
[module: UnverifiableCode]
namespace SafetyStatus
{
	[BepInPlugin("Searica.Valheim.SafetyStatus", "SafetyStatus", "1.2.1")]
	[BepInDependency("com.jotunn.jotunn", "2.21.3")]
	internal sealed class SafetyStatus : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(EffectArea))]
		internal static class EffectAreaPatch
		{
			[HarmonyPostfix]
			[HarmonyPatch("Awake")]
			private static void AwakePostfix(EffectArea __instance)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				if ((int)__instance.m_type == 4)
				{
					__instance.m_statusEffect = "SafeStatusEffect";
					__instance.m_statusEffectHash = SafeEffectHash;
				}
			}

			[HarmonyPrefix]
			[HarmonyPatch("CustomFixedUpdate")]
			private static void CustomFixedUpdatePrefex(EffectArea __instance, float deltaTime)
			{
				if (Object.op_Implicit((Object)(object)__instance))
				{
					__instance.m_collidedWithCharacter = __instance.m_collidedWithCharacter.Where((Character x) => IsValidCollidedWithCharacter(x)).ToList();
				}
			}

			private static bool IsValidCollidedWithCharacter(Character item)
			{
				if (!Object.op_Implicit((Object)(object)item) || item.GetSEMan() == null || !Object.op_Implicit((Object)(object)item.GetSEMan().m_nview) || !item.GetSEMan().m_nview.IsValid())
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Piece))]
		internal static class PiecePatch
		{
			[HarmonyPostfix]
			[HarmonyPriority(200)]
			[HarmonyPatch("Awake")]
			private static void AwakePostfix(Piece __instance)
			{
				if (Object.op_Implicit((Object)(object)__instance))
				{
					AddSafeEffect(((Component)__instance).gameObject);
				}
			}

			[HarmonyPostfix]
			[HarmonyPriority(200)]
			[HarmonyPatch("SetCreator")]
			private static void SetCreatorPostfix(Piece __instance)
			{
				if (Object.op_Implicit((Object)(object)__instance))
				{
					AddSafeEffect(((Component)__instance).gameObject);
				}
			}

			private static void AddSafeEffect(GameObject gameObject)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Invalid comparison between Unknown and I4
				if (!Object.op_Implicit((Object)(object)gameObject))
				{
					return;
				}
				EffectArea[] componentsInChildren = gameObject.GetComponentsInChildren<EffectArea>();
				foreach (EffectArea val in componentsInChildren)
				{
					if ((int)val.m_type == 4)
					{
						val.m_statusEffect = "SafeStatusEffect";
						val.m_statusEffectHash = SafeEffectHash;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Player))]
		internal static class PlayerPatch
		{
			[HarmonyPostfix]
			[HarmonyPatch("UpdateEnvStatusEffects")]
			private static void UpdateEnvStatusEffectsPostFix(Player __instance)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				EffectArea val = EffectArea.IsPointInsideArea(((Component)__instance).transform.position, (Type)4, 1f);
				if (((Character)__instance).m_seman.HaveStatusEffect(SafeEffectHash) && !Object.op_Implicit((Object)(object)val))
				{
					((Character)__instance).m_seman.RemoveStatusEffect(SafeEffectHash, false);
				}
			}
		}

		internal const string Author = "Searica";

		public const string PluginName = "SafetyStatus";

		public const string PluginGUID = "Searica.Valheim.SafetyStatus";

		public const string PluginVersion = "1.2.1";

		internal static CustomStatusEffect SafeEffect;

		internal const string SafeEffectName = "SafeStatusEffect";

		internal static int SafeEffectHash;

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.SafetyStatus");
			Game.isModded = true;
			PrefabManager.OnVanillaPrefabsAvailable += AddCustomStatusEffect;
		}

		private void AddCustomStatusEffect()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			try
			{
				StatusEffect obj = ScriptableObject.CreateInstance<StatusEffect>();
				((Object)obj).name = "SafeStatusEffect";
				obj.m_name = "Safe";
				obj.m_icon = Cache.GetPrefab<CraftingStation>("piece_workbench").m_icon;
				obj.m_startMessageType = (MessageType)1;
				obj.m_startMessage = "You feel safer";
				obj.m_stopMessageType = (MessageType)1;
				obj.m_stopMessage = "You feel less safe";
				SafeEffect = new CustomStatusEffect(obj, false);
				SafeEffectHash = SafeEffect.StatusEffect.NameHash();
				ItemManager.Instance.AddStatusEffect(SafeEffect);
			}
			finally
			{
				PrefabManager.OnVanillaPrefabsAvailable -= AddCustomStatusEffect;
			}
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void LogDebug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void LogError(object data)
		{
			_logSource.LogError(data);
		}

		internal static void LogFatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void LogInfo(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void LogMessage(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void LogWarning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
}
namespace SafetyStatus.Extensions
{
	internal static class EventExtensions
	{
		public static void SafeInvoke(this Action events)
		{
			if (events == null)
			{
				return;
			}
			Delegate[] invocationList = events.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action action = (Action)invocationList[i];
				try
				{
					action();
				}
				catch (Exception ex)
				{
					Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}");
				}
			}
		}

		public static void SafeInvoke<TArg1>(this Action<TArg1> events, TArg1 arg1)
		{
			if (events == null)
			{
				return;
			}
			Delegate[] invocationList = events.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action<TArg1> action = (Action<TArg1>)invocationList[i];
				try
				{
					action(arg1);
				}
				catch (Exception ex)
				{
					Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}");
				}
			}
		}

		public static void SafeInvoke<TArg1, TArg2>(this Action<TArg1, TArg2> events, TArg1 arg1, TArg2 arg2)
		{
			if (events == null)
			{
				return;
			}
			Delegate[] invocationList = events.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action<TArg1, TArg2> action = (Action<TArg1, TArg2>)invocationList[i];
				try
				{
					action(arg1, arg2);
				}
				catch (Exception ex)
				{
					Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}");
				}
			}
		}

		public static void SafeInvoke<TEventArg>(this EventHandler<TEventArg> events, object sender, TEventArg arg1)
		{
			if (events == null)
			{
				return;
			}
			Delegate[] invocationList = events.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				EventHandler<TEventArg> eventHandler = (EventHandler<TEventArg>)invocationList[i];
				try
				{
					eventHandler(sender, arg1);
				}
				catch (Exception ex)
				{
					Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {eventHandler.Method.DeclaringType.Name}.{eventHandler.Method.Name}:\n{ex}");
				}
			}
		}
	}
	internal static class GameObjectExtensions
	{
		internal static GameObject DeepCopy(this GameObject obj)
		{
			bool activeSelf = obj.activeSelf;
			obj.SetActive(false);
			GameObject result = Object.Instantiate<GameObject>(obj);
			obj.SetActive(activeSelf);
			return result;
		}

		public static bool HasComponent<T>(this GameObject gameObject) where T : Component
		{
			return (Object)(object)gameObject.GetComponent<T>() != (Object)null;
		}

		public static bool HasComponent(this GameObject gameObject, string componentName)
		{
			return (Object)(object)gameObject.GetComponent(componentName) != (Object)null;
		}

		public static void DestroyComponentsInChildren<T>(this GameObject gameObject, bool includeInactive = false) where T : Component
		{
			T[] componentsInChildren = gameObject.GetComponentsInChildren<T>(includeInactive);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
		}

		public static bool HasAnyComponent(this GameObject gameObject, params Type[] components)
		{
			foreach (Type type in components)
			{
				if ((Object)(object)gameObject.GetComponent(type) != (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		public static bool HasAnyComponent(this GameObject gameObject, params string[] componentNames)
		{
			foreach (string text in componentNames)
			{
				if ((Object)(object)gameObject.GetComponent(text) != (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		public static bool HasAllComponents(this GameObject gameObject, params string[] componentNames)
		{
			foreach (string text in componentNames)
			{
				if ((Object)(object)gameObject.GetComponent(text) == (Object)null)
				{
					return false;
				}
			}
			return true;
		}

		public static bool HasAllComponents(this GameObject gameObject, params Type[] components)
		{
			foreach (Type type in components)
			{
				if ((Object)(object)gameObject.GetComponent(type) == (Object)null)
				{
					return false;
				}
			}
			return true;
		}

		public static bool HasAnyComponentInChildren(this GameObject gameObject, bool includeInactive = false, params Type[] components)
		{
			foreach (Type type in components)
			{
				if ((Object)(object)gameObject.GetComponentInChildren(type, includeInactive) != (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		public static bool HasComponentInChildren<T>(this GameObject gameObject, bool includeInactive = false) where T : Component
		{
			return (Object)(object)gameObject.GetComponentInChildren<T>(includeInactive) != (Object)null;
		}

		internal static T GetComponentInChildrenByName<T>(this GameObject gameObject, string name, bool includeInactive = false) where T : Component
		{
			T[] componentsInChildren = gameObject.GetComponentsInChildren<T>(includeInactive);
			foreach (T val in componentsInChildren)
			{
				if (((Object)(object)val).name == name)
				{
					return val;
				}
			}
			Log.LogWarning("No T with name " + name + " found for GameObject: " + ((Object)gameObject).name);
			return default(T);
		}

		internal static Mesh GetMesh(this GameObject gameObject, string meshName)
		{
			MeshFilter[] componentsInChildren = gameObject.GetComponentsInChildren<MeshFilter>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Mesh mesh = componentsInChildren[i].mesh;
				if (!((Object)(object)mesh == (Object)null) && ((Object)mesh).name.RemoveSuffix("Instance").Trim() == meshName)
				{
					return mesh;
				}
			}
			Log.LogWarning("Could not find Mesh: " + meshName + " for GameObject: " + ((Object)gameObject).name);
			return null;
		}
	}
	internal static class TypeExtensions
	{
		internal static List<T> GetAllPublicConstantValues<T>(this Type type)
		{
			return (from fi in type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)
				where fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(T)
				select fi into x
				select (T)x.GetRawConstantValue()).ToList();
		}

		internal static List<T> GetAllPublicStaticValues<T>(this Type type)
		{
			return (from fi in type.GetFields(BindingFlags.Static | BindingFlags.Public)
				where fi.FieldType == typeof(T)
				select fi into x
				select (T)x.GetValue(null)).ToList();
		}
	}
	internal static class GenericExtensions
	{
		private const BindingFlags AllBindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty;

		public static void CopyFields(this object target, object source)
		{
			if (target == null || source == null)
			{
				throw new Exception("Target or/and Source Objects are null");
			}
			Type type = source.GetType();
			FieldInfo[] fields = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (FieldInfo fieldInfo in fields)
			{
				FieldInfo field = type.GetField(fieldInfo.Name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
				if (!(field == null) && field.IsInitOnly && field.FieldType.IsAssignableFrom(fieldInfo.FieldType))
				{
					field.SetValue(source, fieldInfo.GetValue(target));
				}
			}
		}

		internal static T Ref<T>(this T o) where T : Object
		{
			if (!Object.op_Implicit((Object)(object)o))
			{
				return default(T);
			}
			return o;
		}
	}
	internal static class IEnumerableExtensions
	{
		internal static void Dispose(this IEnumerable<IDisposable> collection)
		{
			foreach (IDisposable item in collection)
			{
				if (item != null)
				{
					try
					{
						item.Dispose();
					}
					catch (Exception)
					{
						Log.LogWarning("Could not dispose of item");
					}
				}
			}
		}
	}
	internal static class ReflectionUtils
	{
		public const BindingFlags AllBindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty;

		internal static MethodInfo GetMethod(Type type, string name, Type[] types)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == name && HasMatchingParameterTypes(0, types, methodInfo.GetParameters()))
				{
					return methodInfo;
				}
			}
			return null;
		}

		internal static MethodInfo GetGenericMethod(Type type, string name, int genericParameterCount, Type[] types)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.IsGenericMethod && methodInfo.ContainsGenericParameters && methodInfo.Name == name && HasMatchingParameterTypes(genericParameterCount, types, methodInfo.GetParameters()))
				{
					return methodInfo;
				}
			}
			return null;
		}

		private static bool HasMatchingParameterTypes(int genericParameterCount, Type[] types, ParameterInfo[] parameters)
		{
			if (parameters.Length < genericParameterCount || parameters.Length != types.Length)
			{
				return false;
			}
			int num = 0;
			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i].ParameterType.IsGenericParameter)
				{
					num++;
				}
				else if (types[i] != parameters[i].ParameterType)
				{
					return false;
				}
			}
			if (num != genericParameterCount)
			{
				return false;
			}
			return true;
		}
	}
	internal static class StringExtensions
	{
		internal static bool ContainsAny(this string str, params string[] substrings)
		{
			foreach (string value in substrings)
			{
				if (str.Contains(value))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool EndsWithAny(this string str, params string[] suffixes)
		{
			foreach (string value in suffixes)
			{
				if (str.EndsWith(value))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool StartsWithAny(this string str, params string[] suffixes)
		{
			foreach (string value in suffixes)
			{
				if (str.StartsWith(value))
				{
					return true;
				}
			}
			return false;
		}

		internal static string RemoveSuffix(this string s, string suffix)
		{
			if (s.EndsWith(suffix))
			{
				return s.Substring(0, s.Length - suffix.Length);
			}
			return s;
		}

		internal static string RemovePrefix(this string s, string prefix)
		{
			if (s.StartsWith(prefix))
			{
				return s.Substring(prefix.Length, s.Length - prefix.Length);
			}
			return s;
		}

		internal static string CapitalizeFirstLetter(this string s)
		{
			if (s.Length == 0)
			{
				return s;
			}
			if (s.Length == 1)
			{
				return $"{char.ToUpper(s[0])}";
			}
			return char.ToUpper(s[0]) + s.Substring(1);
		}

		internal static string EmptyIfNull(this object value)
		{
			if (value == null)
			{
				return string.Empty;
			}
			return value.ToString();
		}
	}
	internal static class TransformExtensions
	{
		public static Transform FindDeepChild(this Transform transform, string childName, bool breadthFirst = true)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if (breadthFirst)
			{
				Queue<Transform> queue = new Queue<Transform>();
				queue.Enqueue(transform);
				while (queue.Count > 0)
				{
					Transform val = queue.Dequeue();
					if (((Object)val).name == childName)
					{
						return val;
					}
					foreach (Transform item2 in val)
					{
						Transform item = item2;
						queue.Enqueue(item);
					}
				}
				return null;
			}
			foreach (Transform item3 in transform)
			{
				Transform val2 = item3;
				if (((Object)val2).name == childName)
				{
					return val2;
				}
				Transform val3 = val2.FindDeepChild(childName);
				if ((Object)(object)val3 != (Object)null)
				{
					return val3;
				}
			}
			return null;
		}
	}
}
namespace SafetyStatus.Configs
{
	internal static class ConfigManager
	{
		internal enum LoggerLevel
		{
			Low,
			Medium,
			High
		}

		private static string ConfigFileName;

		private static string ConfigFileFullPath;

		private static ConfigFile configFile;

		private static BaseUnityPlugin ConfigurationManager;

		private const string ConfigManagerGUID = "com.bepis.bepinex.configurationmanager";

		private const string MainSection = "Global";

		private static readonly ConfigurationManagerAttributes AdminConfig = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};

		private static readonly ConfigurationManagerAttributes ClientConfig = new ConfigurationManagerAttributes
		{
			IsAdminOnly = false
		};

		private const char ZWS = '\u200b';

		internal static ConfigEntry<LoggerLevel> Verbosity { get; private set; }

		internal static LoggerLevel VerbosityLevel => Verbosity.Value;

		internal static bool IsVerbosityLow => Verbosity.Value >= LoggerLevel.Low;

		internal static bool IsVerbosityMedium => Verbosity.Value >= LoggerLevel.Medium;

		internal static bool IsVerbosityHigh => Verbosity.Value >= LoggerLevel.High;

		internal static event Action OnConfigWindowClosed;

		internal static event Action OnConfigFileReloaded;

		private static void InvokeOnConfigWindowClosed()
		{
			ConfigManager.OnConfigWindowClosed?.SafeInvoke();
		}

		private static void InvokeOnConfigFileReloaded()
		{
			ConfigManager.OnConfigFileReloaded?.SafeInvoke();
		}

		internal static ConfigEntry<T> BindConfig<T>(string section, string name, T value, string description, AcceptableValueBase acceptVals = null, bool synced = true)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			string extendedDescription = GetExtendedDescription(description, synced);
			return configFile.Bind<T>(section, name, value, new ConfigDescription(extendedDescription, acceptVals, new object[1] { synced ? AdminConfig : ClientConfig }));
		}

		internal static string SetStringPriority(string sectionName, int priority)
		{
			if (priority == 0)
			{
				return sectionName;
			}
			return new string('\u200b', priority) + sectionName;
		}

		internal static string GetExtendedDescription(string description, bool synchronizedSetting)
		{
			return description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]");
		}

		internal static void Init(string GUID, ConfigFile config)
		{
			configFile = config;
			configFile.SaveOnConfigSet = false;
			ConfigFileName = GUID + ".cfg";
			ConfigFileFullPath = Paths.ConfigPath + Path.DirectorySeparatorChar + ConfigFileName;
		}

		internal static void SetUpConfig()
		{
			Verbosity = BindConfig("Global", "Verbosity", LoggerLevel.Low, "Low will log basic information about the mod. Medium will log information that is useful for troubleshooting. High will log a lot of information, do not set it to this without good reason as it will slow down your game.", null, synced: false);
			Save();
		}

		private static bool DisableSaveOnConfigSet()
		{
			bool saveOnConfigSet = configFile.SaveOnConfigSet;
			configFile.SaveOnConfigSet = false;
			return saveOnConfigSet;
		}

		internal static void SaveOnConfigSet(bool value)
		{
			configFile.SaveOnConfigSet = value;
		}

		internal static void Save()
		{
			configFile.Save();
		}

		internal static void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReloadConfigFile;
			fileSystemWatcher.Created += ReloadConfigFile;
			fileSystemWatcher.Renamed += ReloadConfigFile;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private static void ReloadConfigFile(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				Log.LogInfo("Reloading config file");
				bool value = DisableSaveOnConfigSet();
				configFile.Reload();
				SaveOnConfigSet(value);
				InvokeOnConfigFileReloaded();
			}
			catch
			{
				Log.LogError("There was an issue loading your " + ConfigFileName);
				Log.LogError("Please check your config entries for spelling and format!");
			}
		}

		internal static void CheckForConfigManager()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType != 4 && Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.configurationmanager", out var value) && Object.op_Implicit((Object)(object)value.Instance))
			{
				ConfigurationManager = value.Instance;
				Log.LogDebug("Configuration manager found, hooking DisplayingWindowChanged");
				EventInfo @event = ((object)ConfigurationManager).GetType().GetEvent("DisplayingWindowChanged");
				if (@event != null)
				{
					Action<object, object> action = OnConfigManagerDisplayingWindowChanged;
					Delegate handler = Delegate.CreateDelegate(@event.EventHandlerType, action.Target, action.Method);
					@event.AddEventHandler(ConfigurationManager, handler);
				}
			}
		}

		private static void OnConfigManagerDisplayingWindowChanged(object sender, object e)
		{
			if (!(bool)((object)ConfigurationManager).GetType().GetProperty("DisplayingWindow").GetValue(ConfigurationManager, null))
			{
				InvokeOnConfigWindowClosed();
			}
		}
	}
}