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 MoreBattery v1.2.6
MoreBattery.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CSync.Lib; using CSync.Util; using GameNetcodeStuff; using HarmonyLib; using MoreBatteryMod.Patches; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace MoreBatteryMod { [BepInPlugin("MoreBattery", "MoreBattery", "1.2.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static Plugin Instance; internal ManualLogSource Log; private Harmony harmony; public static MoreBatteryConfig ConfigInstance; public static ConfigEntry<bool> ShowDebugUI; public static ConfigEntry<bool> ForceAntiCheatTest; private static GameObject hudGo; private void Awake() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } Log = ((BaseUnityPlugin)this).Logger; ConfigInstance = new MoreBatteryConfig(((BaseUnityPlugin)this).Config); ShowDebugUI = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDebugUI", false, "If true, shows a basic text overlay on the screen when holding or using a battery-operated item."); Log.LogInfo((object)("ShowDebugUI bound. Value = " + ShowDebugUI.Value)); ForceAntiCheatTest = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ForceAntiCheatTest", false, "[TESTING ONLY] If true, forces the anti-cheat fallback as if you are in a vanilla lobby (multiplier locked to 1.0x). Leave false for normal gameplay."); Log.LogInfo((object)("ForceAntiCheatTest bound. Value = " + ForceAntiCheatTest.Value)); try { harmony = new Harmony("MoreBattery"); harmony.PatchAll(typeof(MoreBatteryModPatches)); SceneManager.sceneLoaded += OnSceneLoaded; Log.LogInfo((object)"MoreBattery v1.2.6 with CSync networking support loaded successfully!"); } catch (Exception ex) { Log.LogError((object)("Failed to apply patches: " + ex.ToString())); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if ((Object)(object)hudGo == (Object)null) { Log.LogInfo((object)("[MoreBattery] Spawning HUD GameObject on scene loaded: " + ((Scene)(ref scene)).name)); try { hudGo = new GameObject("MoreBatteryHUD"); Object.DontDestroyOnLoad((Object)(object)hudGo); hudGo.AddComponent<MoreBatteryHUD>(); Log.LogInfo((object)"[MoreBattery] Successfully spawned HUD GameObject!"); } catch (Exception ex) { Log.LogError((object)("[MoreBattery] Failed to spawn HUD GameObject: " + ex.ToString())); } } } } public class MoreBatteryHUD : MonoBehaviour { private bool _onGuiLoggedOnce; private bool _hudLoggedOnce; private void OnGUI() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_063f: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) if (!_onGuiLoggedOnce) { Plugin.Instance.Log.LogInfo((object)("[MoreBattery HUD] Component OnGUI first call! ShowDebugUI = " + ((Plugin.ShowDebugUI != null) ? Plugin.ShowDebugUI.Value.ToString() : "null"))); _onGuiLoggedOnce = true; } if (Plugin.ShowDebugUI == null || !Plugin.ShowDebugUI.Value) { return; } int num = 340; int num2 = 120; int num3 = 10; int num4 = 10; if (!_hudLoggedOnce) { Plugin.Instance.Log.LogInfo((object)("[MoreBattery HUD] Component OnGUI drawing at (" + num3 + "," + num4 + ") size " + num + "x" + num2)); _hudLoggedOnce = true; } Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(0f, 0f, 0f, 0.75f); GUI.Box(new Rect((float)num3, (float)num4, (float)num, (float)num2), ""); GUI.backgroundColor = backgroundColor; GUIStyle val = new GUIStyle(GUI.skin.label); val.fontStyle = (FontStyle)1; val.normal.textColor = Color.yellow; val.fontSize = 14; GUIStyle val2 = new GUIStyle(GUI.skin.label); val2.normal.textColor = Color.white; val2.fontSize = 12; GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 10), (float)(num - 30), 20f), "MoreBattery Debug Info", val); PlayerControllerB localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer == (Object)null) { return; } GrabbableObject activeBatteryItem = GetActiveBatteryItem(localPlayer); if ((Object)(object)activeBatteryItem == (Object)null || (Object)(object)activeBatteryItem.itemProperties == (Object)null) { GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 25), (float)(num - 30), 18f), "Status: Active & Loaded (No Item)", val2); string text = (((Object)(object)localPlayer.currentlyHeldObject != (Object)null) ? ((Object)localPlayer.currentlyHeldObject).name : "null"); string text2 = (((Object)(object)localPlayer.ItemOnlySlot != (Object)null) ? ((Object)localPlayer.ItemOnlySlot).name : "null"); GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 43), (float)(num - 30), 18f), "Held: " + text + " | Utility: " + text2, val2); string text3 = (((Object)(object)localPlayer.pocketedFlashlight != (Object)null) ? ((Object)localPlayer.pocketedFlashlight).name : "null"); GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 61), (float)(num - 30), 18f), "Pocketed Flashlight: " + text3, val2); string text4 = "null"; if (localPlayer.ItemSlots != null && localPlayer.currentItemSlot >= 0 && localPlayer.currentItemSlot < localPlayer.ItemSlots.Length) { GrabbableObject val3 = localPlayer.ItemSlots[localPlayer.currentItemSlot]; text4 = (((Object)(object)val3 != (Object)null) ? ((Object)val3).name : "null"); } GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 79), (float)(num - 30), 18f), "Slot " + localPlayer.currentItemSlot + ": " + text4, val2); string text5 = "None"; if (localPlayer.ItemSlots != null) { for (int i = 0; i < localPlayer.ItemSlots.Length; i++) { if ((Object)(object)localPlayer.ItemSlots[i] != (Object)null && localPlayer.ItemSlots[i] is FlashlightItem) { text5 = "Slot " + i + ": " + ((Object)localPlayer.ItemSlots[i]).name + " (Used: " + localPlayer.ItemSlots[i].isBeingUsed + ")"; break; } } } GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 97), (float)(num - 30), 18f), "Found in Inventory: " + text5, val2); } else { Item itemProperties = activeBatteryItem.itemProperties; float num5 = itemProperties.batteryUsage; if (MoreBatteryModPatches.OriginalDurations.TryGetValue(itemProperties, out var value)) { num5 = value; } float batteryUsage = itemProperties.batteryUsage; float num6 = ((activeBatteryItem.insertedBattery != null) ? (activeBatteryItem.insertedBattery.charge * 100f) : 0f); float num7 = ((activeBatteryItem.insertedBattery != null) ? (activeBatteryItem.insertedBattery.charge * batteryUsage) : 0f); GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 30), (float)(num - 30), 20f), "Item Name: " + itemProperties.itemName, val2); GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 48), (float)(num - 30), 20f), "Vanilla Max Duration: " + num5.ToString("F1") + " seconds", val2); GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 66), (float)(num - 30), 20f), "Current Max Duration: " + batteryUsage.ToString("F1") + " seconds (" + (batteryUsage / num5).ToString("F2") + "x)", val2); string text6 = "Battery Charge: " + num6.ToString("F1") + "% (approx. " + num7.ToString("F1") + "s left)"; if (activeBatteryItem.insertedBattery != null && activeBatteryItem.insertedBattery.empty) { text6 = "Battery Charge: EMPTY (0.0s)"; } GUI.Label(new Rect((float)(num3 + 15), (float)(num4 + 84), (float)(num - 30), 20f), text6, val2); } } private PlayerControllerB GetLocalPlayer() { if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) { return GameNetworkManager.Instance.localPlayerController; } if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.localPlayerController != (Object)null) { return StartOfRound.Instance.localPlayerController; } return null; } private GrabbableObject GetActiveBatteryItem(PlayerControllerB player) { if ((Object)(object)player.currentlyHeldObject != (Object)null && (Object)(object)player.currentlyHeldObject.itemProperties != (Object)null && player.currentlyHeldObject.itemProperties.requiresBattery) { return player.currentlyHeldObject; } if ((Object)(object)player.ItemOnlySlot != (Object)null && (Object)(object)player.ItemOnlySlot.itemProperties != (Object)null && player.ItemOnlySlot.itemProperties.requiresBattery) { return player.ItemOnlySlot; } if ((Object)(object)player.pocketedFlashlight != (Object)null && (Object)(object)player.pocketedFlashlight.itemProperties != (Object)null && player.pocketedFlashlight.itemProperties.requiresBattery) { return player.pocketedFlashlight; } if (player.ItemSlots != null && player.currentItemSlot >= 0 && player.currentItemSlot < player.ItemSlots.Length) { GrabbableObject val = player.ItemSlots[player.currentItemSlot]; if ((Object)(object)val != (Object)null && (Object)(object)val.itemProperties != (Object)null && val.itemProperties.requiresBattery) { return val; } } if (player.ItemSlots != null) { GrabbableObject result = null; for (int i = 0; i < player.ItemSlots.Length; i++) { GrabbableObject val2 = player.ItemSlots[i]; if ((Object)(object)val2 != (Object)null && (Object)(object)val2.itemProperties != (Object)null && val2.itemProperties.requiresBattery) { if (val2.isBeingUsed) { return val2; } result = val2; } } return result; } return null; } } public class MoreBatteryConfig : SyncedConfig2<MoreBatteryConfig> { public bool Synced; [SyncedEntryField] public SyncedEntry<float> BatteryMultiplier; [SyncedEntryField] public SyncedEntry<bool> ApplyToAllFlashlights; [SyncedEntryField] public SyncedEntry<string> CustomItemNames; [SyncedEntryField] public SyncedEntry<string> ExcludedItemNames; public MoreBatteryConfig(ConfigFile cfg) : base("MoreBattery") { EventHandler eventHandler = delegate { Synced = true; Plugin.Instance.Log.LogInfo((object)"MoreBattery: Configuration successfully synchronized with host!"); }; base.InitialSyncCompleted += eventHandler; BatteryMultiplier = Extensions.BindSyncedEntry<float>(cfg, "General", "BatteryMultiplier", 1.5f, "The multiplier applied to the battery life (duration in seconds) of flashlights and light sources. 1.0 keeps it vanilla."); ApplyToAllFlashlights = Extensions.BindSyncedEntry<bool>(cfg, "General", "ApplyToAllFlashlights", true, "If true, automatically applies the battery multiplier to all items inheriting from FlashlightItem."); CustomItemNames = Extensions.BindSyncedEntry<string>(cfg, "General", "CustomItemNames", "Lantern,Elite Flashlight,EliteFlashlight", "A comma-separated list of additional item names (case-insensitive) to apply the battery multiplier to."); ExcludedItemNames = Extensions.BindSyncedEntry<string>(cfg, "General", "ExcludedItemNames", "", "A comma-separated list of item names to exclude from receiving the battery multiplier."); ConfigManager.Register<MoreBatteryConfig>((SyncedConfig2<MoreBatteryConfig>)this); } } public static class PluginInfo { public const string PLUGIN_GUID = "MoreBattery"; public const string PLUGIN_NAME = "MoreBattery"; public const string PLUGIN_VERSION = "1.2.6"; } } namespace MoreBatteryMod.Patches { [HarmonyPatch(typeof(GrabbableObject))] public static class MoreBatteryModPatches { public static readonly Dictionary<Item, float> OriginalDurations = new Dictionary<Item, float>(); private static readonly HashSet<Item> modifiedItems = new HashSet<Item>(); private static readonly HashSet<string> customNamesList = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly HashSet<string> excludedNamesList = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static bool listsInitialized = false; private static void InitializeLists() { customNamesList.Clear(); excludedNamesList.Clear(); string value = Plugin.ConfigInstance.CustomItemNames.Value; if (!string.IsNullOrEmpty(value)) { string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string text2 = text.Trim(); if (!string.IsNullOrEmpty(text2)) { customNamesList.Add(text2); } } } string value2 = Plugin.ConfigInstance.ExcludedItemNames.Value; if (!string.IsNullOrEmpty(value2)) { string[] array2 = value2.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text3 in array2) { string text4 = text3.Trim(); if (!string.IsNullOrEmpty(text4)) { excludedNamesList.Add(text4); } } } listsInitialized = true; } [HarmonyPostfix] [HarmonyPatch("Start")] public static void MoreBatteryPatch(GrabbableObject __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.itemProperties == (Object)null) { return; } Item itemProperties = __instance.itemProperties; if (!itemProperties.requiresBattery) { return; } if (!OriginalDurations.ContainsKey(itemProperties)) { OriginalDurations[itemProperties] = itemProperties.batteryUsage; } if (modifiedItems.Contains(itemProperties)) { return; } if (!listsInitialized) { InitializeLists(); } bool flag = false; if (Plugin.ConfigInstance.ApplyToAllFlashlights.Value && __instance is FlashlightItem) { flag = true; } if (!flag && !string.IsNullOrEmpty(itemProperties.itemName) && customNamesList.Contains(itemProperties.itemName)) { flag = true; } if (flag && !string.IsNullOrEmpty(itemProperties.itemName) && excludedNamesList.Contains(itemProperties.itemName)) { flag = false; } if (flag) { float batteryUsage = itemProperties.batteryUsage; float num = Plugin.ConfigInstance.BatteryMultiplier.Value; bool flag2 = !Plugin.ConfigInstance.Synced; bool flag3 = Plugin.ForceAntiCheatTest != null && Plugin.ForceAntiCheatTest.Value; if (flag2 || flag3) { string text = (flag3 ? "ForceAntiCheatTest is enabled" : "lobby is not synced (vanilla host)"); Plugin.Instance.Log.LogInfo((object)("[AntiCheat] Reverting multiplier to 1.0x — " + text)); num = 1f; } itemProperties.batteryUsage = batteryUsage * num; modifiedItems.Add(itemProperties); Plugin.Instance.Log.LogInfo((object)("Applied battery multiplier of " + num + "x to item: '" + itemProperties.itemName + "' (Original battery life: " + batteryUsage + "s -> New battery life: " + itemProperties.batteryUsage + "s)")); } } } }