Decompiled source of UpgradeEveryRound v2.0.3

UpgradeEveryRound.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using REPOLib.Modules;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;

[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("UpgradeEveryRound")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.3")]
[assembly: AssemblyInformationalVersion("2.0.3+5afcb5a3443f338f580af04e2dbfb911a7c75e80")]
[assembly: AssemblyProduct("Upgrade Every Round")]
[assembly: AssemblyTitle("UpgradeEveryRound")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.3.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 UpgradeEveryRound
{
	[HarmonyPatch(typeof(StatsUI), "Update")]
	public static class StatsUIPatch
	{
		private static void Prefix(ref float ___showStatsTimer)
		{
			if (UpgradeMenu.isOpen)
			{
				___showStatsTimer = 5f;
			}
		}
	}
	[HarmonyPatch(typeof(StatsManager))]
	[HarmonyPatch("Start")]
	public static class StatsManagerStartPatch
	{
		private static void Prefix(StatsManager __instance)
		{
			__instance.dictionaryOfDictionaries.Add("playerUpgradesUsed", new Dictionary<string, int>());
		}

		private static void Postfix(ref StatsManager __instance)
		{
			ModUpgradeHandler.BuildExtraUpgradeList();
		}
	}
	[HarmonyPatch(typeof(RunManager))]
	[HarmonyPatch("LeaveToMainMenu")]
	public static class RunManagerMainMenuPatch
	{
		private static void Prefix()
		{
			UpgradeMenu.isOpen = false;
		}
	}
	internal static class ModUpgradeHandler
	{
		private static bool initialized = false;

		public static Dictionary<int, ConfigEntry<bool>> AllowExtras = new Dictionary<int, ConfigEntry<bool>>();

		public static Dictionary<int, string> ExtraLabels = new Dictionary<int, string>();

		public static Dictionary<string, GameObject> ExtraUpgrades = new Dictionary<string, GameObject>();

		public static List<BitVector32> ExtraConfigs = new List<BitVector32>();

		internal static void DoUpgrade(string upgradeLabel, string _steamID)
		{
			if ((Object)(object)ExtraUpgrades[upgradeLabel] == (Object)null)
			{
				PlayerUpgrade upgrade = Upgrades.GetUpgrade(upgradeLabel.Replace(" ", ""));
				if (upgrade != null)
				{
					upgrade.AddLevel(_steamID, 1);
				}
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(ExtraUpgrades[upgradeLabel]);
			MonoBehaviour[] components = val.GetComponents<MonoBehaviour>();
			for (int i = 0; i < components.Length; i++)
			{
				Traverse val2 = Traverse.Create((object)components[i]).Method("Start", Array.Empty<Type>(), (object[])null);
				if (val2.MethodExists())
				{
					val2.GetValue(Array.Empty<object>());
				}
			}
			ItemToggle component = val.GetComponent<ItemToggle>();
			ItemUpgrade component2 = val.GetComponent<ItemUpgrade>();
			Traverse.Create((object)component).Field<int>("playerTogglePhotonID").Value = SemiFunc.PlayerGetFromSteamID(_steamID).photonView.ViewID;
			Traverse obj = Traverse.Create((object)component2);
			obj.Field<PhysGrabObjectImpactDetector>("impactDetector").Value.destroyDisable = true;
			obj.Method("PlayerUpgrade", Array.Empty<Type>(), (object[])null).GetValue(Array.Empty<object>());
			Object.Destroy((Object)(object)val);
		}

		public static void BuildExtraUpgradeList()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			if (initialized)
			{
				return;
			}
			Plugin.Logger.LogMessage((object)"Building extra upgrades list");
			int num = 0;
			Regex regex = new Regex("(?<!^)(?=[A-Z])");
			AllowExtras.Clear();
			ExtraLabels.Clear();
			ExtraConfigs.Clear();
			foreach (PlayerUpgrade playerUpgrade in Upgrades.PlayerUpgrades)
			{
				string text = string.Join(" ", regex.Split(playerUpgrade.UpgradeId));
				ConfigEntry<bool> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Enabled upgrades", "Enable " + text, true, new ConfigDescription("Allows " + text + " Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
				AllowExtras.Add(num, val);
				ExtraLabels.Add(num, text);
				ExtraUpgrades.Add(text, null);
				val.SettingChanged += Plugin.ConfigUpdated;
				UpdateExtraConfig(num, val);
				num++;
			}
			string[] source = new string[8] { "Map Player Count", "Stamina", "Extra Jump", "Range", "Strength", "Health", "Sprint Speed", "Tumble Launch" };
			foreach (Item item in from x in Items.GetItems()
				where (int)x.itemType == 3
				select x)
			{
				string itemName = item.itemName;
				string text2 = itemName.Substring(0, itemName.Length - 8).Trim();
				if (!ExtraUpgrades.ContainsKey(text2) && !source.Contains(text2))
				{
					ConfigEntry<bool> val2 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Enabled upgrades", "Enable " + text2, true, new ConfigDescription("Allows " + text2 + " Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
					AllowExtras.Add(num, val2);
					ExtraLabels.Add(num, text2);
					ExtraUpgrades.Add(text2, item.prefab);
					val2.SettingChanged += Plugin.ConfigUpdated;
					UpdateExtraConfig(num, val2);
					num++;
				}
			}
			Plugin.localNetworkData = new NetworkData();
			initialized = true;
		}

		private static int UpdateExtraConfig(int configIndex, ConfigEntry<bool> allowCustomUpgrade)
		{
			int num = configIndex / 32;
			int bit = configIndex % 32;
			while (ExtraConfigs.Count <= num)
			{
				ExtraConfigs.Add(default(BitVector32));
			}
			BitVector32 value = ExtraConfigs[num];
			value[bit] = allowCustomUpgrade.Value;
			ExtraConfigs[num] = value;
			return num;
		}

		public static bool AllowCustomUpgradeByIndex(int configIndex)
		{
			int num = configIndex / 32;
			int bit = configIndex % 32;
			return new BitVector32(Plugin.CurrentNetworkData.extraData[num])[bit];
		}
	}
	[Serializable]
	public record NetworkData
	{
		public int upgradesPerRound;

		public bool limitedChoices;

		public int numChoices;

		public bool allowMapCount;

		public bool allowEnergy;

		public bool allowExtraJump;

		public bool allowRange;

		public bool allowStrength;

		public bool allowHealth;

		public bool allowSpeed;

		public bool allowTumbleLaunch;

		public int[] extraData;

		public NetworkData()
		{
			upgradesPerRound = Plugin.upgradesPerRound.Value;
			limitedChoices = Plugin.limitedChoices.Value;
			numChoices = Plugin.numChoices.Value;
			allowMapCount = Plugin.allowMapCount.Value;
			allowEnergy = Plugin.allowEnergy.Value;
			allowExtraJump = Plugin.allowExtraJump.Value;
			allowRange = Plugin.allowRange.Value;
			allowStrength = Plugin.allowStrength.Value;
			allowHealth = Plugin.allowHealth.Value;
			allowSpeed = Plugin.allowSpeed.Value;
			allowTumbleLaunch = Plugin.allowTumbleLaunch.Value;
			extraData = ModUpgradeHandler.ExtraConfigs.Select((BitVector32 config) => config.Data).ToArray();
		}

		public static byte[] Serealize(object data)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream memoryStream = new MemoryStream();
			binaryFormatter.Serialize(memoryStream, data);
			return memoryStream.ToArray();
		}

		public static NetworkData Deserialize(byte[] arrBytes)
		{
			using MemoryStream memoryStream = new MemoryStream();
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			memoryStream.Write(arrBytes, 0, arrBytes.Length);
			memoryStream.Seek(0L, SeekOrigin.Begin);
			return (NetworkData)binaryFormatter.Deserialize(memoryStream);
		}
	}
	[HarmonyPatch(typeof(SemiFunc))]
	[HarmonyPatch("OnLevelGenDone")]
	internal static class OnLevelGenDonePatch
	{
		internal static void Postfix()
		{
			UERNetworkManager.levelLoaded = true;
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				UpgradeMenu.OpenMenu();
			}
		}
	}
	[BepInPlugin("dev.redfops.repo.upgradeeveryround", "Upgrade Every Round", "2.0.3")]
	[BepInDependency("nickklmao.menulib", "2.1.3")]
	[BepInDependency("REPOLib", "2.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static EventHandler <0>__ConfigUpdated;

			public static Action<EventData> <1>__HandleConfigUpdateEvent;

			public static Action<EventData> <2>__HandleClientUpgradeEvent;

			public static DeserializeMethod <3>__Deserialize;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static SerializeMethod <>9__25_0;

			internal byte[] <Awake>b__25_0(object x)
			{
				return NetworkData.Serealize(x);
			}
		}

		public const string modGUID = "dev.redfops.repo.upgradeeveryround";

		public const string modName = "Upgrade Every Round";

		public const string modVersion = "2.0.3";

		public static ConfigEntry<int> upgradesPerRound;

		public static ConfigEntry<bool> limitedChoices;

		public static ConfigEntry<int> numChoices;

		public static Plugin Instance;

		public static ConfigEntry<bool> allowMapCount;

		public static ConfigEntry<bool> allowEnergy;

		public static ConfigEntry<bool> allowExtraJump;

		public static ConfigEntry<bool> allowRange;

		public static ConfigEntry<bool> allowStrength;

		public static ConfigEntry<bool> allowHealth;

		public static ConfigEntry<bool> allowSpeed;

		public static ConfigEntry<bool> allowTumbleLaunch;

		public static NetworkData localNetworkData;

		public static NetworkData remoteNetworkData;

		public static NetworkedEvent ConfigUpdateEvent;

		public static NetworkedEvent ClientUpgradeEvent;

		public static RaiseEventOptions ConfigUpdateEventOptions = new RaiseEventOptions
		{
			CachingOption = (EventCaching)4,
			Receivers = (ReceiverGroup)0
		};

		public static RaiseEventOptions ClientUpgradeEventOptions = new RaiseEventOptions
		{
			Receivers = (ReceiverGroup)2
		};

		internal static ManualLogSource Logger;

		private readonly Harmony harmony = new Harmony("dev.redfops.repo.upgradeeveryround");

		public static NetworkData CurrentNetworkData
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)GameManager.instance) || SemiFunc.IsMasterClientOrSingleplayer())
				{
					return localNetworkData;
				}
				if (remoteNetworkData == null)
				{
					Logger.LogError((object)"Missing remote data");
					return localNetworkData;
				}
				return remoteNetworkData;
			}
		}

		public static int UpgradesPerRound => CurrentNetworkData.upgradesPerRound;

		public static bool LimitedChoices => CurrentNetworkData.limitedChoices;

		public static int NumChoices => CurrentNetworkData.numChoices;

		public static bool AllowMapCount => CurrentNetworkData.allowMapCount;

		public static bool AllowEnergy => CurrentNetworkData.allowEnergy;

		public static bool AllowExtraJump => CurrentNetworkData.allowExtraJump;

		public static bool AllowRange => CurrentNetworkData.allowRange;

		public static bool AllowStrength => CurrentNetworkData.allowStrength;

		public static bool AllowHealth => CurrentNetworkData.allowHealth;

		public static bool AllowSpeed => CurrentNetworkData.allowSpeed;

		public static bool AllowTumbleLaunch => CurrentNetworkData.allowTumbleLaunch;

		private void Awake()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Expected O, but got Unknown
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Expected O, but got Unknown
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Expected O, but got Unknown
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			upgradesPerRound = ((BaseUnityPlugin)this).Config.Bind<int>("Upgrades", "Upgrades Per Round", 1, new ConfigDescription("Number of upgrades per round", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 7), Array.Empty<object>()));
			limitedChoices = ((BaseUnityPlugin)this).Config.Bind<bool>("Upgrades", "Limited random choices", false, new ConfigDescription("Only presents a fixed number of random options", (AcceptableValueBase)null, Array.Empty<object>()));
			numChoices = ((BaseUnityPlugin)this).Config.Bind<int>("Upgrades", "Number of choices", 3, new ConfigDescription("Number of options to choose from per upgrade", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
			allowMapCount = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Map Player Count", true, new ConfigDescription("Allows Map Player Count Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			allowEnergy = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Stamina", true, new ConfigDescription("Allows Stamina Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			allowExtraJump = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Extra Jump", true, new ConfigDescription("Allows Extra Jump Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			allowRange = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Range", true, new ConfigDescription("Allows Range Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			allowStrength = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Strength", true, new ConfigDescription("Allows Strength Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			allowHealth = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Health", true, new ConfigDescription("Allows Health Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			allowSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Speed", true, new ConfigDescription("Allows Speed Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			allowTumbleLaunch = ((BaseUnityPlugin)this).Config.Bind<bool>("Enabled upgrades", "Enable Tumble Launch", true, new ConfigDescription("Allows Tumble Launch Upgrade to be chosen", (AcceptableValueBase)null, Array.Empty<object>()));
			upgradesPerRound.SettingChanged += ConfigUpdated;
			limitedChoices.SettingChanged += ConfigUpdated;
			numChoices.SettingChanged += ConfigUpdated;
			allowMapCount.SettingChanged += ConfigUpdated;
			allowEnergy.SettingChanged += ConfigUpdated;
			allowExtraJump.SettingChanged += ConfigUpdated;
			allowRange.SettingChanged += ConfigUpdated;
			allowStrength.SettingChanged += ConfigUpdated;
			allowHealth.SettingChanged += ConfigUpdated;
			allowSpeed.SettingChanged += ConfigUpdated;
			allowTumbleLaunch.SettingChanged += ConfigUpdated;
			ConfigUpdateEvent = new NetworkedEvent("ConfigUpdate", (Action<EventData>)HandleConfigUpdateEvent);
			ClientUpgradeEvent = new NetworkedEvent("ClientUpgrade", (Action<EventData>)HandleClientUpgradeEvent);
			harmony.PatchAll(typeof(SceneSwitchPatch));
			harmony.PatchAll(typeof(OnLevelGenDonePatch));
			harmony.PatchAll(typeof(SteamManagerPatch));
			harmony.PatchAll(typeof(RunManagerMainMenuPatch));
			harmony.PatchAll(typeof(StatsManagerStartPatch));
			harmony.PatchAll(typeof(StatsUIPatch));
			Type typeFromHandle = typeof(NetworkData);
			object obj = <>c.<>9__25_0;
			if (obj == null)
			{
				SerializeMethod val = (object x) => NetworkData.Serealize(x);
				<>c.<>9__25_0 = val;
				obj = (object)val;
			}
			object obj2 = <>O.<3>__Deserialize;
			if (obj2 == null)
			{
				DeserializeMethod val2 = NetworkData.Deserialize;
				<>O.<3>__Deserialize = val2;
				obj2 = (object)val2;
			}
			PhotonPeer.RegisterType(typeFromHandle, (byte)248, (SerializeMethod)obj, (DeserializeMethod)obj2);
			((MonoBehaviour)this).StartCoroutine(UERNetworkManager.Go());
			Logger.LogInfo((object)"Plugin UpgradeEveryRound is loaded!");
		}

		internal static void ConfigUpdated(object sender, EventArgs args)
		{
			localNetworkData = new NetworkData();
			if (SemiFunc.IsMultiplayer() && PhotonNetwork.IsMasterClient)
			{
				SendConfig();
			}
		}

		public static void SendConfig()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ConfigUpdateEvent.RaiseEvent((object)localNetworkData, ConfigUpdateEventOptions, SendOptions.SendReliable);
		}

		private static void HandleConfigUpdateEvent(EventData eventData)
		{
			remoteNetworkData = (NetworkData)eventData.CustomData;
		}

		public static void DoUpgradeClient(string upgradeLabel, string _steamID)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			string text = upgradeLabel + ";;;" + _steamID;
			ClientUpgradeEvent.RaiseEvent((object)text, ClientUpgradeEventOptions, SendOptions.SendReliable);
		}

		private static void HandleClientUpgradeEvent(EventData eventData)
		{
			string obj = (string)eventData.CustomData;
			string text = obj.Split(";;;")[0];
			string text2 = obj.Split(";;;")[1];
			switch (text)
			{
			case "Stamina":
				PunManager.instance.UpgradePlayerEnergy(text2);
				break;
			case "Extra Jump":
				PunManager.instance.UpgradePlayerExtraJump(text2);
				break;
			case "Range":
				PunManager.instance.UpgradePlayerGrabRange(text2);
				break;
			case "Strength":
				PunManager.instance.UpgradePlayerGrabStrength(text2);
				break;
			case "Health":
				PunManager.instance.UpgradePlayerHealth(text2);
				break;
			case "Sprint Speed":
				PunManager.instance.UpgradePlayerSprintSpeed(text2);
				break;
			case "Tumble Launch":
				PunManager.instance.UpgradePlayerTumbleLaunch(text2);
				break;
			case "Map Player Count":
				PunManager.instance.UpgradeMapPlayerCount(text2);
				break;
			default:
				ModUpgradeHandler.DoUpgrade(text, text2);
				break;
			}
			PunManager.instance.UpdateStat("playerUpgradesUsed", text2, StatsManager.instance.dictionaryOfDictionaries["playerUpgradesUsed"][text2] + 1);
		}

		public static void ApplyUpgrade(string _steamID, REPOPopupPage popupPage)
		{
			StatsUI.instance.Fetch();
			StatsUI.instance.ShowStats();
			CameraGlitch.Instance.PlayUpgrade();
			int num = (UERNetworkManager.upgradesUsedLocal = NumUpgradesUsed(_steamID) + 1);
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				PunManager.instance.UpdateStat("playerUpgradesUsed", _steamID, num);
			}
			UpgradeMenu.isOpen = false;
			popupPage.ClosePage(true);
			if (RunManager.instance.levelsCompleted * UpgradesPerRound > num)
			{
				UpgradeMenu.createMenu(_steamID).OpenPage(false);
				UpgradeMenu.isOpen = true;
			}
		}

		public static int NumUpgradesUsed(string _steamID)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return UERNetworkManager.upgradesUsedLocal;
			}
			return StatsManager.instance.dictionaryOfDictionaries["playerUpgradesUsed"][_steamID];
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradeMapPlayerCount")]
	public static class UpgradeMapPlayerCountPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradeMapPlayerCountRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeMapPlayerCount[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerEnergy")]
	public static class UpgradePlayerEnergyPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradePlayerEnergyCountRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeStamina[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerExtraJump")]
	public static class UpgradePlayerExtraJumpPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradePlayerExtraJumpRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeExtraJump[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerGrabRange")]
	public static class UpgradePlayerGrabRangePatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradePlayerGrabRangeRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeRange[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerGrabStrength")]
	public static class UpgradePlayerGrabStrengthPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradePlayerGrabStrengthRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeStrength[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerHealth")]
	public static class UpgradePlayerHealthPatch
	{
		private static void Postfix(string playerName, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradePlayerHealthRPC", (RpcTarget)1, new object[2]
				{
					playerName,
					___statsManager.playerUpgradeHealth[playerName]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerSprintSpeed")]
	public static class UpgradePlayerSprintSpeedPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradePlayerSprintSpeedRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeSpeed[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerTumbleLaunch")]
	public static class UpgradePlayerTumbleLaunchPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer() && UpgradeMenu.isOpen)
			{
				___photonView.RPC("UpgradePlayerTumbleLaunchRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeLaunch[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(SemiFunc))]
	[HarmonyPatch("OnSceneSwitch")]
	internal static class SceneSwitchPatch
	{
		private static void Prefix()
		{
			UERNetworkManager.LevelChange();
		}
	}
	[HarmonyPatch(typeof(SteamManager))]
	internal static class SteamManagerPatch
	{
		[HarmonyPatch("UnlockLobby")]
		[HarmonyPostfix]
		internal static void UnlockLobbyPostfix()
		{
			Plugin.SendConfig();
		}
	}
	public static class UERNetworkManager
	{
		[CompilerGenerated]
		private sealed class <Go>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					if (!Object.op_Implicit((Object)(object)GameManager.instance) || SemiFunc.IsMasterClientOrSingleplayer())
					{
						synced = false;
						levelLoaded = false;
						menuOpened = false;
						upgradesUsedLocal = -1;
					}
					else
					{
						if (!joinedGame)
						{
							StatsManager.instance.dictionaryOfDictionaries["playerUpgradesUsed"][SteamClient.SteamId.Value.ToString()] = -1;
							joinedGame = true;
						}
						if (levelLoaded)
						{
							synced = StatsManager.instance.statsSynced;
							if (synced && levelLoaded && !menuOpened && StatsManager.instance.dictionaryOfDictionaries["playerUpgradesUsed"][SteamClient.SteamId.Value.ToString()] != -1)
							{
								if (upgradesUsedLocal == -1)
								{
									upgradesUsedLocal = StatsManager.instance.dictionaryOfDictionaries["playerUpgradesUsed"][SteamClient.SteamId.Value.ToString()];
								}
								UpgradeMenu.OpenMenu();
								menuOpened = true;
							}
						}
					}
				}
				else
				{
					<>1__state = -1;
				}
				<>2__current = (object)new WaitForFixedUpdate();
				<>1__state = 1;
				return true;
			}

			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 static bool synced = false;

		public static bool levelLoaded = false;

		public static bool menuOpened = false;

		private static bool joinedGame = false;

		public static int upgradesUsedLocal = -1;

		[IteratorStateMachine(typeof(<Go>d__5))]
		public static IEnumerator Go()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Go>d__5(0);
		}

		public static void LevelChange()
		{
			synced = false;
			levelLoaded = false;
			menuOpened = false;
		}
	}
	public static class UpgradeMenu
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__3_0;

			internal void <createMenu>b__3_0()
			{
				isOpen = false;
			}
		}

		public static bool isOpen;

		public static bool choseUpgrade;

		public static void OpenMenu()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!isOpen && !((IEnumerable<Level>)(object)new Level[3]
			{
				RunManager.instance.levelMainMenu,
				RunManager.instance.levelLobbyMenu,
				RunManager.instance.levelTutorial
			}).Contains(RunManager.instance.levelCurrent))
			{
				string steamID = SteamClient.SteamId.Value.ToString();
				int num = RunManager.instance.levelsCompleted * Plugin.UpgradesPerRound;
				if (Plugin.NumUpgradesUsed(steamID) < num)
				{
					MenuManager.instance.PageCloseAll();
					REPOPopupPage obj = createMenu(steamID);
					isOpen = true;
					obj.OpenPage(false);
				}
			}
		}

		public static REPOPopupPage createMenu(string _steamID)
		{
			//IL_0063: 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)
			//IL_006e: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: 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_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Expected O, but got Unknown
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Expected O, but got Unknown
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Expected O, but got Unknown
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Expected O, but got Unknown
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Expected O, but got Unknown
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Expected O, but got Unknown
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Expected O, but got Unknown
			choseUpgrade = false;
			StatsUI.instance.Fetch();
			StatsUI.instance.ShowStats();
			REPOPopupPage repoPopupPage = MenuAPI.CreateREPOPopupPage("Choose an upgrade", (PresetSide)1, false, true, 1.5f);
			UnityEvent onPageEnd = repoPopupPage.menuPage.onPageEnd;
			object obj = <>c.<>9__3_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					isOpen = false;
				};
				<>c.<>9__3_0 = val;
				obj = (object)val;
			}
			onPageEnd.AddListener((UnityAction)obj);
			List<int> list = new List<int>(8) { 0, 1, 2, 3, 4, 5, 6, 7 };
			List<bool> list2 = new List<bool>(8)
			{
				Plugin.AllowEnergy,
				Plugin.AllowExtraJump,
				Plugin.AllowRange,
				Plugin.AllowStrength,
				Plugin.AllowHealth,
				Plugin.AllowSpeed,
				Plugin.AllowTumbleLaunch,
				Plugin.AllowMapCount
			};
			foreach (KeyValuePair<int, ConfigEntry<bool>> allowExtra in ModUpgradeHandler.AllowExtras)
			{
				int key = allowExtra.Key;
				list.Add(list.Count);
				list2.Add(ModUpgradeHandler.AllowCustomUpgradeByIndex(key));
			}
			int numChoices = (Plugin.LimitedChoices ? Plugin.NumChoices : list.Count);
			int num = 0;
			for (int j = 0; j < list.Count; j++)
			{
				if (!list2[j])
				{
					list.RemoveAt(j - num);
					num++;
				}
			}
			numChoices = Mathf.Min(numChoices, list.Count);
			_ = new Vector2[8]
			{
				new Vector2(390f, 18f),
				new Vector2(530f, 18f),
				new Vector2(390f, 60f),
				new Vector2(530f, 60f),
				new Vector2(390f, 102f),
				new Vector2(530f, 102f),
				new Vector2(390f, 144f),
				new Vector2(530f, 144f)
			};
			for (int i = 0; i < numChoices; i++)
			{
				int index = (Plugin.LimitedChoices ? Random.Range(0, list.Count) : 0);
				int choice = list[index];
				list.RemoveAt(index);
				_ = i;
				switch (choice)
				{
				case 0:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Stamina", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradePlayerEnergy(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Stamina", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				case 1:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Extra Jump", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradePlayerExtraJump(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Extra Jump", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				case 2:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Range", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradePlayerGrabRange(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Range", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				case 3:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Strength", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradePlayerGrabStrength(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Strength", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				case 4:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Health", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradePlayerHealth(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Health", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				case 5:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Sprint Speed", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradePlayerSprintSpeed(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Sprint Speed", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				case 6:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Tumble Launch", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradePlayerTumbleLaunch(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Tumble Launch", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				case 7:
					repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
					{
						CreateButton(parent, "Map Player Count", delegate
						{
							if (SemiFunc.IsMasterClientOrSingleplayer())
							{
								PunManager.instance.UpgradeMapPlayerCount(_steamID);
							}
							else
							{
								Plugin.DoUpgradeClient("Map Player Count", _steamID);
							}
						}, i, numChoices, _steamID, repoPopupPage);
					});
					continue;
				}
				repoPopupPage.AddElement((BuilderDelegate)delegate(Transform parent)
				{
					CreateButton(parent, ModUpgradeHandler.ExtraLabels[choice - 8], delegate
					{
						if (SemiFunc.IsMasterClientOrSingleplayer())
						{
							ModUpgradeHandler.DoUpgrade(ModUpgradeHandler.ExtraLabels[choice - 8], _steamID);
						}
						else
						{
							Plugin.DoUpgradeClient(ModUpgradeHandler.ExtraLabels[choice - 8], _steamID);
						}
					}, i, numChoices, _steamID, repoPopupPage);
				});
			}
			return repoPopupPage;
		}

		private static REPOButton CreateButton(Transform parent, string buttonText, Action upgradeStat, int buttonNumber, int totalButtons, string _steamID, REPOPopupPage page)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			(Vector2, float) buttonPos = GetButtonPos(buttonNumber, totalButtons);
			Vector2 item = buttonPos.Item1;
			float item2 = buttonPos.Item2;
			REPOButton obj = MenuAPI.CreateREPOButton(buttonText, (Action)delegate
			{
				if (!choseUpgrade)
				{
					choseUpgrade = true;
					upgradeStat();
					Plugin.ApplyUpgrade(_steamID, page);
				}
			}, parent, item);
			TextMeshProUGUI labelTMP = obj.labelTMP;
			((TMP_Text)labelTMP).fontSize = ((TMP_Text)labelTMP).fontSize * item2;
			return obj;
		}

		private static (Vector2, float) GetButtonPos(int buttonNumber, int totalButtons)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (totalButtons <= 8)
			{
				return (new Vector2(370f + (float)(140 * (buttonNumber % 2)), 270f - 52f * (float)(buttonNumber / 2)), 0.9f);
			}
			float num = 252f;
			int num2 = 8;
			float num3 = num / (42f * (float)(totalButtons / num2));
			float num4 = num3 * 42f;
			float num5 = num3 * 180f;
			num2 = Math.Max((int)(370f / num5), 2);
			while (num2 != 1)
			{
				num2--;
				num3 = Math.Min(num / (42f * (float)(totalButtons / num2)), 2f / (float)num2);
				num4 = num3 * 42f;
				num5 = num3 * 180f;
				if (!((float)(totalButtons / num2) * num4 < num))
				{
					break;
				}
			}
			num2++;
			num3 = Math.Min(num / (42f * (float)(totalButtons / num2)), 2f / (float)num2);
			num4 = num3 * 42f;
			num5 = num3 * 180f;
			return (new Vector2(370f + (float)(buttonNumber % num2) * num5, 270f - (float)(buttonNumber / num2) * num4), num3 * 0.9f);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "UpgradeEveryRound";

		public const string PLUGIN_NAME = "Upgrade Every Round";

		public const string PLUGIN_VERSION = "2.0.3";
	}
}