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 RefillAllTorches v1.0.0
plugins\RefillAllTorches\RefillAllTorches.dll
Decompiled 9 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Andejx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Automatically refills every fuel-burning light source in Valheim, for free or at a cost of exactly one fuel item per refill.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RefillAllTorches")] [assembly: AssemblyTitle("RefillAllTorches")] [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 RefillAllTorches { [BepInPlugin("Andejx.RefillAllTorches", "RefillAllTorches", "1.0.0")] public sealed class RefillAllTorchesPlugin : BaseUnityPlugin { public enum RefillTrigger { Always, HalfOrLess, OneUnitLeft } public enum FuelType { Other, Wood, Resin, Coal, Guck, GreydwarfEye } public const string PluginGuid = "Andejx.RefillAllTorches"; public const string PluginName = "RefillAllTorches"; public const string PluginVersion = "1.0.0"; private const float FuelEpsilon = 0.001f; private ConfigEntry<bool> _enabled; private ConfigEntry<float> _radius; private ConfigEntry<float> _checkInterval; private ConfigEntry<bool> _consumeFuelItem; private ConfigEntry<RefillTrigger> _refillTrigger; private ConfigEntry<bool> _enableWood; private ConfigEntry<bool> _enableResin; private ConfigEntry<bool> _enableCoal; private ConfigEntry<bool> _enableGuck; private ConfigEntry<bool> _enableGreydwarfEye; private ConfigEntry<bool> _notifyWhenRefilled; private ConfigEntry<bool> _debugLogging; private float _nextScanTime; private void Awake() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch for RefillAllTorches."); _radius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Radius", 20f, new ConfigDescription("Distance in meters around your character that RefillAllTorches checks. 0 = every loaded light source, regardless of distance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), Array.Empty<object>())); _checkInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CheckInterval", 1f, new ConfigDescription("Seconds between scans.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), Array.Empty<object>())); _consumeFuelItem = ((BaseUnityPlugin)this).Config.Bind<bool>("Refill", "ConsumeFuelItem", false, "false = refill for free. true = each refill costs exactly 1 of the light's fuel item from your inventory, and the light is topped up to full either way."); _refillTrigger = ((BaseUnityPlugin)this).Config.Bind<RefillTrigger>("Refill", "RefillTrigger", RefillTrigger.HalfOrLess, "When to refill: Always = whenever below full (don't care, just refill). HalfOrLess = only when fuel is at half or less. OneUnitLeft = only when 1 fuel unit or less remains. Relevant mainly with ConsumeFuelItem = true."); _enableWood = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuels", "Wood", true, "Refill light sources that burn Wood: campfire, bonfire, hearth, iron fire pit."); _enableResin = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuels", "Resin", true, "Refill light sources that burn Resin: standing wood torch, standing iron torch, sconce, Jack-o-turnip."); _enableCoal = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuels", "Coal", true, "Refill light sources that burn Coal: standing brazier, hanging brazier."); _enableGuck = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuels", "Guck", true, "Refill light sources that burn Guck: standing green-burning iron torch."); _enableGreydwarfEye = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuels", "GreydwarfEye", true, "Refill light sources that burn Greydwarf eyes: standing blue-burning iron torch, blue standing brazier."); _notifyWhenRefilled = ((BaseUnityPlugin)this).Config.Bind<bool>("Feedback", "NotifyWhenRefilled", false, "Show a center-screen message when lights are refilled."); _debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Feedback", "DebugLogging", false, "Write refill details to the BepInEx log."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RefillAllTorches 1.0.0 loaded."); } private void Update() { if (_enabled.Value && !(Time.time < _nextScanTime)) { _nextScanTime = Time.time + Mathf.Max(0.1f, _checkInterval.Value); Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead()) { RefillNearbyLights(localPlayer); } } } private void RefillNearbyLights(Player player) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } bool value = _consumeFuelItem.Value; float value2 = _radius.Value; float num = ((value2 <= 0f) ? float.MaxValue : (value2 * value2)); Vector3 position = ((Component)player).transform.position; int num2 = 0; int num3 = 0; Fireplace[] array = Object.FindObjectsByType<Fireplace>((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Fireplace val in array) { if ((Object)(object)val == (Object)null || val.m_infiniteFuel || !val.m_canRefill || (Object)(object)((Component)val).GetComponent<Smelter>() != (Object)null || (Object)(object)((Component)val).GetComponent<CookingStation>() != (Object)null || (Object)(object)val.m_fuelItem == (Object)null || val.m_fuelItem.m_itemData == null || val.m_fuelItem.m_itemData.m_shared == null) { continue; } string name = val.m_fuelItem.m_itemData.m_shared.m_name; if (!IsFuelEnabled(FuelTypeOf(name, ((Object)val.m_fuelItem).name))) { continue; } Vector3 val2 = ((Component)val).transform.position - position; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { continue; } ZDO zDO = component.GetZDO(); if (zDO == null) { continue; } float maxFuel = val.m_maxFuel; if (maxFuel <= 0f) { continue; } float num4 = zDO.GetFloat(ZDOVars.s_fuel, 0f); if (num4 >= maxFuel - 0.001f || !MatchesTrigger(_refillTrigger.Value, num4, maxFuel)) { continue; } if (value) { if (inventory.CountItems(name, -1, true) <= 0) { continue; } inventory.RemoveItem(name, 1, -1, true); num3++; } if (!component.HasOwner()) { component.ClaimOwnership(); } component.InvokeRPC("RPC_AddFuelAmount", new object[1] { maxFuel - num4 }); num2++; if (_debugLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Refilled '" + ((Object)((Component)val).gameObject).name + "' (" + name + ") " + $"from {num4:0.##}/{maxFuel:0.##} to full" + (value ? " using 1 fuel item." : " for free."))); } } if (num2 > 0 && _notifyWhenRefilled.Value && (Object)(object)MessageHud.instance != (Object)null) { string text = (value ? string.Format("{0}: topped up {1} light(s), used {2} fuel item(s)", "RefillAllTorches", num2, num3) : string.Format("{0}: topped up {1} light(s)", "RefillAllTorches", num2)); MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true); } } private bool IsFuelEnabled(FuelType type) { return type switch { FuelType.Wood => _enableWood.Value, FuelType.Resin => _enableResin.Value, FuelType.Coal => _enableCoal.Value, FuelType.Guck => _enableGuck.Value, FuelType.GreydwarfEye => _enableGreydwarfEye.Value, _ => true, }; } public static FuelType FuelTypeOf(string fuelToken, string itemName) { FuelType fuelType = FuelTypeOf(fuelToken); if (fuelType == FuelType.Other) { return FuelTypeOf(itemName); } return fuelType; } public static FuelType FuelTypeOf(string identifier) { if (string.IsNullOrEmpty(identifier)) { return FuelType.Other; } switch (identifier) { case "$item_wood": return FuelType.Wood; case "$item_resin": return FuelType.Resin; case "$item_coal": return FuelType.Coal; case "$item_guck": return FuelType.Guck; case "$item_greydwarfeye": return FuelType.GreydwarfEye; default: { string text = identifier.ToLowerInvariant(); switch (text) { case "wood": return FuelType.Wood; case "resin": return FuelType.Resin; case "coal": return FuelType.Coal; case "guck": return FuelType.Guck; case "greydwarfeye": return FuelType.GreydwarfEye; default: if (text.Contains("charcoal") && text.Contains("resin")) { return FuelType.Other; } if (text.Contains("resin")) { return FuelType.Resin; } if (text.Contains("guck")) { return FuelType.Guck; } if (text.Contains("coal")) { return FuelType.Coal; } if (text.Contains("greydwarf") || text.Contains("eye")) { return FuelType.GreydwarfEye; } if (text.Contains("wood")) { return FuelType.Wood; } return FuelType.Other; } } } } public static bool MatchesTrigger(RefillTrigger trigger, float currentFuel, float maxFuel) { return trigger switch { RefillTrigger.HalfOrLess => currentFuel <= maxFuel * 0.5f + 0.001f, RefillTrigger.OneUnitLeft => currentFuel <= 1.001f, _ => true, }; } } } namespace PocketResin { [BepInPlugin("zach.pocketresin", "PocketResin", "1.0.0")] public sealed class PocketResinPlugin : BaseUnityPlugin { private sealed class Candidate { public Fireplace Fireplace; public ZNetView NetView; public float FuelPercent; public float Distance; } public const string PluginGuid = "zach.pocketresin"; public const string PluginName = "PocketResin"; public const string PluginVersion = "1.0.0"; private const string ResinInternalName = "$item_resin"; private const float FuelEpsilon = 0.001f; private ConfigEntry<bool> _enabled; private ConfigEntry<float> _radius; private ConfigEntry<float> _checkInterval; private ConfigEntry<float> _refillBelowPercent; private ConfigEntry<float> _targetFillPercent; private ConfigEntry<int> _keepResinReserve; private ConfigEntry<int> _maxResinPerScan; private ConfigEntry<int> _maxResinPerObjectPerScan; private ConfigEntry<bool> _onlyOwnedPieces; private ConfigEntry<bool> _notifyWhenFuelAdded; private ConfigEntry<bool> _debugLogging; private ConfigEntry<KeyboardShortcut> _toggleShortcut; private float _nextScanTime; private bool _sessionPaused; private void Awake() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_01fd: Unknown result type (might be due to invalid IL or missing references) _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch for PocketResin."); _radius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Radius", 4f, new ConfigDescription("Distance in meters around your character that PocketResin checks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>())); _checkInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CheckInterval", 0.5f, new ConfigDescription("Seconds between scans. 0.50 is responsive while staying lightweight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); _refillBelowPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Fuel", "RefillBelowPercent", 1f, new ConfigDescription("Only consider a resin object when its fuel is below this fraction.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); _targetFillPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Fuel", "TargetFillPercent", 1f, new ConfigDescription("Fill toward this fraction of maximum fuel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); _keepResinReserve = ((BaseUnityPlugin)this).Config.Bind<int>("Fuel", "KeepResinReserve", 0, new ConfigDescription("Number of Resin to always keep in your inventory.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>())); _maxResinPerScan = ((BaseUnityPlugin)this).Config.Bind<int>("Fuel", "MaxResinPerScan", 0, new ConfigDescription("Maximum Resin spent in one scan. 0 = unlimited.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>())); _maxResinPerObjectPerScan = ((BaseUnityPlugin)this).Config.Bind<int>("Fuel", "MaxResinPerObjectPerScan", 0, new ConfigDescription("Maximum Resin added to one object per scan. 0 = unlimited.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>())); _onlyOwnedPieces = ((BaseUnityPlugin)this).Config.Bind<bool>("Multiplayer", "OnlyOwnedPieces", false, "If true, only refill build pieces created by your player."); _toggleShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "ToggleShortcut", new KeyboardShortcut((KeyCode)114, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Pause/unpause PocketResin for the current session. Default: Left Alt + R."); _notifyWhenFuelAdded = ((BaseUnityPlugin)this).Config.Bind<bool>("Feedback", "NotifyWhenFuelAdded", false, "Show a center-screen message when Resin is added."); _debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Feedback", "DebugLogging", false, "Write detailed refill information to the BepInEx log."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"PocketResin 1.0.0 loaded."); } private void Update() { HandleToggleShortcut(); if (_enabled.Value && !_sessionPaused && !(Time.time < _nextScanTime)) { _nextScanTime = Time.time + Mathf.Max(0.1f, _checkInterval.Value); Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead()) { RefillNearbyResinObjects(localPlayer); } } } private void HandleToggleShortcut() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (_toggleShortcut == null) { return; } KeyboardShortcut value = _toggleShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _sessionPaused = !_sessionPaused; string text = (_sessionPaused ? "OFF" : "ON"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("PocketResin: " + text)); if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, "PocketResin: " + text, 0, (Sprite)null, false, true); } } } private void RefillNearbyResinObjects(Player player) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } int num = inventory.CountItems("$item_resin", -1, true); int num2 = Mathf.Max(0, num - Mathf.Max(0, _keepResinReserve.Value)); if (num2 <= 0) { return; } int num3 = ((_maxResinPerScan.Value <= 0) ? num2 : Mathf.Min(num2, _maxResinPerScan.Value)); float num4 = Mathf.Max(0.5f, _radius.Value); float num5 = num4 * num4; Vector3 position = ((Component)player).transform.position; Fireplace[] array = Object.FindObjectsByType<Fireplace>((FindObjectsInactive)0, (FindObjectsSortMode)0); List<Candidate> list = new List<Candidate>(); Fireplace[] array2 = array; foreach (Fireplace val in array2) { if ((Object)(object)val == (Object)null || val.m_infiniteFuel) { continue; } Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude > num5 || !UsesResin(val) || (_onlyOwnedPieces.Value && !IsOwnedByPlayer(player, val))) { continue; } ZNetView val3 = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)val).GetComponentInParent<ZNetView>(); } if ((Object)(object)val3 == (Object)null || !val3.IsValid()) { continue; } ZDO zDO = val3.GetZDO(); if (zDO == null) { continue; } float maxFuel = val.m_maxFuel; if (!(maxFuel <= 0f)) { float num6 = zDO.GetFloat(ZDOVars.s_fuel, 0f); float num7 = Mathf.Clamp01(num6 / maxFuel); if (!(num7 >= Mathf.Clamp01(_refillBelowPercent.Value)) && Mathf.FloorToInt(maxFuel * Mathf.Clamp01(_targetFillPercent.Value) - num6 + 0.001f) > 0) { list.Add(new Candidate { Fireplace = val, NetView = val3, FuelPercent = num7, Distance = Mathf.Sqrt(sqrMagnitude) }); } } } list.Sort(delegate(Candidate a, Candidate b) { int num15 = a.FuelPercent.CompareTo(b.FuelPercent); return (num15 == 0) ? a.Distance.CompareTo(b.Distance) : num15; }); int num8 = 0; foreach (Candidate item in list) { if (num3 <= 0) { break; } ZDO zDO2 = item.NetView.GetZDO(); if (zDO2 == null) { continue; } float num9 = zDO2.GetFloat(ZDOVars.s_fuel, 0f); int num10 = Mathf.FloorToInt(item.Fireplace.m_maxFuel * Mathf.Clamp01(_targetFillPercent.Value) - num9 + 0.001f); if (num10 > 0) { int num11 = Mathf.Min((_maxResinPerObjectPerScan.Value <= 0) ? num10 : Mathf.Min(num10, _maxResinPerObjectPerScan.Value), num3); int num12 = inventory.CountItems("$item_resin", -1, true); int num13 = Mathf.Max(0, num12 - Mathf.Max(0, _keepResinReserve.Value)); num11 = Mathf.Min(num11, num13); if (num11 <= 0) { break; } inventory.RemoveItem("$item_resin", num11, -1, true); for (int num14 = 0; num14 < num11; num14++) { item.NetView.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } num3 -= num11; num8 += num11; if (_debugLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Refilled '{((Object)((Component)item.Fireplace).gameObject).name}' with {num11} Resin " + $"at {item.Distance:0.0}m.")); } } } if (num8 > 0 && _notifyWhenFuelAdded.Value && (Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, $"PocketResin: added {num8} Resin", 0, (Sprite)null, false, true); } } private static bool UsesResin(Fireplace fireplace) { if ((Object)(object)fireplace.m_fuelItem == (Object)null || fireplace.m_fuelItem.m_itemData == null || fireplace.m_fuelItem.m_itemData.m_shared == null) { return false; } return string.Equals(fireplace.m_fuelItem.m_itemData.m_shared.m_name, "$item_resin", StringComparison.Ordinal); } private static bool IsOwnedByPlayer(Player player, Fireplace fireplace) { Piece val = ((Component)fireplace).GetComponent<Piece>(); if ((Object)(object)val == (Object)null) { val = ((Component)fireplace).GetComponentInParent<Piece>(); } if ((Object)(object)val == (Object)null) { return true; } return val.GetCreator() == player.GetPlayerID(); } } }