Decompiled source of AbsorptionEitrShield v0.3.14

AbsorptionEitrShield.dll

Decompiled 13 hours 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("AbsorptionEitrShield")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AbsorptionEitrShield")]
[assembly: AssemblyTitle("AbsorptionEitrShield")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AbsorptionEitrShield
{
	[BepInPlugin("com.absorptioneitrshield.mod", "AbsorptionEitrShield", "0.3.14")]
	public sealed class AbsorptionEitrShieldPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <InitNetWhenReady>d__11 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public AbsorptionEitrShieldPlugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (ZRoutedRpc.instance == null)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				Net.EnsureRegistered();
				if (Net.IsServer())
				{
					Net.ServerApplyFromLocalConfigAndBroadcast();
				}
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <RevertClientConfigNextFrame>d__14 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public AbsorptionEitrShieldPlugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					_suppressConfigEvents = true;
					try
					{
						CfgModEnabled.Value = Net.Synced_ModEnabled;
						CfgUseRecharge.Value = Net.Synced_UseRecharge;
					}
					finally
					{
						_suppressConfigEvents = false;
					}
					return false;
				}
			}

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

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

		public const string ModName = "AbsorptionEitrShield";

		public const string ModGUID = "com.absorptioneitrshield.mod";

		public const string ModVersion = "0.3.14";

		internal static ManualLogSource Log;

		internal static AbsorptionEitrShieldPlugin Instance;

		private Harmony _harmony = null;

		internal static ConfigEntry<bool> CfgModEnabled;

		internal static ConfigEntry<bool> CfgUseRecharge;

		private static bool _suppressConfigEvents;

		private void Awake()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			CfgModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ModEnabled", true, "Enable/disable AbsorptionEitrShield (AUTHORITY/HOST). Client configs are ignored.");
			CfgUseRecharge = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseRecharge", true, "If true: shield activates only when Eitr is full; disables at 0-1 until full again. If false: shield always works.");
			CfgModEnabled.SettingChanged += OnConfigChanged;
			CfgUseRecharge.SettingChanged += OnConfigChanged;
			_harmony = new Harmony("com.absorptioneitrshield.mod");
			_harmony.PatchAll();
			((Component)this).gameObject.AddComponent<LocalPlayerBootstrap>();
			Log.LogWarning((object)"AbsorptionEitrShield v0.3.14 loaded.");
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(InitNetWhenReady());
		}

		[IteratorStateMachine(typeof(<InitNetWhenReady>d__11))]
		private IEnumerator InitNetWhenReady()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitNetWhenReady>d__11(0)
			{
				<>4__this = this
			};
		}

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

		private void OnConfigChanged(object sender, EventArgs e)
		{
			if (_suppressConfigEvents)
			{
				return;
			}
			if (Net.IsServer())
			{
				Net.ServerApplyFromLocalConfigAndBroadcast();
			}
			else if (Net.IsConnected())
			{
				if (Net.IsLocalAdmin())
				{
					Net.ClientRequestChange(CfgModEnabled.Value, CfgUseRecharge.Value);
				}
				else
				{
					((MonoBehaviour)Instance).StartCoroutine(RevertClientConfigNextFrame());
				}
			}
		}

		[IteratorStateMachine(typeof(<RevertClientConfigNextFrame>d__14))]
		private IEnumerator RevertClientConfigNextFrame()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RevertClientConfigNextFrame>d__14(0)
			{
				<>4__this = this
			};
		}

		internal static void SetLocalConfigSilently(bool modEnabled, bool useRecharge)
		{
			_suppressConfigEvents = true;
			try
			{
				CfgModEnabled.Value = modEnabled;
				CfgUseRecharge.Value = useRecharge;
			}
			finally
			{
				_suppressConfigEvents = false;
			}
		}
	}
	internal static class LocalPlayer
	{
		private static readonly FieldInfo FI_LocalPlayer = AccessTools.Field(typeof(Player), "m_localPlayer");

		public static Player Get()
		{
			try
			{
				object? obj = FI_LocalPlayer?.GetValue(null);
				return (Player)((obj is Player) ? obj : null);
			}
			catch
			{
				return null;
			}
		}

		public static bool IsLocal(Character c)
		{
			Player val = (Player)(object)((c is Player) ? c : null);
			if (val == null)
			{
				return false;
			}
			Player val2 = Get();
			return (Object)(object)val2 != (Object)null && val2 == val;
		}
	}
	internal sealed class LocalPlayerBootstrap : MonoBehaviour
	{
		private float _next;

		private void Update()
		{
			if (Time.time < _next)
			{
				return;
			}
			_next = Time.time + 0.5f;
			if (!((Object)(object)ZNet.instance != (Object)null) || !Net.IsServer() || !ZNet.instance.IsDedicated())
			{
				Player val = LocalPlayer.Get();
				if (!((Object)(object)val == (Object)null) && (Object)(object)((Component)val).GetComponent<ShieldUpdater>() == (Object)null)
				{
					((Component)val).gameObject.AddComponent<ShieldUpdater>();
				}
			}
		}
	}
	internal static class DieCommandBypass
	{
		private static int _charges;

		private static float _until;

		private const float WindowSeconds = 0.75f;

		private const int MaxCharges = 6;

		public static void ArmLocal()
		{
			_charges = 6;
			_until = Time.time + 0.75f;
		}

		public static bool ConsumeLocalIfArmed()
		{
			if (_charges <= 0)
			{
				return false;
			}
			if (Time.time > _until)
			{
				_charges = 0;
				return false;
			}
			_charges--;
			return true;
		}
	}
	internal static class DieBypassServerRegistry
	{
		private struct Entry
		{
			public int Charges;

			public float Until;
		}

		private const float WindowSeconds = 0.75f;

		private const int MaxCharges = 8;

		private static readonly Dictionary<long, Entry> Entries = new Dictionary<long, Entry>(64);

		public static void ArmForSender(long senderUid)
		{
			if (senderUid > 0)
			{
				Entries[senderUid] = new Entry
				{
					Charges = 8,
					Until = Time.time + 0.75f
				};
			}
		}

		public static bool ConsumeForSender(long senderUid)
		{
			if (senderUid <= 0)
			{
				return false;
			}
			if (!Entries.TryGetValue(senderUid, out var value))
			{
				return false;
			}
			if (Time.time > value.Until || value.Charges <= 0)
			{
				Entries.Remove(senderUid);
				return false;
			}
			value.Charges--;
			if (value.Charges <= 0)
			{
				Entries.Remove(senderUid);
			}
			else
			{
				Entries[senderUid] = value;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class Terminal_DieCommand_Patch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private Type <t>5__1;

			private MethodInfo <m>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<t>5__1 = null;
				<m>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<t>5__1 = typeof(Terminal);
					<m>5__2 = <t>5__1.GetMethod("TryRunCommand", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
					{
						typeof(string),
						typeof(bool)
					}, null);
					if (<m>5__2 != null)
					{
						<>2__current = <m>5__2;
						<>1__state = 1;
						return true;
					}
					goto IL_00b0;
				case 1:
					<>1__state = -1;
					goto IL_00b0;
				case 2:
					<>1__state = -1;
					goto IL_0123;
				case 3:
					{
						<>1__state = -1;
						break;
					}
					IL_0123:
					<m>5__2 = <t>5__1.GetMethod("RunCommand", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
					if (<m>5__2 != null)
					{
						<>2__current = <m>5__2;
						<>1__state = 3;
						return true;
					}
					break;
					IL_00b0:
					<m>5__2 = <t>5__1.GetMethod("TryRunCommand", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3]
					{
						typeof(string),
						typeof(bool),
						typeof(bool)
					}, null);
					if (<m>5__2 != null)
					{
						<>2__current = <m>5__2;
						<>1__state = 2;
						return true;
					}
					goto IL_0123;
				}
				return false;
			}

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

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

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

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

		[IteratorStateMachine(typeof(<TargetMethods>d__0))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__0(-2);
		}

		private static void Prefix(string text)
		{
			try
			{
				if (IsDieCommand(text))
				{
					DieCommandBypass.ArmLocal();
					Net.ClientArmDieBypass();
				}
			}
			catch
			{
			}
		}

		private static bool IsDieCommand(string text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string text2 = text.Trim().ToLowerInvariant();
			if (text2.StartsWith("/"))
			{
				text2 = text2.Substring(1).TrimStart(Array.Empty<char>());
			}
			return text2 == "die" || text2.StartsWith("die ");
		}
	}
	internal static class Runtime
	{
		public static bool ModEnabled => Net.IsServer() ? AbsorptionEitrShieldPlugin.CfgModEnabled.Value : Net.Synced_ModEnabled;

		public static bool UseRecharge => Net.IsServer() ? AbsorptionEitrShieldPlugin.CfgUseRecharge.Value : Net.Synced_UseRecharge;
	}
	internal sealed class ShieldState
	{
		public bool Active;

		public float LastMaxEitr;
	}
	internal static class ShieldSystem
	{
		private static readonly ConditionalWeakTable<Player, ShieldState> States = new ConditionalWeakTable<Player, ShieldState>();

		private const float FullEps = 0.01f;

		private const float DrainThreshold = 1.01f;

		private static readonly MethodInfo GetMaxEitrMI = AccessTools.Method(typeof(Player), "GetMaxEitr", Type.EmptyTypes, (Type[])null);

		private static readonly FieldInfo FI_MaxEitr = AccessTools.Field(typeof(Player), "m_maxEitr");

		public static ShieldState Get(Player p)
		{
			return States.GetOrCreateValue(p);
		}

		public static float ReadMaxEitr(Player p)
		{
			try
			{
				if (GetMaxEitrMI != null)
				{
					return (float)GetMaxEitrMI.Invoke(p, null);
				}
			}
			catch
			{
			}
			try
			{
				if (FI_MaxEitr != null)
				{
					return Convert.ToSingle(FI_MaxEitr.GetValue(p));
				}
			}
			catch
			{
			}
			return 0f;
		}

		public static void Evaluate(Player p)
		{
			ShieldState shieldState = Get(p);
			if (!Runtime.ModEnabled)
			{
				shieldState.Active = false;
				return;
			}
			float num = ReadMaxEitr(p);
			if (num <= 0.001f)
			{
				shieldState.Active = false;
				shieldState.LastMaxEitr = 0f;
				return;
			}
			if (!Runtime.UseRecharge)
			{
				shieldState.Active = true;
				shieldState.LastMaxEitr = num;
				return;
			}
			float num2;
			try
			{
				num2 = p.GetEitr();
			}
			catch
			{
				num2 = 0f;
			}
			if (shieldState.LastMaxEitr > 0.001f && num > shieldState.LastMaxEitr + 0.01f && num2 < num - 0.01f)
			{
				shieldState.Active = false;
			}
			shieldState.LastMaxEitr = num;
			if (shieldState.Active)
			{
				if (num2 <= 1.01f)
				{
					shieldState.Active = false;
				}
			}
			else if (num2 >= num - 0.01f)
			{
				shieldState.Active = true;
			}
		}
	}
	internal sealed class ShieldUpdater : MonoBehaviour
	{
		private Player _player;

		private void Awake()
		{
			_player = ((Component)this).GetComponent<Player>();
		}

		private void Update()
		{
			try
			{
				if (!((Object)(object)_player == (Object)null) && !((Character)_player).IsDead() && (!((Object)(object)ZNet.instance != (Object)null) || !Net.IsServer() || !ZNet.instance.IsDedicated()) && LocalPlayer.IsLocal((Character)(object)_player))
				{
					ShieldSystem.Evaluate(_player);
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch]
	internal static class Character_ApplyDamage_Patch
	{
		private struct DamageState
		{
			public bool Active;

			public bool ShieldActiveAtHit;

			public float HpBefore;

			public ZDOID Attacker;

			public Vector3 Point;

			public Vector3 Dir;

			public bool DieBypass;

			public bool IsOwner;
		}

		[CompilerGenerated]
		private sealed class <KillNextFrame>d__7 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Character target;

			public int instanceId;

			public ZDOID attacker;

			public Vector3 point;

			public Vector3 dir;

			private Player <p>5__1;

			private HitData <killHit>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<p>5__1 = null;
				<killHit>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Expected O, but got Unknown
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Expected O, but got Unknown
				//IL_0116: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_016e: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					try
					{
						if ((Object)(object)target == (Object)null)
						{
							return false;
						}
						if (target.IsDead())
						{
							return false;
						}
						ref Player reference = ref <p>5__1;
						Character obj = target;
						reference = (Player)(object)((obj is Player) ? obj : null);
						if (<p>5__1 == null)
						{
							return false;
						}
						if (Net.IsConnected() && !Net.IsLocalOwner(target))
						{
							return false;
						}
						_bypass = true;
						DeathInvoker.TryInvoke(<p>5__1);
						if (target.IsDead())
						{
							return false;
						}
						<killHit>5__2 = new HitData();
						<killHit>5__2.m_attacker = attacker;
						<killHit>5__2.m_point = ((point == Vector3.zero) ? ((Component)target).transform.position : point);
						<killHit>5__2.m_dir = ((dir == Vector3.zero) ? Vector3.forward : dir);
						<killHit>5__2.m_damage.m_blunt = 999999f;
						target.Damage(<killHit>5__2);
						if (!target.IsDead())
						{
							DeathInvoker.TryInvoke(<p>5__1);
						}
						<p>5__1 = null;
						<killHit>5__2 = null;
					}
					finally
					{
						_bypass = false;
						_killScheduled.Remove(instanceId);
					}
					return false;
				}
			}

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

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

		[CompilerGenerated]
		private sealed class <TargetMethods>d__4 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private Type <t>5__1;

			private MethodInfo[] <>s__2;

			private int <>s__3;

			private MethodInfo <m>5__4;

			private ParameterInfo[] <ps>5__5;

			private int <i>5__6;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<t>5__1 = null;
				<>s__2 = null;
				<m>5__4 = null;
				<ps>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_010b;
				}
				<>1__state = -1;
				<t>5__1 = typeof(Character);
				<>s__2 = <t>5__1.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				<>s__3 = 0;
				goto IL_0128;
				IL_0128:
				if (<>s__3 < <>s__2.Length)
				{
					<m>5__4 = <>s__2[<>s__3];
					if (<m>5__4.Name != "ApplyDamage")
					{
						goto IL_011a;
					}
					<ps>5__5 = <m>5__4.GetParameters();
					<i>5__6 = 0;
					while (<i>5__6 < <ps>5__5.Length)
					{
						if (<ps>5__5[<i>5__6].ParameterType == typeof(HitData))
						{
							<>2__current = <m>5__4;
							<>1__state = 1;
							return true;
						}
						<i>5__6++;
					}
					goto IL_010b;
				}
				<>s__2 = null;
				return false;
				IL_010b:
				<ps>5__5 = null;
				<m>5__4 = null;
				goto IL_011a;
				IL_011a:
				<>s__3++;
				goto IL_0128;
			}

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

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

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

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

		private static bool _bypass;

		private static readonly HashSet<int> _killScheduled = new HashSet<int>();

		private static readonly FieldInfo FI_NView = AccessTools.Field(typeof(Character), "m_nview");

		[IteratorStateMachine(typeof(<TargetMethods>d__4))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__4(-2);
		}

		private static void Prefix(Character __instance, HitData hit, ref DamageState __state)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			__state = default(DamageState);
			if (_bypass || (Object)(object)__instance == (Object)null || hit == null || __instance.IsDead())
			{
				return;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && (__state.IsOwner = !Net.IsConnected() || Net.IsLocalOwner(__instance)))
			{
				if (DieCommandBypass.ConsumeLocalIfArmed())
				{
					__state.DieBypass = true;
					return;
				}
				ShieldSystem.Evaluate(val);
				__state.Active = true;
				__state.ShieldActiveAtHit = ShieldSystem.Get(val).Active;
				__state.HpBefore = __instance.GetHealth();
				__state.Attacker = hit.m_attacker;
				__state.Point = hit.m_point;
				__state.Dir = hit.m_dir;
			}
		}

		private static void Postfix(Character __instance, HitData hit, DamageState __state)
		{
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			if (_bypass || !__state.IsOwner || !__state.Active || __state.DieBypass || (Object)(object)__instance == (Object)null || hit == null)
			{
				return;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val == null || !Runtime.ModEnabled || !__state.ShieldActiveAtHit)
			{
				return;
			}
			float health = __instance.GetHealth();
			float num = __state.HpBefore - health;
			if (num < 0f)
			{
				num = 0f;
			}
			if (num <= 0.0001f)
			{
				return;
			}
			float num2 = num;
			float num3;
			try
			{
				num3 = Mathf.Max(0f, val.GetEitr());
			}
			catch
			{
				num3 = 0f;
			}
			float num4 = Mathf.Min(num2, num3);
			float num5 = num2 - num4;
			if (num5 < 0f)
			{
				num5 = 0f;
			}
			if (num4 > 0.0001f)
			{
				__instance.AddEitr(0f - num4);
			}
			float num6 = __state.HpBefore - num5;
			if (num6 < 0f)
			{
				num6 = 0f;
			}
			__instance.SetHealth(num6);
			if (num6 <= 0.0001f && !__instance.IsDead())
			{
				__instance.SetHealth(1f);
				int instanceID = ((Object)__instance).GetInstanceID();
				if (_killScheduled.Add(instanceID))
				{
					((MonoBehaviour)AbsorptionEitrShieldPlugin.Instance).StartCoroutine(KillNextFrame(__instance, instanceID, __state.Attacker, __state.Point, __state.Dir));
				}
			}
		}

		[IteratorStateMachine(typeof(<KillNextFrame>d__7))]
		private static IEnumerator KillNextFrame(Character target, int instanceId, ZDOID attacker, Vector3 point, Vector3 dir)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <KillNextFrame>d__7(0)
			{
				target = target,
				instanceId = instanceId,
				attacker = attacker,
				point = point,
				dir = dir
			};
		}
	}
	internal static class DeathInvoker
	{
		private static readonly MethodInfo RpcOnDeath = AccessTools.Method(typeof(Player), "RPC_OnDeath", new Type[1] { typeof(long) }, (Type[])null);

		private static readonly MethodInfo OnDeath = AccessTools.Method(typeof(Player), "OnDeath", Type.EmptyTypes, (Type[])null);

		public static bool TryInvoke(Player p)
		{
			try
			{
				if (RpcOnDeath != null)
				{
					RpcOnDeath.Invoke(p, new object[1] { 0L });
					if (((Character)p).IsDead())
					{
						return true;
					}
				}
				if (OnDeath != null)
				{
					OnDeath.Invoke(p, null);
					if (((Character)p).IsDead())
					{
						return true;
					}
				}
			}
			catch (Exception ex)
			{
				AbsorptionEitrShieldPlugin.Log.LogWarning((object)("[AES] DeathInvoker error: " + ex.GetType().Name + ": " + ex.Message));
			}
			return ((Character)p).IsDead();
		}
	}
	internal static class Net
	{
		[CompilerGenerated]
		private sealed class <RequestSyncWhenConnected>d__37 : IEnumerator<object>, IDisposable, IEnumerator
		{
			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 <RequestSyncWhenConnected>d__37(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

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

			private bool MoveNext()
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)ZNet.instance == (Object)null || !IsConnected() || ZRoutedRpc.instance == null)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AES_RequestSync", new object[1] { (object)new ZPackage() });
				return false;
			}

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

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

		private const string RPC_RequestSync = "AES_RequestSync";

		private const string RPC_SetSettings = "AES_SetSettings";

		private const string RPC_RequestChange = "AES_RequestChange";

		private const string RPC_ArmDieBypass = "AES_ArmDieBypass";

		private static bool _registered;

		internal static bool Synced_ModEnabled = true;

		internal static bool Synced_UseRecharge = true;

		private static readonly MethodInfo ZNet_IsServer = TryGetMethod(typeof(ZNet), "IsServer", Type.EmptyTypes);

		private static readonly MethodInfo ZNet_IsConnected_NoArgs = TryGetMethod(typeof(ZNet), "IsConnected", Type.EmptyTypes);

		private static readonly MethodInfo ZNet_IsConnected_WithLong = TryGetMethod(typeof(ZNet), "IsConnected", new Type[1] { typeof(long) });

		private static readonly MethodInfo ZNet_GetUID = TryGetMethod(typeof(ZNet), "GetUID", Type.EmptyTypes);

		private static readonly MethodInfo ZNet_IsAdmin_NoArgs = TryGetMethod(typeof(ZNet), "IsAdmin", Type.EmptyTypes);

		private static readonly MethodInfo ZNet_IsAdmin_WithLong = TryGetMethod(typeof(ZNet), "IsAdmin", new Type[1] { typeof(long) });

		private static readonly FieldInfo ZNet_m_peers = TryGetField(typeof(ZNet), "m_peers");

		private static readonly Type ZNetPeerType = typeof(ZNet).Assembly.GetType("ZNetPeer");

		private static readonly FieldInfo Peer_uid = ((ZNetPeerType != null) ? TryGetField(ZNetPeerType, "m_uid") : null);

		private static readonly FieldInfo Peer_admin = ((ZNetPeerType != null) ? TryGetField(ZNetPeerType, "m_admin") : null);

		private static readonly FieldInfo FI_NView = AccessTools.Field(typeof(Character), "m_nview");

		private static readonly MethodInfo MI_ZNetView_IsOwner = AccessTools.Method(typeof(ZNetView), "IsOwner", Type.EmptyTypes, (Type[])null);

		private static readonly MethodInfo MI_ZNetView_GetZDO = AccessTools.Method(typeof(ZNetView), "GetZDO", Type.EmptyTypes, (Type[])null);

		private static readonly MethodInfo MI_ZDO_GetOwner = AccessTools.Method(typeof(ZDO), "GetOwner", Type.EmptyTypes, (Type[])null);

		private static readonly FieldInfo FI_ZDO_Owner = AccessTools.Field(typeof(ZDO), "m_owner");

		private static readonly MethodInfo MI_ZDO_GetLong = AccessTools.Method(typeof(ZDO), "GetLong", new Type[2]
		{
			typeof(string),
			typeof(long)
		}, (Type[])null);

		private static MethodInfo TryGetMethod(Type t, string name, Type[] args)
		{
			try
			{
				return t.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, args, null);
			}
			catch
			{
				return null;
			}
		}

		private static FieldInfo TryGetField(Type t, string name)
		{
			try
			{
				return t.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			catch
			{
				return null;
			}
		}

		public static long TryGetLocalUid()
		{
			try
			{
				if ((Object)(object)ZNet.instance != (Object)null && ZNet_GetUID != null)
				{
					return (long)ZNet_GetUID.Invoke(ZNet.instance, null);
				}
			}
			catch
			{
			}
			return 0L;
		}

		public static bool IsLocalOwner(Character c)
		{
			try
			{
				if ((Object)(object)c == (Object)null || FI_NView == null)
				{
					return false;
				}
				object? value = FI_NView.GetValue(c);
				ZNetView val = (ZNetView)((value is ZNetView) ? value : null);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				if (MI_ZNetView_IsOwner != null)
				{
					return (bool)MI_ZNetView_IsOwner.Invoke(val, null);
				}
				ZDO zDO = GetZDO(val);
				if (zDO == null)
				{
					return false;
				}
				long zDOOwner = GetZDOOwner(zDO);
				long num = TryGetLocalUid();
				return zDOOwner != 0L && num != 0L && zDOOwner == num;
			}
			catch
			{
				return false;
			}
		}

		private static ZDO GetZDO(ZNetView nview)
		{
			try
			{
				if (MI_ZNetView_GetZDO != null)
				{
					object? obj = MI_ZNetView_GetZDO.Invoke(nview, null);
					return (ZDO)((obj is ZDO) ? obj : null);
				}
			}
			catch
			{
			}
			try
			{
				return nview.GetZDO();
			}
			catch
			{
				return null;
			}
		}

		private static long GetZDOOwner(ZDO zdo)
		{
			try
			{
				if (MI_ZDO_GetOwner != null)
				{
					return (long)MI_ZDO_GetOwner.Invoke(zdo, null);
				}
			}
			catch
			{
			}
			try
			{
				if (FI_ZDO_Owner != null)
				{
					return (long)FI_ZDO_Owner.GetValue(zdo);
				}
			}
			catch
			{
			}
			try
			{
				if (MI_ZDO_GetLong != null)
				{
					return (long)MI_ZDO_GetLong.Invoke(zdo, new object[2] { "owner", 0L });
				}
			}
			catch
			{
			}
			return 0L;
		}

		private static bool IsPeerAdmin(long uid)
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			if (ZNet_m_peers == null || ZNetPeerType == null || Peer_uid == null || Peer_admin == null)
			{
				return false;
			}
			object value;
			try
			{
				value = ZNet_m_peers.GetValue(ZNet.instance);
			}
			catch
			{
				return false;
			}
			if (!(value is IEnumerable enumerable))
			{
				return false;
			}
			foreach (object item in enumerable)
			{
				if (item == null || item.GetType() != ZNetPeerType)
				{
					continue;
				}
				try
				{
					long num = (long)Peer_uid.GetValue(item);
					if (num != uid)
					{
						continue;
					}
					return (bool)Peer_admin.GetValue(item);
				}
				catch
				{
				}
			}
			return false;
		}

		public static bool IsServer()
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			try
			{
				if (ZNet_IsServer != null)
				{
					return (bool)ZNet_IsServer.Invoke(ZNet.instance, null);
				}
			}
			catch
			{
			}
			return false;
		}

		public static bool IsConnected()
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			try
			{
				if (ZNet_IsConnected_NoArgs != null)
				{
					return (bool)ZNet_IsConnected_NoArgs.Invoke(ZNet.instance, null);
				}
				if (ZNet_IsConnected_WithLong != null)
				{
					long num = TryGetLocalUid();
					return (bool)ZNet_IsConnected_WithLong.Invoke(ZNet.instance, new object[1] { num });
				}
			}
			catch
			{
			}
			return ZRoutedRpc.instance != null;
		}

		public static bool IsLocalAdmin()
		{
			if (IsServer())
			{
				return true;
			}
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			try
			{
				if (ZNet_IsAdmin_NoArgs != null)
				{
					return (bool)ZNet_IsAdmin_NoArgs.Invoke(ZNet.instance, null);
				}
			}
			catch
			{
			}
			try
			{
				long uid = TryGetLocalUid();
				return IsPeerAdmin(uid);
			}
			catch
			{
			}
			return false;
		}

		private static bool IsSenderAdmin(long sender)
		{
			if (!IsServer())
			{
				return false;
			}
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			try
			{
				if (ZNet_IsAdmin_WithLong != null)
				{
					return (bool)ZNet_IsAdmin_WithLong.Invoke(ZNet.instance, new object[1] { sender });
				}
			}
			catch
			{
			}
			return IsPeerAdmin(sender);
		}

		public static void EnsureRegistered()
		{
			if (!_registered && ZRoutedRpc.instance != null)
			{
				_registered = true;
				ZRoutedRpc.instance.Register<ZPackage>("AES_RequestSync", (Action<long, ZPackage>)RPC_RequestSync_Handler);
				ZRoutedRpc.instance.Register<ZPackage>("AES_SetSettings", (Action<long, ZPackage>)RPC_SetSettings_Handler);
				ZRoutedRpc.instance.Register<ZPackage>("AES_RequestChange", (Action<long, ZPackage>)RPC_RequestChange_Handler);
				ZRoutedRpc.instance.Register<ZPackage>("AES_ArmDieBypass", (Action<long, ZPackage>)RPC_ArmDieBypass_Handler);
				((MonoBehaviour)AbsorptionEitrShieldPlugin.Instance).StartCoroutine(RequestSyncWhenConnected());
			}
		}

		public static void ClientArmDieBypass()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			try
			{
				if (ZRoutedRpc.instance != null && IsConnected())
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AES_ArmDieBypass", new object[1] { (object)new ZPackage() });
				}
			}
			catch
			{
			}
		}

		private static void RPC_ArmDieBypass_Handler(long sender, ZPackage pkg)
		{
			if (IsServer())
			{
				DieBypassServerRegistry.ArmForSender(sender);
			}
		}

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

		public static void ServerApplyFromLocalConfigAndBroadcast()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			if (IsServer() && ZRoutedRpc.instance != null)
			{
				Synced_ModEnabled = AbsorptionEitrShieldPlugin.CfgModEnabled.Value;
				Synced_UseRecharge = AbsorptionEitrShieldPlugin.CfgUseRecharge.Value;
				ZPackage val = new ZPackage();
				val.Write(Synced_ModEnabled);
				val.Write(Synced_UseRecharge);
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AES_SetSettings", new object[1] { val });
			}
		}

		public static void ClientRequestChange(bool modEnabled, bool useRecharge)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			if (ZRoutedRpc.instance != null)
			{
				ZPackage val = new ZPackage();
				val.Write(modEnabled);
				val.Write(useRecharge);
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AES_RequestChange", new object[1] { val });
			}
		}

		private static void RPC_RequestSync_Handler(long sender, ZPackage pkg)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (IsServer() && ZRoutedRpc.instance != null)
			{
				ZPackage val = new ZPackage();
				val.Write(AbsorptionEitrShieldPlugin.CfgModEnabled.Value);
				val.Write(AbsorptionEitrShieldPlugin.CfgUseRecharge.Value);
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "AES_SetSettings", new object[1] { val });
			}
		}

		private static void RPC_SetSettings_Handler(long sender, ZPackage pkg)
		{
			bool flag = pkg.ReadBool();
			bool flag2 = pkg.ReadBool();
			Synced_ModEnabled = flag;
			Synced_UseRecharge = flag2;
			AbsorptionEitrShieldPlugin.SetLocalConfigSilently(flag, flag2);
		}

		private static void RPC_RequestChange_Handler(long sender, ZPackage pkg)
		{
			if (IsServer() && ZRoutedRpc.instance != null)
			{
				bool modEnabled = pkg.ReadBool();
				bool useRecharge = pkg.ReadBool();
				if (IsSenderAdmin(sender))
				{
					AbsorptionEitrShieldPlugin.SetLocalConfigSilently(modEnabled, useRecharge);
					ServerApplyFromLocalConfigAndBroadcast();
				}
			}
		}
	}
}