Decompiled source of ValheimInfiniteFire v1.4.0

plugins/ValheimInfiniteFire.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Managers;
using UnityEngine;
using ValheimInfiniteFire.common;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValheimInfiniteFire")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimInfiniteFire")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.4.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
namespace ValheimInfiniteFire
{
	internal static class FireSchedule
	{
		private readonly struct Window
		{
			public readonly float From;

			public readonly float To;

			public Window(float from, float to)
			{
				From = from;
				To = to;
			}
		}

		private static readonly Dictionary<int, Window> Windows = new Dictionary<int, Window>();

		private static readonly Dictionary<int, long> OffSince = new Dictionary<int, long>();

		private static readonly HashSet<string> SubscribedSchedule = new HashSet<string>();

		private static readonly HashSet<string> WarnedValues = new HashSet<string>();

		private static double LastClockRead = double.NegativeInfinity;

		private static bool SubscribedToSync;

		private static readonly int LitByHandKey = StringExtensionMethods.GetStableHashCode("InfiniteFire_litByHand");

		public const string SettingDescription = "Hours of the in game day this piece stays unlit, as Start-End on a 24 hour clock. 06:00-18:00 keeps it dark through the day and lit at night. Accepts 6, 6.5 and 06:30, and wraps past midnight (22:00-04:00). Leave empty for no schedule. A start equal to its end is ambiguous and is treated as no schedule.";

		public const string Section = "off_schedule";

		public static int Count => Windows.Count;

		public static void OnPrefabsRegistered()
		{
			Fireplace[] array = Resources.FindObjectsOfTypeAll<Fireplace>();
			foreach (Fireplace val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string prefabName = Utils.GetPrefabName(((Object)((Component)val).gameObject).name);
				if (!ValConfig.ScheduleConfigs.TryGetValue(prefabName, out var value))
				{
					value = ValConfig.BindServerConfig("off_schedule", prefabName, "", "Hours of the in game day this piece stays unlit, as Start-End on a 24 hour clock. 06:00-18:00 keeps it dark through the day and lit at night. Accepts 6, 6.5 and 06:30, and wraps past midnight (22:00-04:00). Leave empty for no schedule. A start equal to its end is ambiguous and is treated as no schedule.");
					ValConfig.ScheduleConfigs[prefabName] = value;
					Logger.LogDebug("Registering [off_schedule] " + prefabName + " = " + value.Value);
				}
				if (SubscribedSchedule.Add(prefabName))
				{
					value.SettingChanged += delegate
					{
						ReadConfig();
					};
				}
			}
			if (!SubscribedToSync)
			{
				SubscribedToSync = true;
				SynchronizationManager.OnConfigurationSynchronized += delegate
				{
					ReadConfig();
					WarnInvalid();
				};
				SynchronizationManager.OnConfigurationWindowClosed += WarnInvalid;
			}
			ReadConfig();
			WarnInvalid();
		}

		private static void ReadConfig()
		{
			Windows.Clear();
			OffSince.Clear();
			LastClockRead = double.NegativeInfinity;
			foreach (KeyValuePair<string, ConfigEntry<string>> scheduleConfig in ValConfig.ScheduleConfigs)
			{
				string value = scheduleConfig.Value.Value;
				if (!string.IsNullOrEmpty(value) && value.Trim().Length != 0 && TryParseWindow(value, out var from, out var to))
				{
					Windows[StringExtensionMethods.GetStableHashCode(scheduleConfig.Key)] = new Window(from, to);
					Logger.LogDebug($"Scheduling {scheduleConfig.Key} off from {from:0.##} to {to:0.##}");
				}
			}
		}

		private static void WarnInvalid()
		{
			foreach (KeyValuePair<string, ConfigEntry<string>> scheduleConfig in ValConfig.ScheduleConfigs)
			{
				string value = scheduleConfig.Value.Value;
				if (!string.IsNullOrEmpty(value) && value.Trim().Length != 0 && !TryParseWindow(value, out var _, out var _) && WarnedValues.Add(scheduleConfig.Key + "=" + value))
				{
					Logger.LogWarning("Ignoring [off_schedule] " + scheduleConfig.Key + " = " + value + ", it is not a Start-End time range.");
				}
			}
		}

