Decompiled source of UnlimitedJail v1.1.0

UnlimitedJail.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using FMODUnity;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SuperFantasyKingdom;
using SuperFantasyKingdom.TitleScreen;
using SuperFantasyKingdom.UI;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("UnlimitedJail")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+14a22b142920a276e529c9edd73b255a4bf0cc56")]
[assembly: AssemblyProduct("Unlimited Jail")]
[assembly: AssemblyTitle("UnlimitedJail")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 UnlimitedJail
{
	[BepInPlugin("ownly.unlimitedjail", "Unlimited Jail", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID).PatchAll();
		}
	}
	internal static class Filter
	{
		public static void Apply(UnlockedUnitsManager manager)
		{
			List<string> stashed = Stash.Units;
			Traverse obj = Traverse.Create((object)manager);
			List<string> value = obj.Field("m_UnlockedUnits").GetValue<List<string>>();
			List<string> value2 = obj.Field("m_Banned").GetValue<List<string>>();
			foreach (string item in stashed)
			{
				value.Remove(item);
				if (!value2.Contains(item))
				{
					value2.Add(item);
				}
			}
			value2.RemoveAll((string id) => id != "empty" && !stashed.Contains(id));
		}
	}
	[HarmonyPatch(typeof(UnlockedUnitsManager), "Awake")]
	internal static class Patch_UnlockedUnitsAwake
	{
		private static void Postfix(UnlockedUnitsManager __instance)
		{
			try
			{
				Filter.Apply(__instance);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(UnlockedUnitsManager), "SetBannedUnits")]
	internal static class Patch_SetBannedUnits
	{
		private static void Postfix(UnlockedUnitsManager __instance)
		{
			try
			{
				Filter.Apply(__instance);
			}
			catch
			{
			}
		}
	}
	internal static class Jail
	{
		internal const string Empty = "empty";

		private static readonly HashSet<string> s_Warned = new HashSet<string>();

		public static string Force(string jailed)
		{
			if (!string.IsNullOrEmpty(jailed) && jailed != "empty" && s_Warned.Add(jailed))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("jail slot held " + jailed + " - the mod frees it, jail it from the selection screen to keep it held back"));
				}
			}
			return "empty";
		}

		public static void Paint(TitleScreenJail jail, int index)
		{
			List<string> units = Stash.Units;
			Traverse val = Traverse.Create((object)jail);
			GameObject value = val.Field("jail" + index).GetValue<GameObject>();
			GameObject value2 = val.Field("jail" + index + "Rubble").GetValue<GameObject>();
			Image value3 = val.Field("jail" + index + "Door").GetValue<Image>();
			ImageAnimator value4 = val.Field("jail" + index + "Jailed").GetValue<ImageAnimator>();
			if (units.Count < index)
			{
				return;
			}
			Unit unit = AddressablesManager.Instance.GetUnit(units[index - 1]);
			if ((Object)(object)unit == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("stashed unit has no prefab: " + units[index - 1]));
				}
			}
			else
			{
				value.SetActive(true);
				value2.SetActive(false);
				value3.sprite = val.Field("spriteDoorClosed").GetValue<Sprite>();
				value4.SetSprites(((UnitBase)unit).GetIdleSprites());
				((Component)value4).gameObject.SetActive(true);
			}
		}
	}
	[HarmonyPatch(typeof(RaceDataManager), "GetJail1")]
	internal static class Patch_GetJail1
	{
		private static void Postfix(ref string __result)
		{
			__result = Jail.Force(__result);
		}
	}
	[HarmonyPatch(typeof(RaceDataManager), "GetJail2")]
	internal static class Patch_GetJail2
	{
		private static void Postfix(ref string __result)
		{
			__result = Jail.Force(__result);
		}
	}
	[HarmonyPatch(typeof(RaceDataManager), "GetJail3")]
	internal static class Patch_GetJail3
	{
		private static void Postfix(ref string __result)
		{
			__result = Jail.Force(__result);
		}
	}
	[HarmonyPatch(typeof(TitleScreenJail), "ShowJail1")]
	internal static class Patch_ShowJail1
	{
		private static void Postfix(TitleScreenJail __instance)
		{
			try
			{
				Jail.Paint(__instance, 1);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(TitleScreenJail), "ShowJail2")]
	internal static class Patch_ShowJail2
	{
		private static void Postfix(TitleScreenJail __instance)
		{
			try
			{
				Jail.Paint(__instance, 2);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(TitleScreenJail), "ShowJail3")]
	internal static class Patch_ShowJail3
	{
		private static void Postfix(TitleScreenJail __instance)
		{
			try
			{
				Jail.Paint(__instance, 3);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(TitleScreenJail), "SetJailed")]
	internal static class Patch_SetJailed
	{
		private static bool Prefix(TitleScreenJail __instance)
		{
			try
			{
				Traverse val = Traverse.Create((object)__instance);
				int value = val.Field("m_SelectedCell").GetValue<int>();
				if (value >= 1 && value <= 3)
				{
					Button value2 = val.Field("jail" + value + "Button").GetValue<Button>();
					if ((Object)(object)value2 != (Object)null)
					{
						GamepadManager.Instance.SetGameObjectToSelect(((Component)value2).gameObject, true);
					}
				}
				val.Field("m_SelectedCell").SetValue((object)0);
				__instance.Decorate();
			}
			catch
			{
			}
			return false;
		}
	}
	internal static class Catalog
	{
		private static readonly Color JailedTile = new Color(0.6f, 0.24f, 0.22f, 1f);

		private static readonly Color JailedIcon = new Color(0.38f, 0.16f, 0.15f, 1f);

		private static readonly Dictionary<string, GameObject> s_Entries = new Dictionary<string, GameObject>();

		public static void Track(string key, GameObject button)
		{
			s_Entries[key] = button;
			Paint(key);
		}

		public static void Paint(string key)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (s_Entries.TryGetValue(key, out var value) && !((Object)(object)value == (Object)null))
			{
				bool flag = Stash.Contains(key);
				Image component = value.GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					((Graphic)component).color = (flag ? JailedTile : Color.white);
				}
				Transform val = value.transform.Find("Icon");
				if ((Object)(object)val != (Object)null)
				{
					((Graphic)((Component)val).GetComponent<Image>()).color = (flag ? JailedIcon : Color.white);
				}
			}
		}
	}
	[HarmonyPatch(typeof(UICatalogJail), "Unit")]
	internal static class Patch_CatalogUnit
	{
		private static void Postfix(string key, GameObject button)
		{
			try
			{
				Catalog.Track(key, button);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(UICatalogJail), "CanAddUnit")]
	internal static class Patch_CanAddUnit
	{
		private static void Postfix(Unit unit, ref bool __result)
		{
			try
			{
				if (!__result && Stash.Contains(((Entity)unit).GetEntityIdentifier()))
				{
					__result = true;
				}
			}
			catch
			{
			}
		}
	}
	internal static class Coins
	{
		private const float Margin = 14f;

		private const int WalkLimit = 4;

		private static GameObject s_Widget;

		private static Text s_Text;

		public static void Show()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_Widget != (Object)null)
			{
				return;
			}
			TitleScreenHeroSelectionManager instance = TitleScreenHeroSelectionManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Traverse val = Traverse.Create((object)instance);
			Text value = val.Field("coins").GetValue<Text>();
			GameObject value2 = Traverse.Create((object)AchievementManager.Instance).Field("achievementOverlay").GetValue<GameObject>();
			if ((Object)(object)value == (Object)null || (Object)(object)value2 == (Object)null || (Object)(object)value2.GetComponent<RectTransform>() == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"no coin widget to clone, the catalog opens without a counter");
				}
				return;
			}
			Transform obj = WidgetRoot(val, ((Component)value).transform);
			if ((Object)(object)obj == (Object)(object)((Component)value).transform)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"the coin counter has no widget around it, cloning the number alone");
				}
			}
			RectTransform component = ((Component)obj).GetComponent<RectTransform>();
			? val2;
			if (!((Object)(object)component != (Object)null))
			{
				val2 = Vector2.zero;
			}
			else
			{
				Rect rect = component.rect;
				float width = ((Rect)(ref rect)).width;
				rect = component.rect;
				val2 = new Vector2(width, ((Rect)(ref rect)).height);
			}
			Vector2 sizeDelta = (Vector2)val2;
			s_Widget = Object.Instantiate<GameObject>(((Component)obj).gameObject, value2.transform);
			((Object)s_Widget).name = "UnlimitedJailCoins";
			RectTransform component2 = s_Widget.GetComponent<RectTransform>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.anchorMin = new Vector2(0f, 1f);
				component2.anchorMax = new Vector2(0f, 1f);
				component2.pivot = new Vector2(0f, 1f);
				component2.sizeDelta = sizeDelta;
				component2.anchoredPosition = new Vector2(14f, -14f);
			}
			Graphic[] componentsInChildren = s_Widget.GetComponentsInChildren<Graphic>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].raycastTarget = false;
			}
			s_Text = s_Widget.GetComponentInChildren<Text>(true);
			Refresh();
		}

		public static void Hide()
		{
			if ((Object)(object)s_Widget != (Object)null)
			{
				Object.Destroy((Object)(object)s_Widget);
				s_Widget = null;
				s_Text = null;
			}
		}

		public static void Refresh()
		{
			if ((Object)(object)s_Text != (Object)null)
			{
				s_Text.text = TitleScreenHeroSelectionManager.Instance.GetCoinsRemaining().ToString();
			}
		}

		private static Transform WidgetRoot(Traverse throne, Transform coins)
		{
			Transform[] array = (Transform[])(object)new Transform[3]
			{
				Counter(throne, "shards"),
				Counter(throne, "faith"),
				Counter(throne, "superMetal")
			};
			if ((Object)(object)array[0] == (Object)null && (Object)(object)array[1] == (Object)null && (Object)(object)array[2] == (Object)null)
			{
				return coins;
			}
			Transform val = coins;
			for (int i = 0; i < 4; i++)
			{
				Transform parent = val.parent;
				if ((Object)(object)parent == (Object)null || (Object)(object)((Component)parent).GetComponent<Canvas>() != (Object)null || Holds(parent, array))
				{
					break;
				}
				val = parent;
			}
			return val;
		}

		private static bool Holds(Transform parent, Transform[] siblings)
		{
			foreach (Transform val in siblings)
			{
				if ((Object)(object)val != (Object)null && val.IsChildOf(parent))
				{
					return true;
				}
			}
			return false;
		}

		private static Transform Counter(Traverse throne, string field)
		{
			Text value = throne.Field(field).GetValue<Text>();
			if (!((Object)(object)value != (Object)null))
			{
				return null;
			}
			return ((Component)value).transform;
		}
	}
	[HarmonyPatch(typeof(AchievementManager), "OpenJail")]
	internal static class Patch_OpenJail
	{
		private static void Postfix()
		{
			try
			{
				Coins.Show();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("could not build the coin counter: " + ex));
				}
			}
		}
	}
	[HarmonyPatch(typeof(AchievementManager), "Close")]
	internal static class Patch_AchievementClose
	{
		private static void Postfix(bool __result)
		{
			try
			{
				if (__result)
				{
					Coins.Hide();
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(TitleScreenHeroSelectionManager), "CloseJailSelection")]
	internal static class Patch_CloseJailSelection
	{
		private static bool Prefix()
		{
			//IL_0089: 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)
			try
			{
				UICatalogManager instance = UICatalogManager.Instance;
				if ((Object)(object)instance == (Object)null || !instance.IsUnitDetailsOpen())
				{
					return true;
				}
				Traverse obj = Traverse.Create((object)instance);
				obj.Method("CloseUnitDetails", Array.Empty<object>()).GetValue();
				obj.Method("Generate", new Type[2]
				{
					typeof(CatalogType),
					typeof(int)
				}, new object[2]
				{
					(object)(CatalogType)7,
					0
				}).GetValue();
				RuntimeManager.PlayOneShot("event:/SFX/UI/Cancel", default(Vector3));
				return false;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("could not step back to the selection: " + ex));
				}
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(TitleScreenHeroSelectionManager), "SelectJailedUnit")]
	internal static class Patch_SelectJailedUnit
	{
		private static bool Prefix(string key)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Stash.Toggle(key);
				Catalog.Paint(key);
				RuntimeManager.PlayOneShot(Stash.Contains(key) ? "event:/SFX/UI/Confirm" : "event:/SFX/UI/Cancel", default(Vector3));
				UICatalogManager.Instance.OnSelect(key, false);
				TitleScreenHeroSelectionManager.Instance.UpdateKingdomData();
				Coins.Refresh();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("could not toggle " + key + ": " + ex));
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(TitleScreenHeroSelectionManager), "GetCoinsRemaining")]
	internal static class Patch_CoinsRemaining
	{
		private static void Postfix(ref int __result)
		{
			try
			{
				__result = Mathf.Max(0, __result - Stash.CoinCost);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(ResourceManager), "GiveStartingResources")]
	internal static class Patch_StartingCoins
	{
		private static void Postfix(ResourceManager __instance)
		{
			try
			{
				int num = Mathf.Min(Stash.CoinCost, __instance.GetCoins());
				if (num > 0)
				{
					__instance.SpendResource((ResourceType)12, num);
				}
			}
			catch
			{
			}
		}
	}
	internal static class Stash
	{
		private static readonly List<string> s_Units = new List<string>();

		private static string s_Key;

		public static List<string> Units
		{
			get
			{
				Reload();
				return s_Units;
			}
		}

		public static int CoinCost => Mathf.Max(0, Units.Count - 3);

		public static bool Contains(string entityIdentifier)
		{
			return Units.Contains(entityIdentifier);
		}

		public static void Toggle(string entityIdentifier)
		{
			Reload();
			if (!s_Units.Remove(entityIdentifier))
			{
				s_Units.Add(entityIdentifier);
			}
			Write();
		}

		private static void Reload()
		{
			string text = CurrentKey();
			if (text == s_Key)
			{
				return;
			}
			s_Key = text;
			s_Units.Clear();
			try
			{
				string path = PathFor(text);
				if (!File.Exists(path))
				{
					return;
				}
				string[] array = File.ReadAllLines(path);
				for (int i = 0; i < array.Length; i++)
				{
					string text2 = array[i].Trim();
					if (text2.Length > 0 && !s_Units.Contains(text2))
					{
						s_Units.Add(text2);
					}
				}
			}
			catch
			{
			}
		}

		private static void Write()
		{
			try
			{
				string path = PathFor(s_Key);
				Directory.CreateDirectory(Path.GetDirectoryName(path));
				File.WriteAllLines(path, s_Units.ToArray());
			}
			catch
			{
			}
		}

		private static string CurrentKey()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return Helper.Instance.GetRaceString(MainManager.Instance.GetSelectedKingdom(), false) + "_" + (SettingsManager.Instance.GetProfile() + 1);
			}
			catch
			{
				return "unknown";
			}
		}

		private static string PathFor(string key)
		{
			return Path.Combine(Path.Combine(Paths.ConfigPath, "UnlimitedJail"), key + ".txt");
		}
	}
}