Decompiled source of HolyDLL v1.0.9

holy.dll

Decompiled 4 months ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using ExtraSkillSlots;
using IL.RoR2;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.RuntimeDetour.HookGen;
using On.RoR2;
using R2API;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;

[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.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("holy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+98a72ea644539a0d2b9c53adbbab475bd63bd5b1")]
[assembly: AssemblyProduct("holy")]
[assembly: AssemblyTitle("holy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace HolyHolyHoly;

[BepInPlugin("xyz.yekoc.Holy", "HolyHolyHOLY", "1.0.9")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class HolyPlugin : BaseUnityPlugin
{
	public class HolyData
	{
		public StatHookEventArgs args;

		public bool OnLevel;

		public bool statsDirty;

		public float prevMaxHealth;

		public float prevMaxShield;
	}

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

		public static Func<Delegate, bool> <>9__12_3;

		public static Action<Stage> <>9__12_1;

		public static Func<Func<float>, float> <>9__12_2;

		public static Func<KeyValuePair<Delegate, Stack<IDetour>>, bool> <>9__14_0;

		public static Func<Instruction, bool> <>9__16_0;

		public static Action<CharacterBody> <>9__16_1;

		public static Func<Instruction, bool> <>9__17_2;

		public static Func<CharacterBody, HolyData> <>9__17_4;

		public static orig_RecalculateStats <>9__17_3;

		public static Func<Instruction, bool> <>9__17_5;

		public static Func<Instruction, bool> <>9__17_6;

		public static Func<Instruction, bool> <>9__17_7;

		public static Func<Instruction, bool> <>9__17_8;

		public static Func<bool, CharacterBody, bool> <>9__17_1;

		public static Func<Instruction, bool> <>9__18_1;

		public static Func<Instruction, bool> <>9__18_2;

		public static Func<Instruction, bool> <>9__18_3;

		public static Func<Instruction, bool> <>9__18_4;

		public static Action<CharacterBody> <>9__18_5;

		public static Action<ILCursor> <>9__18_0;

		public static Func<KeyValuePair<CharacterBody, HolyData>, bool> <>9__20_0;

		public static Func<CharacterBody, bool> <>9__20_1;

		public static Action<CharacterBody> <>9__20_2;

		public static orig_RecalculateStats <>9__20_3;

		public static Action<CharacterBody> <>9__21_1;

		public static Func<Instruction, bool> <>9__21_2;

		public static Manipulator <>9__21_0;

		internal bool <Awake>b__12_3(Delegate del)
		{
			return del.GetType() == typeof(hook_RecalculateStats);
		}

		internal void <Awake>b__12_1(Stage stage)
		{
			queue.Clear();
		}

		internal float <Awake>b__12_2(Func<float> orig)
		{
			return currentGrav;
		}

		internal bool <ExtraSkillSlots>b__14_0(KeyValuePair<Delegate, Stack<IDetour>> pair)
		{
			return pair.Key.GetType() == typeof(Manipulator) && pair.Key.Method.DeclaringType == typeof(ExtraCharacterBody);
		}

		internal bool <OnLevelUp>b__16_0(Instruction x)
		{
			return ILPatternMatchingExt.MatchRet(x);
		}

		internal void <OnLevelUp>b__16_1(CharacterBody cb)
		{
			queue.GetOrAdd(cb, new HolyData()).OnLevel = true;
		}

		internal bool <UnVisualize>b__17_2(Instruction x)
		{
			return ILPatternMatchingExt.MatchRet(x);
		}

		internal HolyData <UnVisualize>b__17_4(CharacterBody body)
		{
			return new HolyData();
		}

		internal void <UnVisualize>b__17_3(CharacterBody body)
		{
		}

		internal bool <UnVisualize>b__17_5(Instruction x)
		{
			return ILPatternMatchingExt.MatchLdarg(x, 0);
		}

		internal bool <UnVisualize>b__17_6(Instruction x)
		{
			return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(CharacterBody).GetMethod("UpdateAllTemporaryVisualEffects", (BindingFlags)(-1)));
		}

		internal bool <UnVisualize>b__17_7(Instruction x)
		{
			return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(NetworkServer).GetProperty("active").GetGetMethod());
		}

		internal bool <UnVisualize>b__17_8(Instruction x)
		{
			ILLabel val = default(ILLabel);
			return ILPatternMatchingExt.MatchBrfalse(x, ref val);
		}

		internal bool <UnVisualize>b__17_1(bool active, CharacterBody cb)
		{
			return !queue.GetOrAdd(cb, new HolyData()).statsDirty && active;
		}

		internal bool <RecalculateStatsAPIRuiner>b__18_1(Instruction x)
		{
			return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(ILCursor).GetMethod("EmitDelegate").MakeGenericMethod(typeof(Action<CharacterBody>)));
		}

		internal bool <RecalculateStatsAPIRuiner>b__18_2(Instruction x)
		{
			return ILPatternMatchingExt.MatchPop(x);
		}

		internal bool <RecalculateStatsAPIRuiner>b__18_3(Instruction x)
		{
			return ILPatternMatchingExt.MatchLdloc(x, 0);
		}

		internal bool <RecalculateStatsAPIRuiner>b__18_4(Instruction x)
		{
			FieldReference val = default(FieldReference);
			return ILPatternMatchingExt.MatchLdfld(x, ref val);
		}

		internal void <RecalculateStatsAPIRuiner>b__18_0(ILCursor cursor)
		{
			cursor.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)delegate(CharacterBody body)
			{
				if (!queue.GetOrAdd(body, new HolyData()).statsDirty)
				{
					RecalculateStatsAPI.GetStatMods(body);
				}
			});
		}

		internal void <RecalculateStatsAPIRuiner>b__18_5(CharacterBody body)
		{
			if (!queue.GetOrAdd(body, new HolyData()).statsDirty)
			{
				RecalculateStatsAPI.GetStatMods(body);
			}
		}

		internal bool <FixedUpdate>b__20_0(KeyValuePair<CharacterBody, HolyData> pair)
		{
			return pair.Value.statsDirty;
		}

		internal bool <FixedUpdate>b__20_1(CharacterBody b)
		{
			return queue[b].statsDirty;
		}

		internal void <FixedUpdate>b__20_2(CharacterBody body)
		{
			body.RecalculateStats();
		}

		internal void <FixedUpdate>b__20_3(CharacterBody body)
		{
		}

		internal void <.ctor>b__21_0(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(CharacterBody).GetMethod("RecalculateStats"))
			}))
			{
				ILLabel val2 = val.MarkLabel();
				int index = val.Index;
				val.Index = index - 1;
				val.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)delegate(CharacterBody cb)
				{
					if (!queue.ContainsKey(cb))
					{
						queue.TryAdd(cb, new HolyData());
					}
					queue[cb].statsDirty = true;
					cb.statsDirty = false;
				});
				val.Emit(OpCodes.Br, (object)val2);
				val.Emit(OpCodes.Ldarg_0);
				index = val.Index;
				val.Index = index + 1;
			}
		}

		internal void <.ctor>b__21_1(CharacterBody cb)
		{
			if (!queue.ContainsKey(cb))
			{
				queue.TryAdd(cb, new HolyData());
			}
			queue[cb].statsDirty = true;
			cb.statsDirty = false;
		}

		internal bool <.ctor>b__21_2(Instruction x)
		{
			return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(CharacterBody).GetMethod("RecalculateStats"));
		}
	}

	private static bool extraSkillSlots;

	private static float currentGrav;

	private ILHook sprint;

	private ILHook ih;

	private Hook h;

	private Hook trajGrav;

	[CompilerGenerated]
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private static hook_RecalculateStats m_hookStealer;

	private static ConcurrentDictionary<CharacterBody, HolyData> queue = new ConcurrentDictionary<CharacterBody, HolyData>(Environment.ProcessorCount * 2, 100);

	private Manipulator Taskifier;

	public static event hook_RecalculateStats hookStealer
	{
		[CompilerGenerated]
		add
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			hook_RecalculateStats val = HolyPlugin.m_hookStealer;
			hook_RecalculateStats val2;
			do
			{
				val2 = val;
				hook_RecalculateStats value2 = (hook_RecalculateStats)Delegate.Combine((Delegate?)(object)val2, (Delegate?)(object)value);
				val = Interlocked.CompareExchange(ref HolyPlugin.m_hookStealer, value2, val2);
			}
			while (val != val2);
		}
		[CompilerGenerated]
		remove
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			hook_RecalculateStats val = HolyPlugin.m_hookStealer;
			hook_RecalculateStats val2;
			do
			{
				val2 = val;
				hook_RecalculateStats value2 = (hook_RecalculateStats)Delegate.Remove((Delegate?)(object)val2, (Delegate?)(object)value);
				val = Interlocked.CompareExchange(ref HolyPlugin.m_hookStealer, value2, val2);
			}
			while (val != val2);
		}
	}

	private void Awake()
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_00d1: 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: Expected O, but got Unknown
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Expected O, but got Unknown
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Expected O, but got Unknown
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Expected O, but got Unknown
		Run.onRunStartGlobal += delegate
		{
			MethodInfo method = typeof(CharacterBody).GetMethod("RecalculateStats");
			object obj = typeof(HookEndpointManager).GetMethod("GetEndpoint", (BindingFlags)(-1)).Invoke(null, new object[1] { typeof(CharacterBody).GetMethod("RecalculateStats") });
			Dictionary<Delegate, Stack<IDetour>> dictionary = obj.GetType().GetField("HookMap", (BindingFlags)(-1)).GetValue(obj) as Dictionary<Delegate, Stack<IDetour>>;
			if (dictionary.Count > 1)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Stealing RecalculateStats hooks to prevent potential crashes...");
				foreach (Delegate item in dictionary.Keys.Where((Delegate del) => del.GetType() == typeof(hook_RecalculateStats)).ToList())
				{
					while (dictionary.ContainsKey(item))
					{
						hookStealer += (hook_RecalculateStats)(object)((item is hook_RecalculateStats) ? item : null);
						HookEndpointManager.Remove((MethodBase)method, item);
					}
				}
				if (!extraSkillSlots && Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.ExtraSkillSlots"))
				{
					ExtraSkillSlots();
					extraSkillSlots = true;
				}
				((BaseUnityPlugin)this).Logger.LogDebug((object)"Remaining IL Hooks:");
				foreach (IDetour item2 in obj.GetType().GetField("HookList", (BindingFlags)(-1)).GetValue(obj) as List<IDetour>)
				{
					if (item2 != null && ((object)item2).GetType() == typeof(ILHook))
					{
						((BaseUnityPlugin)this).Logger.LogDebug(HookEndpointManager.GetOwner((Delegate)(object)((ILHook)((item2 is ILHook) ? item2 : null)).Manipulator));
					}
				}
			}
		};
		Stage.onStageStartGlobal += delegate
		{
			queue.Clear();
		};
		CharacterBody.FixedUpdate += Taskifier;
		CharacterMaster.OnBodyStart += Taskifier;
		CharacterBody.OnCalculatedLevelChanged += new Manipulator(OnLevelUp);
		sprint = new ILHook((MethodBase)typeof(CharacterBody).GetProperty("isSprinting").GetSetMethod(), Taskifier);
		trajGrav = new Hook((MethodBase)typeof(Trajectory).GetProperty("defaultGravity", (BindingFlags)(-1)).GetGetMethod(nonPublic: true), (Delegate)(Func<Func<float>, float>)((Func<float> orig) => currentGrav));
		currentGrav = Physics.gravity.y;
		ih = new ILHook((MethodBase)typeof(RecalculateStatsAPI).GetMethod("HookRecalculateStats", (BindingFlags)(-1)), new Manipulator(RecalculateStatsAPIRuiner));
		h = new Hook((MethodBase)typeof(RecalculateStatsAPI).GetMethod("GetStatMods", (BindingFlags)(-1)), typeof(HolyPlugin).GetMethod("RecalculateStatsAPIRuiner2", (BindingFlags)(-1)));
		CharacterBody.RecalculateStats += new Manipulator(UnVisualize);
	}

	private void OnDestroy()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Expected O, but got Unknown
		CharacterBody.FixedUpdate -= Taskifier;
		CharacterMaster.OnBodyStart -= Taskifier;
		CharacterBody.OnCalculatedLevelChanged -= new Manipulator(OnLevelUp);
		CharacterBody.RecalculateStats -= new Manipulator(UnVisualize);
		trajGrav.Undo();
		sprint.Undo();
		h.Undo();
		ih.Undo();
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	private void ExtraSkillSlots()
	{
		((BaseUnityPlugin)this).Logger.LogDebug((object)"Stealing ExtraSkillSlots RecalculateStats IL Hook");
		object obj = typeof(HookEndpointManager).GetMethod("GetEndpoint", (BindingFlags)(-1)).Invoke(null, new object[1] { typeof(CharacterBody).GetMethod("RecalculateStats") });
		IEnumerable<KeyValuePair<Delegate, Stack<IDetour>>> source = (obj.GetType().GetField("HookMap", (BindingFlags)(-1)).GetValue(obj) as Dictionary<Delegate, Stack<IDetour>>).Where((KeyValuePair<Delegate, Stack<IDetour>> pair) => pair.Key.GetType() == typeof(Manipulator) && pair.Key.Method.DeclaringType == typeof(ExtraCharacterBody));
		if (source.Count() != 0)
		{
			HookEndpointManager.Remove((MethodBase)typeof(CharacterBody).GetMethod("RecalculateStats"), source.First().Key);
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	private void ExtraSkillStats(CharacterBody body)
	{
		if (Object.op_Implicit((Object)(object)((body == null) ? null : body.skillLocator?.primary)))
		{
			ExtraCharacterBody.RecalculateCooldowns(body, body.skillLocator.primary.cooldownScale, body.skillLocator.primary.flatCooldownReduction);
		}
	}

	private void OnLevelUp(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		if (val.TryGotoNext(new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchRet(x)
		}))
		{
			ILLabel val2 = val.MarkLabel();
			val.Index -= 1;
			val.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)delegate(CharacterBody cb)
			{
				queue.GetOrAdd(cb, new HolyData()).OnLevel = true;
			});
			val.Emit(OpCodes.Br, (object)val2);
			val.Emit(OpCodes.Ldarg_0);
		}
	}

	private void UnVisualize(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		if (val.TryGotoNext(new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchRet(x)
		}))
		{
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)delegate(CharacterBody cb)
			{
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Expected O, but got Unknown
				if (!queue.GetOrAdd(cb, (CharacterBody body) => new HolyData()).statsDirty)
				{
					hook_RecalculateStats obj = HolyPlugin.hookStealer;
					if (obj != null)
					{
						object obj2 = <>c.<>9__17_3;
						if (obj2 == null)
						{
							orig_RecalculateStats val3 = delegate
							{
							};
							<>c.<>9__17_3 = val3;
							obj2 = (object)val3;
						}
						obj.Invoke((orig_RecalculateStats)obj2, cb);
					}
					if (extraSkillSlots)
					{
						ExtraSkillStats(cb);
					}
				}
			});
		}
		if (val.TryGotoPrev((MoveType)0, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(CharacterBody).GetMethod("UpdateAllTemporaryVisualEffects", (BindingFlags)(-1)))
		}))
		{
			val.MoveAfterLabels();
			val.RemoveRange(2);
		}
		ILLabel val2 = default(ILLabel);
		if (val.TryGotoPrev((MoveType)0, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(NetworkServer).GetProperty("active").GetGetMethod()),
			(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val2)
		}))
		{
			int index = val.Index;
			val.Index = index + 1;
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<bool, CharacterBody, bool>>((Func<bool, CharacterBody, bool>)((bool active, CharacterBody cb) => !queue.GetOrAdd(cb, new HolyData()).statsDirty && active));
		}
	}

	private void RecalculateStatsAPIRuiner(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		ILLabel val2 = val.DefineLabel();
		if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(ILCursor).GetMethod("EmitDelegate").MakeGenericMethod(typeof(Action<CharacterBody>))),
			(Instruction x) => ILPatternMatchingExt.MatchPop(x)
		}))
		{
			return;
		}
		val2 = val.MarkLabel();
		FieldReference val3 = default(FieldReference);
		if (!val.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0),
			(Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val3)
		}))
		{
			return;
		}
		val.EmitDelegate<Action<ILCursor>>((Action<ILCursor>)delegate(ILCursor cursor)
		{
			cursor.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)delegate(CharacterBody body)
			{
				if (!queue.GetOrAdd(body, new HolyData()).statsDirty)
				{
					RecalculateStatsAPI.GetStatMods(body);
				}
			});
		});
		val.Emit(OpCodes.Br, (object)val2);
		val.Emit(OpCodes.Ldloc_0);
	}

	private static void RecalculateStatsAPIRuiner2(Action<CharacterBody> orig, CharacterBody cb)
	{
		orig(cb);
		queue.GetOrAdd(cb, new HolyData()).args = RecalculateStatsAPI.StatMods;
	}

	private void FixedUpdate()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Expected O, but got Unknown
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)Run.instance))
		{
			return;
		}
		currentGrav = Physics.gravity.y;
		foreach (CharacterBody item in queue.Keys.ToList())
		{
			HolyData value;
			if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.healthComponent) && item.healthComponent.alive)
			{
				if (queue[item].statsDirty)
				{
					queue[item].prevMaxHealth = item.maxHealth;
					queue[item].prevMaxShield = item.maxShield;
					RecalculateStatsAPI.GetStatMods(item);
				}
			}
			else if (!queue.TryRemove(item, out value))
			{
				queue[item].statsDirty = false;
			}
		}
		List<KeyValuePair<CharacterBody, HolyData>> list = queue.Where((KeyValuePair<CharacterBody, HolyData> pair) => pair.Value.statsDirty).ToList();
		Parallel.ForEach(queue.Keys.Where((CharacterBody b) => queue[b].statsDirty), delegate(CharacterBody body)
		{
			body.RecalculateStats();
		});
		foreach (KeyValuePair<CharacterBody, HolyData> item2 in queue)
		{
			if (Object.op_Implicit((Object)(object)item2.Key.healthComponent))
			{
				if (item2.Value.OnLevel)
				{
					item2.Key.OnLevelUp();
				}
				if (item2.Value.statsDirty)
				{
					item2.Key.UpdateAllTemporaryVisualEffects();
					hook_RecalculateStats obj = HolyPlugin.hookStealer;
					if (obj != null)
					{
						object obj2 = <>c.<>9__20_3;
						if (obj2 == null)
						{
							orig_RecalculateStats val = delegate
							{
							};
							<>c.<>9__20_3 = val;
							obj2 = (object)val;
						}
						obj.Invoke((orig_RecalculateStats)obj2, item2.Key);
					}
					if (extraSkillSlots)
					{
						ExtraSkillStats(item2.Key);
					}
					if (NetworkServer.active)
					{
						HealthComponent healthComponent = item2.Key.healthComponent;
						float num = item2.Key.maxHealth - item2.Value.prevMaxHealth;
						if (num > 0f)
						{
							healthComponent.Heal(num, default(ProcChainMask), false);
						}
						else if (healthComponent.health > item2.Key.maxHealth)
						{
							healthComponent.Networkhealth = Mathf.Max(healthComponent.health + num, item2.Key.maxHealth);
						}
						float num2 = item2.Key.maxShield - item2.Value.prevMaxShield;
						if (num2 > 0f)
						{
							healthComponent.RechargeShield(num2);
						}
						else if (healthComponent.shield > item2.Key.maxShield)
						{
							healthComponent.Networkshield = Mathf.Max(healthComponent.shield + num2, item2.Key.maxShield);
						}
					}
				}
			}
			item2.Value.statsDirty = false;
			item2.Value.OnLevel = false;
		}
	}

	public HolyPlugin()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		object obj = <>c.<>9__21_0;
		if (obj == null)
		{
			Manipulator val = delegate(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val2 = new ILCursor(il);
				while (val2.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(CharacterBody).GetMethod("RecalculateStats"))
				}))
				{
					ILLabel val3 = val2.MarkLabel();
					int index = val2.Index;
					val2.Index = index - 1;
					val2.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)delegate(CharacterBody cb)
					{
						if (!queue.ContainsKey(cb))
						{
							queue.TryAdd(cb, new HolyData());
						}
						queue[cb].statsDirty = true;
						cb.statsDirty = false;
					});
					val2.Emit(OpCodes.Br, (object)val3);
					val2.Emit(OpCodes.Ldarg_0);
					index = val2.Index;
					val2.Index = index + 1;
				}
			};
			<>c.<>9__21_0 = val;
			obj = (object)val;
		}
		Taskifier = (Manipulator)obj;
		((BaseUnityPlugin)this)..ctor();
	}
}