Decompiled source of Coroner v2.4.1

Coroner.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Xml.Linq;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using StaticNetcodeLib;
using TMPro;
using Unity.Netcode;
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("EliteMasterEric")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A Lethal Company plugin which overhauls the end-of-mission performance report with new information, including cause of death for any deceased players with some fun easter eggs thrown in too.")]
[assembly: AssemblyFileVersion("2.4.1.0")]
[assembly: AssemblyInformationalVersion("2.4.1+8626d7985f5122271a270e3ab7373ebd9dfa5235")]
[assembly: AssemblyProduct("Coroner")]
[assembly: AssemblyTitle("Coroner")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.4.1.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 Coroner
{
	internal class AdvancedDeathTracker
	{
		public static Dictionary<int, AdvancedCauseOfDeath?> causeOfDeathDictionary = new Dictionary<int, AdvancedCauseOfDeath?>();

		public static void ClearDeathTracker()
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				StoreLocalCauseOfDeath((int)val.playerClientId, null, overrideExisting: true);
			}
		}

		public static void SetCauseOfDeath(int playerIndex, AdvancedCauseOfDeath? causeOfDeath, bool forceOverride = false)
		{
			if (!causeOfDeath.HasValue)
			{
				NetworkRPC.ReportCauseOfDeathServerRpc(playerIndex, null, forceOverride);
				return;
			}
			AdvancedCauseOfDeath value = causeOfDeath.Value;
			Plugin.Instance.PluginLogger.LogDebug(string.Format("Serializing {0} to {1}{2}", value, value.GetLanguageTag(), forceOverride ? " (FORCED)" : ""));
			NetworkRPC.ReportCauseOfDeathServerRpc(playerIndex, value.GetLanguageTag(), forceOverride);
			StoreLocalCauseOfDeath(playerIndex, causeOfDeath, forceOverride);
		}

		public static void SetCauseOfDeath(PlayerControllerB playerController, AdvancedCauseOfDeath? causeOfDeath, bool forceOverride = false)
		{
			SetCauseOfDeath((int)playerController.playerClientId, causeOfDeath, forceOverride);
		}

		public static void StoreLocalCauseOfDeath(int playerId, AdvancedCauseOfDeath? causeOfDeath, bool overrideExisting)
		{
			if (!overrideExisting && (!causeOfDeath.HasValue || HasCauseOfDeath(playerId)))
			{
				if (!causeOfDeath.HasValue)
				{
					Plugin.Instance.PluginLogger.LogDebug($"Ignoring null cause of death for player {playerId}");
					return;
				}
				string languageTag = causeOfDeath.Value.GetLanguageTag();
				AdvancedCauseOfDeath? causeOfDeath2 = GetCauseOfDeath(playerId, shouldGuess: false);
				string arg = ((!causeOfDeath2.HasValue) ? "null" : causeOfDeath2.Value.GetLanguageTag());
				Plugin.Instance.PluginLogger.LogWarning($"Player {playerId} already has a cause of death set ({arg}), not overwriting it with {languageTag}.");
			}
			else if (!causeOfDeath.HasValue)
			{
				Plugin.Instance.PluginLogger.LogDebug($"Clearing cause of death for player {playerId}");
				causeOfDeathDictionary[playerId] = null;
			}
			else
			{
				AdvancedCauseOfDeath? causeOfDeath3 = GetCauseOfDeath(playerId, shouldGuess: false);
				string arg2 = ((!causeOfDeath3.HasValue) ? "null" : causeOfDeath3.Value.GetLanguageTag());
				string languageTag2 = causeOfDeath.Value.GetLanguageTag();
				Plugin.Instance.PluginLogger.LogDebug($"Storing cause of death {languageTag2} (overriding {arg2}) for player {playerId}!");
				causeOfDeathDictionary[playerId] = causeOfDeath;
			}
		}

		private static AdvancedCauseOfDeath? FetchCauseOfDeathVariable(PlayerControllerB playerController)
		{
			if (!HasCauseOfDeath(playerController))
			{
				return null;
			}
			return causeOfDeathDictionary[(int)playerController.playerClientId];
		}

		public static AdvancedCauseOfDeath? GetCauseOfDeath(int playerIndex, bool shouldGuess = true)
		{
			if (playerIndex < 0 || playerIndex >= StartOfRound.Instance.allPlayerScripts.Length)
			{
				return null;
			}
			PlayerControllerB playerController = StartOfRound.Instance.allPlayerScripts[playerIndex];
			return GetCauseOfDeath(playerController, shouldGuess);
		}

		public static bool HasCauseOfDeath(int playerIndex)
		{
			if (playerIndex < 0 || playerIndex >= StartOfRound.Instance.allPlayerScripts.Length)
			{
				return false;
			}
			return HasCauseOfDeath(StartOfRound.Instance.allPlayerScripts[playerIndex]);
		}

		public static bool HasCauseOfDeath(PlayerControllerB playerController)
		{
			return causeOfDeathDictionary.ContainsKey((int)playerController.playerClientId) && causeOfDeathDictionary[(int)playerController.playerClientId].HasValue;
		}

		public static AdvancedCauseOfDeath? GetCauseOfDeath(PlayerControllerB playerController, bool shouldGuess = true)
		{
			AdvancedCauseOfDeath? advancedCauseOfDeath = FetchCauseOfDeathVariable(playerController);
			if (advancedCauseOfDeath.HasValue)
			{
				AdvancedCauseOfDeath value = advancedCauseOfDeath.Value;
				Plugin.Instance.PluginLogger.LogDebug($"Player {playerController.playerClientId} has custom cause of death stored! {value.GetLanguageTag()}");
				return value;
			}
			if (!shouldGuess)
			{
				Plugin.Instance.PluginLogger.LogDebug($"Player {playerController.playerClientId} has no custom cause of death stored! Returning null...");
				return null;
			}
			Plugin.Instance.PluginLogger.LogDebug($"Player {playerController.playerClientId} has no custom cause of death stored! Using fallback...");
			return GuessCauseOfDeath(playerController);
		}

		public static AdvancedCauseOfDeath GuessCauseOfDeath(PlayerControllerB playerController)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if (playerController.isPlayerDead)
			{
				if (IsHoldingJetpack(playerController))
				{
					if ((int)playerController.causeOfDeath == 2)
					{
						return AdvancedCauseOfDeath.Player_Jetpack_Gravity;
					}
					if ((int)playerController.causeOfDeath == 3)
					{
						return AdvancedCauseOfDeath.Player_Jetpack_Blast;
					}
				}
				return playerController.causeOfDeath;
			}
			return AdvancedCauseOfDeath.Unknown;
		}

		public static GrabbableObject? GetHeldObject(PlayerControllerB playerController)
		{
			GrabbableObject currentlyHeldObjectServer = playerController.currentlyHeldObjectServer;
			if ((Object)(object)currentlyHeldObjectServer == (Object)null)
			{
				return null;
			}
			GameObject gameObject = ((Component)currentlyHeldObjectServer).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				return null;
			}
			return gameObject.GetComponent<GrabbableObject>();
		}

		public static bool IsHoldingJetpack(PlayerControllerB playerController)
		{
			GrabbableObject heldObject = GetHeldObject(playerController);
			if ((Object)(object)heldObject == (Object)null)
			{
				return false;
			}
			if (heldObject is JetpackItem)
			{
				return true;
			}
			return false;
		}

		public static bool IsHoldingShovel(PlayerControllerB playerController)
		{
			GrabbableObject heldObject = GetHeldObject(playerController);
			if ((Object)(object)heldObject == (Object)null)
			{
				return false;
			}
			if (heldObject is Shovel && ((Object)((Component)heldObject).gameObject).name.StartsWith("Shovel"))
			{
				return true;
			}
			return false;
		}

		public static bool IsHoldingStopSign(PlayerControllerB playerController)
		{
			GrabbableObject heldObject = GetHeldObject(playerController);
			if ((Object)(object)heldObject == (Object)null)
			{
				return false;
			}
			if (heldObject is Shovel && ((Object)((Component)heldObject).gameObject).name.StartsWith("StopSign"))
			{
				return true;
			}
			return false;
		}

		public static bool IsHoldingYieldSign(PlayerControllerB playerController)
		{
			GrabbableObject heldObject = GetHeldObject(playerController);
			if ((Object)(object)heldObject == (Object)null)
			{
				return false;
			}
			if (heldObject is Shovel && ((Object)((Component)heldObject).gameObject).name.StartsWith("YieldSign"))
			{
				return true;
			}
			return false;
		}

		public static bool IsHoldingShotgun(PlayerControllerB playerController)
		{
			GrabbableObject heldObject = GetHeldObject(playerController);
			if ((Object)(object)heldObject == (Object)null)
			{
				return false;
			}
			if (heldObject is ShotgunItem)
			{
				return true;
			}
			return false;
		}

		public static bool IsHoldingKnife(PlayerControllerB playerController)
		{
			GrabbableObject heldObject = GetHeldObject(playerController);
			if ((Object)(object)heldObject == (Object)null)
			{
				return false;
			}
			if (heldObject is KnifeItem)
			{
				return true;
			}
			return false;
		}

		public static string StringifyCauseOfDeath(AdvancedCauseOfDeath? causeOfDeath)
		{
			return StringifyCauseOfDeath(causeOfDeath, Plugin.RANDOM);
		}

		public static string StringifyCauseOfDeath(AdvancedCauseOfDeath? causeOfDeath, Random random)
		{
			string[] array = SelectCauseOfDeath(causeOfDeath);
			if (array.Length > 1 && (!causeOfDeath.HasValue || !Plugin.Instance.PluginConfig.ShouldUseSeriousDeathMessages()))
			{
				int num = random.Next(array.Length);
				return array[num];
			}
			return array[0];
		}

		public static string[] SelectCauseOfDeath(AdvancedCauseOfDeath? causeOfDeath)
		{
			if (!causeOfDeath.HasValue)
			{
				return Plugin.Instance.LanguageHandler.GetValuesByTag("FunnyNote");
			}
			if (AdvancedCauseOfDeath.IsCauseOfDeathRegistered(causeOfDeath))
			{
				return causeOfDeath.Value.GetLanguageValues();
			}
			return Plugin.Instance.LanguageHandler.GetValuesByTag("DeathUnknown");
		}
	}
	public struct AdvancedCauseOfDeath
	{
		public static readonly Dictionary<string, AdvancedCauseOfDeath> Registry = new Dictionary<string, AdvancedCauseOfDeath>();

		private static int NextId = 100;

		public static AdvancedCauseOfDeath Unknown = BuildFromExisting("DeathUnknown", (CauseOfDeath)0);

		public static AdvancedCauseOfDeath Bludgeoning = BuildFromExisting("DeathBludgeoning", (CauseOfDeath)1);

		public static AdvancedCauseOfDeath Gravity = BuildFromExisting("DeathGravity", (CauseOfDeath)2);

		public static AdvancedCauseOfDeath Blast = BuildFromExisting("DeathBlast", (CauseOfDeath)3);

		public static AdvancedCauseOfDeath Strangulation = BuildFromExisting("DeathStrangulation", (CauseOfDeath)4);

		public static AdvancedCauseOfDeath Suffocation = BuildFromExisting("DeathSuffocation", (CauseOfDeath)5);

		public static AdvancedCauseOfDeath Mauling = BuildFromExisting("DeathMauling", (CauseOfDeath)6);

		public static AdvancedCauseOfDeath Gunshots = BuildFromExisting("DeathGunshots", (CauseOfDeath)7);

		public static AdvancedCauseOfDeath Crushing = BuildFromExisting("DeathCrushing", (CauseOfDeath)8);

		public static AdvancedCauseOfDeath Drowning = BuildFromExisting("DeathDrowning", (CauseOfDeath)9);

		public static AdvancedCauseOfDeath Abandoned = BuildFromExisting("DeathAbandoned", (CauseOfDeath)10);

		public static AdvancedCauseOfDeath Electrocution = BuildFromExisting("DeathElectrocution", (CauseOfDeath)11);

		public static AdvancedCauseOfDeath Kicking = BuildFromExisting("DeathKicking", (CauseOfDeath)12);

		public static AdvancedCauseOfDeath Burning = BuildFromExisting("DeathBurning", (CauseOfDeath)13);

		public static AdvancedCauseOfDeath Stabbing = BuildFromExisting("DeathStabbing", (CauseOfDeath)14);

		public static AdvancedCauseOfDeath Fan = BuildFromExisting("DeathFan", (CauseOfDeath)15);

		public static AdvancedCauseOfDeath Inertia = BuildFromExisting("DeathInertia", (CauseOfDeath)16);

		public static AdvancedCauseOfDeath Scratching = BuildFromExisting("DeathScratching", (CauseOfDeath)18);

		public static AdvancedCauseOfDeath Snipping = BuildFromExisting("DeathSnipped", (CauseOfDeath)17);

		public static AdvancedCauseOfDeath Enemy_BaboonHawk = Build("DeathEnemyBaboonHawk");

		public static AdvancedCauseOfDeath Enemy_Bracken = Build("DeathEnemyBracken");

		public static AdvancedCauseOfDeath Enemy_BunkerSpider = Build("DeathEnemyBunkerSpider");

		public static AdvancedCauseOfDeath Enemy_CircuitBees = Build("DeathEnemyCircuitBees");

		public static AdvancedCauseOfDeath Enemy_CoilHead = Build("DeathEnemyCoilHead");

		public static AdvancedCauseOfDeath Enemy_EarthLeviathan = Build("DeathEnemyEarthLeviathan");

		public static AdvancedCauseOfDeath Enemy_EyelessDog = Build("DeathEnemyEyelessDog");

		public static AdvancedCauseOfDeath Enemy_GhostGirl = Build("DeathEnemyGhostGirl");

		public static AdvancedCauseOfDeath Enemy_HoarderBug = Build("DeathEnemyHoarderBug");

		public static AdvancedCauseOfDeath Enemy_Hygrodere = Build("DeathEnemyHygrodere");

		public static AdvancedCauseOfDeath Enemy_Jester = Build("DeathEnemyJester");

		public static AdvancedCauseOfDeath Enemy_LassoMan = Build("DeathEnemyLassoMan");

		public static AdvancedCauseOfDeath Enemy_SnareFlea = Build("DeathEnemySnareFlea");

		public static AdvancedCauseOfDeath Enemy_SporeLizard = Build("DeathEnemySporeLizard");

		public static AdvancedCauseOfDeath Enemy_Thumper = Build("DeathEnemyThumper");

		public static AdvancedCauseOfDeath Enemy_ForestGiant_Eaten = Build("DeathEnemyForestGiantEaten");

		public static AdvancedCauseOfDeath Enemy_ForestGiant_Death = Build("DeathEnemyForestGiantDeath");

		public static AdvancedCauseOfDeath Enemy_MaskedPlayer_Wear = Build("DeathEnemyMaskedPlayerWear");

		public static AdvancedCauseOfDeath Enemy_MaskedPlayer_Victim = Build("DeathEnemyMaskedPlayerVictim");

		public static AdvancedCauseOfDeath Enemy_Nutcracker_Kicked = Build("DeathEnemyNutcrackerKicked");

		public static AdvancedCauseOfDeath Enemy_Nutcracker_Shot = Build("DeathEnemyNutcrackerShot");

		public static AdvancedCauseOfDeath Enemy_Butler_Stab = Build("DeathEnemyButlerStab");

		public static AdvancedCauseOfDeath Enemy_Butler_Explode = Build("DeathEnemyButlerExplode");

		public static AdvancedCauseOfDeath Enemy_MaskHornets = Build("DeathEnemyMaskHornets");

		public static AdvancedCauseOfDeath Enemy_TulipSnake_Drop = Build("DeathEnemyTulipSnakeDrop");

		public static AdvancedCauseOfDeath Enemy_Old_Bird_Rocket = Build("DeathEnemyOldBirdRocket");

		public static AdvancedCauseOfDeath Enemy_Old_Bird_Charge = Build("DeathEnemyOldBirdCharge");

		public static AdvancedCauseOfDeath Enemy_Old_Bird_Stomp = Build("DeathEnemyOldBirdStomp");

		public static AdvancedCauseOfDeath Enemy_Old_Bird_Torch = Build("DeathEnemyOldBirdTorch");

		public static AdvancedCauseOfDeath Enemy_KidnapperFox = Build("DeathEnemyKidnapperFox");

		public static AdvancedCauseOfDeath Enemy_Barber = Build("DeathEnemyBarber");

		public static AdvancedCauseOfDeath Enemy_Maneater = Build("DeathEnemyManeater");

		public static AdvancedCauseOfDeath Enemy_Giant_Sapsucker = Build("DeathEnemyGiantSapsucker");

		public static AdvancedCauseOfDeath Enemy_Cadaver_Growth = Build("DeathEnemyCadaverGrowth");

		public static AdvancedCauseOfDeath Enemy_Cadaver_Bloom = Build("DeathEnemyCadaverBloom");

		public static AdvancedCauseOfDeath Enemy_Feiopar = Build("DeathEnemyFeiopar");

		public static AdvancedCauseOfDeath Player_Jetpack_Gravity = Build("DeathPlayerJetpackGravity");

		public static AdvancedCauseOfDeath Player_Jetpack_Blast = Build("DeathPlayerJetpackBlast");

		public static AdvancedCauseOfDeath Player_Quicksand = Build("DeathPlayerQuicksand");

		public static AdvancedCauseOfDeath Player_Ladder = Build("DeathPlayerLadder");

		public static AdvancedCauseOfDeath Player_Murder_Shovel = Build("DeathPlayerMurderShovel");

		public static AdvancedCauseOfDeath Player_Murder_Stop_Sign = Build("DeathPlayerMurderStopSign");

		public static AdvancedCauseOfDeath Player_Murder_Yield_Sign = Build("DeathPlayerMurderYieldSign");

		public static AdvancedCauseOfDeath Player_Murder_Shotgun = Build("DeathPlayerMurderShotgun");

		public static AdvancedCauseOfDeath Player_Murder_Knife = Build("DeathPlayerMurderKnife");

		public static AdvancedCauseOfDeath Player_StunGrenade = Build("DeathPlayerStunGrenade");

		public static AdvancedCauseOfDeath Player_EasterEgg = Build("DeathPlayerEasterEgg");

		public static AdvancedCauseOfDeath Player_Electric_Chair = Build("DeathPlayerElectricChair");

		public static AdvancedCauseOfDeath Player_Vomiting = Build("DeathPlayerVomiting");

		public static AdvancedCauseOfDeath Player_Cruiser_Driver = Build("DeathPlayerCruiserDriver");

		public static AdvancedCauseOfDeath Player_Cruiser_Passenger = Build("DeathPlayerCruiserPassenger");

		public static AdvancedCauseOfDeath Player_Cruiser_Explode_Bystander = Build("DeathPlayerCruiserExplodeBystander");

		public static AdvancedCauseOfDeath Player_Cruiser_Ran_Over = Build("DeathPlayerCruiserRanOver");

		public static AdvancedCauseOfDeath Pit_Generic = Build("DeathPitGeneric");

		public static AdvancedCauseOfDeath Pit_Facility_Pit = Build("DeathPitFacilityPit");

		public static AdvancedCauseOfDeath Pit_Facility_Catwalk_Jump = Build("DeathPitFacilityCatwalkJump");

		public static AdvancedCauseOfDeath Pit_Mine_Pit = Build("DeathPitMinePit");

		public static AdvancedCauseOfDeath Pit_Mine_Cave = Build("DeathPitMineCave");

		public static AdvancedCauseOfDeath Pit_Mine_Elevator = Build("DeathPitMineElevator");

		public static AdvancedCauseOfDeath Other_Landmine = Build("DeathOtherLandmine");

		public static AdvancedCauseOfDeath Other_Turret = Build("DeathOtherTurret");

		public static AdvancedCauseOfDeath Other_Lightning = Build("DeathOtherLightning");

		public static AdvancedCauseOfDeath Other_Meteor = Build("DeathOtherMeteor");

		public static AdvancedCauseOfDeath Other_DepositItemsDesk = Build("DeathOtherDepositItemsDesk");

		public static AdvancedCauseOfDeath Other_Dropship = Build("DeathOtherItemDropship");

		public static AdvancedCauseOfDeath Other_Spike_Trap = Build("DeathOtherSpikeTrap");

		public static AdvancedCauseOfDeath Other_OutOfBounds = Build("DeathOtherOutOfBounds");

		private int statusCode;

		private string languageTag;

		public static AdvancedCauseOfDeath Build(string languageTag)
		{
			int nextId = NextId;
			NextId++;
			AdvancedCauseOfDeath advancedCauseOfDeath = default(AdvancedCauseOfDeath);
			advancedCauseOfDeath.statusCode = nextId;
			advancedCauseOfDeath.languageTag = languageTag;
			AdvancedCauseOfDeath advancedCauseOfDeath2 = advancedCauseOfDeath;
			Register(languageTag, advancedCauseOfDeath2);
			return advancedCauseOfDeath2;
		}

		public static AdvancedCauseOfDeath BuildFromExisting(string languageTag, CauseOfDeath statusCode)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			AdvancedCauseOfDeath advancedCauseOfDeath = default(AdvancedCauseOfDeath);
			advancedCauseOfDeath.statusCode = (int)statusCode;
			advancedCauseOfDeath.languageTag = languageTag;
			AdvancedCauseOfDeath advancedCauseOfDeath2 = advancedCauseOfDeath;
			Register(languageTag, advancedCauseOfDeath2);
			return advancedCauseOfDeath2;
		}

		private static void Register(string key, AdvancedCauseOfDeath value)
		{
			if (IsTagRegistered(key))
			{
				Plugin.Instance.PluginLogger.LogError("Tried to register duplicate Cause of Death key (" + key + ")!");
			}
			else if (IsCauseOfDeathRegistered(value))
			{
				Plugin.Instance.PluginLogger.LogError($"Tried to register Cause of Death twice ({value})!");
			}
			else
			{
				Registry.Add(key, value);
			}
		}

		public static AdvancedCauseOfDeath? Fetch(string? key)
		{
			if (key == null)
			{
				return null;
			}
			if (!Registry.ContainsKey(key))
			{
				return null;
			}
			return Registry[key];
		}

		public static bool IsTagRegistered(string key)
		{
			return Registry.ContainsKey(key);
		}

		public static bool IsCauseOfDeathRegistered(AdvancedCauseOfDeath? value)
		{
			if (!value.HasValue)
			{
				return false;
			}
			return Registry.ContainsValue(value.Value);
		}

		private static AdvancedCauseOfDeath ConvertCauseOfDeath(CauseOfDeath causeOfDeath)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected I4, but got Unknown
			return (int)causeOfDeath switch
			{
				0 => Unknown, 
				1 => Bludgeoning, 
				2 => Gravity, 
				3 => Blast, 
				4 => Strangulation, 
				5 => Suffocation, 
				6 => Mauling, 
				7 => Gunshots, 
				8 => Crushing, 
				9 => Drowning, 
				10 => Abandoned, 
				11 => Electrocution, 
				13 => Burning, 
				15 => Fan, 
				14 => Stabbing, 
				_ => Unknown, 
			};
		}

		public string GetLanguageTag()
		{
			return languageTag;
		}

		public string[] GetLanguageValues()
		{
			return Plugin.Instance.LanguageHandler.GetValuesByTag(languageTag);
		}

		public override bool Equals(object obj)
		{
			return obj is AdvancedCauseOfDeath advancedCauseOfDeath && statusCode == advancedCauseOfDeath.statusCode;
		}

		public override int GetHashCode()
		{
			return HashCode.Combine(statusCode, languageTag);
		}

		public static bool operator ==(AdvancedCauseOfDeath left, AdvancedCauseOfDeath right)
		{
			return left.statusCode == right.statusCode;
		}

		public static bool operator !=(AdvancedCauseOfDeath left, AdvancedCauseOfDeath right)
		{
			return left.statusCode != right.statusCode;
		}

		public static bool operator ==(CauseOfDeath left, AdvancedCauseOfDeath right)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)left == right.statusCode;
		}

		public static bool operator !=(CauseOfDeath left, AdvancedCauseOfDeath right)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)left != right.statusCode;
		}

		public static bool operator ==(AdvancedCauseOfDeath left, CauseOfDeath right)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between I4 and Unknown
			return left.statusCode == (int)right;
		}

		public static bool operator !=(AdvancedCauseOfDeath left, CauseOfDeath right)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between I4 and Unknown
			return left.statusCode != (int)right;
		}

		public static implicit operator AdvancedCauseOfDeath(CauseOfDeath value)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return ConvertCauseOfDeath(value);
		}

		public static implicit operator CauseOfDeath(AdvancedCauseOfDeath value)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return (CauseOfDeath)value.statusCode;
		}

		public override string ToString()
		{
			return "AdvancedCauseOfDeath(" + languageTag + ")";
		}
	}
	public class API
	{
		public static void SetCauseOfDeath(PlayerControllerB player, AdvancedCauseOfDeath causeOfDeath)
		{
			bool flag = false;
			AdvancedDeathTracker.SetCauseOfDeath(player, causeOfDeath);
		}

		public static void SetCauseOfDeath(int playerId, AdvancedCauseOfDeath causeOfDeath)
		{
			bool flag = false;
			AdvancedDeathTracker.SetCauseOfDeath(playerId, causeOfDeath);
		}

		public static void ClearCauseOfDeath(PlayerControllerB player)
		{
			ClearCauseOfDeath((int)player.playerClientId);
		}

		public static void ClearCauseOfDeath(int playerId)
		{
			AdvancedDeathTracker.StoreLocalCauseOfDeath(playerId, null, overrideExisting: true);
		}

		public static AdvancedCauseOfDeath? GetCauseOfDeath(PlayerControllerB player)
		{
			return AdvancedDeathTracker.GetCauseOfDeath(player);
		}

		public static AdvancedCauseOfDeath? GetCauseOfDeath(int playerId)
		{
			return AdvancedDeathTracker.GetCauseOfDeath(playerId);
		}

		public static AdvancedCauseOfDeath Register(string key)
		{
			return AdvancedCauseOfDeath.Build(key);
		}

		public static bool IsRegistered(string key)
		{
			return AdvancedCauseOfDeath.IsTagRegistered(key);
		}

		public static string StringifyCauseOfDeath(AdvancedCauseOfDeath causeOfDeath, Random? random)
		{
			return AdvancedDeathTracker.StringifyCauseOfDeath(causeOfDeath, (random != null) ? random : Plugin.RANDOM);
		}
	}
	internal class EnumeratorPatch : IEnumerable
	{
		public IEnumerator targetEnumerator;

		public Action? prefixAction;

		public Action? postfixAction;

		public Action<object?>? preStepAction;

		public Action<object?>? postStepAction;

		public Func<object?, object?>? stepAction;

		public EnumeratorPatch(IEnumerator targetEnumerator)
		{
			this.targetEnumerator = targetEnumerator;
		}

		public IEnumerator GetEnumerator()
		{
			if (prefixAction != null)
			{
				prefixAction();
			}
			while (targetEnumerator.MoveNext())
			{
				object value = targetEnumerator.Current;
				if (preStepAction != null)
				{
					preStepAction(value);
				}
				yield return (stepAction != null) ? stepAction(value) : value;
				if (postStepAction != null)
				{
					postStepAction(value);
				}
			}
			if (postfixAction != null)
			{
				postfixAction();
			}
		}
	}
	internal class LanguageHandler
	{
		public const string DEFAULT_LANGUAGE = "en-us";

		public const string TAG_FUNNY_NOTES = "FunnyNote";

		public const string TAG_UI_NOTES = "UINotes";

		public const string TAG_UI_DEATH = "UICauseOfDeath";

		public const string TAG_DEATH_GENERIC_BLUDGEONING = "DeathBludgeoning";

		public const string TAG_DEATH_GENERIC_GRAVITY = "DeathGravity";

		public const string TAG_DEATH_GENERIC_BLAST = "DeathBlast";

		public const string TAG_DEATH_GENERIC_STRANGULATION = "DeathStrangulation";

		public const string TAG_DEATH_GENERIC_SUFFOCATION = "DeathSuffocation";

		public const string TAG_DEATH_GENERIC_MAULING = "DeathMauling";

		public const string TAG_DEATH_GENERIC_GUNSHOTS = "DeathGunshots";

		public const string TAG_DEATH_GENERIC_CRUSHING = "DeathCrushing";

		public const string TAG_DEATH_GENERIC_DROWNING = "DeathDrowning";

		public const string TAG_DEATH_GENERIC_ABANDONED = "DeathAbandoned";

		public const string TAG_DEATH_GENERIC_ELECTROCUTION = "DeathElectrocution";

		public const string TAG_DEATH_GENERIC_KICKING = "DeathKicking";

		public const string TAG_DEATH_GENERIC_BURNING = "DeathBurning";

		public const string TAG_DEATH_GENERIC_STABBING = "DeathStabbing";

		public const string TAG_DEATH_GENERIC_FAN = "DeathFan";

		public const string TAG_DEATH_GENERIC_INERTIA = "DeathInertia";

		public const string TAG_DEATH_GENERIC_SNIPPING = "DeathSnipped";

		public const string TAG_DEATH_GENERIC_SCRATCHING = "DeathScratching";

		public const string TAG_DEATH_ENEMY_BABOON_HAWK = "DeathEnemyBaboonHawk";

		public const string TAG_DEATH_ENEMY_BRACKEN = "DeathEnemyBracken";

		public const string TAG_DEATH_ENEMY_BUNKER_SPIDER = "DeathEnemyBunkerSpider";

		public const string TAG_DEATH_ENEMY_CIRCUIT_BEES = "DeathEnemyCircuitBees";

		public const string TAG_DEATH_ENEMY_COILHEAD = "DeathEnemyCoilHead";

		public const string TAG_DEATH_ENEMY_EARTH_LEVIATHAN = "DeathEnemyEarthLeviathan";

		public const string TAG_DEATH_ENEMY_EYELESS_DOG = "DeathEnemyEyelessDog";

		public const string TAG_DEATH_ENEMY_GHOST_GIRL = "DeathEnemyGhostGirl";

		public const string TAG_DEATH_ENEMY_HOARDER_BUG = "DeathEnemyHoarderBug";

		public const string TAG_DEATH_ENEMY_HYGRODERE = "DeathEnemyHygrodere";

		public const string TAG_DEATH_ENEMY_JESTER = "DeathEnemyJester";

		public const string TAG_DEATH_ENEMY_LASSO_MAN = "DeathEnemyLassoMan";

		public const string TAG_DEATH_ENEMY_SNARE_FLEA = "DeathEnemySnareFlea";

		public const string TAG_DEATH_ENEMY_SPORE_LIZARD = "DeathEnemySporeLizard";

		public const string TAG_DEATH_ENEMY_THUMPER = "DeathEnemyThumper";

		public const string TAG_DEATH_ENEMY_FOREST_GIANT_EATEN = "DeathEnemyForestGiantEaten";

		public const string TAG_DEATH_ENEMY_FOREST_GIANT_DEATH = "DeathEnemyForestGiantDeath";

		public const string TAG_DEATH_ENEMY_MASKED_PLAYER_WEAR = "DeathEnemyMaskedPlayerWear";

		public const string TAG_DEATH_ENEMY_MASKED_PLAYER_VICTIM = "DeathEnemyMaskedPlayerVictim";

		public const string TAG_DEATH_ENEMY_NUTCRACKER_KICKED = "DeathEnemyNutcrackerKicked";

		public const string TAG_DEATH_ENEMY_NUTCRACKER_SHOT = "DeathEnemyNutcrackerShot";

		public const string TAG_DEATH_ENEMY_BUTLER_STAB = "DeathEnemyButlerStab";

		public const string TAG_DEATH_ENEMY_BUTLER_EXPLODE = "DeathEnemyButlerExplode";

		public const string TAG_DEATH_ENEMY_MASK_HORNETS = "DeathEnemyMaskHornets";

		public const string TAG_DEATH_ENEMY_TULIP_SNAKE_DROP = "DeathEnemyTulipSnakeDrop";

		public const string TAG_DEATH_ENEMY_OLD_BIRD_ROCKET = "DeathEnemyOldBirdRocket";

		public const string TAG_DEATH_ENEMY_OLD_BIRD_STOMP = "DeathEnemyOldBirdStomp";

		public const string TAG_DEATH_ENEMY_OLD_BIRD_CHARGE = "DeathEnemyOldBirdCharge";

		public const string TAG_DEATH_ENEMY_OLD_BIRD_TORCH = "DeathEnemyOldBirdTorch";

		public const string TAG_DEATH_ENEMY_KIDNAPPER_FOX = "DeathEnemyKidnapperFox";

		public const string TAG_DEATH_ENEMY_BARBER = "DeathEnemyBarber";

		public const string TAG_DEATH_ENEMY_MANEATER = "DeathEnemyManeater";

		public const string TAG_DEATH_ENEMY_GIANT_SAPSUCKER = "DeathEnemyGiantSapsucker";

		public const string TAG_DEATH_ENEMY_CADAVER_GROWTH = "DeathEnemyCadaverGrowth";

		public const string TAG_DEATH_ENEMY_CADAVER_BLOOM = "DeathEnemyCadaverBloom";

		public const string TAG_DEATH_ENEMY_FEIOPAR = "DeathEnemyFeiopar";

		public const string TAG_DEATH_PLAYER_JETPACK_GRAVITY = "DeathPlayerJetpackGravity";

		public const string TAG_DEATH_PLAYER_JETPACK_BLAST = "DeathPlayerJetpackBlast";

		public const string TAG_DEATH_PLAYER_LADDER = "DeathPlayerLadder";

		public const string TAG_DEATH_PLAYER_MURDER_SHOVEL = "DeathPlayerMurderShovel";

		public const string TAG_DEATH_PLAYER_MURDER_STOP_SIGN = "DeathPlayerMurderStopSign";

		public const string TAG_DEATH_PLAYER_MURDER_YIELD_SIGN = "DeathPlayerMurderYieldSign";

		public const string TAG_DEATH_PLAYER_MURDER_KNIFE = "DeathPlayerMurderKnife";

		public const string TAG_DEATH_PLAYER_EASTER_EGG = "DeathPlayerEasterEgg";

		public const string TAG_DEATH_PLAYER_MURDER_SHOTGUN = "DeathPlayerMurderShotgun";

		public const string TAG_DEATH_PLAYER_QUICKSAND = "DeathPlayerQuicksand";

		public const string TAG_DEATH_PLAYER_STUN_GRENADE = "DeathPlayerStunGrenade";

		public const string TAG_DEATH_PLAYER_ELECTRIC_CHAIR = "DeathPlayerElectricChair";

		public const string TAG_DEATH_PLAYER_VOMITING = "DeathPlayerVomiting";

		public const string TAG_DEATH_PLAYER_CRUISER_DRIVER = "DeathPlayerCruiserDriver";

		public const string TAG_DEATH_PLAYER_CRUISER_PASSENGER = "DeathPlayerCruiserPassenger";

		public const string TAG_DEATH_PLAYER_CRUISER_EXPLODE_BYSTANDER = "DeathPlayerCruiserExplodeBystander";

		public const string TAG_DEATH_PLAYER_CRUISER_RAN_OVER = "DeathPlayerCruiserRanOver";

		public const string TAG_DEATH_PIT_GENERIC = "DeathPitGeneric";

		public const string TAG_DEATH_PIT_FACILITY_PIT = "DeathPitFacilityPit";

		public const string TAG_DEATH_PIT_FACILITY_CATWALK_JUMP = "DeathPitFacilityCatwalkJump";

		public const string TAG_DEATH_PIT_MINE_PIT = "DeathPitMinePit";

		public const string TAG_DEATH_PIT_MINE_CAVE = "DeathPitMineCave";

		public const string TAG_DEATH_PIT_MINE_ELEVATOR = "DeathPitMineElevator";

		public const string TAG_DEATH_OTHER_DEPOSIT_ITEMS_DESK = "DeathOtherDepositItemsDesk";

		public const string TAG_DEATH_OTHER_ITEM_DROPSHIP = "DeathOtherItemDropship";

		public const string TAG_DEATH_OTHER_LANDMINE = "DeathOtherLandmine";

		public const string TAG_DEATH_OTHER_TURRET = "DeathOtherTurret";

		public const string TAG_DEATH_OTHER_LIGHTNING = "DeathOtherLightning";

		public const string TAG_DEATH_OTHER_METEOR = "DeathOtherMeteor";

		public const string TAG_DEATH_OTHER_SPIKE_TRAP = "DeathOtherSpikeTrap";

		public const string TAG_DEATH_OTHER_OUT_OF_BOUNDS = "DeathOtherOutOfBounds";

		public const string TAG_DEATH_UNKNOWN = "DeathUnknown";

		public string languageCode;

		private Dictionary<string, List<string>> languageData;

		private bool fallback;

		public LanguageHandler(string languageCode, bool fallback = false)
		{
			Plugin.Instance.PluginLogger.LogInfo("Coroner loading " + (fallback ? "fallback " : "") + "language support: " + languageCode);
			this.languageCode = languageCode;
			this.fallback = fallback;
			languageData = new Dictionary<string, List<string>>();
			LoadLanguageData(languageCode);
		}

		private void LoadLanguageData(string languageCode)
		{
			if (!Directory.Exists(Plugin.Instance.GetConfigPath()))
			{
				Plugin.Instance.PluginLogger.LogError("Config folder not found at: " + Plugin.Instance.GetConfigPath());
				string path = Plugin.AssemblyDirectory + "/BepInEx/config/EliteMasterEric-Coroner/Strings_" + languageCode + ".xml";
				if (File.Exists(path))
				{
					Plugin.Instance.PluginLogger.LogError("IMPORTANT: You didn't install the mod correctly! Move the BepInEx/config folder to the right spot!");
				}
				else
				{
					Plugin.Instance.PluginLogger.LogError("Try reinstalling the mod from scratch.");
				}
				return;
			}
			if (!File.Exists(Plugin.Instance.GetConfigPath() + "/Strings_" + languageCode + ".xml"))
			{
				Plugin.Instance.PluginLogger.LogError("Localization File not found at: " + Plugin.Instance.GetConfigPath());
				return;
			}
			Plugin.Instance.PluginLogger.LogInfo("Loading language data from config folder: " + Plugin.Instance.GetConfigPath());
			XDocument xDocument = XDocument.Load(Plugin.Instance.GetConfigPath() + "/Strings_" + languageCode + ".xml");
			if (xDocument == null)
			{
				Plugin.Instance.PluginLogger.LogError("Localization could not be parsed at: " + Plugin.Instance.GetConfigPath() + "/Strings_" + languageCode + ".xml");
				return;
			}
			PopulateLanguageData(xDocument);
			string[] array = Directory.GetFiles(Plugin.Instance.GetConfigPath(), "Strings_" + languageCode + "_*.xml").ToArray();
			Plugin.Instance.PluginLogger.LogInfo($"Loading {array.Length} additional language data files from config folder");
			for (int i = 0; i < array.Length; i++)
			{
				Plugin.Instance.PluginLogger.LogInfo("Loading additional language data file: " + array[i]);
				XDocument languageDoc = XDocument.Load(array[i]);
				PopulateLanguageData(languageDoc, append: true);
			}
			Plugin.Instance.PluginLogger.LogInfo($"Success, loaded {languageData.Count()} types of language tags with {CountLanguageEntries()} total entries.");
		}

		public void PopulateLanguageData(XDocument languageDoc, bool append = false)
		{
			if (!append)
			{
				languageData.Clear();
			}
			XElement xElement = languageDoc.Descendants("strings").First();
			foreach (XElement item in xElement.Descendants())
			{
				string text = item.Name.ToString();
				string value = item.Attribute("text").Value;
				if (!languageData.ContainsKey(text))
				{
					languageData[text] = new List<string>();
				}
				List<string> list = languageData[text];
				if (list != null)
				{
					list.Add(value);
					languageData[text] = list;
				}
				else
				{
					Plugin.Instance.PluginLogger.LogError("Current values for key '" + text + "' is null!");
				}
			}
		}

		public int CountLanguageEntries()
		{
			return languageData.Sum<KeyValuePair<string, List<string>>>((KeyValuePair<string, List<string>> x) => x.Value.Count);
		}

		public string GetFirstValueByTag(string tag)
		{
			return GetValuesByTag(tag)[0];
		}

		public string[] GetValuesByTag(string tag)
		{
			if (languageData.Count == 0 && languageCode != "en-us")
			{
				Plugin.Instance.PluginLogger.LogWarning("No language data loaded for '" + languageCode + "', displaying fallback language en-us...");
				return Plugin.Instance.FallbackLanguageHandler.GetValuesByTag(tag);
			}
			if (languageData.Count == 0)
			{
				Plugin.Instance.PluginLogger.LogWarning("No language data loaded for default language, displaying error text...");
				return new string[1] { "{'" + tag + "'}" };
			}
			if (!languageData.ContainsKey(tag) && languageCode != "en-us")
			{
				Plugin.Instance.PluginLogger.LogWarning("No values found for tag '" + tag + "' in language '" + languageCode + "', displaying fallback language en-us...");
				return Plugin.Instance.FallbackLanguageHandler.GetValuesByTag(tag);
			}
			if (!languageData.ContainsKey(tag))
			{
				Plugin.Instance.PluginLogger.LogWarning("No values found for tag '" + tag + "' in language '" + languageCode + "', displaying error text...");
				return new string[1] { "{'" + tag + "'}" };
			}
			List<string> list = languageData[tag];
			if ((list == null || list.Count == 0) && languageCode != "en-us")
			{
				Plugin.Instance.PluginLogger.LogWarning("No values found for tag '" + tag + "' in language '" + languageCode + "', displaying fallback language en-us...");
				return Plugin.Instance.FallbackLanguageHandler.GetValuesByTag(tag);
			}
			if (list == null || list.Count == 0)
			{
				Plugin.Instance.PluginLogger.LogWarning("No values found for tag '" + tag + "' in language '" + languageCode + "', displaying error text...");
				return new string[1] { "{'" + tag + "'}" };
			}
			return list.ToArray();
		}
	}
	[StaticNetcode]
	internal class NetworkRPC
	{
		[ServerRpc(RequireOwnership = false)]
		public static void ReportCauseOfDeathServerRpc(int playerClientId, string? codLanguageTag, bool forceOverride)
		{
			Plugin.Instance.PluginLogger.LogDebug(string.Format("Server received cause of death via RPC: ({0}, {1})", playerClientId, (codLanguageTag == null) ? "null" : codLanguageTag));
			BroadcastCauseOfDeathClientRpc(playerClientId, codLanguageTag, forceOverride);
		}

		[ClientRpc(/*Could not decode attribute arguments.*/)]
		public static void BroadcastCauseOfDeathClientRpc(int playerClientId, string? codLanguageTag, bool forceOverride)
		{
			Plugin.Instance.PluginLogger.LogDebug(string.Format("Client received cause of death via RPC: ({0}, {1})", playerClientId, (codLanguageTag == null) ? "null" : codLanguageTag));
			if (codLanguageTag == null || !AdvancedCauseOfDeath.IsTagRegistered(codLanguageTag))
			{
				Plugin.Instance.PluginLogger.LogError("Could not deserialize cause of death (" + codLanguageTag + ")");
				return;
			}
			AdvancedCauseOfDeath? advancedCauseOfDeath = AdvancedCauseOfDeath.Fetch(codLanguageTag);
			Plugin.Instance.PluginLogger.LogDebug($"Deserialized cause of death to {advancedCauseOfDeath}");
			AdvancedDeathTracker.StoreLocalCauseOfDeath(playerClientId, advancedCauseOfDeath, forceOverride);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_ID = "Coroner";

		public const string PLUGIN_NAME = "Coroner";

		public const string PLUGIN_AUTHOR = "EliteMasterEric";

		public const string PLUGIN_VERSION = "2.3.0";

		public const string PLUGIN_GUID = "com.elitemastereric.coroner";
	}
	[BepInPlugin("com.elitemastereric.coroner", "Coroner", "2.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static readonly Random RANDOM = new Random();

		public PluginLogger PluginLogger;

		internal PluginConfig PluginConfig;

		internal LanguageHandler LanguageHandler;

		internal LanguageHandler FallbackLanguageHandler;

		public static Plugin Instance { get; private set; }

		public static string AssemblyDirectory
		{
			get
			{
				string codeBase = Assembly.GetExecutingAssembly().CodeBase;
				UriBuilder uriBuilder = new UriBuilder(codeBase);
				string path = Uri.UnescapeDataString(uriBuilder.Path);
				return Path.GetDirectoryName(path);
			}
		}

		private void Awake()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			Instance = this;
			PluginLogger = new PluginLogger(((BaseUnityPlugin)this).Logger);
			Harmony val = new Harmony("com.elitemastereric.coroner");
			val.PatchAll();
			PluginLogger.LogInfo("Plugin Coroner (com.elitemastereric.coroner) is loaded!");
			LoadConfig();
			LoadLanguageHandlers();
		}

		public string GetConfigPath()
		{
			return Paths.ConfigPath + "/EliteMasterEric-Coroner";
		}

		public void LoadLanguageHandlers()
		{
			LanguageHandler = new LanguageHandler(PluginConfig.GetSelectedLanguage());
			FallbackLanguageHandler = new LanguageHandler("en-us", fallback: true);
		}

		private void LoadConfig()
		{
			PluginConfig = new PluginConfig();
			PluginConfig.BindConfig(((BaseUnityPlugin)this).Config);
		}
	}
	public class PluginLogger
	{
		private ManualLogSource manualLogSource;

		public PluginLogger(ManualLogSource manualLogSource)
		{
			this.manualLogSource = manualLogSource;
		}

		public void LogFatal(object data)
		{
			manualLogSource.LogFatal(data);
		}

		public void LogError(object data)
		{
			manualLogSource.LogError(data);
		}

		public void LogWarning(object data)
		{
			manualLogSource.LogWarning(data);
		}

		public void LogMessage(object data)
		{
			manualLogSource.LogMessage(data);
		}

		public void LogInfo(object data)
		{
			manualLogSource.LogInfo(data);
		}

		public void LogDebug(object data)
		{
			manualLogSource.LogDebug(data);
		}
	}
	internal class PluginConfig
	{
		private ConfigEntry<bool>? DisplayCauseOfDeath = null;

		private ConfigEntry<bool>? SeriousDeathMessages = null;

		private ConfigEntry<bool>? DisplayFunnyNotes = null;

		private ConfigEntry<bool>? DeathReplacesNotes = null;

		private ConfigEntry<string>? LanguagePicker = null;

		public void BindConfig(ConfigFile _config)
		{
			DisplayCauseOfDeath = _config.Bind<bool>("General", "DisplayCauseOfDeath", true, "Display the cause of death in the player notes.");
			SeriousDeathMessages = _config.Bind<bool>("General", "SeriousDeathMessages", false, "Cause of death messages are more to-the-point.");
			DisplayFunnyNotes = _config.Bind<bool>("General", "DisplayFunnyNotes", true, "Display a random note when the player has no notes.");
			DeathReplacesNotes = _config.Bind<bool>("General", "DeathReplacesNotes", true, "True to replace notes when the player dies, false to append.");
			LanguagePicker = _config.Bind<string>("Language", "LanguagePicker", "en-us", "Select a language to use.");
		}

		public bool ShouldDisplayCauseOfDeath()
		{
			if (DisplayCauseOfDeath == null)
			{
				Plugin.Instance.PluginLogger.LogWarning("Invalid access to uninstantiated config value DisplayCauseOfDeath");
				return true;
			}
			return DisplayCauseOfDeath.Value;
		}

		public bool ShouldUseSeriousDeathMessages()
		{
			if (SeriousDeathMessages == null)
			{
				Plugin.Instance.PluginLogger.LogWarning("Invalid access to uninstantiated config value SeriousDeathMessages");
				return false;
			}
			return SeriousDeathMessages.Value;
		}

		public bool ShouldDisplayFunnyNotes()
		{
			if (DisplayFunnyNotes == null)
			{
				Plugin.Instance.PluginLogger.LogWarning("Invalid access to uninstantiated config value DisplayFunnyNotes");
				return true;
			}
			return DisplayFunnyNotes.Value;
		}

		public bool ShouldDeathReplaceNotes()
		{
			if (DeathReplacesNotes == null)
			{
				Plugin.Instance.PluginLogger.LogWarning("Invalid access to uninstantiated config value DeathReplacesNotes");
				return true;
			}
			return DeathReplacesNotes.Value;
		}

		public string GetSelectedLanguage()
		{
			if (LanguagePicker == null)
			{
				Plugin.Instance.PluginLogger.LogWarning("Invalid access to uninstantiated config value LanguagePicker");
				return "en-us";
			}
			return LanguagePicker.Value.Replace('_', '-');
		}
	}
}
namespace Coroner.Patch
{
	internal class CauseOfDeathPatch
	{
		public const string KILL_PLAYER_SIGNATURE = "Void KillPlayer(UnityEngine.Vector3, Boolean, CauseOfDeath, Int32, UnityEngine.Vector3, Boolean)";

