Decompiled source of Zombies v0.3.12

synaxin.zombies.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using Unity.Netcode;
using UnityEngine;
using Zombies.Scripts;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("synaxin.zombies")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.12.0")]
[assembly: AssemblyInformationalVersion("0.3.12")]
[assembly: AssemblyProduct("synaxin.zombies")]
[assembly: AssemblyTitle("synaxin.zombies")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.12.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace Zombies
{
	internal class ConfigHandler
	{
		public readonly ConfigEntry<int> tryForTicks;

		public readonly ConfigEntry<float> infectionChance;

		public readonly ConfigEntry<float> proximityChance;

		public readonly ConfigEntry<int> infectionTimeMin;

		public readonly ConfigEntry<int> infectionTimeMax;

		public readonly ConfigEntry<int> wakeTickAmount;

		public readonly ConfigEntry<int> proxWakeTickAmount;

		public readonly ConfigEntry<int> proxHeldWakeTickAmount;

		public readonly ConfigEntry<bool> zombiesDropBodies;

		public readonly ConfigEntry<bool> droppedBodiesInfection;

		public readonly ConfigEntry<bool> infectLivingPlayers;

		public readonly ConfigEntry<float> livingInfectionChance;

		public readonly ConfigEntry<float> livingInfectionModifier;

		public readonly ConfigEntry<bool> reviveOnDeath;

		public readonly ConfigEntry<float> reviveOnDeathChance;

		public readonly ConfigEntry<bool> onlyReviveWhileAlone;

		public ConfigHandler(ConfigFile cfg)
		{
			tryForTicks = cfg.Bind<int>("General", "InfectionTickAmount", 60, "Amount of ticks to try for infection\nA tick is ~= 2s");
			infectionChance = cfg.Bind<float>("General", "InfectionChance", 0.8f, "% Chance per tick of infecting a body");
			proximityChance = cfg.Bind<float>("General", "ProximityChance", 25f, "% Chance for zombie to be proximity trigger");
			infectionTimeMin = cfg.Bind<int>("General", "InfectionTimeMin", 30, "Minimum ticks before infection is complete\nA tick is ~= 2s");
			infectionTimeMax = cfg.Bind<int>("General", "InfectionTimeMax", 90, "Maximum ticks before infection is complete\nA tick is ~= 2s");
			wakeTickAmount = cfg.Bind<int>("General", "WakeTickAmount", 10, "Amount of ticks a waking zombie will seize\nbefore waking up.\nWake ticks are 0.2s");
			proxWakeTickAmount = cfg.Bind<int>("General", "ProxWakeTickAmount", 10, "Amount of ticks a proximity waking zombie will seize\nbefore waking up.\nWake ticks are 0.2s");
			proxHeldWakeTickAmount = cfg.Bind<int>("General", "ProxHeldWakeTickAmount", 13, "Amount of ticks a held proximity waking zombie will seize\nbefore waking up.\nWake ticks are 0.2s");
			zombiesDropBodies = cfg.Bind<bool>("General", "ZombiesDropBodies", true, "Makes converted/zombified players drop bodies");
			droppedBodiesInfection = cfg.Bind<bool>("General", "InfectDeadConverted", true, "Can dead converted players be infected again\nWill not work without Zombies Drop Bodies");
			infectLivingPlayers = cfg.Bind<bool>("General", "InfectLivingPlayers", true, "Can living players be infected on taking damage");
			reviveOnDeath = cfg.Bind<bool>("MirageLegacyFunction", "ReviveOnDeath", true, "Makes it possible for masked to spawn immediately after player dies");
			reviveOnDeathChance = cfg.Bind<float>("MirageLegacyFunction", "ReviveOnDeathChance", 5f, "Chance for masked to instantly spawn");
			onlyReviveWhileAlone = cfg.Bind<bool>("MirageLegacyFunction", "OnlyReviveWhileAlone", false, "Revive On Death only applies while player is alone");
			ClearOrphanedEntries(cfg);
			cfg.Save();
			cfg.SaveOnConfigSet = true;
		}

		private static void ClearOrphanedEntries(ConfigFile cfg)
		{
			PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries");
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg);
			dictionary.Clear();
		}
	}
	[BepInPlugin("synaxin.zombies", "synaxin.zombies", "0.3.12")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Zombies : BaseUnityPlugin
	{
		public static EnemyType maskEnemy;

		public static bool ModelReplacementAPIFound;

		public static Dictionary<MaskedPlayerEnemy, bool> ZombieList;

		internal static bool foundMasked;

		public static Zombies Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		internal static ConfigHandler BoundConfig { get; private set; }

		internal static PlayerControllerB Player { get; set; }

		internal static ZombieNetworkManager Networking { get; set; }

		internal static InfectionHandler Infection { get; set; }

		public static BodySpawnHandler BodySpawn { get; set; }

		internal static ModelReplacementCompat ModelReplaceScript { get; set; }

		private void Awake()
		{
			ZombieList = new Dictionary<MaskedPlayerEnemy, bool>();
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			BoundConfig = new ConfigHandler(((BaseUnityPlugin)this).Config);
			Networking = new ZombieNetworkManager();
			BodySpawn = new BodySpawnHandler();
			Patch();
			if (Chainloader.PluginInfos.ContainsKey("meow.ModelReplacementAPI"))
			{
				ModelReplacementAPIFound = true;
				ModelReplaceScript = new ModelReplacementCompat();
				Logger.LogMessage((object)"Model Replacement API found");
			}
			Logger.LogInfo((object)"Zombies v0.3.12 has loaded!");
		}

		public static void AddZombie(MaskedPlayerEnemy mask, bool proximity)
		{
			if (!ZombieList.ContainsKey(mask))
			{
				ZombieList.Add(mask, proximity);
			}
		}

		public static void RemoveZombie(MaskedPlayerEnemy mask)
		{
			if (ZombieList.ContainsKey(mask))
			{
				ZombieList.Remove(mask);
			}
		}

		public static void ClearZombies()
		{
			ZombieList.Clear();
		}

		public static (bool, bool) GetZombie(MaskedPlayerEnemy mask)
		{
			if (ZombieList.ContainsKey(mask))
			{
				return (true, ZombieList[mask]);
			}
			return (false, false);
		}

		public static bool GetConverted(PlayerControllerB player)
		{
			if (BodySpawn != null)
			{
				Logger.LogDebug((object)$"Got Converted, {BodySpawn.convertedList.Count}");
				return BodySpawn.ContainsPlayer(player);
			}
			return false;
		}

		public static void TryRemoveConverted(PlayerControllerB player)
		{
			BodySpawn.RemovePlayer(player);
		}

		public static void ClearConverted()
		{
			BodySpawn.ResetList();
		}

		internal static void SetReplacementModelVisible(PlayerControllerB player)
		{
			Logger.LogDebug((object)"Model Replacement Logic");
			if (ModelReplacementAPIFound && ModelReplaceScript != null)
			{
				ModelReplaceScript.SetBodyVisible(player);
			}
		}

		internal static void Patch()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("synaxin.zombies");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "synaxin.zombies";

		public const string PLUGIN_NAME = "synaxin.zombies";

		public const string PLUGIN_VERSION = "0.3.12";
	}
}
namespace Zombies.Scripts
{
	public class BodySpawnHandler
	{
		public List<PlayerControllerB> convertedList = new List<PlayerControllerB>();

		public void AddBody(PlayerControllerB player)
		{
			Zombies.Logger.LogMessage((object)"Addbody fired!");
			if (!convertedList.Contains(player))
			{
				Zombies.Logger.LogMessage((object)"Body added to list!");
				convertedList.Add(player);
			}
		}

		public bool ContainsPlayer(PlayerControllerB player)
		{
			return convertedList.Contains(player);
		}

		public void RemovePlayer(PlayerControllerB player)
		{
			if (convertedList.Contains(player))
			{
				convertedList.Remove(player);
			}
		}

		public void ResetList()
		{
			convertedList.Clear();
		}
	}
	internal class InfectionHandler
	{
		private static int deadTicks = Mathf.Abs(Zombies.BoundConfig.tryForTicks.Value);

		private static float infectionChance = Mathf.Abs(Zombies.BoundConfig.infectionChance.Value);

		private static int infectionMinTicks = Mathf.Abs(Zombies.BoundConfig.infectionTimeMin.Value);

		private static int infectionMaxTicks = Mathf.Abs(Zombies.BoundConfig.infectionTimeMax.Value);

		private static float proxChance = Mathf.Abs(Zombies.BoundConfig.proximityChance.Value);

		private static float timeForTick = 2f;

		private static float currentTickTime = 0f;

		private static float timeForProxTick = 0.1f;

		private static float currentProxTickTime = 0f;

		private static bool tickProximity = false;

		private static float proxDistance = 5f;

		private static int wakeTicks = Zombies.BoundConfig.wakeTickAmount.Value;

		private static int proxWakeTicks = Zombies.BoundConfig.proxWakeTickAmount.Value;

		private static int proxHeldWakeTicks = Zombies.BoundConfig.proxHeldWakeTickAmount.Value;

		private static float timeForWakeTick = 0.2f;

		private static float currentWakeTickTime = 0f;

		private static bool tickWake = false;

		private static bool reviveOnDeath = Zombies.BoundConfig.reviveOnDeath.Value;

		private static float reviveOnDeathChance = Zombies.BoundConfig.reviveOnDeathChance.Value;

		private static bool reviveOnDeathAlone = Zombies.BoundConfig.onlyReviveWhileAlone.Value;

		private static Dictionary<PlayerControllerB, InfectionInfo> deadList = new Dictionary<PlayerControllerB, InfectionInfo>();

		private static Dictionary<NetworkObjectReference, PlayerControllerB> bodyList = new Dictionary<NetworkObjectReference, PlayerControllerB>();

		private static Dictionary<PlayerControllerB, InfectionInfo> infectedList = new Dictionary<PlayerControllerB, InfectionInfo>();

		private static List<PlayerControllerB> deadConvertedList = new List<PlayerControllerB>();

		private static List<PlayerControllerB> instaExceptionsList = new List<PlayerControllerB>();

		private int previousLiving;

		private Random rand = new Random();

		public void Reset()
		{
			deadList.Clear();
			bodyList.Clear();
			infectedList.Clear();
			deadConvertedList.Clear();
			Zombies.ClearZombies();
			tickProximity = false;
			tickWake = false;
			currentTickTime = 0f;
			currentWakeTickTime = 0f;
			currentProxTickTime = 0f;
		}

		public bool GetReviveAlone()
		{
			return reviveOnDeathAlone;
		}

		public void RollInstaSpawn()
		{
			Dictionary<ulong, bool> dictionary = new Dictionary<ulong, bool>();
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.isPlayerControlled)
				{
					bool value = (float)(rand.Next(0, 1000) / 10) <= reviveOnDeathChance;
					dictionary.Add(val.actualClientId, value);
				}
			}
			Zombies.Networking.instaSpawnList.Clear();
			Zombies.Networking.SendInstaSpawnChange(dictionary);
		}

		public void AppendInstaSpawn(Dictionary<ulong, bool> dict)
		{
			Dictionary<ulong, bool> instaSpawnList = Zombies.Networking.instaSpawnList;
			foreach (var (key, value) in dict)
			{
				if (instaSpawnList.ContainsKey(key))
				{
					instaSpawnList[key] = value;
				}
				else
				{
					instaSpawnList.Add(key, value);
				}
			}
			Zombies.Networking.SendInstaSpawnChange(instaSpawnList);
		}

		public bool RollInstaSpawn(ulong playerID)
		{
			return (float)rand.Next(0, 100) <= reviveOnDeathChance;
		}

		public void ClearInfected()
		{
			deadList.Clear();
			bodyList.Clear();
			deadConvertedList.Clear();
			instaExceptionsList.Clear();
		}

		public void AddDeadBody(ulong playerID)
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)playerID)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[(uint)playerID];
			if (deadConvertedList.Contains(val))
			{
				return;
			}
			bool flag = false;
			if (reviveOnDeath && StartOfRound.Instance.shipHasLanded && !instaExceptionsList.Contains(val))
			{
				Zombies.Logger.LogDebug((object)"Check for Zombie -- Killplayer");
				if (Zombies.Networking.instaSpawnList.ContainsKey(val.actualClientId))
				{
					Zombies.Logger.LogDebug((object)"Zombie In Spawnlist -- Killplayer");
					if (Zombies.Networking.instaSpawnList[val.actualClientId])
					{
						Zombies.Logger.LogDebug((object)"Insta Spawn on -- Killplayer");
						flag = true;
						if (Zombies.Infection.GetReviveAlone() && !val.isPlayerAlone)
						{
							Zombies.Logger.LogDebug((object)"Not Alone -- Killplayer");
							flag = false;
						}
					}
					if (flag)
					{
						Zombies.Logger.LogDebug((object)"Spawning Zombie -- Killplayer");
						if (Zombies.Infection != null)
						{
							if (!instaExceptionsList.Contains(val))
							{
								instaExceptionsList.Add(val);
							}
							Zombies.Networking.SendMaskSpawnMessage(val, val.playerClientId);
							return;
						}
					}
				}
			}
			if (flag)
			{
				return;
			}
			Zombies.Logger.LogMessage((object)$"Adding Player {val.playerClientId} to deadlist");
			bool flag2 = true;
			foreach (var (val4, val5) in bodyList)
			{
				if ((Object)(object)val == (Object)(object)val5)
				{
					flag2 = false;
					Zombies.Logger.LogMessage((object)"Cancelling Add");
				}
			}
			if (flag2 && !deadList.ContainsKey(val))
			{
				if (!instaExceptionsList.Contains(val))
				{
					instaExceptionsList.Add(val);
				}
				deadList.Add(val, new InfectionInfo(val, deadTicks, infectionChance, infectionMinTicks, infectionMaxTicks, proxChance, wakeTicks));
				if (deadList.ContainsKey(val) && deadList[val].GetProximity())
				{
					deadList[val].SetWakeTicks(proxWakeTicks);
				}
			}
		}

		public void AddZombie(NetworkObjectReference enemy, PlayerControllerB player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || bodyList.ContainsKey(enemy))
			{
				return;
			}
			Zombies.Logger.LogDebug((object)"Added Player to Zombie List");
			if (deadList.ContainsKey(player))
			{
				deadList.Remove(player);
			}
			if (bodyList.ContainsValue(player))
			{
				List<NetworkObjectReference> list = new List<NetworkObjectReference>();
				bool flag = false;
				foreach (var (item, val3) in bodyList)
				{
					if ((Object)(object)val3 == (Object)(object)player)
					{
						list.Add(item);
						flag = true;
					}
				}
				if (flag)
				{
					foreach (NetworkObjectReference item2 in list)
					{
						Zombies.Networking.SendBodyChangeMessage(item2);
						bodyList.Remove(item2);
					}
				}
			}
			bodyList.Add(enemy, player);
			if (!Zombies.BoundConfig.droppedBodiesInfection.Value || !Zombies.BoundConfig.zombiesDropBodies.Value)
			{
				deadConvertedList.Add(player);
			}
		}

		public void ReplaceDeadBody(NetworkObject target)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			List<NetworkObjectReference> list = new List<NetworkObjectReference>();
			NetworkObject val5 = default(NetworkObject);
			foreach (KeyValuePair<NetworkObjectReference, PlayerControllerB> body in bodyList)
			{
				var (val3, val4) = (KeyValuePair<NetworkObjectReference, PlayerControllerB>)(ref body);
				if (((NetworkObjectReference)(ref val3)).TryGet(ref val5, (NetworkManager)null) && (Object)(object)val5 == (Object)(object)target)
				{
					Vector3[] position = (Vector3[])(object)new Vector3[1] { ((Component)target).transform.position };
					Zombies.Networking.SendZombieDeadMessage(new ZombieDeadInfo(val4.playerClientId, position, val3));
					list.Add(val3);
				}
			}
			foreach (NetworkObjectReference item in list)
			{
				if (bodyList.ContainsKey(item))
				{
					Zombies.Logger.LogDebug((object)"Removing Reference");
					PlayerControllerB val6 = bodyList[item];
					bodyList.Remove(item);
					AddDeadBody(val6.playerClientId);
				}
			}
		}

		public void TickThroughRevivals()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if (previousLiving < StartOfRound.Instance.livingPlayers && StartOfRound.Instance.shipHasLanded && bodyList.Count > 0)
			{
				List<NetworkObjectReference> list = new List<NetworkObjectReference>();
				foreach (var (item, val3) in bodyList)
				{
					if (val3.isPlayerDead)
					{
						continue;
					}
					Zombies.Logger.LogDebug((object)"Revived player removed from bodylist");
					list.Add(item);
					if (reviveOnDeath)
					{
						if (Zombies.Networking.instaSpawnList.ContainsKey(val3.actualClientId))
						{
							Zombies.Networking.instaSpawnList[val3.actualClientId] = RollInstaSpawn(val3.actualClientId);
						}
						else
						{
							Zombies.Networking.instaSpawnList.Add(val3.actualClientId, RollInstaSpawn(val3.actualClientId));
						}
					}
				}
				foreach (NetworkObjectReference item2 in list)
				{
					Zombies.Networking.SendBodyChangeMessage(item2);
					bodyList.Remove(item2);
				}
			}
			previousLiving = StartOfRound.Instance.livingPlayers;
		}

		public void TickThroughBodies()
		{
			if (!NetworkManager.Singleton.IsHost && !NetworkManager.Singleton.IsServer)
			{
				return;
			}
			if (deadList.Count > 0)
			{
				TickInfection();
				if (tickProximity)
				{
					ProximityCheck();
				}
				if (tickWake)
				{
					WakeTick();
				}
			}
			else
			{
				currentTickTime = 0f;
			}
		}

		private void TickInfection()
		{
			bool flag = false;
			bool flag2 = false;
			currentTickTime += Time.deltaTime;
			if (!(currentTickTime >= timeForTick))
			{
				return;
			}
			List<PlayerControllerB> list = new List<PlayerControllerB>();
			currentTickTime = 0f;
			foreach (var (val2, infectionInfo2) in deadList)
			{
				try
				{
					if (infectionInfo2.GetState() < 0 || (Object)(object)val2.deadBody == (Object)null || val2.deadBody.deactivated)
					{
						list.Add(val2);
						continue;
					}
					Zombies.Networking.SendSyncMessageServer(val2.playerClientId, val2);
					int num = infectionInfo2.Tick();
					Zombies.Logger.LogDebug((object)$"Body {val2} Ticked! State: {num}");
					switch (num)
					{
					case 2:
						if (!infectionInfo2.GetProximity() || (infectionInfo2.GetProximity() && infectionInfo2.GetState() == 4 && !infectionInfo2.GetParentSet()))
						{
							Zombies.Networking.SendBloodMessage(val2.playerClientId);
						}
						Zombies.Logger.LogDebug((object)$"Ticking Infection! ID{val2.actualClientId}");
						break;
					case 3:
						Zombies.Logger.LogDebug((object)$"Infection Complete! ID{val2.actualClientId}");
						infectionInfo2.SetTarget(val2);
						infectionInfo2.WakeUp();
						break;
					case 4:
						Zombies.Logger.LogDebug((object)"Infection Complete! Proximity ID{body.playerClientId}");
						flag = true;
						break;
					case 5:
						flag2 = true;
						break;
					}
				}
				catch
				{
					Zombies.Logger.LogWarning((object)"Tried to tick infection on a missing player! This is probably because a player left.");
				}
			}
			foreach (PlayerControllerB item in list)
			{
				deadList[item].Finish();
				deadList.Remove(item);
			}
			tickProximity = flag;
			tickWake = flag2;
		}

		private void ProximityCheck()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			currentProxTickTime += Time.deltaTime;
			if (!(currentProxTickTime >= timeForProxTick))
			{
				return;
			}
			int num = 0;
			Zombies.Logger.LogDebug((object)"Ticking Proximity!");
			currentProxTickTime = 0f;
			foreach (var (val2, infectionInfo2) in deadList)
			{
				if (infectionInfo2.GetState() != 4)
				{
					continue;
				}
				num++;
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val3 in allPlayerScripts)
				{
					if (!val3.isPlayerControlled || val3.isPlayerDead || !((Object)(object)((Component)val3).gameObject != (Object)(object)((Component)val2).gameObject) || !((Object)(object)val2.deadBody != (Object)null))
					{
						continue;
					}
					float num2 = Vector3.Distance(((Component)val2.deadBody).gameObject.transform.position, ((Component)val3).gameObject.transform.position);
					if (!(num2 <= proxDistance))
					{
						continue;
					}
					if (!infectionInfo2.GetParentSet())
					{
						bool flag = false;
						if ((Object)(object)val3.currentlyHeldObjectServer != (Object)null)
						{
							Zombies.Logger.LogDebug((object)("Held Object = " + ((Object)val3.currentlyHeldObjectServer).name));
							if (((Object)((Component)val3.currentlyHeldObjectServer).gameObject).name == "RagdollGrabbableObject(Clone)")
							{
								Zombies.Logger.LogDebug((object)"After Held Object");
								if ((Object)(object)((Component)((Component)val3.currentlyHeldObjectServer).transform.parent.parent.parent).gameObject == (Object)(object)((Component)val2.deadBody).gameObject)
								{
									flag = true;
									Zombies.Logger.LogDebug((object)"Zombie Adopted!");
									infectionInfo2.SetParentalFigure(val3, ((Component)val3.currentlyHeldObjectServer).gameObject);
									infectionInfo2.SetWakeTicks(proxHeldWakeTicks);
								}
							}
						}
						if (!flag)
						{
							Zombies.Logger.LogDebug((object)"Found Target! No parent");
							infectionInfo2.SetTarget(val3);
							infectionInfo2.WakeUp();
							num--;
							tickWake = true;
						}
					}
					else if ((Object)(object)val3 != (Object)(object)infectionInfo2.GetParentalFigure())
					{
						Zombies.Logger.LogDebug((object)"Found Target!");
						infectionInfo2.SetTarget(val3);
						infectionInfo2.WakeUp();
						num--;
						tickWake = true;
					}
					else
					{
						bool flag2 = false;
						if ((Object)(object)val3.currentlyHeldObjectServer != (Object)null && (Object)(object)((Component)val3.currentlyHeldObjectServer).gameObject == (Object)(object)infectionInfo2.GetRagdoll())
						{
							flag2 = true;
						}
						if (!flag2)
						{
							Zombies.Logger.LogDebug((object)"Found Target! !found");
							infectionInfo2.SetTarget(val3);
							infectionInfo2.WakeUp();
							num--;
							tickWake = true;
						}
					}
				}
			}
			if (num <= 0)
			{
				tickProximity = false;
			}
		}

		private void WakeTick()
		{
			currentWakeTickTime += Time.deltaTime;
			if (!(currentWakeTickTime >= timeForWakeTick))
			{
				return;
			}
			int num = 0;
			Zombies.Logger.LogDebug((object)"Ticking Wake!");
			currentWakeTickTime = 0f;
			List<PlayerControllerB> list = new List<PlayerControllerB>();
			foreach (var (val2, infectionInfo2) in deadList)
			{
				if (infectionInfo2.GetState() == 5)
				{
					num++;
					Zombies.Logger.LogDebug((object)$"Wake Tick on {val2.actualClientId}");
					infectionInfo2.WakeTick();
					Zombies.Networking.SendWakeMessage(val2.playerClientId);
				}
				if (infectionInfo2.GetState() == 6)
				{
					list.Add(val2);
				}
			}
			foreach (PlayerControllerB item in list)
			{
				deadList[item].Finish();
				Zombies.Networking.SendMaskSpawnMessage(item, deadList[item].GetTarget().actualClientId);
				deadList.Remove(item);
			}
			if (num <= 0)
			{
				tickWake = false;
			}
			Zombies.Logger.LogDebug((object)"Wake Tick Complete!");
		}

		public Dictionary<ulong, Vector3> GetPositions()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<ulong, Vector3> dictionary = new Dictionary<ulong, Vector3>();
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.isPlayerControlled)
				{
					dictionary.Add(val.actualClientId, ((Component)val).transform.position);
				}
			}
			return dictionary;
		}
	}
	internal class BodySyncInfo
	{
		public readonly ulong bodyID;

		public readonly Vector3 position;

		public BodySyncInfo(ulong id, Vector3 position)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			bodyID = id;
			this.position = position;
		}

		public bool GetDifference(Vector3 newPos, float posDif)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			if (Vector3.Distance(position, newPos) >= posDif)
			{
				result = true;
			}
			return result;
		}
	}
	internal class ZombieSpawnInfo
	{
		public readonly ulong playerID;

		public readonly ulong targetID;

		public readonly NetworkObjectReference enemy;

		public ZombieSpawnInfo(ulong playerID, ulong targetID)
		{
			this.playerID = playerID;
			this.targetID = targetID;
		}

		public ZombieSpawnInfo(ulong playerID, ulong targetID, NetworkObjectReference enemy)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			this.playerID = playerID;
			this.targetID = targetID;
			this.enemy = enemy;
		}
	}
	internal class ZombieDeadInfo
	{
		public readonly ulong playerID;

		public readonly Vector3[] position;

		public readonly NetworkObjectReference enemy;

		private Vector3[] bodyPartPositions;

		public ZombieDeadInfo(ulong playerID, Vector3[] position, NetworkObjectReference enemy)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			this.playerID = playerID;
			this.position = position;
			this.enemy = enemy;
		}
	}
	public class ModelReplacementCompat
	{
		public void SetBodyVisible(PlayerControllerB player)
		{
			Zombies.Logger.LogDebug((object)"Model Replacement API Found");
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			BodyReplacementBase val = default(BodyReplacementBase);
			if (((Component)player).gameObject.TryGetComponent<BodyReplacementBase>(ref val))
			{
				Zombies.Logger.LogDebug((object)"Found Body Replacement Base");
				if ((Object)(object)val.replacementDeadBody != (Object)null)
				{
					val.replacementDeadBody.gameObject.SetActive(true);
				}
			}
			else
			{
				Zombies.Logger.LogDebug((object)"Did not find Body Replacement Base");
			}
		}
	}
	internal class RPCStuff
	{
	}
	internal class InfectionInfo
	{
		private Random rand = new Random((int)Time.time);

		private int deadTime;

		private readonly int deadTicks;

		private readonly float infectionChance;

		private int infectionTime;

		private readonly int infectionTicks = 10;

		private bool infected;

		private PlayerControllerB parentalFigure;

		private bool parentSet;

		private GameObject parentRagdoll;

		private PlayerControllerB targetPlayer;

		private readonly bool proximity;

		private bool done;

		private int state;

		private int wakeTicks = 10;

		private int wakeTime;

		public InfectionInfo(PlayerControllerB player, int deadTicks, float infectionChance, int inMinTicks, int inMaxTicks, float proxChance, int wakeTicks)
		{
			targetPlayer = player;
			this.deadTicks = deadTicks;
			this.infectionChance = infectionChance;
			infectionTicks = inMinTicks + rand.Next(inMaxTicks - inMinTicks);
			proximity = (float)(rand.Next(1000) / 10) < proxChance;
			this.wakeTicks = wakeTicks;
		}

		public int Tick()
		{
			if (state < 0 || state == 5)
			{
				return state;
			}
			if (!infected)
			{
				bool flag = RollInfection(infectionChance);
				deadTime++;
				if (flag)
				{
					state = 1;
					return 1;
				}
				if (deadTime >= deadTicks)
				{
					state = -1;
					return -1;
				}
				state = 0;
				return 0;
			}
			infectionTime++;
			if (infectionTime >= infectionTicks && state <= 4)
			{
				if (proximity)
				{
					state = 4;
					return 4;
				}
				state = 3;
				return 3;
			}
			state = 2;
			return 2;
		}

		public int WakeTick()
		{
			wakeTime++;
			if (wakeTime >= wakeTicks)
			{
				state = 6;
				return 6;
			}
			return 5;
		}

		public void Finish()
		{
			done = true;
			state = -2;
		}

		public bool GetProximity()
		{
			return proximity;
		}

		public int GetState()
		{
			return state;
		}

		public void SetParentalFigure(PlayerControllerB parent, GameObject ragdoll)
		{
			parentSet = true;
			parentalFigure = parent;
			parentRagdoll = ragdoll;
		}

		public void SetWakeTicks(int newWakeTicks)
		{
			wakeTicks = newWakeTicks;
		}

		public void SetTarget(PlayerControllerB target)
		{
			targetPlayer = target;
		}

		public bool GetParentSet()
		{
			return parentSet;
		}

		public PlayerControllerB GetParentalFigure()
		{
			return parentalFigure;
		}

		public GameObject GetRagdoll()
		{
			return parentRagdoll;
		}

		public PlayerControllerB GetTarget()
		{
			return targetPlayer;
		}

		public void WakeUp()
		{
			state = 5;
		}

		private bool RollInfection(float chance)
		{
			float num = rand.Next(100000) / 1000;
			if (num <= chance)
			{
				infected = true;
				return true;
			}
			return false;
		}
	}
	public class ZombieNetworkManager : MonoBehaviour
	{
		private Random rand = new Random();

		private LNetworkMessage<(ulong, ulong)> deadBodyMessage;

		private LNetworkMessage<ulong> bloodDropMessage;

		private LNetworkMessage<BodySyncInfo> bodySyncMessage;

		private LNetworkMessage<ulong> zombieWakeMessage;

		private LNetworkMessage<(NetworkObjectReference, ZombieSpawnInfo)> maskSpawnMessage;

		private LNetworkMessage<ZombieDeadInfo> zombieDeadMessage;

		private LNetworkMessage<ZombieSpawnInfo> maskSpawnResponseMessage;

		private LNetworkMessage<NetworkObjectReference> maskDespawnMessage;

		private LNetworkMessage<NetworkObjectReference> maskChangeBodyMessage;

		private Dictionary<NetworkObjectReference, List<ulong>> maskDespawnList = new Dictionary<NetworkObjectReference, List<ulong>>();

		private Dictionary<NetworkObjectReference, List<ulong>> maskSpawnList = new Dictionary<NetworkObjectReference, List<ulong>>();

		internal Dictionary<ulong, bool> instaSpawnList = new Dictionary<ulong, bool>();

		private LNetworkMessage<Dictionary<ulong, bool>> instaSpawnMessage;

		public static bool set;

		public ZombieNetworkManager()
		{
			if (!set)
			{
				Zombies.Logger.LogDebug((object)"Setting Up Network Manager");
				deadBodyMessage = LNetworkMessage<(ulong, ulong)>.Connect("AddDeadBody", (Action<(ulong, ulong), ulong>)null, (Action<(ulong, ulong)>)null, (Action<(ulong, ulong), ulong>)null);
				bloodDropMessage = LNetworkMessage<ulong>.Connect("BloodDrop", (Action<ulong, ulong>)null, (Action<ulong>)null, (Action<ulong, ulong>)null);
				bodySyncMessage = LNetworkMessage<BodySyncInfo>.Connect("DeadBodySync", (Action<BodySyncInfo, ulong>)null, (Action<BodySyncInfo>)null, (Action<BodySyncInfo, ulong>)null);
				zombieWakeMessage = LNetworkMessage<ulong>.Connect("ZombieWake", (Action<ulong, ulong>)null, (Action<ulong>)null, (Action<ulong, ulong>)null);
				maskSpawnMessage = LNetworkMessage<(NetworkObjectReference, ZombieSpawnInfo)>.Connect("MaskSpawn", (Action<(NetworkObjectReference, ZombieSpawnInfo), ulong>)null, (Action<(NetworkObjectReference, ZombieSpawnInfo)>)null, (Action<(NetworkObjectReference, ZombieSpawnInfo), ulong>)null);
				zombieDeadMessage = LNetworkMessage<ZombieDeadInfo>.Connect("ZombieDead", (Action<ZombieDeadInfo, ulong>)null, (Action<ZombieDeadInfo>)null, (Action<ZombieDeadInfo, ulong>)null);
				maskDespawnMessage = LNetworkMessage<NetworkObjectReference>.Connect("DespawnMask", (Action<NetworkObjectReference, ulong>)null, (Action<NetworkObjectReference>)null, (Action<NetworkObjectReference, ulong>)null);
				maskSpawnResponseMessage = LNetworkMessage<ZombieSpawnInfo>.Connect("MaskSpawnResponse", (Action<ZombieSpawnInfo, ulong>)null, (Action<ZombieSpawnInfo>)null, (Action<ZombieSpawnInfo, ulong>)null);
				maskChangeBodyMessage = LNetworkMessage<NetworkObjectReference>.Connect("MaskBodyChange", (Action<NetworkObjectReference, ulong>)null, (Action<NetworkObjectReference>)null, (Action<NetworkObjectReference, ulong>)null);
				instaSpawnMessage = LNetworkMessage<Dictionary<ulong, bool>>.Connect("InstaSpawnChange", (Action<Dictionary<ulong, bool>, ulong>)null, (Action<Dictionary<ulong, bool>>)null, (Action<Dictionary<ulong, bool>, ulong>)null);
				deadBodyMessage.OnServerReceived += OnDeadMessageServer;
				bodySyncMessage.OnServerReceived += OnSyncMessageServer;
				bodySyncMessage.OnClientReceived += OnSyncMessageClient;
				bloodDropMessage.OnServerReceived += OnBloodDropServer;
				bloodDropMessage.OnClientReceived += OnBloodDropClient;
				zombieWakeMessage.OnServerReceived += OnZombieWakeServer;
				zombieWakeMessage.OnClientReceived += OnZombieWakeClient;
				maskSpawnMessage.OnServerReceived += OnMaskSpawnServer;
				maskSpawnMessage.OnClientReceived += OnMaskSpawnClient;
				zombieDeadMessage.OnServerReceived += OnZombieDeadServer;
				zombieDeadMessage.OnClientReceived += OnZombieDeadClient;
				maskDespawnMessage.OnServerReceived += OnDespawnServer;
				maskChangeBodyMessage.OnServerReceived += OnBodyChangeServer;
				maskChangeBodyMessage.OnClientReceived += OnBodyChangeClient;
				instaSpawnMessage.OnServerReceived += OnInstaSpawnChangeServer;
				instaSpawnMessage.OnClientReceived += OnInstaSpawnChangeClient;
				set = true;
			}
		}

		internal void SendDeadMessage(ulong id, ulong actualID)
		{
			Zombies.Logger.LogMessage((object)$"Sent Dead Message from {id}");
			deadBodyMessage.SendServer((id, actualID));
		}

		private void OnDeadMessageServer((ulong, ulong) pID, ulong id2)
		{
			Zombies.Logger.LogMessage((object)$"Received Dead Message from {pID.Item1}, {id2}");
			if (pID.Item2 == id2)
			{
				Zombies.Infection.AddDeadBody(pID.Item1);
			}
		}

		internal void SendSyncMessageServer(ulong id, PlayerControllerB body)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)body.deadBody).gameObject;
			if (!((Object)(object)gameObject == (Object)null))
			{
				BodySyncInfo bodySyncInfo = new BodySyncInfo(id, gameObject.transform.position);
				bodySyncMessage.SendServer(bodySyncInfo);
			}
		}

		internal void OnSyncMessageServer(BodySyncInfo info, ulong id)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)info.bodyID)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[info.bodyID];
			if (!((Object)(object)val == (Object)null))
			{
				GameObject gameObject = ((Component)val.deadBody).gameObject;
				if (!((Object)(object)gameObject == (Object)null))
				{
					BodySyncInfo bodySyncInfo = new BodySyncInfo(info.bodyID, gameObject.transform.position);
					bodySyncMessage.SendClients(bodySyncInfo);
				}
			}
		}

		internal void OnSyncMessageClient(BodySyncInfo info)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)info.bodyID)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[info.bodyID];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			DeadBodyInfo deadBody = val.deadBody;
			if (!((Object)(object)deadBody == (Object)null))
			{
				GameObject gameObject = ((Component)val.deadBody).gameObject;
				if (info.GetDifference(gameObject.transform.position, 2f))
				{
					Zombies.Logger.LogDebug((object)$"Perfoming Body Sync On {info.bodyID}");
					gameObject.transform.position = info.position;
				}
			}
		}

		internal void SendBloodMessage(ulong playerID)
		{
			Zombies.Logger.LogDebug((object)"SendBloodMessage");
			bloodDropMessage.SendServer(playerID);
		}

		private void OnBloodDropServer(ulong playerID, ulong id)
		{
			Zombies.Logger.LogDebug((object)"OnBloodMessageServer");
			bloodDropMessage.SendClients(playerID);
		}

		private void OnBloodDropClient(ulong playerID)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Zombies.Logger.LogDebug((object)"OnBloodMessageClient");
			if (StartOfRound.Instance.allPlayerScripts.Length >= (int)playerID)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerID];
				if (!((Object)(object)val == (Object)null))
				{
					val.bloodDropTimer = -1f;
					val.DropBlood(Vector3.down, true, false);
				}
			}
		}

		internal void SendWakeMessage(ulong playerID)
		{
			zombieWakeMessage.SendServer(playerID);
		}

		private void OnZombieWakeServer(ulong playerID, ulong id)
		{
			zombieWakeMessage.SendClients(playerID);
		}

		private void OnZombieWakeClient(ulong playerID)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)playerID)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerID];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			val.bloodDropTimer = -1f;
			val.AddBloodToBody();
			val.DropBlood(Vector3.down, true, false);
			val.DropBlood(new Vector3(0.7f, -0f, 0.7f), true, false);
			val.DropBlood(new Vector3(-0.7f, -0f, 0.7f), true, false);
			val.DropBlood(new Vector3(0.7f, -0f, -0.7f), true, false);
			val.DropBlood(new Vector3(-0.7f, -0f, -0.7f), true, false);
			if ((Object)(object)val.deadBody != (Object)null)
			{
				for (int i = 0; i < val.deadBody.bodyParts.Length; i++)
				{
					val.deadBody.bodyParts[i].drag = 0f;
					val.deadBody.bodyParts[i].AddForce(new Vector3(0f, 5000f, 0f), (ForceMode)0);
				}
			}
		}

		internal void SendMaskSpawnMessage(PlayerControllerB player, ulong target)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				Zombies.Logger.LogMessage((object)$"Sent Mask {player}");
				maskSpawnMessage.SendServer((default(NetworkObjectReference), new ZombieSpawnInfo(player.playerClientId, target)));
			}
		}

		private void OnMaskSpawnServer((NetworkObjectReference, ZombieSpawnInfo) info, ulong playerID)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)playerID)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[info.Item2.playerID];
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)playerID)
			{
				return;
			}
			PlayerControllerB val2 = StartOfRound.Instance.allPlayerScripts[info.Item2.targetID];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val;
			}
			if ((Object)(object)val.deadBody == (Object)null)
			{
				return;
			}
			Vector3 val3 = ((Component)val.deadBody).transform.position;
			Quaternion val4 = Quaternion.Euler(Vector3.zero);
			bool proximity = false;
			if (info.Item2.playerID != info.Item2.targetID)
			{
				proximity = true;
				Dictionary<ulong, Vector3> positions = Zombies.Infection.GetPositions();
				Vector3 val5 = positions[info.Item2.targetID];
				Zombies.Logger.LogDebug((object)$"OnSpawn {val5}");
				Zombies.Logger.LogDebug((object)$"Target Player {info.Item2.targetID}, Pos1 {val3}, pos2 {val5}");
				Vector3 val6 = Vector3.Normalize(val3 - val5);
				val6.y = 0f;
				val4 = Quaternion.LookRotation(val6);
				float num = Mathf.Clamp01(5f / Vector3.Distance(val3, val5));
				val3 = Vector3.Lerp(val3, val5, num);
			}
			NetworkObjectReference val7 = RoundManager.Instance.SpawnEnemyGameObject(val3, ((Quaternion)(ref val4)).eulerAngles.y, -1, Zombies.maskEnemy);
			NetworkObject val8 = default(NetworkObject);
			if (((NetworkObjectReference)(ref val7)).TryGet(ref val8, (NetworkManager)null))
			{
				Zombies.Infection.AddZombie(val7, val);
				Debug.Log((object)"Got network object for mask enemy");
				MaskedPlayerEnemy component = ((Component)val8).GetComponent<MaskedPlayerEnemy>();
				Zombies.AddZombie(component, proximity);
				component.SetSuit(val.currentSuitID);
				component.mimickingPlayer = val;
				((EnemyAI)component).SetEnemyOutside(!val.isInsideFactory);
				component.SetVisibilityOfMaskedEnemy();
				val.redirectToEnemy = (EnemyAI)(object)component;
				if ((Object)(object)val.deadBody != (Object)null)
				{
					val.deadBody.DeactivateBody(false);
				}
			}
			Zombies.Logger.LogMessage((object)$"Received Mask Server {info.Item2}");
			maskSpawnMessage.SendClients((val7, new ZombieSpawnInfo(info.Item2.playerID, info.Item2.targetID, val7)));
		}

		private void OnMaskSpawnClient((NetworkObjectReference, ZombieSpawnInfo) info)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Zombies.Logger.LogMessage((object)$"Received Client, {info.Item1}");
			((MonoBehaviour)StartOfRound.Instance).StartCoroutine(waitForMimicEnemySpawn(info.Item1, info.Item2, info.Item2.playerID));
		}

		private IEnumerator waitForMimicEnemySpawn(NetworkObjectReference netObjectRef, ZombieSpawnInfo info, ulong id)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Zombies.Logger.LogDebug((object)"Entered Spawn Coroutine");
			NetworkObject netObject = null;
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)id)
			{
				yield break;
			}
			PlayerControllerB player = StartOfRound.Instance.allPlayerScripts[id];
			if ((Object)(object)player == (Object)null)
			{
				yield break;
			}
			float startTime = Time.realtimeSinceStartup;
			yield return (object)new WaitUntil((Func<bool>)(() => (double)Time.realtimeSinceStartup - (double)startTime > 20.0 || ((NetworkObjectReference)(ref netObjectRef)).TryGet(ref netObject, (NetworkManager)null)));
			if ((Object)(object)player.deadBody == (Object)null)
			{
				startTime = Time.realtimeSinceStartup;
				yield return (object)new WaitUntil((Func<bool>)(() => (double)Time.realtimeSinceStartup - (double)startTime > 20.0 || (Object)(object)player.deadBody != (Object)null));
			}
			if (!((Object)(object)player.deadBody == (Object)null) && (Object)(object)netObject != (Object)null)
			{
				Zombies.Logger.LogDebug((object)"Spawn Coroutine Found Netobj");
				player.deadBody.DeactivateBody(false);
				MaskedPlayerEnemy component = ((Component)netObject).GetComponent<MaskedPlayerEnemy>();
				component.mimickingPlayer = player;
				component.SetSuit(player.currentSuitID);
				((EnemyAI)component).SetEnemyOutside(!player.isInsideFactory);
				component.SetVisibilityOfMaskedEnemy();
				((EnemyAI)component).creatureAnimator.SetTrigger("HitEnemy");
				player.redirectToEnemy = (EnemyAI)(object)component;
			}
		}

		internal void SendZombieDeadMessage(ZombieDeadInfo info)
		{
			Zombies.Logger.LogDebug((object)"SendZombieDeadMessage");
			zombieDeadMessage.SendServer(info);
		}

		private void OnZombieDeadServer(ZombieDeadInfo info, ulong id)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			Zombies.Logger.LogDebug((object)"OnZombieDeadServer");
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)info.playerID)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[info.playerID];
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			Zombies.Logger.LogDebug((object)"OnZombieDeadServer2");
			NetworkObjectReference enemy = info.enemy;
			NetworkObject val2 = default(NetworkObject);
			if (((NetworkObjectReference)(ref enemy)).TryGet(ref val2, (NetworkManager)null))
			{
				MaskedPlayerEnemy mask = default(MaskedPlayerEnemy);
				if (((Component)val2).TryGetComponent<MaskedPlayerEnemy>(ref mask))
				{
					Zombies.RemoveZombie(mask);
				}
				Transform[] bodyPartArray = GetBodyPartArray(((Component)val2).gameObject);
				Vector3[] array = (Vector3[])(object)new Vector3[bodyPartArray.Length];
				for (int i = 0; i < bodyPartArray.Length; i++)
				{
					array[i] = bodyPartArray[i].position;
					Zombies.Logger.LogDebug((object)$"{bodyPartArray[i].position}, {array[i]}");
				}
				ZombieDeadInfo zombieDeadInfo = new ZombieDeadInfo(info.playerID, array, info.enemy);
				zombieDeadMessage.SendClients(zombieDeadInfo);
			}
		}

		private void OnZombieDeadClient(ZombieDeadInfo info)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			Zombies.Logger.LogDebug((object)"OnZombieDeadClient");
			if (StartOfRound.Instance.allPlayerScripts.Length < (int)info.playerID)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[info.playerID];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			NetworkObjectReference enemy = info.enemy;
			NetworkObject val2 = default(NetworkObject);
			if (!((NetworkObjectReference)(ref enemy)).TryGet(ref val2, (NetworkManager)null))
			{
				return;
			}
			Zombies.Logger.LogDebug((object)"OnZombieDeadClient2");
			Zombies.Logger.LogDebug((object)"OnZombieDeadClient3");
			Zombies.Logger.LogDebug((object)$"{info.position},");
			Zombies.Logger.LogDebug((object)"OnZombieDeadClient4");
			if (Zombies.BoundConfig.zombiesDropBodies.Value)
			{
				val.deadBody.overrideSpawnPosition = true;
				((Component)val.deadBody).gameObject.SetActive(true);
				Zombies.SetReplacementModelVisible(val);
				val.deadBody.SetBodyPartsKinematic(false);
				for (int i = 0; i < info.position.Length; i++)
				{
					Zombies.Logger.LogDebug((object)$"OnZombieDeadClient5, {info.position[i]}");
					val.deadBody.bodyParts[i].position = info.position[i];
					val.deadBody.bodyParts[i].velocity = Vector3.zero;
				}
				val.deadBody.seenByLocalPlayer = false;
				Zombies.Logger.LogDebug((object)"OnZombieDeadClient6");
				Zombies.Logger.LogDebug((object)"OnZombieDeadClient7");
				val.deadBody.deactivated = false;
				Zombies.Logger.LogDebug((object)"OnZombieDeadClient8");
				val.redirectToEnemy = null;
			}
			Zombies.Logger.LogDebug((object)"OnZombieDeadClient9");
			if ((Object)(object)val2 != (Object)null)
			{
				Zombies.Logger.LogDebug((object)"OnZombieDeadClient10");
				if (Zombies.BoundConfig.droppedBodiesInfection.Value)
				{
					((Component)val2).gameObject.SetActive(false);
					maskDespawnMessage.SendServer(info.enemy);
				}
			}
			Zombies.Logger.LogDebug((object)"OnZombieDeadClient11");
			if ((NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost) && Zombies.BoundConfig.droppedBodiesInfection.Value)
			{
				Zombies.Infection.AddDeadBody(val.playerClientId);
			}
		}

		private void OnDespawnServer(NetworkObjectReference enemy, ulong id)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (maskDespawnList.ContainsKey(enemy))
			{
				maskDespawnList[enemy].Add(id);
			}
			else
			{
				maskDespawnList.Add(enemy, new List<ulong>());
				maskDespawnList[enemy].Add(id);
			}
			if (maskDespawnList[enemy].Count >= StartOfRound.Instance.ClientPlayerList.Count)
			{
				NetworkObject val = default(NetworkObject);
				if (((NetworkObjectReference)(ref enemy)).TryGet(ref val, (NetworkManager)null))
				{
					val.Despawn(true);
				}
				maskDespawnList.Remove(enemy);
			}
		}

		internal void SendBodyChangeMessage(NetworkObjectReference reference)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			maskChangeBodyMessage.SendServer(reference);
		}

		private void OnBodyChangeServer(NetworkObjectReference reference, ulong id)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			maskChangeBodyMessage.SendClients(reference);
		}

		private void OnBodyChangeClient(NetworkObjectReference reference)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)StartOfRound.Instance).StartCoroutine(waitForBodyChangeRef(reference));
		}

		private IEnumerator waitForBodyChangeRef(NetworkObjectReference reference)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Zombies.Logger.LogDebug((object)"Entered Spawn Coroutine");
			NetworkObject netObject1 = null;
			Zombies.Logger.LogMessage((object)"Changing Body");
			float startTime = Time.realtimeSinceStartup;
			yield return (object)new WaitUntil((Func<bool>)(() => (double)Time.realtimeSinceStartup - (double)startTime > 10.0 || ((NetworkObjectReference)(ref reference)).TryGet(ref netObject1, (NetworkManager)null)));
			if ((Object)(object)netObject1 != (Object)null)
			{
				Zombies.Logger.LogDebug((object)"Change Body Coroutine Found Netobj");
				MaskedPlayerEnemy component = ((Component)netObject1).GetComponent<MaskedPlayerEnemy>();
				if ((Object)(object)component.mimickingPlayer != (Object)null)
				{
					component.mimickingPlayer.redirectToEnemy = null;
				}
			}
		}

		internal void SendInstaSpawnChange(Dictionary<ulong, bool> dict)
		{
			instaSpawnMessage.SendServer(dict);
		}

		private void OnInstaSpawnChangeServer(Dictionary<ulong, bool> dict, ulong id)
		{
			instaSpawnMessage.SendClients(dict);
		}

		private void OnInstaSpawnChangeClient(Dictionary<ulong, bool> dict)
		{
			instaSpawnList = dict;
		}

		private Transform[] GetBodyPartArray(GameObject mask)
		{
			Transform[] array = (Transform[])(object)new Transform[11];
			GameObject gameObject = ((Component)mask.transform.Find("ScavengerModel").Find("metarig")).gameObject;
			Transform val = gameObject.transform.Find("spine");
			Transform child = val.GetChild(0).GetChild(0);
			Transform child2 = child.GetChild(0);
			Transform val2 = child2.Find("spine.004");
			Transform val3 = child2.Find("shoulder.L");
			Transform child3 = val3.GetChild(0);
			Transform child4 = child3.GetChild(0);
			Transform val4 = child2.Find("shoulder.R");
			Transform child5 = val4.GetChild(0);
			Transform child6 = child5.GetChild(0);
			Transform val5 = val.Find("thigh.L");
			Transform child7 = val5.GetChild(0);
			Transform val6 = val.Find("thigh.R");
			Transform child8 = val6.GetChild(0);
			array[0] = val2;
			array[1] = child6;
			array[2] = child4;
			array[3] = child8;
			array[4] = child7;
			array[5] = child;
			array[6] = mask.transform;
			array[7] = val6;
			array[8] = val5;
			array[9] = child3;
			array[10] = child5;
			return array;
		}
	}
}
namespace Zombies.Patches
{
	[HarmonyPatch(typeof(DeadBodyInfo))]
	internal class DeadBodyInfoPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void StartPatch(DeadBodyInfo __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Zombies.Logger.LogDebug((object)$"DeadBodyStartPost {((Component)__instance).gameObject.transform.position}");
			for (int i = 0; i < __instance.playerScript.bodyParts.Length; i++)
			{
				Zombies.Logger.LogDebug((object)$"Bodypart {((Object)__instance.bodyParts[i]).name} Position {__instance.bodyParts[i].position}");
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	internal class EnemyAIPatch
	{
		[HarmonyPatch("KillEnemy")]
		[HarmonyPrefix]
		public static void KillEnemyPatch(EnemyAI __instance)
		{
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsHost)
			{
				Zombies.Infection.ReplaceDeadBody(((NetworkBehaviour)__instance).NetworkObject);
			}
		}

		[HarmonyPatch("KillEnemyOnOwnerClient")]
		[HarmonyPostfix]
		private static void KillEnemyOwnerPatch(EnemyAI __instance)
		{
			Zombies.Logger.LogDebug((object)"Enemy Killed OwnerClient");
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatch
	{
		[HarmonyPatch("StartHost")]
		[HarmonyPostfix]
		public static void StartHostPost()
		{
			Zombies.Logger.LogDebug((object)"New Infection Handler Made!");
			Zombies.Infection = new InfectionHandler();
		}

		[HarmonyPatch("StartDisconnect")]
		[HarmonyPostfix]
		public static void StartDisconnectPost()
		{
			if (Zombies.Infection != null)
			{
				Zombies.Infection.Reset();
				Zombies.Infection = null;
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	internal class MaskedPlayerEnemyPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(MaskedPlayerEnemy __instance)
		{
			((EnemyAI)__instance).timeSinceSpawn = 4f;
			((EnemyAI)__instance).creatureAnimator.SetTrigger("HitEnemy");
			Zombies.Logger.LogMessage((object)"Zombies Start Patch MaskedPlayerEnemy");
			((EnemyAI)__instance).SwitchToBehaviourState(0);
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void UpdatePatch(MaskedPlayerEnemy __instance)
		{
			if ((Object)(object)__instance.lastPlayerKilled != (Object)null)
			{
				__instance.lastPlayerKilled = null;
			}
			if (__instance.playersKilled.Count > 0)
			{
				__instance.playersKilled.Clear();
			}
		}

		[HarmonyPatch("KillPlayerAnimationClientRpc")]
		[HarmonyPostfix]
		private static void KillPlayerClientPatch(MaskedPlayerEnemy __instance)
		{
			Zombies.Logger.LogMessage((object)"Added Body to list!");
			Zombies.BodySpawn.AddBody(((EnemyAI)__instance).inSpecialAnimationWithPlayer);
		}

		[HarmonyPatch("CreateMimicClientRpc")]
		[HarmonyPrefix]
		private static void CreateMimicPatch(MaskedPlayerEnemy __instance, NetworkObjectReference netObjectRef, bool inFactory, int playerKilled)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				Zombies.Logger.LogDebug((object)$"Dead From Masked {netObjectRef}, {inFactory}, {playerKilled}");
				if (StartOfRound.Instance.ClientPlayerList.ContainsKey(((EnemyAI)__instance).inSpecialAnimationWithPlayer.actualClientId))
				{
					Zombies.Infection.AddZombie(netObjectRef, StartOfRound.Instance.allPlayerScripts[StartOfRound.Instance.ClientPlayerList[((EnemyAI)__instance).inSpecialAnimationWithPlayer.actualClientId]]);
				}
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	[HarmonyPatch("SetVisibilityOfMaskedEnemy")]
	public static class SetVisPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator, MethodBase method)
		{
			Zombies.Logger.LogDebug((object)"Transpiler fired Vispatch");
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			List<CodeInstruction> collection = BuildInstructionsToInsert(method, generator);
			Zombies.Logger.LogDebug((object)list.Count);
			list.InsertRange(0, collection);
			return list.AsEnumerable();
		}

		private static List<CodeInstruction>? BuildInstructionsToInsert(MethodBase method, ILGenerator ilGen)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			Zombies.Logger.LogDebug((object)"CodeInstructions constructing");
			List<CodeInstruction> list = new List<CodeInstruction>();
			int num = 0;
			Label label = ilGen.DefineLabel();
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num));
			list.Add(new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(MaskedPlayerEnemy), "enemyEnabled")));
			list.Add(new CodeInstruction(OpCodes.Brtrue_S, (object)label));
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num));
			list.Add(new CodeInstruction(OpCodes.Ldc_I4_1, (object)null));
			list.Add(new CodeInstruction(OpCodes.Stfld, (object)AccessTools.Field(typeof(MaskedPlayerEnemy), "enemyEnabled")));
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num));
			list.Add(new CodeInstruction(OpCodes.Ldc_I4_1, (object)null));
			list.Add(new CodeInstruction(OpCodes.Ldc_I4_0, (object)null));
			list.Add(new CodeInstruction(OpCodes.Callvirt, (object)typeof(MaskedPlayerEnemy).GetMethod("EnableEnemyMesh")));
			list.Add(new CodeInstruction(OpCodes.Ret, (object)null));
			list[10].labels.Add(label);
			Zombies.Logger.LogDebug((object)"CodeInstructions Constructed");
			return list;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem))]
	internal class HauntedMaskItemPatch
	{
		[HarmonyPatch("CreateMimicClientRpc")]
		[HarmonyPrefix]
		private static void CreateMimicPatch(NetworkObjectReference netObjectRef, bool inFactory, HauntedMaskItem __instance)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				Zombies.Logger.LogDebug((object)$"Dead From HauntedMask {netObjectRef}, {inFactory}, {__instance.previousPlayerHeldBy.playerClientId}");
				if (StartOfRound.Instance.ClientPlayerList.ContainsKey(__instance.previousPlayerHeldBy.actualClientId))
				{
					Zombies.Infection.AddZombie(netObjectRef, StartOfRound.Instance.allPlayerScripts[StartOfRound.Instance.ClientPlayerList[__instance.previousPlayerHeldBy.actualClientId]]);
				}
			}
		}

		[HarmonyPatch("FinishAttaching")]
		[HarmonyPrefix]
		private static void AttachPatch(HauntedMaskItem __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && !__instance.finishedAttaching && __instance.previousPlayerHeldBy.AllowPlayerDeath())
			{
				Zombies.Logger.LogMessage((object)"Added Body to list!");
				if (StartOfRound.Instance.ClientPlayerList.ContainsKey(__instance.previousPlayerHeldBy.actualClientId))
				{
					Zombies.BodySpawn.AddBody(StartOfRound.Instance.allPlayerScripts[StartOfRound.Instance.ClientPlayerList[__instance.previousPlayerHeldBy.actualClientId]]);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatch
	{
		[HarmonyPatch("KillPlayer")]
		[HarmonyPostfix]
		public static void KillPlayerPostfix(PlayerControllerB __instance, bool spawnBody)
		{
			Zombies.Logger.LogDebug((object)$"SpawnBody {spawnBody}");
			if (spawnBody)
			{
				Zombies.Logger.LogDebug((object)$"ClientID = {__instance.playerClientId}, ActualID = {__instance.actualClientId}");
				Zombies.Networking.SendDeadMessage(__instance.playerClientId, __instance.actualClientId);
			}
		}

		[HarmonyPatch("SpawnDeadBody")]
		[HarmonyPostfix]
		public static void SpawnDeadBodyPatch(PlayerControllerB __instance)
		{
			if (Zombies.GetConverted(__instance))
			{
				__instance.deadBody.DeactivateBody(false);
				Zombies.TryRemoveConverted(__instance);
			}
			Zombies.Logger.LogDebug((object)"Dead Body Spawned");
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	[HarmonyPatch("KillPlayer")]
	public static class PlayerControllerB_KillPlayer_Patch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator, MethodBase method)
		{
			Zombies.Logger.LogDebug((object)"Transpiler fired");
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			List<CodeInstruction> collection = BuildInstructionsToInsert(method, generator);
			Zombies.Logger.LogDebug((object)list.Count);
			list.InsertRange(0, collection);
			return list.AsEnumerable();
		}

		private static List<CodeInstruction>? BuildInstructionsToInsert(MethodBase method, ILGenerator ilGen)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			Zombies.Logger.LogDebug((object)"CodeInstructions constructing");
			List<CodeInstruction> list = new List<CodeInstruction>();
			int num = 0;
			int num2 = 2;
			int num3 = 4;
			Label label = ilGen.DefineLabel();
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num));
			list.Add(new CodeInstruction(OpCodes.Call, (object)typeof(Zombies).GetMethod("GetConverted")));
			list.Add(new CodeInstruction(OpCodes.Brfalse_S, (object)label));
			list.Add(new CodeInstruction(OpCodes.Ldarg, (object)num));
			list.Add(new CodeInstruction(OpCodes.Call, (object)typeof(Zombies).GetMethod("GetConverted")));
			list.Add(new CodeInstruction(OpCodes.Starg_S, (object)num2));
			list.Add(new CodeInstruction(OpCodes.Ldc_I4_0, (object)null));
			list.Add(new CodeInstruction(OpCodes.Starg_S, (object)num3));
			list.Add(new CodeInstruction(OpCodes.Nop, (object)null));
			list[8].labels.Add(label);
			Zombies.Logger.LogDebug((object)"CodeInstructions Constructed");
			return list;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void UpdatePost()
		{
			if ((NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) && Zombies.Infection != null)
			{
				Zombies.Infection.TickThroughRevivals();
				Zombies.Infection.TickThroughBodies();
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void AwakePost()
		{
			Zombies.Logger.LogMessage((object)"StartOfRound Awake!");
			Zombies.ClearConverted();
			Zombies.ClearZombies();
		}

		[HarmonyPatch("ShipHasLeft")]
		[HarmonyPrefix]
		public static void ShipHasLeftPatch()
		{
			if (Zombies.Infection != null)
			{
				Zombies.Infection.Reset();
				Zombies.Infection.ClearInfected();
			}
			Zombies.ClearConverted();
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatch
	{
		[HarmonyPatch("LoadNewLevel")]
		[HarmonyPrefix]
		private static void LoadLevelPatch()
		{
			if (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost)
			{
				Zombies.Infection.RollInstaSpawn();
			}
			if (Zombies.foundMasked)
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				Zombies.Logger.LogDebug((object)((Object)val).name);
				foreach (SpawnableEnemyWithRarity enemy in val.Enemies)
				{
					Zombies.Logger.LogDebug((object)(((Object)enemy.enemyType).name ?? ""));
					if (((Object)enemy.enemyType).name.Contains("MaskedPlayerEnemy"))
					{
						Zombies.foundMasked = true;
						Zombies.Logger.LogDebug((object)("Masked Type Found " + ((Object)enemy.enemyType).name));
						Zombies.maskEnemy = enemy.enemyType;
						break;
					}
				}
				if (Zombies.foundMasked)
				{
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void GetMaskPrefab(ref SelectableLevel[] ___moonsCatalogueList)
		{
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}