Decompiled source of MoreBadges v0.3.2

MoreBadges.dll

Decompiled a day 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.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MoreBadges")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.3.2")]
[assembly: AssemblyInformationalVersion("0.3.2+a129625a308cd90a4b863e372f1288601419c7f0")]
[assembly: AssemblyProduct("MoreBadges")]
[assembly: AssemblyTitle("MoreBadges")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.2.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace MoreBadges
{
	public enum AchievementUIStyle
	{
		Default,
		Compact
	}
	public class BadgePopupUGUI : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <AnimatePopup>d__13 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public BadgePopupUGUI <>4__this;

			private float <animTime>5__1;

			private float <yStart>5__2;

			private float <yEnd>5__3;

			private float <elapsed>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AnimatePopup>d__13(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: 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_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this.canvasGroup.alpha = 0f;
					<animTime>5__1 = 0.5f;
					<yStart>5__2 = 50f;
					<yEnd>5__3 = -15f;
					<elapsed>5__4 = 0f;
					goto IL_0139;
				case 1:
					<>1__state = -1;
					goto IL_0139;
				case 2:
					<>1__state = -1;
					<elapsed>5__4 = 0f;
					break;
				case 3:
					{
						<>1__state = -1;
						break;
					}
					IL_0139:
					if (<elapsed>5__4 < <animTime>5__1)
					{
						if ((Object)(object)<>4__this.rectTransform == (Object)null)
						{
							return false;
						}
						<>4__this.rectTransform.anchoredPosition = new Vector2(<>4__this.rectTransform.anchoredPosition.x, Mathf.Lerp(<yStart>5__2, <yEnd>5__3, <elapsed>5__4 / <animTime>5__1));
						<>4__this.canvasGroup.alpha = Mathf.Lerp(0f, 1f, <elapsed>5__4 / <animTime>5__1);
						<elapsed>5__4 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					if ((Object)(object)<>4__this.rectTransform == (Object)null)
					{
						return false;
					}
					<>4__this.rectTransform.anchoredPosition = new Vector2(<>4__this.rectTransform.anchoredPosition.x, <yEnd>5__3);
					<>4__this.canvasGroup.alpha = 1f;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 2;
					return true;
				}
				if (<elapsed>5__4 < <animTime>5__1)
				{
					if ((Object)(object)<>4__this.rectTransform == (Object)null)
					{
						return false;
					}
					<>4__this.canvasGroup.alpha = Mathf.Lerp(1f, 0f, <elapsed>5__4 / <animTime>5__1);
					<elapsed>5__4 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 3;
					return true;
				}
				BadgeUIFactory.ClearActivePopup();
				if ((Object)(object)<>4__this.rectTransform != (Object)null && (Object)(object)((Transform)<>4__this.rectTransform).root != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)((Transform)<>4__this.rectTransform).root).gameObject);
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public TextMeshProUGUI achievementTitle;

		public TextMeshProUGUI achievementDescription;

		public Image achievementIcon;

		public CanvasGroup canvasGroup;

		public RectTransform rectTransform;

		private MoreBadgesPlugin.CustomBadge _badge;

		private Coroutine _activeAnimation;

		public void Show(MoreBadgesPlugin.CustomBadge badge, int currentProgress)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			_badge = badge;
			UpdateText(currentProgress);
			if ((Object)(object)badge.icon != (Object)null)
			{
				achievementIcon.sprite = Sprite.Create(badge.icon, new Rect(0f, 0f, (float)((Texture)badge.icon).width, (float)((Texture)badge.icon).height), new Vector2(0.5f, 0.5f));
			}
			StartAnimation();
		}

		public void UpdateProgress(int newProgress)
		{
			UpdateText(newProgress);
			StartAnimation();
		}

		private void UpdateText(int newProgress)
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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)
			bool flag = newProgress >= _badge.progressRequired;
			if (ConfigManager.UIStyle.Value == AchievementUIStyle.Compact)
			{
				if ((Object)(object)achievementDescription != (Object)null)
				{
					if (flag)
					{
						((TMP_Text)achievementDescription).text = "Unlocked";
						((Graphic)achievementDescription).color = new Color(1f, 0.84f, 0f);
					}
					else
					{
						((TMP_Text)achievementDescription).text = $"{newProgress}/{_badge.progressRequired}";
						((Graphic)achievementDescription).color = Color.white;
					}
				}
				return;
			}
			if ((Object)(object)achievementTitle != (Object)null)
			{
				((TMP_Text)achievementTitle).text = _badge.displayName;
				((Graphic)achievementTitle).color = Color.white;
			}
			if ((Object)(object)achievementDescription != (Object)null)
			{
				if (flag)
				{
					((TMP_Text)achievementDescription).text = "Achievement Unlocked";
					((Graphic)achievementDescription).color = new Color(1f, 0.84f, 0f);
				}
				else
				{
					((TMP_Text)achievementDescription).text = $"{_badge.description} ({newProgress}/{_badge.progressRequired})";
					((Graphic)achievementDescription).color = Color.gray;
				}
			}
		}

		private void StartAnimation()
		{
			if (_activeAnimation != null)
			{
				((MonoBehaviour)this).StopCoroutine(_activeAnimation);
			}
			_activeAnimation = ((MonoBehaviour)this).StartCoroutine(AnimatePopup());
		}

		public bool IsForBadge(string badgeName)
		{
			return _badge != null && _badge.name == badgeName;
		}

		public void CloseImmediate()
		{
			if (_activeAnimation != null)
			{
				((MonoBehaviour)this).StopCoroutine(_activeAnimation);
			}
			BadgeUIFactory.ClearActivePopup();
			if ((Object)(object)rectTransform != (Object)null && (Object)(object)((Transform)rectTransform).root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)((Transform)rectTransform).root).gameObject);
			}
		}

		[IteratorStateMachine(typeof(<AnimatePopup>d__13))]
		private IEnumerator AnimatePopup()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimatePopup>d__13(0)
			{
				<>4__this = this
			};
		}
	}
	public static class BadgeUIFactory
	{
		private static TMP_FontAsset _gameFontAsset;

		private static SFX_Instance _achievementSound;

		private static BadgePopupUGUI _activePopup;

		private static TMP_FontAsset GameFont
		{
			get
			{
				if ((Object)(object)_gameFontAsset == (Object)null)
				{
					_gameFontAsset = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)delegate(TMP_FontAsset fontAsset)
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						FaceInfo faceInfo = ((TMP_Asset)fontAsset).faceInfo;
						return ((FaceInfo)(ref faceInfo)).familyName == "Daruma Drop One";
					});
				}
				return _gameFontAsset;
			}
		}

		private static SFX_Instance AchievementSound
		{
			get
			{
				if ((Object)(object)_achievementSound == (Object)null)
				{
					Bonkable val = Resources.FindObjectsOfTypeAll<Bonkable>().FirstOrDefault();
					if ((Object)(object)val != (Object)null && val.bonk != null && val.bonk.Length != 0)
					{
						_achievementSound = val.bonk[0];
					}
				}
				return _achievementSound;
			}
		}

		public static void ClearActivePopup()
		{
			_activePopup = null;
		}

		public static void CreateOrUpdateAchievementPopup(MoreBadgesPlugin.CustomBadge badge, int currentProgress)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Expected O, but got Unknown
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: 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_04ff: Expected O, but got Unknown
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0587: Unknown result type (might be due to invalid IL or missing references)
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Expected O, but got Unknown
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_activePopup != (Object)null)
			{
				if (_activePopup.IsForBadge(badge.name))
				{
					_activePopup.UpdateProgress(currentProgress);
					return;
				}
				_activePopup.CloseImmediate();
			}
			GameObject val = new GameObject("AchievementCanvas");
			Object.DontDestroyOnLoad((Object)(object)val);
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 9999;
			val.AddComponent<CanvasScaler>();
			val.AddComponent<GraphicRaycaster>();
			GameObject val3 = new GameObject("PopupPanel", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(((Component)val2).transform, false);
			Image val4 = val3.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.1f, 0.1f, 0.15f, 0.95f);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(1f, 1f);
			component.anchoredPosition = new Vector2(-15f, 0f);
			GameObject val5 = new GameObject("Icon", new Type[1] { typeof(RectTransform) });
			val5.transform.SetParent(((Component)component).transform, false);
			Image achievementIcon = val5.AddComponent<Image>();
			RectTransform component2 = val5.GetComponent<RectTransform>();
			BadgePopupUGUI badgePopupUGUI = (_activePopup = val3.AddComponent<BadgePopupUGUI>());
			badgePopupUGUI.achievementIcon = achievementIcon;
			badgePopupUGUI.canvasGroup = val3.AddComponent<CanvasGroup>();
			badgePopupUGUI.rectTransform = component;
			if (ConfigManager.UIStyle.Value == AchievementUIStyle.Compact)
			{
				component.sizeDelta = new Vector2(90f, 90f);
				component2.anchorMin = new Vector2(0.5f, 1f);
				component2.anchorMax = new Vector2(0.5f, 1f);
				component2.pivot = new Vector2(0.5f, 1f);
				component2.sizeDelta = new Vector2(60f, 60f);
				component2.anchoredPosition = new Vector2(0f, -5f);
				GameObject val6 = new GameObject("ProgressText", new Type[1] { typeof(RectTransform) });
				val6.transform.SetParent(((Component)component).transform, false);
				TextMeshProUGUI val7 = val6.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val7).font = GameFont;
				((TMP_Text)val7).fontSize = 14f;
				((TMP_Text)val7).alignment = (TextAlignmentOptions)514;
				RectTransform component3 = val6.GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0.5f, 0f);
				component3.anchorMax = new Vector2(0.5f, 0f);
				component3.pivot = new Vector2(0.5f, 0f);
				component3.sizeDelta = new Vector2(80f, 20f);
				component3.anchoredPosition = new Vector2(0f, 5f);
				badgePopupUGUI.achievementDescription = val7;
			}
			else
			{
				component.sizeDelta = new Vector2(260f, 100f);
				component2.anchorMin = new Vector2(0f, 0.5f);
				component2.anchorMax = new Vector2(0f, 0.5f);
				component2.pivot = new Vector2(0f, 0.5f);
				component2.sizeDelta = new Vector2(50f, 50f);
				component2.anchoredPosition = new Vector2(10f, 0f);
				GameObject val8 = new GameObject("Title", new Type[1] { typeof(RectTransform) });
				val8.transform.SetParent(((Component)component).transform, false);
				TextMeshProUGUI val9 = val8.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val9).font = GameFont;
				((TMP_Text)val9).textWrappingMode = (TextWrappingModes)1;
				((TMP_Text)val9).overflowMode = (TextOverflowModes)1;
				((TMP_Text)val9).textWrappingMode = (TextWrappingModes)1;
				((TMP_Text)val9).maxVisibleLines = 2;
				((TMP_Text)val9).fontSize = 16f;
				((Graphic)val9).color = Color.white;
				((TMP_Text)val9).alignment = (TextAlignmentOptions)513;
				RectTransform component4 = val8.GetComponent<RectTransform>();
				component4.anchorMin = new Vector2(0f, 1f);
				component4.anchorMax = new Vector2(1f, 1f);
				component4.pivot = new Vector2(0f, 1f);
				component4.sizeDelta = new Vector2(-80f, 44f);
				component4.anchoredPosition = new Vector2(68f, -8f);
				GameObject val10 = new GameObject("Description", new Type[1] { typeof(RectTransform) });
				val10.transform.SetParent(((Component)component).transform, false);
				TextMeshProUGUI val11 = val10.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val11).font = GameFont;
				((TMP_Text)val11).fontSize = 14f;
				((TMP_Text)val11).alignment = (TextAlignmentOptions)257;
				RectTransform component5 = val10.GetComponent<RectTransform>();
				component5.anchorMin = new Vector2(0f, 1f);
				component5.anchorMax = new Vector2(1f, 1f);
				component5.pivot = new Vector2(0f, 1f);
				component5.sizeDelta = new Vector2(-20f, 36f);
				component5.anchoredPosition = new Vector2(68f, -56f);
				badgePopupUGUI.achievementTitle = val9;
				badgePopupUGUI.achievementDescription = val11;
			}
			badgePopupUGUI.Show(badge, currentProgress);
		}
	}
	public static class ConfigManager
	{
		public static ConfigEntry<bool> EnableBadgePopups { get; private set; }

		public static ConfigEntry<AchievementUIStyle> UIStyle { get; private set; }

		public static void Setup(ConfigFile config)
		{
			EnableBadgePopups = config.Bind<bool>("UI", "EnableBadgePopups", true, "If enabled, a pop-up will appear on badge completion, if disabled it wont appear at all.");
			UIStyle = config.Bind<AchievementUIStyle>("UI", "UIStyle", AchievementUIStyle.Default, "The visual style of the achievement pop-up. 'Default' shows the icon, title, and description. 'Compact' shows only the icon and title.");
		}
	}
	[BepInPlugin("com.snosz.morebadges", "MoreBadges", "0.3.2")]
	public class MoreBadgesPlugin : BaseUnityPlugin
	{
		[Serializable]
		public class CustomBadge
		{
			[JsonProperty]
			public string name;

			[JsonProperty]
			public int progress;

			[JsonProperty]
			public int progressRequired;

			[JsonProperty]
			public bool isUnlocked = false;

			[JsonIgnore]
			public string displayName;

			[JsonIgnore]
			public string description;

			[JsonIgnore]
			public bool runBasedProgress;

			[JsonIgnore]
			public List<string> nameLocalizations = new List<string>();

			[JsonIgnore]
			public List<string> descriptionLocalizations = new List<string>();

			[JsonIgnore]
			public Texture2D? icon;

			public CustomBadge(string name, string displayName, string description, List<string>? nameLocalizations = null, List<string>? descriptionLocalizations = null, Texture2D? icon = null, int progressRequired = 1, bool runBasedProgress = false, bool isUnlocked = false)
			{
				this.name = name;
				progress = 0;
				this.progressRequired = progressRequired;
				this.isUnlocked = isUnlocked;
				this.displayName = displayName;
				this.description = description;
				this.runBasedProgress = runBasedProgress;
				this.icon = icon;
				this.nameLocalizations = ((nameLocalizations != null && nameLocalizations.Count > 0) ? nameLocalizations : new List<string> { displayName });
				this.descriptionLocalizations = ((descriptionLocalizations != null && descriptionLocalizations.Count > 0) ? descriptionLocalizations : new List<string> { description });
				EnsureLocalizationLists(ref this.nameLocalizations, ref this.descriptionLocalizations, displayName, description);
			}

			public CustomBadgeStatus GetCustomBadgeStatus()
			{
				return new CustomBadgeStatus
				{
					progress = progress,
					isUnlocked = isUnlocked
				};
			}
		}

		public class CustomBadgeStatus
		{
			public int progress;

			public bool isUnlocked;
		}

		[HarmonyPatch(typeof(GUIManager), "Awake")]
		public class GUIManagerAwakePatch
		{
			private static void Postfix(GUIManager __instance)
			{
				BadgeManager mainBadgeManager = __instance.mainBadgeManager;
				BadgeData[] badgeData = mainBadgeManager.badgeData;
				int num = badgeData.Length + Instance.badgeDatas.Count;
				mainBadgeManager.badgeData = (BadgeData[])(object)new BadgeData[num];
				Array.Copy(badgeData, 0, mainBadgeManager.badgeData, 0, badgeData.Length);
				int availableBadgeDataIndex = Instance.GetAvailableBadgeDataIndex(mainBadgeManager.badgeData);
				if (availableBadgeDataIndex == -1)
				{
					return;
				}
				Transform val = ((Component)mainBadgeManager).transform.Find("Badges");
				Transform child = val.GetChild(0);
				foreach (KeyValuePair<string, BadgeData> badgeData2 in Instance.badgeDatas)
				{
					BadgeData value = badgeData2.Value;
					availableBadgeDataIndex = Instance.GetAvailableBadgeDataIndex(mainBadgeManager.badgeData);
					if (availableBadgeDataIndex == -1)
					{
						break;
					}
					mainBadgeManager.badgeData[availableBadgeDataIndex] = value;
					Transform val2 = Object.Instantiate<Transform>(child, val);
				}
			}
		}

		[HarmonyPatch(typeof(CharacterData), "SetBadgeStatus")]
		public class SetBadgeStatusPatch
		{
			private static void Prefix(CharacterData __instance, ref BadgeData[] __state)
			{
				BadgeManager mainBadgeManager = GUIManager.instance.mainBadgeManager;
				__state = mainBadgeManager.badgeData;
				if (__state.Length > 64)
				{
					BadgeData[] array = (BadgeData[])(object)new BadgeData[64];
					Array.Copy(__state, array, 64);
					mainBadgeManager.badgeData = array;
				}
			}

			private static void Postfix(CharacterData __instance, BadgeData[] __state)
			{
				GUIManager.instance.mainBadgeManager.badgeData = __state;
			}
		}

		[HarmonyPatch(typeof(BadgeManager), "OnEnable")]
		public class PauseBadgesMenuOnOpenPatch
		{
			private static void Postfix(BadgeManager __instance)
			{
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				if (__instance.initBadgesOnEnable)
				{
					PauseMenuAccoladesPage pauseBadgesMenu = Object.FindFirstObjectByType<PauseMenuAccoladesPage>();
					Instance.currentPage = 0;
					if ((Object)(object)Instance.prevPageButton == (Object)null)
					{
						Instance.InitializeBadgeSashUI(pauseBadgesMenu);
					}
					Instance.UpdatePage();
					Transform transform = ((Component)Instance.prevPageButton).transform;
					Transform transform2 = ((Component)Instance.nextPageButton).transform;
					Button backButton = ((Component)((Component)GUIManager.instance.mainBadgeManager).transform.parent).GetComponent<PauseMenuAccoladesPage>().backButton;
					((Component)Instance.prevPageButton).transform.localPosition = new Vector3(transform.localPosition.x, ((Component)backButton).transform.localPosition.y, transform.localPosition.z);
					((Component)Instance.nextPageButton).transform.localPosition = new Vector3(transform2.localPosition.x, ((Component)backButton).transform.localPosition.y, transform2.localPosition.z);
					PauseBadgesMenu val = Object.FindFirstObjectByType<PauseBadgesMenu>();
					if (!((Object)(object)val == (Object)null))
					{
					}
				}
			}
		}

		[HarmonyPatch(typeof(AchievementManager), "InitRunBasedValues")]
		public class AchievementManagerInitRunBasedValuesPatch
		{
			private static void Postfix()
			{
				foreach (KeyValuePair<string, CustomBadge> badge in Instance.badges)
				{
					if (badge.Value.runBasedProgress)
					{
						badge.Value.progress = 0;
					}
				}
				Instance.badgesEarnedThisRun.Clear();
			}
		}

		[HarmonyPatch(typeof(EndScreen), "GetBadgeUnlocks")]
		public class EndScreenGetBadgeUnlocksPatch
		{
			private static void Postfix(EndScreen __instance, ref List<BadgeData> __result)
			{
				foreach (string item in Instance.badgesEarnedThisRun)
				{
					BadgeData badgeData = Instance.GetBadgeData(item);
					if (!((Object)(object)badgeData == (Object)null))
					{
						__result.Add(badgeData);
					}
				}
			}
		}

		[HarmonyPatch(typeof(GameOverHandler), "LocalPlayerHasClosedEndScreen")]
		public class LocalPlayerHasClosedEndScreenPatch
		{
			private static void Postfix()
			{
				Instance.badgesEarnedThisRun.Clear();
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static class BadgeDataIsLockedPatch
		{
			public static bool Prefix(BadgeData __instance, ref bool __result)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)__instance.linkedAchievement > 0)
				{
					return true;
				}
				CustomBadge customBadge = GetCustomBadge(((Object)__instance).name);
				if (customBadge == null)
				{
					return true;
				}
				__result = !customBadge.isUnlocked;
				return false;
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static class CustomizationOptionIsLockedPatch
		{
			public static bool Prefix(CustomizationOption __instance, ref bool __result)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)__instance.requiredAchievement == 0 && Instance.customizationBadgeRequirements.TryGetValue(((Object)__instance).name, out CustomBadge value))
				{
					__result = !value.isUnlocked;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Customization), "TryGetUnlockedCosmetic")]
		public static class TryGetUnlockedCosmeticPatch
		{
			public static void Postfix(Customization __instance, BadgeData badge, ref CustomizationOption cosmetic, ref bool __result)
			{
				//IL_003c: 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_0044: Unknown result type (might be due to invalid IL or missing references)
				if (!Instance.customizationBadgeRequirements.ContainsKey(((Object)badge).name))
				{
					return;
				}
				foreach (Type value in Enum.GetValues(typeof(Type)))
				{
					CustomizationOption[] list = __instance.GetList(value);
					CustomizationOption[] array = list;
					foreach (CustomizationOption val2 in array)
					{
						if (((Object)val2).name == Instance.customizationBadgeRequirements[((Object)badge).name].name)
						{
							cosmetic = val2;
							__result = true;
							return;
						}
					}
				}
			}
		}

		[HarmonyPatch]
		public static class PauseMenuAccoladesPagePatches
		{
			[HarmonyPrefix]
			[HarmonyPatch(typeof(PauseMenuAccoladesPage), "Start")]
			public static void Prefix_Start(PauseMenuAccoladesPage __instance)
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: 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_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Expected O, but got Unknown
				Transform parent = ((Component)__instance).transform.Find("BadgeSash/Badges");
				Transform val = ((Component)__instance).transform.Find("BadgeSash/Badges2");
				RectTransform component = ((Component)((Component)((Component)__instance).transform.Find("BadgeSash")).transform).gameObject.GetComponent<RectTransform>();
				component.sizeDelta = new Vector2(0f, 330f);
				((Transform)component).localPosition = ((Transform)component).localPosition + new Vector3(0f, -92f, 0f);
				List<Transform> list = new List<Transform>();
				foreach (Transform item2 in val)
				{
					Transform item = item2;
					list.Add(item);
				}
				foreach (Transform item3 in list)
				{
					item3.SetParent(parent);
				}
				((TMP_Text)GUIManager.instance.mainBadgeManager.badgePopupDescription).alignment = (TextAlignmentOptions)258;
			}
		}

		public static MoreBadgesPlugin Instance;

		private static Harmony _harmony;

		private static readonly string OldSavePath = Path.Combine(Paths.ConfigPath, "MoreBadges.json");

		private static readonly string SavePath = Path.Combine(Application.persistentDataPath, "MoreBadges", "MoreBadges.json");

		public Dictionary<string, CustomBadge> badges = new Dictionary<string, CustomBadge>();

		public Dictionary<string, BadgeData> badgeDatas = new Dictionary<string, BadgeData>();

		public List<string> badgesEarnedThisRun = new List<string>();

		public Dictionary<string, CustomBadge> customizationBadgeRequirements = new Dictionary<string, CustomBadge>();

		private Button prevPageButton;

		private Button nextPageButton;

		private static readonly FieldRef<BadgeManager, BadgeUI[]> badgesRef = AccessTools.FieldRefAccess<BadgeManager, BadgeUI[]>("badges");

		private int pageCount = 1;

		private int currentPage = 0;

		public static void EnsureLocalizationLists(ref List<string> nameLocs, ref List<string> descLocs, string defaultName, string defaultDesc)
		{
			int num = 14;
			if (nameLocs == null)
			{
				nameLocs = new List<string>();
			}
			if (descLocs == null)
			{
				descLocs = new List<string>();
			}
			for (int i = 0; i <= num; i++)
			{
				if (nameLocs.Count <= i || string.IsNullOrEmpty(nameLocs[i]))
				{
					if (nameLocs.Count <= i)
					{
						nameLocs.Add(defaultName);
					}
					else
					{
						nameLocs[i] = defaultName;
					}
				}
				if (descLocs.Count <= i || string.IsNullOrEmpty(descLocs[i]))
				{
					if (descLocs.Count <= i)
					{
						descLocs.Add(defaultDesc);
					}
					else
					{
						descLocs[i] = defaultDesc;
					}
				}
			}
		}

		private void Awake()
		{
			Instance = this;
			ConfigManager.Setup(((BaseUnityPlugin)this).Config);
			LoadBadges();
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.snosz.morebadges");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		public static void RegisterBadge(CustomBadge badge, string? cosmeticName = null)
		{
			if (string.IsNullOrEmpty(badge.name))
			{
				return;
			}
			if (!Instance.badges.ContainsKey(badge.name))
			{
				Instance.badges[badge.name] = badge;
				Instance.ApplyLocalizations(badge);
				CreateCustomBadge(badge.name, badge.displayName, badge.description, (Texture)(object)badge.icon);
				if (cosmeticName != null)
				{
					RegisterCustomizationBadgeRequirement(cosmeticName, badge);
				}
				SaveBadges();
				Debug.Log((object)("[MoreBadges] Registered badge: " + badge.name));
				return;
			}
			CustomBadge customBadge = Instance.badges[badge.name];
			customBadge.displayName = badge.displayName;
			customBadge.description = badge.description;
			customBadge.icon = badge.icon;
			customBadge.runBasedProgress = badge.runBasedProgress;
			Instance.ApplyLocalizations(badge);
			CreateCustomBadge(customBadge.name, customBadge.displayName, customBadge.description, (Texture)(object)customBadge.icon);
			if (cosmeticName != null)
			{
				RegisterCustomizationBadgeRequirement(cosmeticName, customBadge);
			}
			SaveBadges();
			Debug.Log((object)("[MoreBadges] Registered badge: " + badge.name));
		}

		public static void RegisterBadgeAssetBundle(AssetBundle bundle)
		{
			CustomBadgeData[] array = bundle.LoadAllAssets<CustomBadgeData>();
			CustomBadgeData[] array2 = array;
			foreach (CustomBadgeData customBadgeData in array2)
			{
				CustomBadge badge = new CustomBadge(((Object)customBadgeData).name, customBadgeData.displayName, customBadgeData.description, customBadgeData.nameLocalizations, customBadgeData.descriptionLocalizations, customBadgeData.icon, customBadgeData.progressRequired, customBadgeData.runBasedProgress);
				RegisterBadge(badge, customBadgeData.cosmeticName);
			}
		}

		public static void RegisterCustomizationBadgeRequirement(string name, CustomBadge badge)
		{
			if (!string.IsNullOrEmpty(name) && !Instance.customizationBadgeRequirements.ContainsKey(name))
			{
				Instance.customizationBadgeRequirements[name] = badge;
			}
		}

		public static void SaveBadges()
		{
			List<CustomBadge> list = Instance.badges.Values.ToList();
			string contents = JsonConvert.SerializeObject((object)list, (Formatting)1);
			File.WriteAllText(SavePath, contents);
		}

		public static void LoadBadges()
		{
			string directoryName = Path.GetDirectoryName(SavePath);
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			if (!File.Exists(SavePath) && File.Exists(OldSavePath))
			{
				try
				{
					File.Move(OldSavePath, SavePath);
				}
				catch (IOException)
				{
					if (!File.Exists(SavePath))
					{
						File.Copy(OldSavePath, SavePath);
						File.Delete(OldSavePath);
					}
				}
			}
			if (!File.Exists(SavePath))
			{
				return;
			}
			string text = File.ReadAllText(SavePath);
			List<CustomBadge> list = JsonConvert.DeserializeObject<List<CustomBadge>>(text);
			if (list != null)
			{
				Instance.badges = list.ToDictionary((CustomBadge b) => b.name, (CustomBadge b) => b);
			}
		}

		public void ApplyLocalizations(CustomBadge badge)
		{
			if (!LocalizedText.mainTable.TryGetValue("NAME_" + badge.displayName.ToUpperInvariant(), out var _))
			{
				LocalizedText.mainTable.Add("NAME_" + badge.displayName.ToUpperInvariant(), badge.nameLocalizations);
				LocalizedText.mainTable.Add("DESC_" + badge.displayName.ToUpperInvariant(), badge.descriptionLocalizations);
			}
		}

		public static BadgeData? CreateCustomBadge(string name, string displayName, string description, Texture icon)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (Instance.badgeDatas.TryGetValue(name, out BadgeData _))
			{
				return null;
			}
			BadgeData val = ScriptableObject.CreateInstance<BadgeData>();
			((Object)val).name = name;
			val.visualID = 100 + Instance.badgeDatas.Count;
			val.displayName = displayName;
			val.description = description;
			val.icon = icon;
			val.linkedAchievement = (ACHIEVEMENTTYPE)0;
			Instance.badgeDatas.Add(name, val);
			return val;
		}

		public static CustomBadge? GetCustomBadge(string name)
		{
			if (Instance.badges.TryGetValue(name, out CustomBadge value))
			{
				return value;
			}
			return null;
		}

		public BadgeData? GetBadgeData(string name)
		{
			if (Instance.badgeDatas.TryGetValue(name, out BadgeData value))
			{
				return value;
			}
			return null;
		}

		public int GetAvailableBadgeDataIndex(BadgeData[] badgeDatas)
		{
			for (int i = 0; i < badgeDatas.Length; i++)
			{
				if ((Object)(object)badgeDatas[i] == (Object)null)
				{
					return i;
				}
			}
			return -1;
		}

		public static void AddProgress(string badgeName, int amount)
		{
			if (Instance.badges.TryGetValue(badgeName, out CustomBadge value) && !value.isUnlocked)
			{
				value.progress += amount;
				if (value.progress >= value.progressRequired)
				{
					HandleBadgeCompleted(value);
					SaveBadges();
				}
				if (!value.runBasedProgress)
				{
					SaveBadges();
				}
			}
		}

		private static void HandleBadgeCompleted(CustomBadge badge)
		{
			badge.progress = badge.progressRequired;
			badge.isUnlocked = true;
			Debug.Log((object)("[MoreBadges] Badge unlocked: " + badge.name));
			if (ConfigManager.EnableBadgePopups.Value)
			{
				BadgeUIFactory.CreateOrUpdateAchievementPopup(badge, badge.progress);
			}
			BadgeData val = Instance.badgeDatas[badge.name];
			if ((Object)(object)val != (Object)null)
			{
				Instance.badgesEarnedThisRun.Add(((Object)val).name);
			}
		}

		public static int GetProgress(string badgeName)
		{
			if (Instance.badges.TryGetValue(badgeName, out CustomBadge value))
			{
				return value.progress;
			}
			return -1;
		}

		public static CustomBadgeStatus? GetCustomBadgeStatus(string badgeName)
		{
			return GetCustomBadge(badgeName)?.GetCustomBadgeStatus();
		}

		private void OnPrevPageButtonClicked()
		{
			currentPage--;
			currentPage = Mathf.Max(currentPage, 0);
			UpdatePage();
		}

		private void OnNextPageButtonClicked()
		{
			currentPage++;
			currentPage = Mathf.Min(currentPage, pageCount);
			UpdatePage();
		}

		private void UpdatePage()
		{
			BadgeUI[] array = badgesRef.Invoke(GUIManager.instance.mainBadgeManager);
			for (int i = 0; i < array.Length; i++)
			{
				int num = currentPage * 64;
				int num2 = num + 64;
				((Component)array[i]).gameObject.SetActive(i >= num && i < num2 && (Object)(object)array[i].data != (Object)null);
			}
			((Component)Instance.prevPageButton).gameObject.SetActive(currentPage > 0);
			((Component)Instance.nextPageButton).gameObject.SetActive(currentPage < pageCount);
		}

		public void InitializeBadgeSashUI(PauseMenuAccoladesPage pauseBadgesMenu)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Expected O, but got Unknown
			Button backButton = pauseBadgesMenu.backButton;
			prevPageButton = Object.Instantiate<Button>(backButton, ((Component)backButton).transform.parent);
			Transform transform = ((Component)prevPageButton).transform;
			transform.localPosition += new Vector3(-300f, 0f, 0f);
			((Graphic)((Component)((Component)prevPageButton).transform.Find("Panel")).GetComponent<Image>()).color = new Color(0.1416f, 0.2925f, 0.1173f, 1f);
			foreach (Transform item in ((Component)prevPageButton).transform)
			{
				Transform val = item;
				if (((Object)val).name == "Border")
				{
					((Graphic)((Component)val).GetComponent<Image>()).color = new Color(0.0512f, 0.434f, 0.115f, 1f);
				}
			}
			if (!LocalizedText.mainTable.TryGetValue("PREVIOUS", out var _))
			{
				List<string> list = new List<string>();
				list.Add("PREVIOUS");
				LocalizedText.mainTable.Add("PREVIOUS", list);
			}
			((Component)prevPageButton).GetComponentInChildren<LocalizedText>().SetIndex("PREVIOUS");
			((TMP_Text)((Component)prevPageButton).GetComponentInChildren<TextMeshProUGUI>()).text = "PREVIOUS";
			nextPageButton = Object.Instantiate<Button>(backButton, ((Component)backButton).transform.parent);
			Transform transform2 = ((Component)nextPageButton).transform;
			transform2.localPosition += new Vector3(300f, 0f, 0f);
			foreach (Transform item2 in ((Component)nextPageButton).transform)
			{
				Transform val2 = item2;
				if (((Object)val2).name == "Border")
				{
					((Graphic)((Component)val2).GetComponent<Image>()).color = new Color(0f, 0.5612f, 0.5943f, 1f);
				}
			}
			((Graphic)((Component)((Component)nextPageButton).transform.Find("Panel")).GetComponent<Image>()).color = new Color(0.185f, 0.394f, 0.6226f, 1f);
			((Component)nextPageButton).GetComponentInChildren<LocalizedText>().SetIndex("NEXT");
			((TMP_Text)((Component)nextPageButton).GetComponentInChildren<TextMeshProUGUI>()).text = "NEXT";
			((UnityEvent)prevPageButton.onClick).AddListener(new UnityAction(OnPrevPageButtonClicked));
			((UnityEvent)nextPageButton.onClick).AddListener(new UnityAction(OnNextPageButtonClicked));
			BadgeManager mainBadgeManager = GUIManager.instance.mainBadgeManager;
			int num = badgesRef.Invoke(mainBadgeManager).Length;
			((Component)prevPageButton).gameObject.SetActive(true);
			((Component)nextPageButton).gameObject.SetActive(true);
			pageCount = (int)Mathf.Ceil((float)(num / 64));
		}
	}
	public class CustomBadgeData : ScriptableObject
	{
		public string displayName;

		public string description;

		public int progressRequired = 1;

		public bool runBasedProgress;

		public Texture2D icon;

		public string cosmeticName;

		public List<string> nameLocalizations = new List<string>();

		public List<string> descriptionLocalizations = new List<string>();
	}
}