Decompiled source of Empress SharedUpgrades v1.1.4

EmpressSharedUpgrades.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[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("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EmpressSharedUpgrades")]
[assembly: AssemblyTitle("EmpressSharedUpgrades")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 Empress.SharedUpgrades
{
	internal static class RepOLibCompat
	{
		private static MethodInfo? _miAddLevel;

		private static bool _installed;

		[ThreadStatic]
		private static bool _localGuard;

		internal static void TryInstall(Harmony harmony, ManualLogSource log)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			if (_installed)
			{
				return;
			}
			Type type = AccessTools.TypeByName("REPOLib.Modules.PlayerUpgrade");
			if (type == null)
			{
				log.LogDebug((object)"[SharedUpgrades:REPOLibCompat] REPOLib not present; skipping compatibility hook.");
				return;
			}
			_miAddLevel = AccessTools.Method(type, "AddLevel", new Type[2]
			{
				typeof(PlayerAvatar),
				typeof(int)
			}, (Type[])null);
			if (_miAddLevel == null)
			{
				log.LogWarning((object)"[SharedUpgrades:REPOLibCompat] Could not find PlayerUpgrade.AddLevel(PlayerAvatar,int); skipping.");
				return;
			}
			HarmonyMethod val = new HarmonyMethod(typeof(RepOLibCompat), "AddLevelPostfix", (Type[])null);
			harmony.Patch((MethodBase)_miAddLevel, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_installed = true;
			log.LogInfo((object)"[SharedUpgrades:REPOLibCompat] Hooked REPOLib.Modules.PlayerUpgrade.AddLevel for team-share propagation.");
		}

		private static void AddLevelPostfix(object __instance, PlayerAvatar playerAvatar, int amount)
		{
			if (__instance == null || (Object)(object)playerAvatar == (Object)null || amount == 0 || _localGuard || !Empress_SharedUpgrades.Ready() || !Empress_SharedUpgrades.IsMasterOrSingle() || Empress_SharedUpgrades.Guard || MoreUpgradesTeamSharingEnabledFor(__instance))
			{
				return;
			}
			try
			{
				_localGuard = true;
				Empress_SharedUpgrades.Guard = true;
				string text = SemiFunc.PlayerGetSteamID(playerAvatar);
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				foreach (string item in Empress_SharedUpgrades.AllSteamIDs())
				{
					if (!string.IsNullOrEmpty(item) && !string.Equals(item, text, StringComparison.Ordinal))
					{
						PlayerAvatar val = SemiFunc.PlayerAvatarGetFromSteamID(item);
						if (Object.op_Implicit((Object)(object)val))
						{
							_miAddLevel?.Invoke(__instance, new object[2] { val, amount });
						}
					}
				}
			}
			catch (Exception arg)
			{
				Empress_SharedUpgrades.Logger.LogWarning((object)$"[SharedUpgrades:REPOLibCompat] Mirror failed: {arg}");
			}
			finally
			{
				Empress_SharedUpgrades.Guard = false;
				_localGuard = false;
			}
		}

		private static bool MoreUpgradesTeamSharingEnabledFor(object playerUpgrade)
		{
			try
			{
				Type type = AccessTools.TypeByName("MoreUpgrades.Plugin");
				if (type == null)
				{
					return false;
				}
				object obj = AccessTools.Field(type, "instance")?.GetValue(null);
				if (obj == null)
				{
					return false;
				}
				FieldInfo fieldInfo = AccessTools.Field(type, "upgradeItems");
				if (fieldInfo == null)
				{
					return false;
				}
				if (!(fieldInfo.GetValue(obj) is IEnumerable enumerable))
				{
					return false;
				}
				foreach (object item in enumerable)
				{
					if (item == null)
					{
						continue;
					}
					object obj2 = AccessTools.Field(item.GetType(), "playerUpgrade")?.GetValue(item);
					if (obj2 != playerUpgrade)
					{
						continue;
					}
					MethodInfo methodInfo = AccessTools.Method(item.GetType(), "HasConfig", new Type[1] { typeof(string) }, (Type[])null);
					if (methodInfo == null)
					{
						return false;
					}
					if (!(bool)methodInfo.Invoke(item, new object[1] { "Allow Team Upgrades" }))
					{
						return false;
					}
					MethodInfo methodInfo2 = AccessTools.Method(item.GetType(), "GetConfig", new Type[1] { typeof(string) }, (Type[])null);
					if (methodInfo2 == null)
					{
						return false;
					}
					MethodInfo methodInfo3 = methodInfo2.MakeGenericMethod(typeof(bool));
					return (bool)methodInfo3.Invoke(item, new object[1] { "Allow Team Upgrades" });
				}
			}
			catch
			{
				return false;
			}
			return false;
		}

		internal static void BootstrapFrom(Empress_SharedUpgrades owner)
		{
			TryInstall(owner.Harmony, Empress_SharedUpgrades.Logger);
		}
	}
	[BepInPlugin("Empress.Empress_SharedUpgrades", "Empress_SharedUpgrades", "1.2.1")]
	public class Empress_SharedUpgrades : BaseUnityPlugin, IOnEventCallback
	{
		internal enum UpgType
		{
			Health,
			Energy,
			ExtraJump,
			MapPlayerCount,
			SprintSpeed,
			GrabStrength,
			ThrowStrength,
			GrabRange,
			CrouchRest,
			TumbleClimb,
			TumbleLaunch,
			TumbleWings
		}

		[CompilerGenerated]
		private sealed class <AllSteamIDs>d__21 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private string <>2__current;

			private int <>l__initialThreadId;

			private List<PlayerAvatar> <list>5__1;

			private List<PlayerAvatar>.Enumerator <>s__2;

			private PlayerAvatar <p>5__3;

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

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

			[DebuggerHidden]
			public <AllSteamIDs>d__21(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<list>5__1 = null;
				<>s__2 = default(List<PlayerAvatar>.Enumerator);
				<p>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						if ((Object)(object)GameDirector.instance == (Object)null)
						{
							return false;
						}
						<list>5__1 = GameDirector.instance.PlayerList;
						if (<list>5__1 == null)
						{
							return false;
						}
						<>s__2 = <list>5__1.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<p>5__3 = null;
						break;
					}
					while (<>s__2.MoveNext())
					{
						<p>5__3 = <>s__2.Current;
						if ((Object)(object)<p>5__3 == (Object)null)
						{
							continue;
						}
						<>2__current = SemiFunc.PlayerGetSteamID(<p>5__3);
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__2 = default(List<PlayerAvatar>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__2).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<string> IEnumerable<string>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <AllSteamIDs>d__21(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<string>)this).GetEnumerator();
			}
		}

		internal static bool Guard;

		private bool _callbacks;

		private const byte EventCode = 195;

		internal static Empress_SharedUpgrades Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded");
		}

		private void OnDestroy()
		{
			if (_callbacks)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
			}
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			if (Ready())
			{
				if (!_callbacks)
				{
					PhotonNetwork.AddCallbackTarget((object)this);
					_callbacks = true;
				}
			}
			else if (_callbacks)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
				_callbacks = false;
			}
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
			RepOLibCompat.BootstrapFrom(this);
		}

		internal static bool Ready()
		{
			if (!PhotonNetwork.IsConnected)
			{
				return false;
			}
			if (!PhotonNetwork.InRoom)
			{
				return false;
			}
			if (SemiFunc.MenuLevel())
			{
				return false;
			}
			if ((Object)(object)LevelGenerator.Instance == (Object)null)
			{
				return false;
			}
			if (!LevelGenerator.Instance.Generated)
			{
				return false;
			}
			PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			return true;
		}

		internal static bool IsMasterOrSingle()
		{
			return SemiFunc.IsMasterClientOrSingleplayer();
		}

		[IteratorStateMachine(typeof(<AllSteamIDs>d__21))]
		internal static IEnumerable<string> AllSteamIDs()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AllSteamIDs>d__21(-2);
		}

		internal static void Propagate(PunManager pm, string sourceSteamID, int value, Action<PunManager, string, int> applier)
		{
			if (!Ready() || !IsMasterOrSingle() || Guard || value == 0)
			{
				return;
			}
			Guard = true;
			try
			{
				foreach (string item in AllSteamIDs())
				{
					if (!string.IsNullOrEmpty(item) && !(item == sourceSteamID))
					{
						applier(pm, item, value);
					}
				}
			}
			finally
			{
				Guard = false;
			}
		}

		internal static void BroadcastRightAway(string sourceSteamID, int value, UpgType type)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (Ready() && IsMasterOrSingle() && !Guard && value != 0)
			{
				object[] array = new object[3]
				{
					sourceSteamID,
					(int)type,
					value
				};
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				};
				PhotonNetwork.RaiseEvent((byte)195, (object)array, val, SendOptions.SendReliable);
			}
		}

		public void OnEvent(EventData photonEvent)
		{
			if (!Ready() || photonEvent.Code != 195 || !(photonEvent.CustomData is object[] array) || array.Length < 3)
			{
				return;
			}
			string a = array[0] as string;
			UpgType type = (UpgType)(int)array[1];
			int value = (int)array[2];
			PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
			if (Object.op_Implicit((Object)(object)val))
			{
				string b = SemiFunc.PlayerGetSteamID(val);
				if (!string.Equals(a, b, StringComparison.Ordinal))
				{
					ApplyRightAwayLocal(type, value);
				}
			}
		}

		internal static void ApplyRightAwayLocal(UpgType type, int value)
		{
			switch (type)
			{
			case UpgType.Health:
			{
				PlayerAvatar val8 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val8))
				{
					int num3 = 20 * value;
					PlayerHealth playerHealth = val8.playerHealth;
					playerHealth.maxHealth += num3;
					if (num3 >= 0)
					{
						val8.playerHealth.Heal(num3, false);
					}
					else
					{
						val8.playerHealth.Hurt(-num3, false, -1);
					}
				}
				break;
			}
			case UpgType.Energy:
			{
				int num = 10 * value;
				PlayerController instance = PlayerController.instance;
				instance.EnergyStart += (float)num;
				float num2 = PlayerController.instance.EnergyCurrent + (float)num;
				if (num2 > PlayerController.instance.EnergyStart)
				{
					num2 = PlayerController.instance.EnergyStart;
				}
				if (num2 < 0f)
				{
					num2 = 0f;
				}
				PlayerController.instance.EnergyCurrent = num2;
				break;
			}
			case UpgType.ExtraJump:
			{
				PlayerController instance4 = PlayerController.instance;
				instance4.JumpExtra += value;
				break;
			}
			case UpgType.MapPlayerCount:
			{
				PlayerAvatar val6 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val6))
				{
					val6.upgradeMapPlayerCount += value;
				}
				break;
			}
			case UpgType.SprintSpeed:
			{
				PlayerController instance2 = PlayerController.instance;
				instance2.SprintSpeed += (float)value;
				PlayerController instance3 = PlayerController.instance;
				instance3.SprintSpeedUpgrades += (float)value;
				break;
			}
			case UpgType.GrabStrength:
			{
				PlayerAvatar val2 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val2))
				{
					PhysGrabber physGrabber = val2.physGrabber;
					physGrabber.grabStrength += 0.2f * (float)value;
				}
				break;
			}
			case UpgType.ThrowStrength:
			{
				PlayerAvatar val9 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val9))
				{
					PhysGrabber physGrabber3 = val9.physGrabber;
					physGrabber3.throwStrength += 0.3f * (float)value;
				}
				break;
			}
			case UpgType.GrabRange:
			{
				PlayerAvatar val7 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val7))
				{
					PhysGrabber physGrabber2 = val7.physGrabber;
					physGrabber2.grabRange += (float)value;
				}
				break;
			}
			case UpgType.CrouchRest:
			{
				PlayerAvatar val5 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val5))
				{
					val5.upgradeCrouchRest += (float)value;
				}
				break;
			}
			case UpgType.TumbleClimb:
			{
				PlayerAvatar val4 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val4))
				{
					val4.upgradeTumbleClimb += (float)value;
				}
				break;
			}
			case UpgType.TumbleLaunch:
			{
				PlayerAvatar val3 = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val3))
				{
					PlayerTumble tumble = val3.tumble;
					tumble.tumbleLaunch += value;
				}
				break;
			}
			case UpgType.TumbleWings:
			{
				PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
				if (Object.op_Implicit((Object)(object)val))
				{
					val.upgradeTumbleWings += (float)value;
				}
				break;
			}
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerHealth")]
	public static class Patch_UpgradePlayerHealth
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeHealth = StatsManager.instance.playerUpgradeHealth;
			playerUpgradeHealth.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerHealth(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.Health);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerEnergy")]
	public static class Patch_UpgradePlayerEnergy
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeStamina = StatsManager.instance.playerUpgradeStamina;
			playerUpgradeStamina.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerEnergy(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.Energy);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerExtraJump")]
	public static class Patch_UpgradePlayerExtraJump
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeExtraJump = StatsManager.instance.playerUpgradeExtraJump;
			playerUpgradeExtraJump.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerExtraJump(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.ExtraJump);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradeMapPlayerCount")]
	public static class Patch_UpgradeMapPlayerCount
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeMapPlayerCount = StatsManager.instance.playerUpgradeMapPlayerCount;
			playerUpgradeMapPlayerCount.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradeMapPlayerCount(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.MapPlayerCount);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerSprintSpeed")]
	public static class Patch_UpgradePlayerSprintSpeed
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeSpeed = StatsManager.instance.playerUpgradeSpeed;
			playerUpgradeSpeed.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerSprintSpeed(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.SprintSpeed);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerGrabStrength")]
	public static class Patch_UpgradePlayerGrabStrength
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeStrength = StatsManager.instance.playerUpgradeStrength;
			playerUpgradeStrength.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerGrabStrength(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.GrabStrength);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerThrowStrength")]
	public static class Patch_UpgradePlayerThrowStrength
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeThrow = StatsManager.instance.playerUpgradeThrow;
			playerUpgradeThrow.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerThrowStrength(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.ThrowStrength);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerGrabRange")]
	public static class Patch_UpgradePlayerGrabRange
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeRange = StatsManager.instance.playerUpgradeRange;
			playerUpgradeRange.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerGrabRange(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.GrabRange);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerCrouchRest")]
	public static class Patch_UpgradePlayerCrouchRest
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeCrouchRest = StatsManager.instance.playerUpgradeCrouchRest;
			playerUpgradeCrouchRest.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerCrouchRest(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.CrouchRest);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerTumbleClimb")]
	public static class Patch_UpgradePlayerTumbleClimb
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeTumbleClimb = StatsManager.instance.playerUpgradeTumbleClimb;
			playerUpgradeTumbleClimb.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerTumbleClimb(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.TumbleClimb);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerTumbleLaunch")]
	public static class Patch_UpgradePlayerTumbleLaunch
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeLaunch = StatsManager.instance.playerUpgradeLaunch;
			playerUpgradeLaunch.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerTumbleLaunch(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.TumbleLaunch);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "UpgradePlayerTumbleWings")]
	public static class Patch_UpgradePlayerTumbleWings
	{
		public static void Prefix(string _steamID, ref int __state)
		{
			Dictionary<string, int> playerUpgradeTumbleWings = StatsManager.instance.playerUpgradeTumbleWings;
			playerUpgradeTumbleWings.TryGetValue(_steamID, out __state);
		}

		public static void Postfix(PunManager __instance, string _steamID, int __result, int __state)
		{
			int num = __result - __state;
			if (num != 0)
			{
				Empress_SharedUpgrades.Propagate(__instance, _steamID, num, delegate(PunManager pm, string id, int v)
				{
					pm.UpgradePlayerTumbleWings(id, v);
				});
				Empress_SharedUpgrades.BroadcastRightAway(_steamID, num, Empress_SharedUpgrades.UpgType.TumbleWings);
			}
		}
	}
}