Decompiled source of MoreBattery v1.2.6

MoreBattery.dll

Decompiled 3 weeks ago
using 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)"));
			}
		}
	}
}