		public const string DAMAGE_PLAYER_SIGNATURE = "Void DamagePlayer(Int32, Boolean, Boolean, CauseOfDeath, Int32, Boolean, UnityEngine.Vector3)";

		public static void LogException(Exception e, string location)
		{
			Plugin.Instance.PluginLogger.LogError("Caught exception in " + location + ": " + e.Message);
			Plugin.Instance.PluginLogger.LogError(e.StackTrace);
		}

		public static bool IsPlayer(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return false;
			}
			return (Object)(object)((Component)collider).gameObject.GetComponent<PlayerControllerB>() != (Object)null;
		}

		public static int LocateKillPlayerCall(List<CodeInstruction> instructions)
		{
			for (int i = 0; i < instructions.Count; i++)
			{
				CodeInstruction val = instructions[i];
				if (val.opcode == OpCodes.Callvirt && val.operand.ToString() == "Void KillPlayer(UnityEngine.Vector3, Boolean, CauseOfDeath, Int32, UnityEngine.Vector3, Boolean)")
				{
					return i;
				}
			}
			return -1;
		}

		public static int LocateDamagePlayerCall(List<CodeInstruction> instructions)
		{
			for (int i = 0; i < instructions.Count; i++)
			{
				CodeInstruction val = instructions[i];
				if (val.opcode == OpCodes.Callvirt && val.operand.ToString() == "Void DamagePlayer(Int32, Boolean, Boolean, CauseOfDeath, Int32, Boolean, UnityEngine.Vector3)")
				{
					return i;
				}
			}
			return -1;
		}

