Decompiled source of ValheimInfiniteFire v1.3.0

plugins/ValheimInfiniteFire.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
namespace ValheimInfiniteFire
{
	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;
				}
			}
		}

		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;
		}
	}
	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.3.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.3.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;
			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 ConfigEntry<bool> EnableDebugMode;

		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();
			};
		}

		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
			} }));
		}
	}
}