		public static bool IsOffNow(ZDO zdo)
		{
			if (Windows.Count == 0)
			{
				return false;
			}
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)EnvMan.instance == (Object)null)
			{
				return false;
			}
			double timeSeconds = instance.GetTimeSeconds();
			if (timeSeconds - LastClockRead >= (double)ValConfig.ScheduleCheckInterval.Value || timeSeconds < LastClockRead)
			{
				ReadClock(timeSeconds);
			}
			if (!OffSince.TryGetValue(zdo.GetPrefab(), out var value))
			{
				return false;
			}
			return zdo.GetLong(LitByHandKey, long.MinValue) < value;
		}

		private static void ReadClock(double now)
		{
			LastClockRead = now;
			float num = ClockHour(now);
			foreach (KeyValuePair<int, Window> window in Windows)
			{
				Window value = window.Value;
				bool num2;
				if (!(value.From < value.To))
				{
					if (num >= value.From)
					{
						goto IL_007d;
					}
					num2 = num < value.To;
				}
				else
				{
					if (!(num >= value.From))
					{
						goto IL_0069;
					}
					num2 = num < value.To;
				}
				if (!num2)
				{
					goto IL_0069;
				}
				goto IL_007d;
				IL_007d:
				if (!OffSince.ContainsKey(window.Key))
				{
					OffSince[window.Key] = WindowOpenedAt(now, value.From);
				}
				continue;
				IL_0069:
				OffSince.Remove(window.Key);
			}
		}

		private static long WindowOpenedAt(double now, float fromHour)
		{
			EnvMan instance = EnvMan.instance;
			if ((Object)(object)instance == (Object)null || instance.m_debugTimeOfDay)
			{
				return (long)now;
			}
			long num = ((instance.m_dayLengthSec > 0) ? instance.m_dayLengthSec : 1200);
			double num2 = Math.Floor(now / (double)num) * (double)num + (double)(UnrescaleDayFraction(fromHour / 24f) * (float)num);
			if (num2 > now)
			{
				num2 -= (double)num;
			}
			return (long)num2;
		}

		private static float UnrescaleDayFraction(float clock)
		{
			if (clock >= 0.25f && clock <= 0.75f)
			{
				return 0.15f + (clock - 0.25f) / 0.5f * 0.7f;
			}
			if (clock < 0.25f)
			{
				return clock / 0.25f * 0.15f;
			}
			return 0.85f + (clock - 0.75f) / 0.25f * 0.15f;
		}

		private static float ClockHour(double now)
		{
			EnvMan instance = EnvMan.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return 0f;
			}
			if (instance.m_debugTimeOfDay)
			{
				return Mathf.Clamp01(instance.m_debugTime) * 24f;
			}
			long num = ((instance.m_dayLengthSec > 0) ? instance.m_dayLengthSec : 1200);
			return RescaleDayFraction(Mathf.Clamp01((float)(now % (double)num) / (float)num)) * 24f;
		}

		private static float RescaleDayFraction(float fraction)
		{
			if (fraction >= 0.15f && fraction <= 0.85f)
			{
				return 0.25f + (fraction - 0.15f) / 0.7f * 0.5f;
			}
			if (fraction < 0.5f)
			{
				return fraction / 0.15f * 0.25f;
			}
			return 0.75f + (fraction - 0.85f) / 0.15f * 0.25f;
		}

		public static float OffUntil(ZDO zdo)
		{
			if (!Windows.TryGetValue(zdo.GetPrefab(), out var value))
			{
				return -1f;
			}
			return value.To;
		}

		public static string FormatHour(float hour)
		{
			int num = Mathf.FloorToInt(hour);
			int num2 = Mathf.RoundToInt((hour - (float)num) * 60f);
			if (num2 >= 60)
			{
				num2 = 0;
				num++;
			}
			return $"{num % 24:00}:{num2:00}";
		}

		public static void LitByHand(ZNetView nview)
		{
			ZNet instance = ZNet.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				if (!nview.HasOwner())
				{
					nview.ClaimOwnership();
				}
				nview.GetZDO().Set(LitByHandKey, (long)instance.GetTimeSeconds());
			}
		}

		public static bool TryParseWindow(string value, out float from, out float to)
		{
			from = 0f;
			to = 0f;
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			string[] array = value.Split(new char[1] { '-' });
			if (array.Length != 2)
			{
				return false;
			}
			if (!TryParseHour(array[0], out from) || !TryParseHour(array[1], out to))
			{
				return false;
			}
			return from != to;
		}

		private static bool TryParseHour(string value, out float hour)
		{
			hour = 0f;
			if (value == null)
			{
				return false;
			}
			value = value.Trim();
			if (value.Length == 0)
			{
				return false;
			}
			if (value.IndexOf(':') >= 0)
			{
				string[] array = value.Split(new char[1] { ':' });
				if (array.Length != 2)
				{
					return false;
				}
				if (!int.TryParse(array[0].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
				{
					return false;
				}
				if (!int.TryParse(array[1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
				{
					return false;
				}
				if (result < 0 || result > 24 || result2 < 0 || result2 > 59)
				{
					return false;
				}
				hour = (float)result + (float)result2 / 60f;
			}
			else if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out hour))
			{
				return false;
			}
			if (hour < 0f || hour > 24f)
			{
				return false;
			}
			if (hour == 24f)
			{
				hour = 0f;
			}
			return true;
		}
	}
	internal static class Patches
	{
		[HarmonyPatch(typeof(Smelter), "GetFuel")]
		internal static class SmelterGetFuel
		{
			[HarmonyPostfix]
			internal static void Postfix(Smelter __instance, ref float __result)
			{
				if (HasInfiniteFuel((Component)(object)__instance))
				{
					__result = Mathf.Max(__instance.m_maxFuel, __instance.m_fuelPerProduct);
				}
			}
		}

		[HarmonyPatch(typeof(Smelter), "SetFuel")]
		internal static class SmelterSetFuel
		{
			[HarmonyPrefix]
			internal static bool Prefix(Smelter __instance)
			{
				return !HasInfiniteFuel((Component)(object)__instance);
			}
		}

		[HarmonyPatch(typeof(Smelter), "RPC_AddFuel")]
		internal static class SmelterAddStoredFuel
		{
			[HarmonyPriority(800)]
			[HarmonyPrefix]
			internal static void Prefix()
			{
				UseStoredFuel = true;
			}

			[HarmonyFinalizer]
			internal static void Finalizer()
			{
				UseStoredFuel = false;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "GetFuel")]
		internal static class CookerGetFuel
		{
			[HarmonyPostfix]
			internal static void Postfix(CookingStation __instance, ref float __result)
			{
				if (HasInfiniteFuel((Component)(object)__instance))
				{
					__result = __instance.m_maxFuel;
				}
			}
		}

		[HarmonyPatch(typeof(CookingStation), "SetFuel")]
		internal static class CookerSetFuel
		{
			[HarmonyPrefix]
			internal static bool Prefix(CookingStation __instance)
			{
				return !HasInfiniteFuel((Component)(object)__instance);
			}
		}

		[HarmonyPatch(typeof(CookingStation), "RPC_AddFuel")]
		internal static class CookerAddStoredFuel
		{
			[HarmonyPriority(800)]
			[HarmonyPrefix]
			internal static void Prefix()
			{
				UseStoredFuel = true;
			}

			[HarmonyFinalizer]
			internal static void Finalizer()
			{
				UseStoredFuel = false;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "DropAllItems")]
		internal static class CookerRefundStoredFuel
		{
			[HarmonyPriority(800)]
			[HarmonyPrefix]
			internal static void Prefix()
			{
				UseStoredFuel = true;
			}

			[HarmonyFinalizer]
			internal static void Finalizer()
			{
				UseStoredFuel = false;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "OnHoverFuelSwitch")]
		internal static class OnHoverDisplayNoFuelRequirementCookingStation
		{
			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPostfix]
			internal static void Postfix(CookingStation __instance, ref string __result)
			{
				if (HasInfiniteFuel((Component)(object)__instance))
				{
					__result = "No Fuel Needed.";
				}
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")]
		internal static class OnHoverDisplayNoFuelRequirementSmelter
		{
			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPostfix]
			internal static void Postfix(Smelter __instance, ref string __result)
			{
				if (HasInfiniteFuel((Component)(object)__instance))
				{
					__result = "No Fuel Needed.";
				}
			}
		}

		[HarmonyPatch(typeof(SmokeSpawner), "IsBlocked")]
		internal static class SmokeSpawnerNeverBlocked
		{
			[HarmonyPostfix]
			internal static void Postfix(ref bool __result)
			{
				if (!ValConfig.SmokeSuffocation.Value)
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Fireplace), "IsBurning")]
		internal static class FireplaceScheduledOff
		{
			[HarmonyPostfix]
			internal static void Postfix(Fireplace __instance, ref bool __result)
			{
				if (__result && FireSchedule.Count != 0)
				{
					ZDO fireZDO = GetFireZDO(__instance);
					if (fireZDO != null && FireSchedule.IsOffNow(fireZDO))
					{
						__result = false;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Fireplace), "Interact")]
		internal static class FireplaceScheduleOverride
		{
			[HarmonyPrefix]
			internal static bool Prefix(Fireplace __instance, bool hold, bool alt, ref bool __result)
			{
				if (FireSchedule.Count == 0 || hold || alt || !__instance.m_canTurnOff)
				{
					return true;
				}
				ZDO fireZDO = GetFireZDO(__instance);
				if (fireZDO == null || fireZDO.GetFloat(ZDOVars.s_fuel, 0f) <= 0f)
				{
					return true;
				}
				if (!FireSchedule.IsOffNow(fireZDO))
				{
					return true;
				}
				FireSchedule.LitByHand(__instance.m_nview);
				if (fireZDO.GetInt(ZDOVars.s_state, 1) != 1)
				{
					return true;
				}
				__instance.UpdateState();
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Fireplace), "GetHoverText")]
		internal static class FireplaceScheduleHover
		{
			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPostfix]
			internal static void Postfix(Fireplace __instance, ref string __result)
			{
				if (FireSchedule.Count == 0)
				{
					return;
				}
				ZDO fireZDO = GetFireZDO(__instance);
				if (fireZDO == null || !FireSchedule.IsOffNow(fireZDO))
				{
					return;
				}
				float num = FireSchedule.OffUntil(fireZDO);
				if (!(num < 0f))
				{
					if (string.IsNullOrEmpty(__result))
					{
						__result = Localization.instance.Localize(__instance.m_name);
					}
					__result = __result + "\nScheduled off until " + FireSchedule.FormatHour(num);
				}
			}
		}

		private static bool UseStoredFuel;

		private static bool HasInfiniteFuel(Component station)
		{
			if (UseStoredFuel)
			{
				return false;
			}
			ValConfig.NoFuelConfigs.TryGetValue(Utils.GetPrefabName(((Object)station.gameObject).name), out var value);
			return value?.Value ?? false;
		}

		private static ZDO GetFireZDO(Fireplace fireplace)
		{
			ZNetView nview = fireplace.m_nview;
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return null;
			}
			return nview.GetZDO();
		}
	}
	internal static class SmokeControl
	{
		private static readonly Dictionary<string, bool> OriginalSpawnerActive = new Dictionary<string, bool>();

		private static readonly Dictionary<string, bool> OriginalTolerateSmoke = new Dictionary<string, bool>();

		private static readonly Dictionary<string, float> OriginalFireDieChance = new Dictionary<string, float>();

		private static readonly HashSet<string> SubscribedSmoke = new HashSet<string>();

		public static void OnPrefabsRegistered()
		{
			DiscoverSmokeSpawners();
			ApplySmokeDamage();
			ApplyFireSuffocation();
		}

		private static void DiscoverSmokeSpawners()
		{
			SmokeSpawner[] array = Resources.FindObjectsOfTypeAll<SmokeSpawner>();
			foreach (SmokeSpawner val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Transform root = ((Component)val).transform.root;
				if ((Object)(object)((Component)root).GetComponent<Piece>() == (Object)null)
				{
					continue;
				}
				string prefabname = Utils.GetPrefabName(((Object)((Component)root).gameObject).name);
				if (!ValConfig.SmokeConfigs.TryGetValue(prefabname, out var value))
				{
					value = ValConfig.BindServerConfig("Smoke", prefabname, value: true, "Enable smoke for this piece. Disabling switches its smoke spawner off entirely, so it costs nothing at runtime.");
					ValConfig.SmokeConfigs[prefabname] = value;
					Logger.LogDebug($"Registering {prefabname} with Smoke {value.Value}");
				}
				if (SubscribedSmoke.Add(prefabname))
				{
					value.SettingChanged += delegate
					{
						ApplySmoke(prefabname);
					};
				}
				ApplySpawnerState(val, root, prefabname, value.Value);
			}
		}

		private static void ApplySmoke(string prefabname)
		{
			if (!ValConfig.SmokeConfigs.TryGetValue(prefabname, out var value))
			{
				return;
			}
			Logger.LogDebug($"Updating {prefabname} to Smoke:{value.Value}");
			SmokeSpawner[] array = Resources.FindObjectsOfTypeAll<SmokeSpawner>();
			foreach (SmokeSpawner val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Transform root = ((Component)val).transform.root;
					if (!((Object)(object)((Component)root).GetComponent<Piece>() == (Object)null) && !(Utils.GetPrefabName(((Object)((Component)root).gameObject).name) != prefabname))
					{
						ApplySpawnerState(val, root, prefabname, value.Value);
					}
				}
			}
		}

		private static void ApplySpawnerState(SmokeSpawner spawner, Transform root, string prefabname, bool enabled)
		{
			string key = prefabname + "|" + RelativePath(((Component)spawner).transform, root);
			if (!OriginalSpawnerActive.TryGetValue(key, out var value))
			{
				value = ((Component)spawner).gameObject.activeSelf;
				OriginalSpawnerActive[key] = value;
			}
			bool flag = enabled && value;
			if (((Component)spawner).gameObject.activeSelf != flag)
			{
				((Component)spawner).gameObject.SetActive(flag);
			}
		}

		private static string RelativePath(Transform child, Transform root)
		{
			StringBuilder stringBuilder = new StringBuilder(((Object)child).name);
			Transform parent = child.parent;
			while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
			{
				stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name);
				parent = parent.parent;
			}
			return stringBuilder.ToString();
		}

		public static void ApplySmokeDamage()
		{
			bool value = ValConfig.SmokeDamage.Value;
			Logger.LogDebug($"Applying SmokeDamage:{value}");
			Character[] array = Resources.FindObjectsOfTypeAll<Character>();
			foreach (Character val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string prefabName = Utils.GetPrefabName(((Object)((Component)val).gameObject).name);
					if (!OriginalTolerateSmoke.TryGetValue(prefabName, out var value2))
					{
						value2 = val.m_tolerateSmoke;
						OriginalTolerateSmoke[prefabName] = value2;
					}
					val.m_tolerateSmoke = !value || value2;
					if (!value && val.m_seman != null)
					{
						val.m_seman.RemoveStatusEffect(SEMan.s_statusEffectSmoked, true);
					}
				}
			}
		}

		public static void ApplyFireSuffocation()
		{
			bool value = ValConfig.SmokeSuffocation.Value;
			Logger.LogDebug($"Applying SmokeSuffocation:{value}");
			Fire[] array = Resources.FindObjectsOfTypeAll<Fire>();
			foreach (Fire val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string prefabName = Utils.GetPrefabName(((Object)((Component)val).gameObject).name);
					if (!OriginalFireDieChance.TryGetValue(prefabName, out var value2))
					{
						value2 = val.m_smokeDieChance;
						OriginalFireDieChance[prefabName] = value2;
					}
					val.m_smokeDieChance = (value ? value2 : 0f);
				}
			}
		}
	}
	[BepInPlugin("MidnightsFX.InfiniteFire", "InfiniteFire", "1.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class ValheimInfiniteFire : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.InfiniteFire";

		public const string PluginName = "InfiniteFire";

		public const string PluginVersion = "1.4.0";

		public ValConfig cfg;

		public static ManualLogSource Log;

		private static readonly HashSet<string> SubscribedFuel = new HashSet<string>();

		public static Harmony HarmonyInstance { get; private set; }

		public void Awake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			HarmonyInstance = new Harmony("MidnightsFX.InfiniteFire");
			HarmonyInstance.PatchAll();
			PrefabManager.OnPrefabsRegistered += FindAllFireTypes;
			PrefabManager.OnPrefabsRegistered += FindAllSmelters;
			PrefabManager.OnPrefabsRegistered += FindAllCookingStation;
			PrefabManager.OnPrefabsRegistered += SmokeControl.OnPrefabsRegistered;
			PrefabManager.OnPrefabsRegistered += FireSchedule.OnPrefabsRegistered;
			Logger.LogDebug("Lets Light it up");
		}

		public static void FindAllCookingStation()
		{
			CookingStation[] array = Resources.FindObjectsOfTypeAll<CookingStation>();
			foreach (CookingStation val in array)
			{
				if (!((Object)(object)val.m_fuelItem == (Object)null))
				{
					string prefabName = Utils.GetPrefabName(((Object)((Component)val).gameObject).name);
					ConfigEntry<bool> val2 = ValConfig.BindServerConfig("InfiniteFuel", prefabName, value: true, "Enable infinite fuel for this cooking station.");
					ValConfig.NoFuelConfigs[prefabName] = val2;
					Logger.LogDebug($"Registering {prefabName} with InfiniteFuel {val2.Value}");
				}
			}
		}

		public static void FindAllFireTypes()
		{
			Fireplace[] array = Resources.FindObjectsOfTypeAll<Fireplace>();
			foreach (Fireplace val in array)
			{
				string prefabname = Utils.GetPrefabName(((Object)((Component)val).gameObject).name);
				ConfigEntry<bool> enableFire = ValConfig.BindServerConfig("InfiniteFire", prefabname, value: true, "Enable infinite fuel for this fire.");
				Logger.LogDebug($"Registering {prefabname} with infinitefire {enableFire.Value}");
				val.m_infiniteFuel = enableFire.Value;
				if (SubscribedFuel.Add(prefabname))
				{
					enableFire.SettingChanged += delegate
					{
						foreach (Fireplace item in from fp in Resources.FindObjectsOfTypeAll<Fireplace>()
							where Utils.GetPrefabName(((Object)((Component)fp).gameObject).name) == prefabname
							select fp)
						{
							Logger.LogDebug($"Updating {((Object)item).name} to InfiniteFire:{enableFire.Value}");
							item.m_infiniteFuel = enableFire.Value;
						}
					};
				}
				ValConfig.NoFuelConfigs[prefabname] = enableFire;
			}
		}

		public static void FindAllSmelters()
		{
			Smelter[] array = Resources.FindObjectsOfTypeAll<Smelter>();
			foreach (Smelter val in array)
			{
				if (!((Object)(object)val.m_fuelItem == (Object)null) && val.m_maxFuel > 0)
				{
					string prefabName = Utils.GetPrefabName(((Object)((Component)val).gameObject).name);
					ConfigEntry<bool> val2 = ValConfig.BindServerConfig("InfiniteFuel", prefabName, value: false, "Enable infinite fuel for this smelter.");
					ValConfig.NoFuelConfigs[prefabName] = val2;
					Logger.LogDebug($"Registering {prefabName} with InfiniteFuel {val2.Value}");
				}
			}
		}
	}
}
namespace ValheimInfiniteFire.common
{
	internal static class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void CheckEnableDebugLogging()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				ValheimInfiniteFire.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				ValheimInfiniteFire.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				ValheimInfiniteFire.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				ValheimInfiniteFire.Log.LogError((object)message);
			}
		}
	}
	internal class ValConfig
	{
		public static ConfigFile cfg;

		public static Dictionary<string, ConfigEntry<bool>> NoFuelConfigs = new Dictionary<string, ConfigEntry<bool>>();

		public static Dictionary<string, ConfigEntry<bool>> SmokeConfigs = new Dictionary<string, ConfigEntry<bool>>();

		public static Dictionary<string, ConfigEntry<string>> ScheduleConfigs = new Dictionary<string, ConfigEntry<string>>();

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<float> ScheduleCheckInterval;

		public static ConfigEntry<bool> SmokeDamage;

		public static ConfigEntry<bool> SmokeSuffocation;

		public ValConfig(ConfigFile cf)
		{
			cfg = cf;
			cfg.SaveOnConfigSet = true;
			CreateConfigValues(cf);
		}

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
			EnableDebugMode.SettingChanged += Logger.enableDebugLogging;
			Logger.CheckEnableDebugLogging();
			SmokeDamage = BindServerConfig("Smoke gameplay", "SmokeDamage", value: true, "Smoke applies the Smoked status effect (2 damage per second) to anyone standing in it. Set false to make every character - players, tames and monsters - ignore smoke completely, which also skips the smoke proximity check each of them runs every 2 seconds.");
			SmokeDamage.SettingChanged += delegate
			{
				SmokeControl.ApplySmokeDamage();
			};
			SmokeSuffocation = BindServerConfig("Smoke gameplay", "SmokeSuffocation", value: true, "Smoke can choke fires. Set false so fireplaces are never reported as blocked by their own smoke, smelters, kilns and blast furnaces never stall on smoke, and spreading fires are never put out by it. Spreading fires still expire after 30 seconds and still die in the rain.");
			SmokeSuffocation.SettingChanged += delegate
			{
				SmokeControl.ApplyFireSuffocation();
			};
			ScheduleCheckInterval = BindServerConfig("off_schedule", "ScheduleCheckInterval", 10f, "How many in game seconds pass before a scheduled fire rechecks the clock. A Valheim day is 1200 seconds and the clock runs faster at night, an hour after dark being 30 seconds against 70 in daylight, so 10 puts a boundary up to about 20 in game minutes late at night and 9 by day. Lower is near enough free, the check is a handful of comparisons and only runs while a fire is loaded.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 120f), advanced: true);
		}

		public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
}