Decompiled source of WeedKillerRefill v1.0.8

WeedKillerRefill.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WeedKillerRefill")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.8.0")]
[assembly: AssemblyInformationalVersion("1.0.8")]
[assembly: AssemblyProduct("WeedKillerRefill")]
[assembly: AssemblyTitle("WeedKillerRefill")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.8.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 WeedKillerRefill
{
	internal static class InputUtil
	{
		private static readonly Dictionary<KeyCode, Key> KeyMap = new Dictionary<KeyCode, Key>
		{
			{
				(KeyCode)97,
				(Key)15
			},
			{
				(KeyCode)98,
				(Key)16
			},
			{
				(KeyCode)99,
				(Key)17
			},
			{
				(KeyCode)100,
				(Key)18
			},
			{
				(KeyCode)101,
				(Key)19
			},
			{
				(KeyCode)102,
				(Key)20
			},
			{
				(KeyCode)103,
				(Key)21
			},
			{
				(KeyCode)104,
				(Key)22
			},
			{
				(KeyCode)105,
				(Key)23
			},
			{
				(KeyCode)106,
				(Key)24
			},
			{
				(KeyCode)107,
				(Key)25
			},
			{
				(KeyCode)108,
				(Key)26
			},
			{
				(KeyCode)109,
				(Key)27
			},
			{
				(KeyCode)110,
				(Key)28
			},
			{
				(KeyCode)111,
				(Key)29
			},
			{
				(KeyCode)112,
				(Key)30
			},
			{
				(KeyCode)113,
				(Key)31
			},
			{
				(KeyCode)114,
				(Key)32
			},
			{
				(KeyCode)115,
				(Key)33
			},
			{
				(KeyCode)116,
				(Key)34
			},
			{
				(KeyCode)117,
				(Key)35
			},
			{
				(KeyCode)118,
				(Key)36
			},
			{
				(KeyCode)119,
				(Key)37
			},
			{
				(KeyCode)120,
				(Key)38
			},
			{
				(KeyCode)121,
				(Key)39
			},
			{
				(KeyCode)122,
				(Key)40
			},
			{
				(KeyCode)48,
				(Key)50
			},
			{
				(KeyCode)49,
				(Key)41
			},
			{
				(KeyCode)50,
				(Key)42
			},
			{
				(KeyCode)51,
				(Key)43
			},
			{
				(KeyCode)52,
				(Key)44
			},
			{
				(KeyCode)53,
				(Key)45
			},
			{
				(KeyCode)54,
				(Key)46
			},
			{
				(KeyCode)55,
				(Key)47
			},
			{
				(KeyCode)56,
				(Key)48
			},
			{
				(KeyCode)57,
				(Key)49
			},
			{
				(KeyCode)32,
				(Key)1
			},
			{
				(KeyCode)304,
				(Key)51
			},
			{
				(KeyCode)303,
				(Key)52
			},
			{
				(KeyCode)306,
				(Key)55
			},
			{
				(KeyCode)305,
				(Key)56
			},
			{
				(KeyCode)308,
				(Key)53
			},
			{
				(KeyCode)307,
				(Key)54
			},
			{
				(KeyCode)9,
				(Key)3
			},
			{
				(KeyCode)301,
				(Key)72
			},
			{
				(KeyCode)8,
				(Key)65
			},
			{
				(KeyCode)13,
				(Key)2
			},
			{
				(KeyCode)27,
				(Key)60
			},
			{
				(KeyCode)273,
				(Key)63
			},
			{
				(KeyCode)274,
				(Key)64
			},
			{
				(KeyCode)276,
				(Key)61
			},
			{
				(KeyCode)275,
				(Key)62
			},
			{
				(KeyCode)277,
				(Key)70
			},
			{
				(KeyCode)127,
				(Key)71
			},
			{
				(KeyCode)278,
				(Key)68
			},
			{
				(KeyCode)279,
				(Key)69
			},
			{
				(KeyCode)280,
				(Key)67
			},
			{
				(KeyCode)281,
				(Key)66
			},
			{
				(KeyCode)282,
				(Key)94
			},
			{
				(KeyCode)283,
				(Key)95
			},
			{
				(KeyCode)284,
				(Key)96
			},
			{
				(KeyCode)285,
				(Key)97
			},
			{
				(KeyCode)286,
				(Key)98
			},
			{
				(KeyCode)287,
				(Key)99
			},
			{
				(KeyCode)288,
				(Key)100
			},
			{
				(KeyCode)289,
				(Key)101
			},
			{
				(KeyCode)290,
				(Key)102
			},
			{
				(KeyCode)291,
				(Key)103
			},
			{
				(KeyCode)292,
				(Key)104
			},
			{
				(KeyCode)293,
				(Key)105
			}
		};

		private static bool _wasDown;

		private static int _edgeFrame = -1;

		private static bool _edgeResult;

		public static bool WasPressedThisFrame(KeyCode keyCode)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			int frameCount = Time.frameCount;
			if (frameCount == _edgeFrame)
			{
				return _edgeResult;
			}
			_edgeFrame = frameCount;
			try
			{
				Keyboard current = Keyboard.current;
				if (current != null && (int)keyCode == 114 && ((ButtonControl)current.rKey).wasPressedThisFrame)
				{
					_edgeResult = true;
					_wasDown = true;
					return true;
				}
				if (current != null && KeyMap.TryGetValue(keyCode, out var value))
				{
					KeyControl val = current[value];
					if (val != null && ((ButtonControl)val).wasPressedThisFrame)
					{
						_edgeResult = true;
						_wasDown = true;
						return true;
					}
				}
			}
			catch
			{
			}
			try
			{
				if (Input.GetKeyDown(keyCode))
				{
					_edgeResult = true;
					_wasDown = true;
					return true;
				}
			}
			catch
			{
			}
			bool num = IsDown(keyCode);
			_edgeResult = num && !_wasDown;
			_wasDown = num;
			return _edgeResult;
		}

		public static bool IsDown(KeyCode keyCode)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Keyboard current = Keyboard.current;
				if (current != null)
				{
					if ((int)keyCode == 114 && ((ButtonControl)current.rKey).isPressed)
					{
						return true;
					}
					if (KeyMap.TryGetValue(keyCode, out var value))
					{
						KeyControl val = current[value];
						if (val != null && ((ButtonControl)val).isPressed)
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				if (Input.GetKey(keyCode))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		public unsafe static string TipLabel(KeyCode keyCode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected I4, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			KeyCode val = keyCode;
			if ((int)val != 13)
			{
				if ((int)val != 27)
				{
					switch (val - 303)
					{
					case 0:
					case 1:
						return "Shift";
					case 2:
					case 3:
						return "Ctrl";
					case 4:
					case 5:
						return "Alt";
					default:
						if ((int)keyCode >= 48 && (int)keyCode <= 57)
						{
							return ((char)(48 + (keyCode - 48))).ToString();
						}
						return ((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString();
					}
				}
				return "Esc";
			}
			return "Enter";
		}
	}
	[HarmonyPatch(typeof(SprayPaintItem), "ItemInteractLeftRight")]
	internal static class SprayPaintShakeRefillPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SprayPaintItem __instance, bool right)
		{
			if (!(!Plugin.Enabled.Value || right) && __instance.isWeedKillerSprayBottle && WeedKillerUtil.IsHeldByLocalPlayer(__instance) && !__instance.isSpraying)
			{
				if (Plugin.OnlyWhenEmpty.Value && !WeedKillerUtil.IsEmpty(__instance))
				{
					__instance.sprayCanShakeMeter = 1f;
					return;
				}
				WeedKillerUtil.Refill(__instance, "Shake.Q");
				WeedKillerUtil.PlayShakeFeedback(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(SprayPaintItem), "LateUpdate")]
	internal static class SprayPaintLateUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(SprayPaintItem __instance)
		{
			if (Plugin.Enabled.Value && Plugin.AllowKeyRefill.Value && __instance.isWeedKillerSprayBottle && WeedKillerUtil.IsHeldByLocalPlayer(__instance))
			{
				RefillController.TickHeld(__instance, "Spray.LateUpdate");
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
	internal static class PlayerLateUpdateRefillPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerControllerB __instance)
		{
			if (Plugin.AllowKeyRefill.Value && !((Object)(object)__instance != (Object)(object)GameNetworkManager.Instance?.localPlayerController))
			{
				RefillController.Tick("Player.LateUpdate");
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class StartOfRoundEnsurePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			WeedKillerRefillBehaviour.EnsureExists();
			Plugin.Log.LogInfo((object)"[StartOfRound.Start] refill behaviour ensured");
		}
	}
	[HarmonyPatch(typeof(HUDManager), "Start")]
	internal static class HudManagerEnsurePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			WeedKillerRefillBehaviour.EnsureExists();
		}
	}
	[HarmonyPatch(typeof(GrabbableObject), "ChargeBatteries")]
	internal static class ChargeBatteriesTankSyncPatch
	{
		[HarmonyPostfix]
		private static void Postfix(GrabbableObject __instance)
		{
			SprayPaintItem val = (SprayPaintItem)(object)((__instance is SprayPaintItem) ? __instance : null);
			if (val == null || !val.isWeedKillerSprayBottle)
			{
				return;
			}
			try
			{
				Battery insertedBattery = ((GrabbableObject)val).insertedBattery;
				if (insertedBattery != null && insertedBattery.charge > val.sprayCanTank)
				{
					val.sprayCanTank = insertedBattery.charge;
					val.sprayCanShakeMeter = 1f;
					val.tryingToUseEmptyCan = insertedBattery.charge <= Plugin.EmptyThreshold.Value;
					Plugin.V($"[ChargeBatteries] synced tank={val.sprayCanTank:0.###} from battery");
				}
			}
			catch
			{
			}
		}
	}
	[BepInPlugin("com.benhough.lethal.WeedKillerRefill", "WeedKillerRefill", "1.0.8")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.benhough.lethal.WeedKillerRefill";

		public const string ModName = "WeedKillerRefill";

		public const string ModVersion = "1.0.8";

		private readonly Harmony _harmony = new Harmony("com.benhough.lethal.WeedKillerRefill");

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> Enabled { get; private set; }

		internal static ConfigEntry<KeyCode> RefillKey { get; private set; }

		internal static ConfigEntry<float> EmptyThreshold { get; private set; }

		internal static ConfigEntry<bool> ShowControlTip { get; private set; }

		internal static ConfigEntry<bool> OnlyWhenEmpty { get; private set; }

		internal static ConfigEntry<bool> Verbose { get; private set; }

		internal static ConfigEntry<bool> AllowKeyRefill { get; private set; }

		private void Awake()
		{
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Allow refilling weed killer with the configured key.");
			RefillKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "RefillKey", (KeyCode)114, "Key to refill a held weed killer.");
			EmptyThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "EmptyThreshold", 0.05f, "Tank/battery charge at or below this counts as empty (0–1).");
			OnlyWhenEmpty = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OnlyWhenEmpty", true, "If true, refill only works when empty. If false, always tops off on key press.");
			ShowControlTip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowControlTip", true, "Show a fixed bottom-screen tip (Refill : [R]) when holding an empty weed killer.");
			Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", true, "Log holding/key/refill traces.");
			AllowKeyRefill = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowKeyRefill", true, "Allow refill with RefillKey (default R).");
			try
			{
				_harmony.PatchAll(typeof(Plugin).Assembly);
				Log.LogInfo((object)"Harmony patches applied (R key refill + ChargeBatteries sync).");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Harmony patch failed: " + ex.Message));
			}
			WeedKillerRefillBehaviour.EnsureExists();
			RefillTipHud.EnsureExists();
			Log.LogInfo((object)string.Format("{0} v{1} loaded. Press {2} to refill.", "WeedKillerRefill", "1.0.8", RefillKey.Value));
		}

		internal static void V(string msg)
		{
			if (Verbose != null && Verbose.Value)
			{
				Log.LogInfo((object)msg);
			}
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.benhough.lethal.WeedKillerRefill";

		public const string PLUGIN_NAME = "WeedKillerRefill";

		public const string PLUGIN_VERSION = "1.0.8";
	}
	internal static class RefillController
	{
		private static bool _loggedHoldingEmpty;

		private static float _nextHeartbeat;

		private static int _lastRefillFrame = -1;

		internal static void Tick(string source)
		{
			if (Plugin.Enabled != null && Plugin.Enabled.Value && Plugin.AllowKeyRefill.Value)
			{
				if (!WeedKillerUtil.TryGetHeldWeedKiller(out SprayPaintItem spray))
				{
					_loggedHoldingEmpty = false;
				}
				else
				{
					TickHeld(spray, source);
				}
			}
		}

		internal static void TickHeld(SprayPaintItem spray, string source)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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)
			if (Plugin.Enabled == null || !Plugin.Enabled.Value || (Object)(object)spray == (Object)null || !Plugin.AllowKeyRefill.Value)
			{
				return;
			}
			bool flag = WeedKillerUtil.IsEmpty(spray);
			if (flag && !_loggedHoldingEmpty)
			{
				_loggedHoldingEmpty = true;
				Plugin.Log.LogInfo((object)$"[{source}] Holding empty weed killer (tank={spray.sprayCanTank:0.###}). Press {Plugin.RefillKey.Value} to refill.");
			}
			else if (!flag)
			{
				_loggedHoldingEmpty = false;
			}
			if (Time.unscaledTime >= _nextHeartbeat)
			{
				_nextHeartbeat = Time.unscaledTime + 8f;
				Plugin.V($"[{source}] holding weedkiller empty={flag} tank={spray.sprayCanTank:0.###} keyDown={InputUtil.IsDown(Plugin.RefillKey.Value)}");
			}
			if (!InputUtil.WasPressedThisFrame(Plugin.RefillKey.Value))
			{
				return;
			}
			int frameCount = Time.frameCount;
			if (frameCount == _lastRefillFrame)
			{
				return;
			}
			_lastRefillFrame = frameCount;
			Plugin.Log.LogInfo((object)$"[{source}] Refill key {Plugin.RefillKey.Value} pressed (empty={flag}, tank={spray.sprayCanTank:0.###}).");
			if (Plugin.OnlyWhenEmpty.Value && !flag)
			{
				return;
			}
			try
			{
				WeedKillerUtil.Refill(spray, source);
				WeedKillerUtil.PlayShakeFeedback(spray);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[" + source + "] Failed to refill: " + ex.Message));
			}
		}
	}
	internal sealed class RefillTipHud : MonoBehaviour
	{
		private static RefillTipHud? _instance;

		private Canvas? _canvas;

		private TextMeshProUGUI? _label;

		private string _lastText = "";

		internal static void EnsureExists()
		{
			//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_001e: Expected O, but got Unknown
			if (!((Object)(object)_instance != (Object)null))
			{
				GameObject val = new GameObject("WeedKillerRefillTipHud");
				Object.DontDestroyOnLoad((Object)val);
				_instance = val.AddComponent<RefillTipHud>();
			}
		}

		private void Awake()
		{
			_instance = this;
			BuildUi();
		}

		private void OnDestroy()
		{
			if ((Object)(object)_instance == (Object)(object)this)
			{
				_instance = null;
			}
		}

		private void BuildUi()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 4800;
			CanvasScaler obj = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			((Component)this).gameObject.AddComponent<GraphicRaycaster>();
			GameObject val = new GameObject("RefillTipLabel", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)this).transform, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.08f);
			component.anchorMax = new Vector2(0.5f, 0.08f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(480f, 40f);
			component.anchoredPosition = Vector2.zero;
			_label = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_label).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_label).fontStyle = (FontStyles)1;
			((TMP_Text)_label).fontSize = 22f;
			((Graphic)_label).color = new Color(0.75f, 0.85f, 1f, 1f);
			((TMP_Text)_label).enableWordWrapping = false;
			((Graphic)_label).raycastTarget = false;
			((TMP_Text)_label).overflowMode = (TextOverflowModes)0;
			((TMP_Text)_label).text = "";
			TryAssignFont();
			((Behaviour)_canvas).enabled = false;
		}

		private void TryAssignFont()
		{
			if ((Object)(object)_label == (Object)null)
			{
				return;
			}
			try
			{
				HUDManager instance = HUDManager.Instance;
				TMP_FontAsset val = null;
				if (instance?.controlTipLines != null)
				{
					TextMeshProUGUI[] controlTipLines = instance.controlTipLines;
					foreach (TextMeshProUGUI val2 in controlTipLines)
					{
						if ((Object)(object)val2 != (Object)null && (Object)(object)((TMP_Text)val2).font != (Object)null)
						{
							val = ((TMP_Text)val2).font;
							break;
						}
					}
				}
				if ((Object)(object)val == (Object)null && (Object)(object)instance?.weightCounter != (Object)null)
				{
					val = ((TMP_Text)instance.weightCounter).font;
				}
				if ((Object)(object)val == (Object)null && (Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
				{
					val = TMP_Settings.defaultFontAsset;
				}
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)_label).font = val;
				}
			}
			catch
			{
			}
		}

		private void LateUpdate()
		{
			if ((Object)(object)_canvas == (Object)null || (Object)(object)_label == (Object)null)
			{
				BuildUi();
			}
			EnsureExists();
			Refresh();
		}

		private void Refresh()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_canvas == (Object)null || (Object)(object)_label == (Object)null)
			{
				return;
			}
			if (Plugin.ShowControlTip == null || !Plugin.ShowControlTip.Value || Plugin.Enabled == null || !Plugin.Enabled.Value || Plugin.AllowKeyRefill == null || !Plugin.AllowKeyRefill.Value)
			{
				SetVisible(visible: false);
				return;
			}
			if (!WeedKillerUtil.TryGetHeldWeedKiller(out SprayPaintItem spray))
			{
				SetVisible(visible: false);
				return;
			}
			if (Plugin.OnlyWhenEmpty.Value && !WeedKillerUtil.IsEmpty(spray))
			{
				SetVisible(visible: false);
				return;
			}
			TryAssignFont();
			string text = InputUtil.TipLabel(Plugin.RefillKey.Value);
			string text2 = "Refill : [" + text + "]";
			if (text2 != _lastText)
			{
				((TMP_Text)_label).text = text2;
				_lastText = text2;
			}
			SetVisible(visible: true);
		}

		private void SetVisible(bool visible)
		{
			if ((Object)(object)_canvas != (Object)null && ((Behaviour)_canvas).enabled != visible)
			{
				((Behaviour)_canvas).enabled = visible;
			}
			if ((Object)(object)_label != (Object)null && ((Component)_label).gameObject.activeSelf != visible)
			{
				((Component)_label).gameObject.SetActive(visible);
			}
		}
	}
	internal sealed class WeedKillerRefillBehaviour : MonoBehaviour
	{
		private static WeedKillerRefillBehaviour? _instance;

		private float _nextAliveLog;

		internal static void EnsureExists()
		{
			//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_001e: Expected O, but got Unknown
			if (!((Object)(object)_instance != (Object)null))
			{
				GameObject val = new GameObject("WeedKillerRefill");
				Object.DontDestroyOnLoad((Object)val);
				_instance = val.AddComponent<WeedKillerRefillBehaviour>();
				RefillTipHud.EnsureExists();
				Plugin.Log.LogInfo((object)"[Behaviour] created");
			}
		}

		private void Awake()
		{
			_instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_instance == (Object)(object)this)
			{
				_instance = null;
			}
		}

		private void LateUpdate()
		{
			if (Time.unscaledTime >= _nextAliveLog)
			{
				_nextAliveLog = Time.unscaledTime + 30f;
				Plugin.V("[Behaviour] LateUpdate alive");
			}
			RefillController.Tick("Behaviour.LateUpdate");
		}
	}
	internal static class WeedKillerUtil
	{
		public static bool TryGetHeldWeedKiller(out SprayPaintItem spray)
		{
			spray = null;
			try
			{
				PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
				if ((Object)(object)val == (Object)null || val.isPlayerDead)
				{
					return false;
				}
				GrabbableObject val2 = val.currentlyHeldObject;
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = val.currentlyHeldObjectServer;
				}
				SprayPaintItem val3 = (SprayPaintItem)(object)((val2 is SprayPaintItem) ? val2 : null);
				if (val3 == null)
				{
					return false;
				}
				if (!val3.isWeedKillerSprayBottle)
				{
					return false;
				}
				spray = val3;
				return true;
			}
			catch
			{
				return false;
			}
		}

		public static bool IsHeldByLocalPlayer(SprayPaintItem spray)
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null || (Object)(object)spray == (Object)null)
			{
				return false;
			}
			if (!((Object)(object)(val.currentlyHeldObject ?? val.currentlyHeldObjectServer) == (Object)(object)spray))
			{
				return (Object)(object)((GrabbableObject)spray).playerHeldBy == (Object)(object)val;
			}
			return true;
		}

		public static bool IsEmpty(SprayPaintItem spray)
		{
			float value = Plugin.EmptyThreshold.Value;
			if (spray.sprayCanTank <= value)
			{
				return true;
			}
			if (spray.tryingToUseEmptyCan)
			{
				return true;
			}
			try
			{
				Battery insertedBattery = ((GrabbableObject)spray).insertedBattery;
				if (insertedBattery != null && (insertedBattery.empty || insertedBattery.charge <= value))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		public static void Refill(SprayPaintItem spray, string source)
		{
			spray.sprayCanTank = 1f;
			spray.sprayCanShakeMeter = 1f;
			spray.tryingToUseEmptyCan = false;
			try
			{
				if ((Object)(object)spray.sprayCanNeedsShakingParticle != (Object)null && spray.sprayCanNeedsShakingParticle.isPlaying)
				{
					spray.sprayCanNeedsShakingParticle.Stop(true, (ParticleSystemStopBehavior)0);
				}
			}
			catch
			{
			}
			try
			{
				Battery insertedBattery = ((GrabbableObject)spray).insertedBattery;
				if (insertedBattery != null)
				{
					insertedBattery.charge = 1f;
					insertedBattery.empty = false;
					((GrabbableObject)spray).insertedBattery = insertedBattery;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Battery refill partial: " + ex.Message));
			}
			try
			{
				if ((Object)(object)((GrabbableObject)spray).itemProperties != (Object)null && ((GrabbableObject)spray).itemProperties.requiresBattery)
				{
					((GrabbableObject)spray).SyncBatteryServerRpc(100);
				}
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("SyncBatteryServerRpc failed: " + ex2.Message));
			}
			try
			{
				((GrabbableObject)spray).ChargeBatteries();
			}
			catch
			{
			}
			try
			{
				((GrabbableObject)spray).SetControlTipsForItem();
			}
			catch
			{
			}
			Plugin.Log.LogInfo((object)$"[{source}] Refilled: tank={spray.sprayCanTank:0.###} shake={spray.sprayCanShakeMeter:0.###} tryingEmpty={spray.tryingToUseEmptyCan}");
		}

		public static void PlayShakeFeedback(SprayPaintItem spray)
		{
			try
			{
				if ((Object)(object)((GrabbableObject)spray).playerHeldBy != (Object)null)
				{
					((GrabbableObject)spray).playerHeldBy.playerBodyAnimator.SetTrigger("shakeItem");
				}
			}
			catch
			{
			}
			try
			{
				if (spray.sprayCanShakeSFX != null && spray.sprayCanShakeSFX.Length != 0 && (Object)(object)spray.sprayAudio != (Object)null)
				{
					RoundManager.PlayRandomClip(spray.sprayAudio, spray.sprayCanShakeSFX, true, 1f, 0, 1000);
					if ((Object)(object)spray.sprayCanShakeEmptySFX != (Object)null)
					{
						WalkieTalkie.TransmitOneShotAudio(spray.sprayAudio, spray.sprayCanShakeEmptySFX, 1f);
					}
				}
			}
			catch
			{
			}
		}
	}
}