Decompiled source of R2API Execute v1.1.2

plugins/R2API.Execute/R2API.Execute.dll

Decompiled 2 weeks ago
using System;
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 IL.RoR2.UI;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using R2API.AutoVersionGen;
using RoR2;
using RoR2.UI;
using UnityEngine;
using UnityEngine.Networking;

[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("R2API.Execute")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+4e459283c1d76de53d34cdd3bf8e3eb2ff4fb35c")]
[assembly: AssemblyProduct("R2API.Execute")]
[assembly: AssemblyTitle("R2API.Execute")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.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 System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace R2API
{
	[AutoVersion]
	public static class ExecuteAPI
	{
		public delegate void CalculateAdditiveExecuteThresholdEventHandler(CharacterBody victimBody, ref float executeFractionAdd);

		public delegate void CalculateAdditiveExecuteThresholdForViewerEventHandler(CharacterBody victimBody, CharacterBody viewerBody, ref float executeFractionAdd);

		public delegate void CalculateExecuteThresholdEventHandler(CharacterBody victimBody, ref float highestExecuteThreshold);

		public delegate void CalculateExecuteThresholdForViewerEventHandler(CharacterBody victimBody, CharacterBody viewerBody, ref float highestExecuteThreshold);

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_ServerDamageDealt <0>__GlobalEventManager_ServerDamageDealt;

			public static hook_GetHealthBarValues <1>__HealthComponent_GetHealthBarValues;

			public static Manipulator <2>__HealthBar_UpdateBarInfos;
		}

		public const string PluginGUID = "com.bepis.r2api.execute";

		public const string PluginName = "R2API.Execute";

		private static bool _hooksEnabled;

		[Tooltip("For stackable executes with cross-mod compat. Calculates the additive execute threshold. Final threshold is calculated by the function: 1 - 1 / (1 + executeFractionAdd)")]
		public static CalculateAdditiveExecuteThresholdEventHandler CalculateAdditiveExecuteThreshold;

		[Tooltip("For stackable executes with cross-mod compat. Calculates the additive execute threshold, factoring in viewer bodies. Final threshold is calculated by the function: 1 - 1 / (1 + executeFractionAdd)")]
		public static CalculateAdditiveExecuteThresholdForViewerEventHandler CalculateAdditiveExecuteThresholdForViewer;

		[Tooltip("For vanilla-like executes that don't stack. Calculates the flat execute threshold.")]
		public static CalculateExecuteThresholdEventHandler CalculateExecuteThreshold;

		[Tooltip("For vanilla-like executes that don't stack. Calculates the flat execute threshold, factoring in viewer bodies.")]
		public static CalculateExecuteThresholdForViewerEventHandler CalculateExecuteThresholdForViewer;

		public const string PluginVersion = "1.1.2";

		internal static void SetHooks()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (!_hooksEnabled)
			{
				object obj = <>O.<0>__GlobalEventManager_ServerDamageDealt;
				if (obj == null)
				{
					hook_ServerDamageDealt val = GlobalEventManager_ServerDamageDealt;
					<>O.<0>__GlobalEventManager_ServerDamageDealt = val;
					obj = (object)val;
				}
				GlobalEventManager.ServerDamageDealt += (hook_ServerDamageDealt)obj;
				object obj2 = <>O.<1>__HealthComponent_GetHealthBarValues;
				if (obj2 == null)
				{
					hook_GetHealthBarValues val2 = HealthComponent_GetHealthBarValues;
					<>O.<1>__HealthComponent_GetHealthBarValues = val2;
					obj2 = (object)val2;
				}
				HealthComponent.GetHealthBarValues += (hook_GetHealthBarValues)obj2;
				object obj3 = <>O.<2>__HealthBar_UpdateBarInfos;
				if (obj3 == null)
				{
					Manipulator val3 = HealthBar_UpdateBarInfos;
					<>O.<2>__HealthBar_UpdateBarInfos = val3;
					obj3 = (object)val3;
				}
				HealthBar.UpdateBarInfos += (Manipulator)obj3;
				_hooksEnabled = true;
			}
		}

		internal static void UnsetHooks()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (_hooksEnabled)
			{
				object obj = <>O.<0>__GlobalEventManager_ServerDamageDealt;
				if (obj == null)
				{
					hook_ServerDamageDealt val = GlobalEventManager_ServerDamageDealt;
					<>O.<0>__GlobalEventManager_ServerDamageDealt = val;
					obj = (object)val;
				}
				GlobalEventManager.ServerDamageDealt -= (hook_ServerDamageDealt)obj;
				object obj2 = <>O.<1>__HealthComponent_GetHealthBarValues;
				if (obj2 == null)
				{
					hook_GetHealthBarValues val2 = HealthComponent_GetHealthBarValues;
					<>O.<1>__HealthComponent_GetHealthBarValues = val2;
					obj2 = (object)val2;
				}
				HealthComponent.GetHealthBarValues -= (hook_GetHealthBarValues)obj2;
				object obj3 = <>O.<2>__HealthBar_UpdateBarInfos;
				if (obj3 == null)
				{
					Manipulator val3 = HealthBar_UpdateBarInfos;
					<>O.<2>__HealthBar_UpdateBarInfos = val3;
					obj3 = (object)val3;
				}
				HealthBar.UpdateBarInfos -= (Manipulator)obj3;
				_hooksEnabled = false;
			}
		}

		private static float ConvertAdditiveFractionToFlat(float executeFractionAdd)
		{
			return 1f - 1f / (1f + executeFractionAdd);
		}

		private static float CalculateExecuteFraction(CharacterBody victimBody, CharacterBody viewerBody)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if ((victimBody.bodyFlags & 0x10) != 0)
			{
				return 0f;
			}
			float executeFractionAdd = 0f;
			float highestExecuteThreshold = 0f;
			CalculateAdditiveExecuteThreshold?.Invoke(victimBody, ref executeFractionAdd);
			CalculateExecuteThreshold?.Invoke(victimBody, ref highestExecuteThreshold);
			if (Object.op_Implicit((Object)(object)viewerBody))
			{
				CalculateAdditiveExecuteThresholdForViewer?.Invoke(victimBody, viewerBody, ref executeFractionAdd);
				CalculateExecuteThresholdForViewer?.Invoke(victimBody, viewerBody, ref highestExecuteThreshold);
			}
			return Mathf.Max(ConvertAdditiveFractionToFlat(executeFractionAdd), highestExecuteThreshold);
		}

		private static HealthBarValues UpdateHealthBarValues(CharacterBody victimBody, CharacterBody viewerBody, HealthBarValues hbv)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)victimBody) && (victimBody.bodyFlags & 0x10) == 0 && Object.op_Implicit((Object)(object)victimBody.healthComponent))
			{
				float num = CalculateExecuteFraction(victimBody, viewerBody);
				float num2 = (1f - hbv.curseFraction) / victimBody.healthComponent.fullCombinedHealth;
				float num3 = Mathf.Clamp01(num * victimBody.healthComponent.fullCombinedHealth * num2);
				hbv.cullFraction = Mathf.Max(hbv.cullFraction, num3);
			}
			return hbv;
		}

		private static void TryExecuteServer(CharacterBody victimBody, DamageReport damageReport)
		{
			HealthComponent healthComponent = victimBody.healthComponent;
			float combinedHealthFraction = healthComponent.combinedHealthFraction;
			float num = CalculateExecuteFraction(victimBody, damageReport.attackerBody);
			if (num > 0f && combinedHealthFraction <= num)
			{
				float num2 = Mathf.Max(healthComponent.combinedHealth, 0f);
				if (healthComponent.barrier > 0f)
				{
					healthComponent.barrier = 0f;
				}
				if (healthComponent.shield > 0f)
				{
					healthComponent.shield = 0f;
				}
				if (healthComponent.health > 0f)
				{
					healthComponent.health = 0f;
				}
				GlobalEventManager.ServerCharacterExecuted(damageReport, num2);
			}
		}

		private static void HealthBar_UpdateBarInfos(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int healthBarValueLoc = -1;
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref healthBarValueLoc),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<HealthBarValues>(x, "cullFraction")
			}))
			{
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldloc, healthBarValueLoc);
				val.EmitDelegate<Func<float, HealthBar, HealthBarValues, float>>((Func<float, HealthBar, HealthBarValues, float>)delegate(float origCullFraction, HealthBar self, HealthBarValues healthBarValues)
				{
					//IL_003d: Unknown result type (might be due to invalid IL or missing references)
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					//IL_0046: Unknown result type (might be due to invalid IL or missing references)
					if (Object.op_Implicit((Object)(object)self.viewerBody) && Object.op_Implicit((Object)(object)self.source) && Object.op_Implicit((Object)(object)self.source.body))
					{
						healthBarValues = UpdateHealthBarValues(self.source.body, self.viewerBody, healthBarValues);
						return Mathf.Max(origCullFraction, healthBarValues.cullFraction);
					}
					return origCullFraction;
				});
			}
			else
			{
				ExecutePlugin.Logger.LogError((object)"HealthBar_UpdateBarInfos IL hook failed.");
			}
		}

		private static HealthBarValues HealthComponent_GetHealthBarValues(orig_GetHealthBarValues orig, HealthComponent self)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return UpdateHealthBarValues(self.body, null, orig.Invoke(self));
		}

		private static void GlobalEventManager_ServerDamageDealt(orig_ServerDamageDealt orig, DamageReport damageReport)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(damageReport);
			if (NetworkServer.active && Object.op_Implicit((Object)(object)damageReport.victimBody) && (damageReport.victimBody.bodyFlags & 0x10) == 0 && Object.op_Implicit((Object)(object)damageReport.victimBody.healthComponent) && damageReport.victimBody.healthComponent.alive)
			{
				TryExecuteServer(damageReport.victimBody, damageReport);
			}
		}
	}
	[BepInPlugin("com.bepis.r2api.execute", "R2API.Execute", "1.1.2")]
	public sealed class ExecutePlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			ExecuteAPI.SetHooks();
		}

		private void OnDestroy()
		{
			ExecuteAPI.UnsetHooks();
		}
	}
}
namespace R2API.AutoVersionGen
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	internal class AutoVersionAttribute : Attribute
	{
	}
}