Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ResinFire v1.2.1
ResinFire.dll
Decompiled 5 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ResinFire")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ResinFire")] [assembly: AssemblyTitle("ResinFire")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ResinFire { [BepInPlugin("snowfarm.valheim.resinfire", "ResinFire", "1.2.1")] public class ResinFirePlugin : BaseUnityPlugin { public const string Guid = "snowfarm.valheim.resinfire"; public const string Name = "ResinFire"; public const string Version = "1.2.1"; private const string DefaultFuelPrefabs = "piece_brazierceiling01,piece_brazierfloor01,piece_brazierfloor02,piece_groundtorch_blue,piece_groundtorch_green"; private const string DefaultRefillPrefabs = "piece_brazierceiling01,piece_brazierfloor01,piece_brazierfloor02,piece_groundtorch_blue,piece_groundtorch_green,piece_sconce,piece_groundtorch,piece_groundtorchwood"; private const string V110FuelPrefabs = "piece_brazierceiling01,piece_brazierfloor01"; private const string V110RefillPrefabs = "piece_brazierceiling01,piece_brazierfloor01,piece_sconce,piece_groundtorch,piece_groundtorchwood"; private static ManualLogSource _log; private static ConfigEntry<bool> _enabled; private static ConfigEntry<string> _fuelItemName; private static ConfigEntry<string> _fuelPrefabs; private static ConfigEntry<string> _refillPrefabs; private static ConfigEntry<float> _radius; private static ConfigEntry<float> _interval; private static ConfigEntry<bool> _verbose; private static readonly List<Fireplace> Fireplaces = new List<Fireplace>(); private static readonly List<Container> Containers = new List<Container>(); private static readonly HashSet<string> FuelTargets = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly HashSet<string> RefillTargets = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static ItemDrop _fuelItem; private static float _radiusSqr; private static bool _loggedNotServer; private void Awake() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) _log = ((BaseUnityPlugin)this).Logger; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Turn the whole plugin on or off."); _fuelItemName = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Fuel", "FuelItem", "Resin", "Item prefab the pieces in FuelPrefabs burn. Use 'Coal' to get vanilla behaviour back."); _fuelPrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Fuel", "FuelPrefabs", "piece_brazierceiling01,piece_brazierfloor01,piece_brazierfloor02,piece_groundtorch_blue,piece_groundtorch_green", "Comma separated prefabs whose fuel item is replaced."); _refillPrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Auto refill", "RefillPrefabs", "piece_brazierceiling01,piece_brazierfloor01,piece_brazierfloor02,piece_groundtorch_blue,piece_groundtorch_green,piece_sconce,piece_groundtorch,piece_groundtorchwood", "Comma separated prefabs that refill themselves from nearby containers."); if (_fuelPrefabs.Value == "piece_brazierceiling01,piece_brazierfloor01") { _fuelPrefabs.Value = "piece_brazierceiling01,piece_brazierfloor01,piece_brazierfloor02,piece_groundtorch_blue,piece_groundtorch_green"; } if (_refillPrefabs.Value == "piece_brazierceiling01,piece_brazierfloor01,piece_sconce,piece_groundtorch,piece_groundtorchwood") { _refillPrefabs.Value = "piece_brazierceiling01,piece_brazierfloor01,piece_brazierfloor02,piece_groundtorch_blue,piece_groundtorch_green,piece_sconce,piece_groundtorch,piece_groundtorchwood"; } _radius = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Auto refill", "Radius", 30f, new ConfigDescription("Search radius for containers, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>())); _interval = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Auto refill", "Interval", 5f, new ConfigDescription("Seconds between refill checks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); _verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Diagnostics", "Verbose", false, "Log a summary every cycle and the reason each fire was skipped."); ParseList(_fuelPrefabs.Value, FuelTargets); ParseList(_refillPrefabs.Value, RefillTargets); _radiusSqr = _radius.Value * _radius.Value; new Harmony("snowfarm.valheim.resinfire").PatchAll(typeof(ResinFirePlugin)); ((MonoBehaviour)this).StartCoroutine(PrefabLoop()); ((MonoBehaviour)this).StartCoroutine(RefillLoop()); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. fuel={2}, radius={3}m", "ResinFire", "1.2.1", _fuelItemName.Value, _radius.Value)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("fuel prefabs : " + string.Join(", ", FuelTargets))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("refill prefabs : " + string.Join(", ", RefillTargets))); } private static void ParseList(string value, HashSet<string> target) { target.Clear(); string[] array = (value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { target.Add(text); } } } [HarmonyPostfix] [HarmonyPatch(typeof(Fireplace), "Awake")] private static void FireplaceAwake(Fireplace __instance) { if (!((Object)(object)__instance == (Object)null)) { if (!Fireplaces.Contains(__instance)) { Fireplaces.Add(__instance); } if ((Object)(object)_fuelItem == (Object)null) { _fuelItem = ResolveFuelItem(); } if ((Object)(object)_fuelItem != (Object)null && FuelTargets.Contains(PrefabName(((Component)__instance).gameObject))) { __instance.m_fuelItem = _fuelItem; } } } [HarmonyPostfix] [HarmonyPatch(typeof(Container), "Awake")] private static void ContainerAwake(Container __instance) { if ((Object)(object)__instance != (Object)null && !Containers.Contains(__instance)) { Containers.Add(__instance); } } private IEnumerator PrefabLoop() { ZNetScene last = null; while (true) { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)last) { last = instance; ApplyFuelToPrefabs(); } yield return (object)new WaitForSeconds(5f); } } private static void ApplyFuelToPrefabs() { if (!_enabled.Value) { return; } _fuelItem = ResolveFuelItem(); if ((Object)(object)_fuelItem == (Object)null) { return; } foreach (string fuelTarget in FuelTargets) { GameObject prefab = ZNetScene.instance.GetPrefab(fuelTarget); if ((Object)(object)prefab == (Object)null) { _log.LogWarning((object)("Prefab '" + fuelTarget + "' not found.")); continue; } Fireplace componentInChildren = prefab.GetComponentInChildren<Fireplace>(true); if ((Object)(object)componentInChildren == (Object)null) { _log.LogWarning((object)("Prefab '" + fuelTarget + "' has no Fireplace component.")); continue; } string text = "?"; if ((Object)(object)componentInChildren.m_fuelItem != (Object)null && componentInChildren.m_fuelItem.m_itemData != null) { text = componentInChildren.m_fuelItem.m_itemData.m_shared.m_name; } componentInChildren.m_fuelItem = _fuelItem; _log.LogInfo((object)("'" + fuelTarget + "' now burns " + _fuelItemName.Value + " (was " + text + ").")); } } private static ItemDrop ResolveFuelItem() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return null; } GameObject itemPrefab = instance.GetItemPrefab(_fuelItemName.Value); if (!Object.op_Implicit((Object)(object)itemPrefab)) { return null; } return itemPrefab.GetComponent<ItemDrop>(); } private IEnumerator RefillLoop() { while (true) { yield return (object)new WaitForSeconds(_interval.Value); if (!_enabled.Value) { continue; } if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { if (!_loggedNotServer) { _loggedNotServer = true; _log.LogInfo((object)"Not the server: auto refill only runs on the server (this peer will not refill)."); } continue; } PruneLists(); int num = 0; int num2 = 0; int num3 = 0; foreach (Fireplace fireplace in Fireplaces) { try { string reason; bool flag = Refill(fireplace, out reason); if (reason != null) { num++; if (reason != "full") { num2++; } if (flag) { num3++; } if (_verbose.Value && !flag && reason != "full") { _log.LogInfo((object)(PrefabName(((Component)fireplace).gameObject) + ": skipped (" + reason + ")")); } } } catch (Exception ex) { _log.LogDebug((object)("Refill failed: " + ex.Message)); } } if (_verbose.Value && num > 0) { _log.LogInfo((object)$"cycle: targets={num} empty={num2} refilled={num3} containers={Containers.Count}"); } } } private static void PruneLists() { Fireplaces.RemoveAll((Fireplace f) => (Object)(object)f == (Object)null); Containers.RemoveAll((Container c) => (Object)(object)c == (Object)null); } private static bool Refill(Fireplace fireplace, out string reason) { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) reason = null; if ((Object)(object)fireplace == (Object)null) { return false; } if (!RefillTargets.Contains(PrefabName(((Component)fireplace).gameObject))) { return false; } if (fireplace.m_infiniteFuel) { reason = "infinite fuel"; return false; } ZNetView component = ((Component)fireplace).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { reason = "no ZNetView"; return false; } if (!component.IsOwner()) { component.ClaimOwnership(); if (!component.IsOwner()) { reason = "fire not owned"; return false; } } ZDO zDO = component.GetZDO(); if (zDO == null) { reason = "no ZDO"; return false; } if (zDO.GetInt(ZDOVars.s_state, 1) != 1) { reason = "switched off"; return false; } float maxFuel = fireplace.m_maxFuel; if (maxFuel <= 0f) { reason = "maxFuel 0"; return false; } float num = zDO.GetFloat(ZDOVars.s_fuel, 0f); if (num >= maxFuel - 0.01f) { reason = "full"; return false; } ItemDrop fuelItem = fireplace.m_fuelItem; if ((Object)(object)fuelItem == (Object)null || fuelItem.m_itemData == null) { reason = "no fuel item"; return false; } string name = fuelItem.m_itemData.m_shared.m_name; int num2 = Mathf.CeilToInt(maxFuel - num); int num3 = 0; int num4 = 0; Vector3 position = ((Component)fireplace).transform.position; foreach (Container container in Containers) { if (num3 >= num2) { break; } if ((Object)(object)container == (Object)null || !((Component)container).gameObject.activeInHierarchy) { continue; } Vector3 val = ((Component)container).transform.position - position; if (((Vector3)(ref val)).sqrMagnitude > _radiusSqr) { continue; } num4++; if (!container.IsOwner()) { if (container.IsInUse()) { continue; } ZNetView component2 = ((Component)container).GetComponent<ZNetView>(); if ((Object)(object)component2 == (Object)null || !component2.IsValid()) { continue; } component2.ClaimOwnership(); if (!container.IsOwner()) { continue; } } Inventory inventory = container.GetInventory(); if (inventory == null) { continue; } int num5 = inventory.CountItems(name, -1, false); if (num5 <= 0) { continue; } ItemData item = inventory.GetItem(name, -1, false); if (item != null) { int num6 = Mathf.Min(num5, num2 - num3); if (inventory.RemoveItem(item, num6)) { num3 += num6; } } } if (num3 <= 0) { reason = ((num4 == 0) ? "no containers in range" : ("no " + name + " in range")); return false; } fireplace.AddFuel((float)num3); _log.LogDebug((object)$"Refilled {((Object)((Component)fireplace).gameObject).name} with {num3} x {name}."); return true; } private static string PrefabName(GameObject go) { if ((Object)(object)go == (Object)null) { return string.Empty; } string text = ((Object)go).name; int num = text.IndexOf("(Clone)", StringComparison.Ordinal); if (num >= 0) { text = text.Substring(0, num); } return text.Trim(); } } }