Decompiled source of TooManySuits v2.0.1

TooManySuits.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
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("TooManySuits")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.1.0")]
[assembly: AssemblyInformationalVersion("2.0.1+85b6d88f27a7a790ab993a3962618a1602891367")]
[assembly: AssemblyProduct("TooManySuits")]
[assembly: AssemblyTitle("TooManySuits")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 TooManySuits
{
	internal class AssetManager
	{
		public TMP_FontAsset VGA437Font { get; private set; }

		public AssetManager()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream("TooManySuits.AssetBundle") ?? throw new InvalidOperationException("Failed to load AssetBundle");
			AssetBundle val = AssetBundle.LoadFromStream(stream);
			VGA437Font = val.LoadAsset<TMP_FontAsset>("Perfect DOS VGA 437 SDF") ?? throw new InvalidOperationException("Failed to load font 'Perfect DOS VGA 437 SDF' from AssetBundle");
		}
	}
	internal class Config
	{
		private readonly ConfigEntry<float> _configLabelScale;

		private readonly ConfigEntry<int> _configSuitsPerPage;

		public float LabelScale => _configLabelScale.Value;

		public int SuitsPerPage => _configSuitsPerPage.Value;

		public Config(ConfigFile cfg)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			_configSuitsPerPage = cfg.Bind<int>("Pagination", "SuitsPerPage", 13, new ConfigDescription("Number of suits per page in the suit rack.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(13, 20), Array.Empty<object>()));
			_configLabelScale = cfg.Bind<float>("UI", "LabelScale", 1f, new ConfigDescription("Size of the text above the suit rack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
			cfg.OrphanedEntries.Clear();
			cfg.Save();
		}
	}
	internal static class LobbyCompatibility
	{
		public static void Init()
		{
			TooManySuits.Logger.LogInfo((object)"Registering plugin with LobbyCompatibility.");
			Version version = Version.Parse("2.0.1");
			PluginHelper.RegisterPlugin("TooManySuits", version, (CompatibilityLevel)0, (VersionStrictness)0);
		}
	}
	public class PaginationController : MonoBehaviour
	{
		private UnlockableSuit[] _allSuits;

		private TextMeshPro _pageTextMesh;

		private GameObject _pageGO;

		private GameObject _previousGO;

		private GameObject _nextGO;

		private bool _shouldUpdate;

		public int SuitsPerPage { get; set; }

		private int CurrentPage { get; set; }

		private int PageCount { get; set; }

		private static Sprite FindInteractIcon()
		{
			Terminal val = Object.FindObjectOfType<Terminal>() ?? throw new InvalidOperationException("Can't find Terminal object");
			InteractTrigger val2 = ((Component)val).GetComponent<InteractTrigger>() ?? throw new InvalidOperationException("Can't find InteractTrigger component from Terminal object");
			return val2.hoverIcon;
		}

		private void Awake()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			if (SuitsPerPage <= 0)
			{
				throw new InvalidOperationException("SuitsPerPage must be >= 0");
			}
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(10f, 10f);
			_pageGO = new GameObject("page");
			_pageGO.transform.SetParent(((Component)this).transform, false);
			_pageTextMesh = CreateTMP(_pageGO, "Page");
			_previousGO = new GameObject("previousButton");
			RectTransform val2 = _previousGO.AddComponent<RectTransform>();
			((Transform)val2).SetParent(((Component)this).transform, false);
			val2.anchorMax = new Vector2(0f, 0.5f);
			val2.anchorMin = new Vector2(0f, 0.5f);
			CreateTMP(_previousGO, "<");
			GameObject val3 = new GameObject("trigger");
			RectTransform val4 = val3.AddComponent<RectTransform>();
			((Transform)val4).SetParent((Transform)(object)val2, false);
			BoxCollider val5 = val3.AddComponent<BoxCollider>();
			val5.size = Vector2.op_Implicit(val);
			InteractTrigger val6 = CreateInteractTrigger(val3);
			((UnityEvent<PlayerControllerB>)(object)val6.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				PreviousPage();
			});
			_nextGO = new GameObject("nextButton");
			RectTransform val7 = _nextGO.AddComponent<RectTransform>();
			((Transform)val7).SetParent(((Component)this).transform, false);
			val7.anchorMax = new Vector2(1f, 0.5f);
			val7.anchorMin = new Vector2(1f, 0.5f);
			CreateTMP(_nextGO, ">");
			GameObject val8 = new GameObject("trigger");
			RectTransform val9 = val8.AddComponent<RectTransform>();
			((Transform)val9).SetParent((Transform)(object)val7, false);
			BoxCollider val10 = val8.AddComponent<BoxCollider>();
			val10.size = Vector2.op_Implicit(val);
			InteractTrigger val11 = CreateInteractTrigger(val8);
			((UnityEvent<PlayerControllerB>)(object)val11.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				NextPage();
			});
			static InteractTrigger CreateInteractTrigger(GameObject go)
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Expected O, but got Unknown
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Expected O, but got Unknown
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Expected O, but got Unknown
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Expected O, but got Unknown
				Sprite val12 = FindInteractIcon();
				InteractTrigger val13 = go.AddComponent<InteractTrigger>();
				((Component)val13).gameObject.tag = "InteractTrigger";
				((Component)val13).gameObject.layer = LayerMask.NameToLayer("InteractableObject");
				val13.interactable = true;
				val13.oneHandedItemAllowed = true;
				val13.holdInteraction = false;
				val13.interactCooldown = false;
				val13.onInteract = new InteractEvent();
				val13.onInteractEarly = new InteractEvent();
				val13.onCancelAnimation = new InteractEvent();
				val13.onStopInteract = new InteractEvent();
				val13.holdingInteractEvent = new InteractEventFloat();
				val13.hoverTip = "";
				val13.disabledHoverTip = "";
				val13.hoverIcon = val12;
				val13.disabledHoverIcon = val12;
				return val13;
			}
			static TextMeshPro CreateTMP(GameObject go, string text)
			{
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				TextMeshPro val14 = go.AddComponent<TextMeshPro>();
				((TMP_Text)val14).autoSizeTextContainer = true;
				((TMP_Text)val14).enableWordWrapping = false;
				((TMP_Text)val14).alignment = (TextAlignmentOptions)514;
				((TMP_Text)val14).text = text;
				((TMP_Text)val14).font = TooManySuits.AssetManager.VGA437Font;
				((TMP_Text)val14).fontMaterial = ((TMP_Asset)TooManySuits.AssetManager.VGA437Font).material;
				((Graphic)val14).color = new Color(255f, 255f, 255f, 255f);
				((TMP_Text)val14).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue);
				((TMP_Text)val14).outlineWidth = 0.25f;
				return val14;
			}
		}

		private void Start()
		{
			TooManySuits.SuitManager.SuitsUpdated += OnSuitsUpdated;
			UpdateSuits();
		}

		private void Update()
		{
			if (_shouldUpdate)
			{
				_shouldUpdate = false;
				UpdateSuits();
			}
		}

		private void OnDestroy()
		{
			TooManySuits.SuitManager.SuitsUpdated -= OnSuitsUpdated;
		}

		private void OnSuitsUpdated()
		{
			_shouldUpdate = true;
		}

		private void UpdateSuits()
		{
			_allSuits = TooManySuits.SuitManager.GetUnlockedSuits().ToArray();
			PageCount = Mathf.CeilToInt((float)_allSuits.Length / (float)SuitsPerPage);
			if (CurrentPage > PageCount - 1)
			{
				CurrentPage = PageCount - 1;
			}
			DisplayCurrentPage();
		}

		private void NextPage()
		{
			if (CurrentPage < PageCount - 1)
			{
				CurrentPage++;
				DisplayCurrentPage();
			}
		}

		private void PreviousPage()
		{
			if (CurrentPage > 0)
			{
				CurrentPage--;
				DisplayCurrentPage();
			}
		}

		private void DisplayCurrentPage()
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			int num = CurrentPage * SuitsPerPage;
			int num2 = Mathf.Min(num + SuitsPerPage, _allSuits.Length);
			float num3 = 0.18f;
			if (TooManySuits.Config.SuitsPerPage > 13 && _allSuits.Length > 13)
			{
				num3 /= (float)Mathf.Min(_allSuits.Length, TooManySuits.Config.SuitsPerPage) / 12f;
			}
			int num4 = 0;
			for (int i = 0; i < _allSuits.Length; i++)
			{
				UnlockableSuit val = _allSuits[i];
				AutoParentToShip component = ((Component)val).gameObject.GetComponent<AutoParentToShip>();
				if (!((Object)(object)component == (Object)null))
				{
					bool flag = i >= num && i < num2;
					Renderer[] componentsInChildren = ((Component)val).gameObject.GetComponentsInChildren<Renderer>();
					foreach (Renderer val2 in componentsInChildren)
					{
						val2.enabled = flag;
					}
					Collider[] componentsInChildren2 = ((Component)val).gameObject.GetComponentsInChildren<Collider>();
					foreach (Collider val3 in componentsInChildren2)
					{
						val3.enabled = flag;
					}
					InteractTrigger component2 = ((Component)val).gameObject.GetComponent<InteractTrigger>();
					((Behaviour)component2).enabled = flag;
					component2.interactable = flag;
					if (flag)
					{
						component.overrideOffset = true;
						component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + StartOfRound.Instance.rightmostSuitPosition.forward * (num3 * (float)num4);
						component.rotationOffset = new Vector3(0f, 90f, 0f);
						num4++;
					}
				}
			}
			((MonoBehaviour)this).StartCoroutine(UpdateLabel());
		}

		private IEnumerator UpdateLabel()
		{
			((TMP_Text)_pageTextMesh).text = $"<b>{CurrentPage + 1}/{PageCount}</b>";
			yield return null;
			TMP_CharacterInfo[] characterInfo = ((TMP_Text)_pageTextMesh).textInfo.characterInfo;
			int characterCount = ((TMP_Text)_pageTextMesh).textInfo.characterCount;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(2f, 0f, 0f);
			Vector3 val2 = new Vector3(0f, 1f, 0f) * ((TMP_Text)_pageTextMesh).outlineWidth;
			_previousGO.transform.localPosition = characterInfo[0].topLeft - val2 * 2f - val + new Vector3(0f, characterInfo[0].baseLine, 0f);
			_nextGO.transform.localPosition = characterInfo[characterCount - 1].topRight - val2 * 2f + val + new Vector3(0f, characterInfo[characterCount - 1].baseLine, 0f);
			_previousGO.SetActive(PageCount > 0 && CurrentPage > 0);
			_nextGO.SetActive(PageCount > 0 && CurrentPage < PageCount - 1);
			_pageGO.SetActive(PageCount > 0);
		}
	}
	[HarmonyPatch]
	internal class Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPriority(600)]
		[HarmonyAfter(new string[] { "x753.More_Suits" })]
		private static void StartPatch()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TooManySuitsPageLabel");
			val.SetActive(false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent(StartOfRound.Instance.rightmostSuitPosition, false);
			((Transform)val2).localPosition = Vector3.zero;
			((Transform)val2).localEulerAngles = Vector3.zero;
			((Transform)val2).localScale = Vector3.one * TooManySuits.Config.LabelScale * 0.05f;
			PaginationController paginationController = val.AddComponent<PaginationController>();
			paginationController.SuitsPerPage = TooManySuits.Config.SuitsPerPage;
			Vector3 val3 = StartOfRound.Instance.rightmostSuitPosition.forward * 2.0700002f / 2f;
			AutoParentToShip val4 = val.AddComponent<AutoParentToShip>();
			val4.overrideOffset = true;
			val4.positionOffset = new Vector3(-2.45f, 3f, -8.41f) + val3;
			val4.rotationOffset = new Vector3(0f, 180f, 0f);
			val.SetActive(true);
			TooManySuits.SuitManager.UpdateSuits();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "PositionSuitsOnRack")]
		[HarmonyPriority(600)]
		[HarmonyAfter(new string[] { "x753.More_Suits" })]
		private static void PositionSuitsOnRackPatch()
		{
			TooManySuits.SuitManager.UpdateSuits();
		}
	}
	internal class SuitManager
	{
		public event Action? SuitsUpdated;

		public IEnumerable<UnlockableSuit> GetUnlockedSuits()
		{
			return from suit in Resources.FindObjectsOfTypeAll<UnlockableSuit>()
				orderby suit.syncedSuitID.Value
				where ((NetworkBehaviour)suit).IsSpawned
				select suit;
		}

		internal void UpdateSuits()
		{
			this.SuitsUpdated?.Invoke();
		}
	}
	[BepInPlugin("TooManySuits", "TooManySuits", "2.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class TooManySuits : BaseUnityPlugin
	{
		internal const string MoreSuitsGuid = "x753.More_Suits";

		internal const int VanillaSuitsPerPage = 13;

		internal const float SuitThickness = 0.18f;

		private static readonly Harmony Harmony = new Harmony("TooManySuits");

		internal static SuitManager SuitManager { get; } = new SuitManager();


		internal static AssetManager AssetManager { get; } = new AssetManager();


		internal static ManualLogSource Logger { get; private set; } = null;


		internal static Config Config { get; private set; } = null;


		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Config = new Config(((BaseUnityPlugin)this).Config);
			Harmony.PatchAll();
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				LobbyCompatibility.Init();
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TooManySuits";

		public const string PLUGIN_NAME = "TooManySuits";

		public const string PLUGIN_VERSION = "2.0.1";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}