Decompiled source of GroupCommandsToggle v1.0.0

GroupCommandsToggle.dll

Decompiled 10 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("GroupCommandsToggle")]
[assembly: AssemblyDescription("Hides the Erenshor party frame's quick-command buttons until a modifier key is held")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GroupCommandsToggle")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3b8f5d14-6c27-4e90-a1d3-5f80b4c2e7a9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GroupCommandsToggle;

[BepInPlugin("com.erenshor.groupcommandstoggle", "Group Commands Toggle", "1.0.0")]
public class GroupCommandsTogglePlugin : BaseUnityPlugin
{
	public enum DumpKeyBinding
	{
		None,
		F1,
		F2,
		F3,
		F4,
		F5,
		F6,
		F7,
		F8,
		F9,
		F10,
		F11,
		F12
	}

	public const string PluginGuid = "com.erenshor.groupcommandstoggle";

	public const string PluginName = "Group Commands Toggle";

	public const string PluginVersion = "1.0.0";

	private static readonly HashSet<string> ButtonLabels = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Attack", "Assist MA", "Follow", "Pull Target", "Guard", "Run Away", "Invis Group", "Manage Roles", "Loot Distribution" };

	private const string AutoPullPrefix = "Auto Pull";

	private const int MinLabelsForCandidate = 7;

	private static ManualLogSource _log;

	private static ConfigEntry<string> _cfgRevealKey;

	private static ConfigEntry<string> _cfgRevealKeyAlt;

	private static KeyCode _revealKey;

	private static KeyCode _revealKeyAlt;

	private static ConfigEntry<string> _cfgContainerOverride;

	private static ConfigEntry<DumpKeyBinding> _cfgDumpKey;

	private static ConfigEntry<bool> _cfgDiagnostics;

	private static ConfigEntry<bool> _cfgHideKickButtons;

	private static readonly List<CanvasGroup> _kickGroups = new List<CanvasGroup>();

	private static bool _kickBound;

	private static bool _kickHidden;

	private static readonly List<GameObject> _targets = new List<GameObject>();

	private static string _lastCandidateSig = "<none>";

	private static readonly Dictionary<int, CanvasGroup> _groupCache = new Dictionary<int, CanvasGroup>();

	private static RaidLootDist _groupLoot;

	private static GameObject _lootButton;

	private static bool _errorLogged;

	private static bool _weAreHiding;

	private static bool _loggedFirstDecision;

	private static bool _lastReveal;

	private static float _rediscoverTimer;

	private static float _statusTimer;

	private const int DriverObjectUpdate = 0;

	private const int DriverObjectLate = 1;

	private const int DriverHarmony = 2;

	private static readonly string[] DriverNames = new string[3] { "driverObject.Update", "driverObject.LateUpdate", "harmony:SimPlayerGrouping.Update" };

	private static readonly bool[] _driverSeen = new bool[3];

	private static bool _lateDriverAlive;

	private static int _lastTickFrame = -1;

	private static GameObject _driverObject;

	private static bool _driverSummaryLogged;

	private static float _driverSummaryTimer = 3f;

	private static bool _appliedOnce;

	private static bool _lastApplied;

	private static bool _interferenceLogged;

	private static KeyCode ToKeyCode(DumpKeyBinding binding)
	{
		if (binding == DumpKeyBinding.None)
		{
			return (KeyCode)0;
		}
		return (KeyCode)(282 + (binding - 1));
	}

	private void Awake()
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Expected O, but got Unknown
		_log = ((BaseUnityPlugin)this).Logger;
		_cfgRevealKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RevealKey", "LeftShift", "Hold this to reveal the group command buttons. Leave blank for none.\nLeftShift matches the key that already shows the Shift+1..8 hotkey\nlabels, so the buttons and their shortcuts appear together.\n\nAny key works. One example of each naming style:\n  LeftShift    a modifier (also LeftControl, LeftAlt, Tab, Space)\n  X            a letter\n  Alpha1       the number row, NOT plain 1\n  Keypad0      the number pad, NOT Numpad0\n  F1           a function key\n  Mouse2       a mouse button, counting from 0");
		_cfgRevealKeyAlt = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RevealKeyAlt", "RightShift", "A second key that does the same thing. Leave blank for none.");
		_revealKey = ParseKey(_cfgRevealKey.Value, "RevealKey");
		_revealKeyAlt = ParseKey(_cfgRevealKeyAlt.Value, "RevealKeyAlt");
		_cfgHideKickButtons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideKickButtons", true, "Hide the X kick buttons beside each party member as well. These fade rather than switch off: the game turns them on and off itself as members join and leave, so switching them off here would fight it and could leave a kick button beside an empty slot.");
		_cfgDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Troubleshooting", "Diagnostics", false, "Logs what the mod found and every time the buttons show or hide. Only worth turning on if something looks wrong and you are sending me a log.");
		_cfgDumpKey = ((BaseUnityPlugin)this).Config.Bind<DumpKeyBinding>("Troubleshooting", "DumpKey", DumpKeyBinding.F9, "Press in-game to log every group-command panel found, with full paths\nand live state. Does nothing unless Diagnostics is on, so this key is\nleft alone for whatever else you use it for.");
		_cfgContainerOverride = ((BaseUnityPlugin)this).Config.Bind<string>("Troubleshooting", "ContainerNameOverride", "", "Leave empty for automatic detection. To force a specific object, put its exact name here -- press DumpKey to list every candidate with its path.");
		_log.LogInfo((object)$"Active. Group command buttons hidden until {_revealKey} or {_revealKeyAlt} is held. Settings apply on restart.");
		ManualLogSource log = _log;
		object[] obj = new object[6]
		{
			((Object)((Component)this).gameObject).name,
			((Component)this).gameObject.activeSelf,
			((Component)this).gameObject.activeInHierarchy,
			((Behaviour)this).enabled,
			((Object)((Component)this).gameObject).hideFlags,
			null
		};
		Scene scene = ((Component)this).gameObject.scene;
		obj[5] = ((Scene)(ref scene)).name;
		log.LogInfo((object)string.Format("Host object: name=\"{0}\" activeSelf={1} activeInHierarchy={2} enabled={3} hideFlags={4} scene=\"{5}\"", obj));
		try
		{
			_driverObject = new GameObject("GroupCommandsToggle_Driver");
			Object.DontDestroyOnLoad((Object)(object)_driverObject);
			_driverObject.AddComponent<ToggleDriver>();
			_log.LogInfo((object)"Spawned own driver GameObject.");
		}
		catch (Exception ex)
		{
			_log.LogError((object)("Could not spawn own driver GameObject: " + ex));
		}
		try
		{
			Harmony.CreateAndPatchAll(typeof(GroupCommandsTogglePlugin), (string)null);
			_log.LogInfo((object)"Harmony patch applied to SimPlayerGrouping.Update.");
		}
		catch (Exception ex2)
		{
			_log.LogError((object)("Harmony patch failed: " + ex2));
		}
	}

	internal static void PumpDriverObjectUpdate()
	{
		Pump(0, isLate: false);
	}

	internal static void PumpDriverObjectLateUpdate()
	{
		Pump(1, isLate: true);
	}

	[HarmonyPatch(typeof(SimPlayerGrouping), "Update")]
	[HarmonyPostfix]
	public static void SimPlayerGrouping_Update_Postfix()
	{
		Pump(2, isLate: false);
	}

	internal static void Pump(int driver, bool isLate)
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!_driverSeen[driver])
			{
				_driverSeen[driver] = true;
				_log.LogInfo((object)("Driver alive: " + DriverNames[driver]));
			}
			if (isLate)
			{
				_lateDriverAlive = true;
			}
			else if (_lateDriverAlive)
			{
				return;
			}
			if (_lastTickFrame != Time.frameCount)
			{
				_lastTickFrame = Time.frameCount;
				if (_cfgDiagnostics.Value && _cfgDumpKey.Value != DumpKeyBinding.None && Input.GetKeyDown(ToKeyCode(_cfgDumpKey.Value)))
				{
					DumpAllCandidates();
				}
				Tick();
			}
		}
		catch (Exception ex)
		{
			if (!_errorLogged)
			{
				_errorLogged = true;
				_log.LogError((object)("Group Commands Toggle hit an error; reported once. " + ex));
			}
		}
	}

	private static void Tick()
	{
		if (!_driverSummaryLogged)
		{
			_driverSummaryTimer -= Time.unscaledDeltaTime;
			if (_driverSummaryTimer <= 0f)
			{
				_driverSummaryLogged = true;
				StringBuilder stringBuilder = new StringBuilder();
				for (int i = 0; i < _driverSeen.Length; i++)
				{
					if (_driverSeen[i])
					{
						if (stringBuilder.Length > 0)
						{
							stringBuilder.Append(", ");
						}
						stringBuilder.Append(DriverNames[i]);
					}
				}
				_log.LogInfo((object)string.Format("Live drivers: {0}. LateUpdate driver alive: {1}.", (stringBuilder.Length == 0) ? "<none>" : stringBuilder.ToString(), _lateDriverAlive));
			}
		}
		bool editUIMode = GameData.EditUIMode;
		bool playerTyping = GameData.PlayerTyping;
		bool flag = IsRevealKeyHeld();
		bool flag2 = editUIMode || (!playerTyping && flag);
		EnsureKickButtons();
		ApplyKickVisibility(flag2);
		if (TargetsLost())
		{
			_rediscoverTimer -= Time.unscaledDeltaTime;
			if (_rediscoverTimer <= 0f)
			{
				_rediscoverTimer = 1f;
				_loggedFirstDecision = false;
				Discover();
			}
		}
		BindLootButton();
		if (_targets.Count == 0)
		{
			LogUnboundStatus();
			return;
		}
		DetectInterference();
		SetTargetsVisible(flag2);
		_weAreHiding = !flag2;
		if (_cfgDiagnostics.Value && (!_loggedFirstDecision || flag2 != _lastReveal))
		{
			_loggedFirstDecision = true;
			_log.LogInfo((object)string.Format("reveal={0} (editUI={1} typing={2} keyHeld={3}) -- {4} button(s), first is \"{5}\" activeInHierarchy={6}", flag2, editUIMode, playerTyping, flag, _targets.Count, ((Object)(object)_targets[0] != (Object)null) ? ((Object)_targets[0]).name : "<destroyed>", ((Object)(object)_targets[0] != (Object)null) ? _targets[0].activeInHierarchy.ToString() : "n/a"));
		}
		_lastReveal = flag2;
	}

	private static void EnsureKickButtons()
	{
		if (_kickBound)
		{
			for (int i = 0; i < _kickGroups.Count; i++)
			{
				if ((Object)(object)_kickGroups[i] == (Object)null)
				{
					_kickBound = false;
					_kickGroups.Clear();
					break;
				}
			}
		}
		if (_kickBound)
		{
			return;
		}
		SimPlayerGrouping simPlayerGrouping = GameData.SimPlayerGrouping;
		if ((Object)(object)simPlayerGrouping == (Object)null)
		{
			return;
		}
		GameObject[] array = (GameObject[])(object)new GameObject[4] { simPlayerGrouping.D1, simPlayerGrouping.D2, simPlayerGrouping.D3, simPlayerGrouping.D4 };
		foreach (GameObject val in array)
		{
			if ((Object)(object)val != (Object)null)
			{
				_kickGroups.Add(GetGroup(val));
			}
		}
		if (_kickGroups.Count != 0)
		{
			_kickBound = true;
			_log.LogInfo((object)("Bound " + _kickGroups.Count + " kick button(s) (SimPlayerGrouping D1-D4). These fade rather than deactivate, so the game keeps full control of which slots actually have a kick button."));
		}
	}

	private static void ApplyKickVisibility(bool reveal)
	{
		if (!_cfgHideKickButtons.Value)
		{
			RestoreKickButtons();
			return;
		}
		float num = (reveal ? 1f : 0f);
		for (int i = 0; i < _kickGroups.Count; i++)
		{
			CanvasGroup val = _kickGroups[i];
			if (!((Object)(object)val == (Object)null) && val.alpha != num)
			{
				val.alpha = num;
				val.interactable = reveal;
				val.blocksRaycasts = reveal;
			}
		}
		_kickHidden = !reveal;
	}

	private static void RestoreKickButtons()
	{
		if (!_kickHidden)
		{
			return;
		}
		for (int i = 0; i < _kickGroups.Count; i++)
		{
			CanvasGroup val = _kickGroups[i];
			if (!((Object)(object)val == (Object)null))
			{
				val.alpha = 1f;
				val.interactable = true;
				val.blocksRaycasts = true;
			}
		}
		_kickHidden = false;
	}

	private static void DetectInterference()
	{
		if (!_cfgDiagnostics.Value || !_appliedOnce || _interferenceLogged)
		{
			return;
		}
		for (int i = 0; i < _targets.Count; i++)
		{
			GameObject val = _targets[i];
			if (!((Object)(object)val == (Object)null) && val.activeSelf != _lastApplied)
			{
				_interferenceLogged = true;
				_log.LogWarning((object)$"Another script is fighting us for \"{((Object)val).name}\": we set activeSelf={_lastApplied}, it is now {val.activeSelf}. Reported once. If this appears, hiding needs to happen later in the frame than whatever is re-enabling it.");
				break;
			}
		}
	}

	private static bool TargetsLost()
	{
		if (_targets.Count == 0)
		{
			return true;
		}
		for (int i = 0; i < _targets.Count; i++)
		{
			if ((Object)(object)_targets[i] == (Object)null)
			{
				return true;
			}
		}
		return false;
	}

	private static void BindLootButton()
	{
		if ((Object)(object)_lootButton != (Object)null || _targets.Count == 0)
		{
			return;
		}
		_groupLoot = GameData.GroupLootDist;
		if ((Object)(object)_groupLoot == (Object)null || (Object)(object)_groupLoot.LootDistButton == (Object)null)
		{
			return;
		}
		Transform transform = ((TMP_Text)_groupLoot.LootDistButton).transform;
		for (int i = 0; i < _targets.Count; i++)
		{
			GameObject val = _targets[i];
			if ((Object)(object)val != (Object)null && transform.IsChildOf(val.transform))
			{
				_lootButton = val;
				if (_cfgDiagnostics.Value)
				{
					_log.LogInfo((object)("\"" + ((Object)val).name + "\" is the Loot Distribution button, which the game reuses as its window's Cancel control. It stays visible while that window is open."));
				}
				break;
			}
		}
	}

	private static bool IsRevealKeyHeld()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		if ((int)_revealKey != 0 && Input.GetKey(_revealKey))
		{
			return true;
		}
		if ((int)_revealKeyAlt != 0)
		{
			return Input.GetKey(_revealKeyAlt);
		}
		return false;
	}

	private static KeyCode ParseKey(string name, string settingName)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(name) || name.Trim().Length == 0)
		{
			return (KeyCode)0;
		}
		try
		{
			return (KeyCode)Enum.Parse(typeof(KeyCode), name.Trim(), ignoreCase: true);
		}
		catch
		{
			_log.LogWarning((object)("\"" + name + "\" is not a key name, so " + settingName + " does nothing. Try LeftShift, RightControl, LeftAlt, Tab, and so on."));
			return (KeyCode)0;
		}
	}

	private static List<Transform> FindCandidates()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<int, Transform> dictionary = new Dictionary<int, Transform>();
		List<Transform> list = new List<Transform>();
		TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
		foreach (TMP_Text val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Scene scene = ((Component)val).gameObject.scene;
			if (!((Scene)(ref scene)).IsValid() || !IsStackLabel(val.text))
			{
				continue;
			}
			Transform parent = val.transform.parent;
			int num = 0;
			while ((Object)(object)parent != (Object)null && num < 4)
			{
				if (CountStackLabels(parent) >= 7)
				{
					int instanceID = ((Object)parent).GetInstanceID();
					if (!dictionary.ContainsKey(instanceID))
					{
						dictionary[instanceID] = parent;
						list.Add(parent);
					}
					break;
				}
				parent = parent.parent;
				num++;
			}
		}
		return list;
	}

	private static void Discover()
	{
		_targets.Clear();
		_lootButton = null;
		List<Transform> list = FindCandidates();
		string text = SignatureOf(list);
		if (text != _lastCandidateSig)
		{
			_lastCandidateSig = text;
			LogCandidates(list);
		}
		if (list.Count == 0)
		{
			return;
		}
		if (!string.IsNullOrEmpty(_cfgContainerOverride.Value))
		{
			string text2 = _cfgContainerOverride.Value.Trim();
			foreach (Transform item in list)
			{
				if (string.Equals(((Object)item).name, text2, StringComparison.Ordinal))
				{
					Accept(item, "ContainerNameOverride");
					return;
				}
			}
			_log.LogWarning((object)("ContainerNameOverride \"" + text2 + "\" matched no candidate; using automatic detection."));
		}
		Transform val = null;
		foreach (Transform item2 in list)
		{
			if (((Component)item2).gameObject.activeInHierarchy && ((Object)(object)val == (Object)null || item2.childCount < val.childCount))
			{
				val = item2;
			}
		}
		if (!((Object)(object)val == (Object)null))
		{
			Accept(val, "auto (smallest rendered)");
		}
	}

	private static string SignatureOf(List<Transform> candidates)
	{
		StringBuilder stringBuilder = new StringBuilder();
		foreach (Transform candidate in candidates)
		{
			stringBuilder.Append(((Object)candidate).GetInstanceID()).Append(':').Append(((Component)candidate).gameObject.activeInHierarchy ? '1' : '0')
				.Append('|');
		}
		return stringBuilder.ToString();
	}

	private static void LogUnboundStatus()
	{
		if (_cfgDiagnostics.Value)
		{
			_statusTimer -= Time.unscaledDeltaTime;
			if (!(_statusTimer > 0f))
			{
				_statusTimer = 5f;
				_log.LogInfo((object)string.Format("Not bound yet: no rendered group command container. GameData.SimPlayerGrouping is {0}. Retrying every second.", ((Object)(object)GameData.SimPlayerGrouping != (Object)null) ? "set" : "null"));
			}
		}
	}

	private static void Accept(Transform container, string how)
	{
		_log.LogInfo((object)("Group command stack container [" + how + "]: " + PathOf(container)));
		StringBuilder stringBuilder = new StringBuilder("Hiding these button objects individually (container, RaidLootDist and AwardLootGroup left alone):");
		for (int i = 0; i < container.childCount; i++)
		{
			Transform child = container.GetChild(i);
			string text = LabelOf(child);
			if (IsStackLabel(text))
			{
				_targets.Add(((Component)child).gameObject);
				stringBuilder.Append("\n  \"").Append(((Object)child).name).Append("\"  \"")
					.Append(text)
					.Append("\"");
			}
		}
		if (_targets.Count == 0)
		{
			_log.LogWarning((object)("No button children matched inside " + PathOf(container) + "; falling back to hiding the container itself."));
			_targets.Add(((Component)container).gameObject);
		}
		else
		{
			_log.LogInfo((object)stringBuilder.ToString());
		}
	}

	private static void LogCandidates(List<Transform> candidates)
	{
		SimPlayerGrouping simPlayerGrouping = GameData.SimPlayerGrouping;
		Transform val = null;
		if ((Object)(object)simPlayerGrouping != (Object)null && (Object)(object)simPlayerGrouping.PullButton != (Object)null)
		{
			val = ((TMP_Text)simPlayerGrouping.PullButton).transform;
		}
		StringBuilder stringBuilder = new StringBuilder("Group command containers found: ").Append(candidates.Count);
		foreach (Transform candidate in candidates)
		{
			bool num = (Object)(object)val != (Object)null && val.IsChildOf(candidate);
			RaidLootDist component = ((Component)candidate).GetComponent<RaidLootDist>();
			stringBuilder.Append("\n  ").Append(PathOf(candidate)).Append("\n      labels=")
				.Append(CountStackLabels(candidate))
				.Append("  children=")
				.Append(candidate.childCount)
				.Append("  activeInHierarchy=")
				.Append(((Component)candidate).gameObject.activeInHierarchy)
				.Append("  activeSelf=")
				.Append(((Component)candidate).gameObject.activeSelf);
			if ((Object)(object)component != (Object)null)
			{
				stringBuilder.Append("  RaidLootDist.UseGroup=").Append(component.UseGroup);
			}
			if (num)
			{
				stringBuilder.Append("  <-- holds SimPlayerGrouping.PullButton");
			}
		}
		_log.LogInfo((object)stringBuilder.ToString());
	}

	private static void DumpAllCandidates()
	{
		List<Transform> list = FindCandidates();
		_log.LogInfo((object)"=== DumpKey pressed ===");
		if (list.Count == 0)
		{
			_log.LogInfo((object)"No group command containers found in the loaded UI.");
		}
		else
		{
			LogCandidates(list);
		}
		StringBuilder stringBuilder = new StringBuilder("Currently targeting ").Append(_targets.Count).Append(" object(s):");
		foreach (GameObject target in _targets)
		{
			stringBuilder.Append("\n  ").Append(((Object)(object)target != (Object)null) ? PathOf(target.transform) : "<destroyed>");
		}
		_log.LogInfo((object)stringBuilder.ToString());
	}

	private static int CountStackLabels(Transform t)
	{
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		TMP_Text[] componentsInChildren = ((Component)t).GetComponentsInChildren<TMP_Text>(true);
		foreach (TMP_Text val in componentsInChildren)
		{
			string text = ((val.text != null) ? val.text.Trim() : "");
			if (IsStackLabel(text))
			{
				hashSet.Add(text.StartsWith("Auto Pull", StringComparison.OrdinalIgnoreCase) ? "Auto Pull" : text);
			}
		}
		return hashSet.Count;
	}

	private static string LabelOf(Transform t)
	{
		TMP_Text componentInChildren = ((Component)t).GetComponentInChildren<TMP_Text>(true);
		if (!((Object)(object)componentInChildren != (Object)null) || componentInChildren.text == null)
		{
			return "";
		}
		return componentInChildren.text.Trim();
	}

	private static bool IsStackLabel(string label)
	{
		if (string.IsNullOrEmpty(label))
		{
			return false;
		}
		label = label.Trim();
		if (!ButtonLabels.Contains(label))
		{
			return label.StartsWith("Auto Pull", StringComparison.OrdinalIgnoreCase);
		}
		return true;
	}

	private static string PathOf(Transform t)
	{
		StringBuilder stringBuilder = new StringBuilder(((Object)t).name);
		Transform parent = t.parent;
		while ((Object)(object)parent != (Object)null)
		{
			stringBuilder.Insert(0, ((Object)parent).name + "/");
			parent = parent.parent;
		}
		return stringBuilder.ToString();
	}

	private static void SetTargetsVisible(bool visible)
	{
		bool flag = !visible && (Object)(object)_groupLoot != (Object)null && (Object)(object)_groupLoot.DistWindow != (Object)null && _groupLoot.DistWindow.activeSelf;
		for (int i = 0; i < _targets.Count; i++)
		{
			GameObject val = _targets[i];
			if (!((Object)(object)val == (Object)null))
			{
				bool flag2 = visible || (flag && (Object)(object)val == (Object)(object)_lootButton);
				if (val.activeSelf != flag2)
				{
					val.SetActive(flag2);
				}
			}
		}
		_lastApplied = visible;
		_appliedOnce = true;
	}

	private static CanvasGroup GetGroup(GameObject go)
	{
		int instanceID = ((Object)go).GetInstanceID();
		if (_groupCache.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null)
		{
			return value;
		}
		CanvasGroup val = go.GetComponent<CanvasGroup>();
		if ((Object)(object)val == (Object)null)
		{
			val = go.AddComponent<CanvasGroup>();
		}
		_groupCache[instanceID] = val;
		return val;
	}
}
internal class ToggleDriver : MonoBehaviour
{
	private void Update()
	{
		GroupCommandsTogglePlugin.PumpDriverObjectUpdate();
	}

	private void LateUpdate()
	{
		GroupCommandsTogglePlugin.PumpDriverObjectLateUpdate();
	}
}