		public static void OverrideKillLocalPlayer(KillLocalPlayer target, AdvancedCauseOfDeath causeOfDeath)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				target.causeOfDeath = causeOfDeath;
			}
		}

		public static void OverrideKillLocalPlayer(GameObject target, AdvancedCauseOfDeath causeOfDeath)
		{
			if (!((Object)(object)target == (Object)null))
			{
				OverrideKillLocalPlayer(target.GetComponent<KillLocalPlayer>(), causeOfDeath);
			}
		}

		public static void OverrideKillLocalPlayer(Transform target, AdvancedCauseOfDeath causeOfDeath)
		{
			if (!((Object)(object)target == (Object)null))
			{
				OverrideKillLocalPlayer(((Component)target).gameObject, causeOfDeath);
			}
		}
	}
	internal class CauseOfDeathPatchState
	{
		private int targetPlayerIndex;

		private bool wasPlayerQueried;

		public bool previousIsPlayerDead;

		public CauseOfDeath? previousCauseOfDeath = null;

		public bool wasHoldingJetpack;

		public CauseOfDeathPatchState()
		{
			targetPlayerIndex = -1;
			wasPlayerQueried = false;
		}

		public void TrySetPlayer(int targetPlayerIndex)
		{
			if (targetPlayerIndex < 0)
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Invalid player index! " + targetPlayerIndex);
			}
			else
			{
				this.targetPlayerIndex = targetPlayerIndex;
			}
		}

		public void TrySetPlayer(PlayerControllerB playerControllerB)
		{
			if ((Object)(object)playerControllerB == (Object)null)
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: PlayerController was null");
			}
			else
			{
				TrySetPlayer((int)playerControllerB.playerClientId);
			}
		}

		public void TrySetPlayer(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Collider was null!");
				return;
			}
			if (!CauseOfDeathPatch.IsPlayer(collider))
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Collider was not a player!");
				return;
			}
			PlayerControllerB component = ((Component)collider).gameObject.GetComponent<PlayerControllerB>();
			TrySetPlayer(component);
		}

		public void QueryPlayerState()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (wasPlayerQueried)
			{
				Plugin.Instance.PluginLogger.LogWarning("Tried to query player state, but we already did that? " + ToString());
				return;
			}
			PlayerControllerB val = FetchPlayer();
			if (!((Object)(object)val == (Object)null))
			{
				Plugin.Instance.PluginLogger.LogDebug("Querying target player parameters pre-death...");
				wasPlayerQueried = true;
				previousIsPlayerDead = val.isPlayerDead;
				previousCauseOfDeath = val.causeOfDeath;
				wasHoldingJetpack = AdvancedDeathTracker.IsHoldingJetpack(val);
				Plugin.Instance.PluginLogger.LogDebug("Query successful!" + wasPlayerQueried);
			}
		}

		public int FetchPlayerIndex()
		{
			if (targetPlayerIndex == -1)
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Index not assigned!");
				return -1;
			}
			return targetPlayerIndex;
		}

		public PlayerControllerB? FetchPlayer()
		{
			if (targetPlayerIndex == -1)
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Index not assigned!");
				return null;
			}
			if (targetPlayerIndex >= StartOfRound.Instance.allPlayerScripts.Length)
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Index out of bounds! " + targetPlayerIndex);
				return null;
			}
			return StartOfRound.Instance.allPlayerScripts[targetPlayerIndex];
		}

		public PlayerControllerB GetPlayer()
		{
			PlayerControllerB val = FetchPlayer();
			if ((Object)(object)val == (Object)null)
			{
				throw new Exception("Could not retrieve player from state!");
			}
			return val;
		}

		public bool ValidateWasntAlreadyDead()
		{
			if (!wasPlayerQueried)
			{
				return false;
			}
			PlayerControllerB val = FetchPlayer();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (previousIsPlayerDead)
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Player was already dead!");
				return false;
			}
			return true;
		}

		public bool ValidateIsPlayerDead(bool verbose = true)
		{
			if (!wasPlayerQueried)
			{
				return false;
			}
			PlayerControllerB val = FetchPlayer();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (!val.isPlayerDead)
			{
				if (verbose)
				{
					Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Player is still alive!");
				}
				return false;
			}
			return true;
		}

		public bool ValidateHasNoCauseOfDeath()
		{
			if (!wasPlayerQueried)
			{
				return false;
			}
			if (AdvancedDeathTracker.HasCauseOfDeath(FetchPlayerIndex()))
			{
				Plugin.Instance.PluginLogger.LogWarning("Could not access dying player: Player already had a precise cause of death!");
				return false;
			}
			return true;
		}

		public override string ToString()
		{
			return $"CauseOfDeathPatchState({targetPlayerIndex}:{wasPlayerQueried}, {previousIsPlayerDead}==false?)";
		}
	}
	internal class CauseOfDeathEnumerator : EnumeratorPatch
	{
		public Action<CauseOfDeathPatchState>? preDeathAction;

		public Action<CauseOfDeathPatchState>? postDeathAction;

		public Action<CauseOfDeathPatchState>? postDeathStepAction;

		public CauseOfDeathEnumerator(IEnumerator targetEnumerator)
			: base(targetEnumerator)
		{
			CauseOfDeathPatchState state = new CauseOfDeathPatchState();
			prefixAction = delegate
			{
				preDeathAction?.Invoke(state);
				Plugin.Instance.PluginLogger.LogDebug("Post step action done: " + state.ToString());
			};
			postfixAction = delegate
			{
				postDeathAction?.Invoke(state);
				Plugin.Instance.PluginLogger.LogDebug("Post step action done: " + state.ToString());
			};
			postStepAction = delegate
			{
				postDeathStepAction?.Invoke(state);
				Plugin.Instance.PluginLogger.LogDebug("Post step action done: " + state.ToString());
			};
		}
	}
	[HarmonyPatch(typeof(BaboonBirdAI), "OnCollideWithPlayer")]
	internal class BaboonBirdAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "BaboonBirdAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Baboon Hawk damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Baboon Hawk killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_BaboonHawk);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "BaboonBirdAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(ButlerBeesEnemyAI), "OnCollideWithPlayer")]
	internal class ButlerBeesEnemyAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ButlerBeesEnemyAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Mask Hornet damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Mask Hornet killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_MaskHornets);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ButlerBeesEnemyAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(ButlerEnemyAI), "OnCollideWithPlayer")]
	internal class ButlerEnemyAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ButlerEnemyAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Butler damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Butler killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Butler_Stab);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ButlerEnemyAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(CadaverBloomAI), "OnCollideWithPlayer")]
	internal class CadaverBloomAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CadaverBloomAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Cadaver Bloom damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Cadaver Bloom killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Cadaver_Bloom);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CadaverBloomAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(GiantKiwiAI), "AnimationEventB")]
	internal class GiantKiwiAIAnimationEventBPatch
	{
		public static void Prefix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(GameNetworkManager.Instance.localPlayerController);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "GiantKiwiAI.AnimationEventB:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Giant Sapsucker damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Giant Sapsucker killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Giant_Sapsucker);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "GiantKiwiAI.AnimationEventB:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(LassoManAI), "OnCollideWithPlayer")]
	internal class LassoManAIOnCollideWithPlayer
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "LassoManAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Lasso Man damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Lasso Man killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_LassoMan);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "LassoManAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(MoveToExitSpecialAnimation), "shockChair")]
	internal class MoveToExitSpecialAnimationShockChairPatch
	{
		public static void Prefix(MoveToExitSpecialAnimation __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(((Component)__instance.interactTrigger.lockedPlayer).GetComponent<PlayerControllerB>());
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "MoveToExitSpecialAnimation.shockChair:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Lasso Man damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Electric Chair killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Player_Electric_Chair);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "MoveToExitSpecialAnimation.shockChair:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(PufferAI), "OnCollideWithPlayer")]
	internal class PufferAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PufferAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Spore Lizard damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Spore Lizard killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_SporeLizard);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PufferAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(PumaAI), "OnCollideWithPlayer")]
	internal class PumaAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PumaAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Feiopar damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Feiopar killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Feiopar);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PumaAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(RadMechAI), "Stomp")]
	internal class RadMechAIStompPatch
	{
		public static void Prefix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(GameNetworkManager.Instance.localPlayerController);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "RadMechAI.Stomp:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Old Bird (Stomp) damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Old Bird killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Old_Bird_Stomp);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "RadMechAI.Stomp:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(RadMechAI), "TorchPlayerAnimation")]
	internal class RadMechAITorchPlayerAnimationPatch
	{
		public static void Postfix(RadMechAI __instance, ref IEnumerator __result)
		{
			RadMechAI __instance2 = __instance;
			try
			{
				CauseOfDeathEnumerator causeOfDeathEnumerator = new CauseOfDeathEnumerator(__result)
				{
					preDeathAction = delegate(CauseOfDeathPatchState __state)
					{
						EnumeratorPrefix(__instance2, __state);
					},
					postDeathStepAction = delegate(CauseOfDeathPatchState __state)
					{
						EnumeratorStepPostfix(__instance2, __state);
					},
					postDeathAction = delegate(CauseOfDeathPatchState __state)
					{
						EnumeratorStepPostfix(__instance2, __state);
					}
				};
				__result = causeOfDeathEnumerator.GetEnumerator();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "RadMechAI.TorchPlayerAnimation:Postfix");
			}
		}

		private static void EnumeratorPrefix(RadMechAI __instance, CauseOfDeathPatchState __state)
		{
			try
			{
				__state.TrySetPlayer(((EnemyAI)__instance).inSpecialAnimationWithPlayer);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "RadMechAI.TorchPlayerAnimation:EnumeratorPrefix");
			}
		}

		private static void EnumeratorStepPostfix(RadMechAI __instance, CauseOfDeathPatchState __state)
		{
			try
			{
				PlayerControllerB player = __state.GetPlayer();
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Old Bird killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Old_Bird_Torch);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "RadMechAI.TorchPlayerAnimation:EnumeratorStepPostfix");
			}
		}
	}
	[HarmonyPatch(typeof(SandSpiderAI), "OnCollideWithPlayer")]
	internal class SandSpiderAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "SandSpiderAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Bunker Spider damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Bunker Spider killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_BunkerSpider);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "SandSpiderAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(BlobAI), "OnCollideWithPlayer")]
	internal class BlobAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "BlobAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Bunker Spider damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Bunker Spider killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Hygrodere);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "BlobAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(CentipedeAI), "DamagePlayerOnIntervals")]
	internal class CentipedeAIDamagePlayerOnIntervalsPatch
	{
		public static void Prefix(CentipedeAI __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(__instance.clingingToPlayer);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CentipedeAI.DamagePlayerOnIntervals:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Centipede damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Centipede killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_SnareFlea);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CentipedeAI.DamagePlayerOnIntervals:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(CrawlerAI), "OnCollideWithPlayer")]
	internal class CrawlerAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CrawlerAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Thumper damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Thumper killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Thumper);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CrawlerAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(RedLocustBees), "BeeKillPlayerOnLocalClient")]
	internal class RedLocustBeesBeeKillPlayerOnLocalClientPatch
	{
		public static void Prefix(int playerId, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(playerId);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "RedLocustBees.BeeKillPlayerOnLocalClient:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Circuit Bees damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Circuit Bees killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_CircuitBees);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "RedLocustBees.BeeKillPlayerOnLocalClient:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(HoarderBugAI), "OnCollideWithPlayer")]
	internal class HoarderBugAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "HoarderBugAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Hoarder Bug damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Hoarder Bug killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_HoarderBug);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "HoarderBugAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(SpringManAI), "OnCollideWithPlayer")]
	internal class SpringManAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "SpringManAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Coil-Head damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Coil-Head killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_CoilHead);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "SpringManAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(ShotgunItem), "ShootGun")]
	internal class ShotgunItemShootGunPatch
	{
		public static void Prefix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(GameNetworkManager.Instance.localPlayerController);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ShotgunItem.ShootGun:Prefix");
			}
		}

		public static void Postfix(ShotgunItem __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Shotgun damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Shotgun killed Player! Checking wielder...");
					if (((GrabbableObject)__instance).isHeldByEnemy)
					{
						Plugin.Instance.PluginLogger.LogDebug("Shotgun (Nutcracker) killed player! Setting special cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Nutcracker_Shot);
					}
					else
					{
						Plugin.Instance.PluginLogger.LogDebug("Shotgun (Player) killed player! Setting special cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Player_Murder_Shotgun);
					}
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ShotgunItem.ShootGun:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(SprayPaintItem), "HealPlayerInfection")]
	internal class SprayPaintItemHealPlayerInfectionPatch
	{
		public static void Prefix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(GameNetworkManager.Instance.localPlayerController);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "SprayPaintItem.HealPlayerInfection:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling vomiting damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Vomiting killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Player_Vomiting);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "SprayPaintItem.HealPlayerInfection:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(StunGrenadeItem), "StunExplosion")]
	internal class StunGrenadeItemStunExplosionPatch
	{
		public static void Prefix(StunGrenadeItem __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(((GrabbableObject)__instance).playerHeldBy);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "StunGrenadeItem.StunExplosion:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Stun Grenade damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Stun Grenade killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Player_StunGrenade);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "StunGrenadeItem.StunExplosion:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(VehicleCollisionTrigger), "OnTriggerEnter")]
	internal class VehicleCollisionTriggerOnTriggerEnterPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				if (!((Component)other).gameObject.CompareTag("Player"))
				{
					Plugin.Instance.PluginLogger.LogDebug("Vehicle collision with non-player...");
					return;
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "VehicleCollisionTrigger.OnTriggerEnter:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Vehicle damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Vehicle (Collision) killed Player (Pedestrian)! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Player_Cruiser_Ran_Over);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "VehicleCollisionTrigger.OnTriggerEnter:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(VehicleController), "DamagePlayerInVehicle")]
	internal class VehicleControllerDamagePlayerInVehiclePatch
	{
		public static void Prefix(VehicleController __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				if (__instance.localPlayerInControl || __instance.localPlayerInPassengerSeat)
				{
					__state.TrySetPlayer(GameNetworkManager.Instance.localPlayerController);
					__state.QueryPlayerState();
				}
				else
				{
					Plugin.Instance.PluginLogger.LogDebug("Couldn't determine player in vehicle...");
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "VehicleController.DamagePlayerInVehicle:Prefix");
			}
		}

		public static void Postfix(VehicleController __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Vehicle damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					if (__instance.localPlayerInControl)
					{
						Plugin.Instance.PluginLogger.LogDebug("Vehicle (Collision) killed Player (Driver)! Setting cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(GameNetworkManager.Instance.localPlayerController, AdvancedCauseOfDeath.Player_Cruiser_Driver);
					}
					else if (__instance.localPlayerInPassengerSeat)
					{
						Plugin.Instance.PluginLogger.LogDebug("Vehicle (Collision) killed Player (Passenger)! Setting cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(GameNetworkManager.Instance.localPlayerController, AdvancedCauseOfDeath.Player_Cruiser_Passenger);
					}
					else
					{
						Plugin.Instance.PluginLogger.LogDebug("Couldn't determine player in vehicle...");
					}
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "VehicleController.DamagePlayerInVehicle:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "PlayerHitGroundEffects")]
	internal class PlayerControllerBPlayerHitGroundEffectsPatch
	{
		public static void Prefix(PlayerControllerB __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(__instance);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PlayerControllerB.PlayerHitGroundEffects:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state.ValidateIsPlayerDead(verbose: false) && __state.ValidateWasntAlreadyDead() && __state.ValidateHasNoCauseOfDeath())
				{
					PlayerControllerB player = __state.GetPlayer();
					FootstepSurface val = StartOfRound.Instance.footstepSurfaces[player.currentFootstepSurfaceIndex];
					if (val != null)
					{
						Plugin.Instance.PluginLogger.LogDebug("Fall damage (surface tag: $" + val.surfaceTag + ") killed Player! Setting cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(player, AdvancedCauseOfDeath.Gravity);
					}
					else
					{
						Plugin.Instance.PluginLogger.LogDebug("Fall damage (unknown surface) killed Player! Setting cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(player, AdvancedCauseOfDeath.Gravity);
					}
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PlayerControllerB.PlayerHitGroundEffects:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerFromOtherClientClientRpc")]
	internal class PlayerControllerBDamagePlayerFromOtherClientClientRpcPatch
	{
		private const string DAMAGE_PLAYER_SIGNATURE = "Void DamagePlayer(Int32, Boolean, Boolean, CauseOfDeath, Int32, Boolean, UnityEngine.Vector3)";

		public static void Prefix(PlayerControllerB __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(__instance);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PlayerControllerB.DamagePlayerFromOtherClientClientRpc:Prefix");
			}
		}

		public static void Postfix(int playerWhoHit, ref CauseOfDeathPatchState __state)
		{
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling friendly fire damage...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					PlayerControllerB player = __state.GetPlayer();
					PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerWhoHit];
					if ((Object)(object)val == (Object)null)
					{
						Plugin.Instance.PluginLogger.LogError("Damage from other player: attacker is null!");
					}
					else if (AdvancedDeathTracker.IsHoldingShotgun(val))
					{
						Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Shotgun! Setting special cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(player, AdvancedCauseOfDeath.Player_Murder_Shotgun);
					}
					else if (AdvancedDeathTracker.IsHoldingKnife(val))
					{
						Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Knife! Setting special cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(player, AdvancedCauseOfDeath.Player_Murder_Knife);
					}
					else if (AdvancedDeathTracker.IsHoldingShovel(val))
					{
						Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Shovel! Setting special cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(player, AdvancedCauseOfDeath.Player_Murder_Shovel);
					}
					else if (AdvancedDeathTracker.IsHoldingStopSign(val))
					{
						Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Stop Sign! Setting special cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(player, AdvancedCauseOfDeath.Player_Murder_Stop_Sign);
					}
					else if (AdvancedDeathTracker.IsHoldingYieldSign(val))
					{
						Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Yield Sign! Setting special cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(player, AdvancedCauseOfDeath.Player_Murder_Yield_Sign);
					}
					else
					{
						Plugin.Instance.PluginLogger.LogWarning($"Player was murdered, by an unknown item {AdvancedDeathTracker.GetHeldObject(val)}! Setting cause of death to: " + ((object)(CauseOfDeath)(ref player.causeOfDeath)).ToString());
						AdvancedDeathTracker.SetCauseOfDeath(player, player.causeOfDeath);
					}
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "PlayerControllerBDamagePlayerFromOtherClientClientRpcPatch:Postfix");
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator, MethodBase method)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			List<CodeInstruction> list2 = BuildInstructionsToInsert(method);
			if (list2 == null)
			{
				Plugin.Instance.PluginLogger.LogError("Could not build instructions to insert in PlayerControllerBDamagePlayerFromOtherClientClientRpcPatch! Safely aborting...");
				return instructions;
			}
			int num = -1;
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (val.opcode == OpCodes.Call && val.operand.ToString() == "Void DamagePlayer(Int32, Boolean, Boolean, CauseOfDeath, Int32, Boolean, UnityEngine.Vector3)")
				{
					num = i;
				}
			}
			if (num == -1)
			{
				Plugin.Instance.PluginLogger.LogError("Could not find PlayerControllerB.DamagePlayer call in PlayerControllerBDamagePlayerFromOtherClientClientRpcPatch! Safely aborting...");
				return instructions;
			}
			Plugin.Instance.PluginLogger.LogDebug("Injecting patch into PlayerControllerB.DamagePlayerFromOtherClientClientRpc...");
			list.InsertRange(num + 1, list2);
			Plugin.Instance.PluginLogger.LogDebug("Done.");
			Plugin.Instance.PluginLogger.LogDebug("Done with all PlayerControllerBDamagePlayerFromOtherClientClientRpcPatch patches.");
			return list;
		}

		private static List<CodeInstruction>? BuildInstructionsToInsert(MethodBase method)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			int num = 0;
			int num2 = 1;
			int num3 = 2;
			int num4 = 3;
			int num5 = 4;
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num));
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num2));
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num3));
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num4));
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num5));
			list.Add(new CodeInstruction(OpCodes.Call, (object)typeof(PlayerControllerBDamagePlayerFromOtherClientClientRpcPatch).GetMethod("MaybeRewriteCauseOfDeath")));
			return list;
		}

		public static void MaybeRewriteCauseOfDeath(PlayerControllerB targetPlayer, int damageAmount, Vector3 hitDirection, int playerWhoHit, int newHealthAmount)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Instance.PluginLogger.LogDebug($"Player damaged another player ${targetPlayer}({damageAmount}, {hitDirection}, {playerWhoHit}, {newHealthAmount})");
			if (targetPlayer.isPlayerDead)
			{
				Plugin.Instance.PluginLogger.LogDebug("Player died from friendly fire damage");
				RewriteCauseOfDeath(targetPlayer, playerWhoHit);
			}
			else
			{
				Plugin.Instance.PluginLogger.LogDebug($"Player did not die from friendly fire (left at ${targetPlayer.health} health)");
			}
		}

		public static void RewriteCauseOfDeath(PlayerControllerB targetPlayer, int playerWhoHitIndex)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerWhoHitIndex];
			if ((Object)(object)targetPlayer == (Object)null)
			{
				Plugin.Instance.PluginLogger.LogError("Damage from other client: victim is null!");
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Instance.PluginLogger.LogError("Damage from other client: attacker is null!");
				return;
			}
			Plugin.Instance.PluginLogger.LogDebug($"Player died from murder ({targetPlayer.causeOfDeath}), determining special cause of death...");
			if (AdvancedDeathTracker.IsHoldingShotgun(val))
			{
				Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Shotgun! Setting special cause of death...");
				AdvancedDeathTracker.SetCauseOfDeath(targetPlayer, AdvancedCauseOfDeath.Player_Murder_Shotgun);
			}
			else if (AdvancedDeathTracker.IsHoldingKnife(val))
			{
				Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Knife! Setting special cause of death...");
				AdvancedDeathTracker.SetCauseOfDeath(targetPlayer, AdvancedCauseOfDeath.Player_Murder_Knife);
			}
			else if (AdvancedDeathTracker.IsHoldingShovel(val))
			{
				Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Shovel! Setting special cause of death...");
				AdvancedDeathTracker.SetCauseOfDeath(targetPlayer, AdvancedCauseOfDeath.Player_Murder_Shovel);
			}
			else if (AdvancedDeathTracker.IsHoldingStopSign(val))
			{
				Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Stop Sign! Setting special cause of death...");
				AdvancedDeathTracker.SetCauseOfDeath(targetPlayer, AdvancedCauseOfDeath.Player_Murder_Stop_Sign);
			}
			else if (AdvancedDeathTracker.IsHoldingYieldSign(val))
			{
				Plugin.Instance.PluginLogger.LogDebug("Player was murdered by Yield Sign! Setting special cause of death...");
				AdvancedDeathTracker.SetCauseOfDeath(targetPlayer, AdvancedCauseOfDeath.Player_Murder_Yield_Sign);
			}
			else
			{
				Plugin.Instance.PluginLogger.LogWarning($"Player was killed by someone else, holding an unknown item {AdvancedDeathTracker.GetHeldObject(val)}! " + ((object)(CauseOfDeath)(ref targetPlayer.causeOfDeath)).ToString());
				AdvancedDeathTracker.SetCauseOfDeath(targetPlayer, targetPlayer.causeOfDeath);
			}
		}
	}
	[HarmonyPatch(typeof(AnimatedObjectFloatSetter), "KillPlayerAtPoint")]
	internal class AnimatedObjectFloatSetterKillPlayerAtPointPatch
	{
		public static void Prefix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(GameNetworkManager.Instance.localPlayerController);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "AnimatedObjectFloatSetter.KillPlayerAtPoint:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling AnimatedObjectFloatSetter death...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogWarning("AnimatedObjectFloatSetter killed Player! Unknown cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Unknown);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "AnimatedObjectFloatSetter.KillPlayerAtPoint:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(BushWolfEnemy), "OnCollideWithPlayer")]
	internal class BushWolfOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "BushWolf.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Kidnapper Fox death...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogWarning("Kidnapper Fox killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_KidnapperFox);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "BushWolf.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(CadaverBloomAI), "BurstForth")]
	internal class CadaverBloomAIBurstForthPatch
	{
		public static void Prefix(PlayerControllerB player, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(player);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CadaverBloomAI.BurstForth:Prefix");
			}
		}

		public static void Postfix(bool kill, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (kill)
				{
					Plugin.Instance.PluginLogger.LogDebug("Handling Cadaver Growth death...");
					if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
					{
						Plugin.Instance.PluginLogger.LogWarning("Cadaver Growth killed Player! Setting cause of death...");
						AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Cadaver_Growth);
					}
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CadaverBloomAI.BurstForth:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(CaveDwellerAI), "KillPlayerAnimationClientRpc")]
	internal class CaveDwellerAIKillPlayerAnimationClientRpcPatch
	{
		public static void Prefix(int playerObjectId, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(playerObjectId);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CaveDwellerAI.KillPlayerAnimationClientRpc:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Maneater death...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogWarning("Maneater killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Maneater);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "CaveDwellerAI.KillPlayerAnimationClientRpc:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(ClaySurgeonAI), "OnCollideWithPlayer")]
	internal class ClaySurgeonAIOnCollideWithPlayerPatch
	{
		public static void Prefix(Collider other, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				__state.TrySetPlayer(other);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ClaySurgeonAI.OnCollideWithPlayer:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Barber death...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Barber killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_Barber);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "ClaySurgeonAI.OnCollideWithPlayer:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(DepositItemsDesk), "AnimationGrabPlayer")]
	internal class DepositItemsDeskAnimationGrabPlayerPatch
	{
		public static void Postfix(DepositItemsDesk __instance, int playerID, ref IEnumerator __result)
		{
			DepositItemsDesk __instance2 = __instance;
			try
			{
				CauseOfDeathEnumerator causeOfDeathEnumerator = new CauseOfDeathEnumerator(__result)
				{
					preDeathAction = delegate(CauseOfDeathPatchState __state)
					{
						EnumeratorPrefix(__instance2, playerID, __state);
					},
					postDeathStepAction = delegate(CauseOfDeathPatchState __state)
					{
						EnumeratorStepPostfix(__instance2, __state);
					},
					postDeathAction = delegate(CauseOfDeathPatchState __state)
					{
						EnumeratorStepPostfix(__instance2, __state);
					}
				};
				__result = causeOfDeathEnumerator.GetEnumerator();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "DepositItemsDesk.AnimationGrabPlayer:Postfix");
			}
		}

		private static void EnumeratorPrefix(DepositItemsDesk __instance, int playerID, CauseOfDeathPatchState __state)
		{
			try
			{
				__state.TrySetPlayer(playerID);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "DepositItemsDesk.AnimationGrabPlayer:EnumeratorPrefix");
			}
		}

		private static void EnumeratorStepPostfix(DepositItemsDesk __instance, CauseOfDeathPatchState __state)
		{
			try
			{
				PlayerControllerB player = __state.GetPlayer();
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Deposit Desk killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Other_DepositItemsDesk);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "DepositItemsDesk.AnimationGrabPlayer:EnumeratorStepPostfix");
			}
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "FinishAttaching")]
	internal class HauntedMaskItemFinishAttachingPatch
	{
		public static void Prefix(HauntedMaskItem __instance, ref CauseOfDeathPatchState __state)
		{
			try
			{
				if (__state == null)
				{
					__state = new CauseOfDeathPatchState();
				}
				PlayerControllerB value = Traverse.Create((object)__instance).Field("previousPlayerHeldBy").GetValue<PlayerControllerB>();
				__state.TrySetPlayer(value);
				__state.QueryPlayerState();
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "HauntedMaskItem.FinishAttaching:Prefix");
			}
		}

		public static void Postfix(ref CauseOfDeathPatchState __state)
		{
			try
			{
				Plugin.Instance.PluginLogger.LogDebug("Handling Haunted Mask death...");
				if (__state.ValidateWasntAlreadyDead() && __state.ValidateIsPlayerDead() && __state.ValidateHasNoCauseOfDeath())
				{
					Plugin.Instance.PluginLogger.LogDebug("Haunted Mask killed Player! Setting cause of death...");
					AdvancedDeathTracker.SetCauseOfDeath(__state.GetPlayer(), AdvancedCauseOfDeath.Enemy_MaskedPlayer_Wear);
				}
			}
			catch (Exception e)
			{
				CauseOfDeathPatch.LogException(e, "HauntedMaskItem.FinishAttaching:Postfix");
			}
		}
	}
	[HarmonyPatch(typeof(JesterAI), "killPlayerAnimation")]
	internal class JesterAIKillPlayerAnimationPatch
	{
		public static void Postfix(JesterAI __instance, int playerId, ref IEnumerator __result)
		{
			JesterAI __instance2 = __instance;
			try
			{
				CauseOfDeath