Decompiled source of Dio Company v1.2.3

BepInEx\plugins\Dio_Company\Dio_Company.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DioCompany.Networking;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.VFX;

[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: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 DioCompany
{
	public static class AmbientAudioFreeze
	{
		private static readonly List<AudioSource> Paused = new List<AudioSource>();

		public static void Freeze(ulong casterClientId)
		{
			Transform val = FindCasterRoot(casterClientId);
			AudioSource[] array = Object.FindObjectsOfType<AudioSource>();
			foreach (AudioSource val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.isPlaying && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val)))
				{
					val2.Pause();
					Paused.Add(val2);
				}
			}
		}

		public static void Unfreeze()
		{
			foreach (AudioSource item in Paused)
			{
				if (!((Object)(object)item == (Object)null))
				{
					item.UnPause();
				}
			}
			Paused.Clear();
		}

		private static Transform FindCasterRoot(ulong casterClientId)
		{
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array == null)
			{
				return null;
			}
			PlayerControllerB[] array2 = array;
			foreach (PlayerControllerB val in array2)
			{
				if ((Object)(object)val != (Object)null && val.playerClientId == casterClientId)
				{
					return ((Component)val).transform.root;
				}
			}
			return null;
		}
	}
	public static class CompanyMonsterFreeze
	{
		public static void SetFrozen(bool frozen)
		{
			DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>();
			if ((Object)(object)val == (Object)null || val.monsterAnimations == null)
			{
				return;
			}
			MonsterAnimation[] monsterAnimations = val.monsterAnimations;
			foreach (MonsterAnimation val2 in monsterAnimations)
			{
				if ((Object)(object)val2?.monsterAnimator != (Object)null)
				{
					val2.monsterAnimator.speed = (frozen ? 0f : 1f);
				}
			}
		}
	}
	public static class DamageQueue
	{
		private class Entry
		{
			public EnemyAI Enemy;

			public int Force;

			public Vector3 HitDirection;

			public PlayerControllerB PlayerWhoHit;

			public bool PlayHitSFX;

			public int HitId;
		}

		private static readonly List<Entry> Pending = new List<Entry>();

		public static void Enqueue(EnemyAI enemy, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitId)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Pending.Add(new Entry
			{
				Enemy = enemy,
				Force = force,
				HitDirection = hitDirection,
				PlayerWhoHit = playerWhoHit,
				PlayHitSFX = playHitSFX,
				HitId = hitId
			});
		}

		public static void ReplayAndClear()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (Pending.Count == 0)
			{
				return;
			}
			List<Entry> list = new List<Entry>(Pending);
			Pending.Clear();
			foreach (Entry item in list)
			{
				if (!((Object)(object)item.Enemy == (Object)null))
				{
					item.Enemy.HitEnemyOnLocalClient(item.Force, item.HitDirection, item.PlayerWhoHit, item.PlayHitSFX, item.HitId);
				}
			}
		}
	}
	public static class ElevatorFreeze
	{
		public static void Freeze()
		{
			SetFrozen(frozen: true);
		}

		public static void Unfreeze()
		{
			SetFrozen(frozen: false);
		}

		private static void SetFrozen(bool frozen)
		{
			MineshaftElevatorController val = RoundManager.Instance?.currentMineshaftElevator;
			if (!((Object)(object)val == (Object)null))
			{
				if ((Object)(object)val.elevatorAnimator != (Object)null)
				{
					val.elevatorAnimator.speed = (frozen ? 0f : 1f);
				}
				AudioSource[] componentsInChildren = ((Component)val).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val2 in componentsInChildren)
				{
					val2.mute = frozen;
				}
			}
		}
	}
	public static class EnemyFreeze
	{
		public static void Freeze()
		{
			SetFrozen(frozen: true);
		}

		public static void Unfreeze()
		{
			SetFrozen(frozen: false);
		}

		private static void SetFrozen(bool frozen)
		{
			List<EnemyAI> list = RoundManager.Instance?.SpawnedEnemies;
			if (list == null)
			{
				return;
			}
			foreach (EnemyAI item in list)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				if ((Object)(object)item.agent != (Object)null)
				{
					item.agent.isStopped = frozen;
					item.agent.updateRotation = !frozen;
				}
				if ((Object)(object)item.creatureAnimator != (Object)null)
				{
					item.creatureAnimator.speed = (frozen ? 0f : 1f);
				}
				AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val in componentsInChildren)
				{
					val.mute = frozen;
				}
				VisualEffect[] componentsInChildren2 = ((Component)item).GetComponentsInChildren<VisualEffect>(true);
				foreach (VisualEffect val2 in componentsInChildren2)
				{
					val2.pause = frozen;
				}
				ParticleSystem[] componentsInChildren3 = ((Component)item).GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val3 in componentsInChildren3)
				{
					if (frozen)
					{
						val3.Pause(true);
					}
					else
					{
						val3.Play(true);
					}
				}
			}
		}
	}
	public static class FanFreeze
	{
		private static bool _loggedOnce;

		public static void SetFrozen(bool frozen)
		{
			if (!_loggedOnce)
			{
				_loggedOnce = true;
				LogAllAnimatorNames();
			}
			Animator[] array = Object.FindObjectsOfType<Animator>();
			foreach (Animator val in array)
			{
				if (!((Object)(object)val == (Object)null) && ((Object)((Component)val).gameObject).name.ToLowerInvariant().Contains("fan"))
				{
					val.speed = (frozen ? 0f : 1f);
				}
			}
		}

		private static void LogAllAnimatorNames()
		{
			Animator[] array = Object.FindObjectsOfType<Animator>();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append($"[DioDiag] {array.Length} Animators in scene: ");
			Animator[] array2 = array;
			foreach (Animator val in array2)
			{
				if ((Object)(object)val != (Object)null)
				{
					stringBuilder.Append(((Object)((Component)val).gameObject).name).Append(", ");
				}
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}
	}
	public static class FlameEffectFreeze
	{
		private static readonly string[] NameKeywords = new string[6] { "fire", "flame", "boost", "thruster", "exhaust", "jet" };

		private static readonly string[] SpeedPropertyCandidates = new string[15]
		{
			"_Speed", "_ScrollSpeed", "_FlowSpeed", "_NoiseSpeed", "_AnimSpeed", "_AnimationSpeed", "_TimeScale", "_FireSpeed", "_DistortSpeed", "_DistortionSpeed",
			"_UVSpeed", "_ScrollXSpeed", "_ScrollYSpeed", "_PanSpeed", "_WarpSpeed"
		};

		private static readonly Dictionary<Material, (string property, float originalValue)> FrozenMaterials = new Dictionary<Material, (string, float)>();

		private static readonly List<Renderer> HiddenRenderers = new List<Renderer>();

		private static readonly List<Light> DisabledLights = new List<Light>();

		public static void SetFrozen(bool frozen)
		{
			if (frozen)
			{
				Renderer[] array = Object.FindObjectsOfType<Renderer>(true);
				foreach (Renderer val in array)
				{
					if ((Object)(object)val == (Object)null || !val.enabled || !MatchesKeyword(((Object)((Component)val).gameObject).name))
					{
						continue;
					}
					LogShaderProperties(val);
					bool flag = false;
					Material[] sharedMaterials = val.sharedMaterials;
					foreach (Material val2 in sharedMaterials)
					{
						if ((Object)(object)val2 == (Object)null || FrozenMaterials.ContainsKey(val2))
						{
							continue;
						}
						string[] speedPropertyCandidates = SpeedPropertyCandidates;
						foreach (string text in speedPropertyCandidates)
						{
							if (val2.HasProperty(text))
							{
								FrozenMaterials[val2] = (text, val2.GetFloat(text));
								val2.SetFloat(text, 0f);
								flag = true;
								break;
							}
						}
					}
					if (!flag && !HiddenRenderers.Contains(val))
					{
						val.enabled = false;
						HiddenRenderers.Add(val);
					}
				}
				Light[] array2 = Object.FindObjectsOfType<Light>(true);
				foreach (Light val3 in array2)
				{
					if (!((Object)(object)val3 == (Object)null) && ((Behaviour)val3).enabled && MatchesKeyword(((Object)((Component)val3).gameObject).name))
					{
						((Behaviour)val3).enabled = false;
						DisabledLights.Add(val3);
					}
				}
				return;
			}
			foreach (KeyValuePair<Material, (string, float)> frozenMaterial in FrozenMaterials)
			{
				if ((Object)(object)frozenMaterial.Key != (Object)null)
				{
					frozenMaterial.Key.SetFloat(frozenMaterial.Value.Item1, frozenMaterial.Value.Item2);
				}
			}
			FrozenMaterials.Clear();
			foreach (Renderer hiddenRenderer in HiddenRenderers)
			{
				if ((Object)(object)hiddenRenderer != (Object)null)
				{
					hiddenRenderer.enabled = true;
				}
			}
			HiddenRenderers.Clear();
			foreach (Light disabledLight in DisabledLights)
			{
				if ((Object)(object)disabledLight != (Object)null)
				{
					((Behaviour)disabledLight).enabled = true;
				}
			}
			DisabledLights.Clear();
		}

		private static bool MatchesKeyword(string name)
		{
			string text = name.ToLowerInvariant();
			string[] nameKeywords = NameKeywords;
			foreach (string value in nameKeywords)
			{
				if (text.Contains(value))
				{
					return true;
				}
			}
			return false;
		}

		private static void LogShaderProperties(Renderer renderer)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Invalid comparison between Unknown and I4
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Invalid comparison between Unknown and I4
			Material[] sharedMaterials = renderer.sharedMaterials;
			foreach (Material val in sharedMaterials)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.shader == (Object)null)
				{
					continue;
				}
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("[DioDiag] Renderer '" + ((Object)((Component)renderer).gameObject).name + "' material '" + ((Object)val).name + "' shader '" + ((Object)val.shader).name + "' float properties: ");
				int propertyCount = val.shader.GetPropertyCount();
				for (int j = 0; j < propertyCount; j++)
				{
					if ((int)val.shader.GetPropertyType(j) == 2 || (int)val.shader.GetPropertyType(j) == 3)
					{
						string propertyName = val.shader.GetPropertyName(j);
						stringBuilder.Append(propertyName).Append('=').Append(val.GetFloat(propertyName))
							.Append(", ");
					}
				}
				Plugin.Log.LogInfo((object)stringBuilder.ToString());
			}
		}
	}
	public static class GlobalEffectsFreeze
	{
		private static readonly List<ParticleSystem> PausedParticles = new List<ParticleSystem>();

		private static readonly List<VisualEffect> PausedVfx = new List<VisualEffect>();

		public static void Freeze()
		{
			ParticleSystem[] array = Object.FindObjectsOfType<ParticleSystem>(true);
			foreach (ParticleSystem val in array)
			{
				if (!((Object)(object)val == (Object)null) && val.isPlaying)
				{
					val.Pause(true);
					PausedParticles.Add(val);
				}
			}
			VisualEffect[] array2 = Object.FindObjectsOfType<VisualEffect>(true);
			foreach (VisualEffect val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null) && !val2.pause)
				{
					val2.pause = true;
					PausedVfx.Add(val2);
				}
			}
		}

		public static void Unfreeze()
		{
			foreach (ParticleSystem pausedParticle in PausedParticles)
			{
				if ((Object)(object)pausedParticle != (Object)null)
				{
					pausedParticle.Play(true);
				}
			}
			foreach (VisualEffect item in PausedVfx)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.pause = false;
				}
			}
			PausedParticles.Clear();
			PausedVfx.Clear();
		}
	}
	public static class HostPermissions
	{
		public static readonly HashSet<ulong> AllowedClientIds = new HashSet<ulong>();

		public static bool IsAllowed(ulong clientId)
		{
			if ((Object)(object)NetworkManager.Singleton != (Object)null && clientId == 0)
			{
				return true;
			}
			return AllowedClientIds.Contains(clientId);
		}
	}
	public static class HygrodereFreeze
	{
		private static readonly Dictionary<Material, float> FrozenFrequency = new Dictionary<Material, float>();

		public static void SetFrozen(bool frozen)
		{
			if (frozen)
			{
				BlobAI[] array = Object.FindObjectsOfType<BlobAI>();
				foreach (BlobAI val in array)
				{
					if (!((Object)(object)val == (Object)null) && ((EnemyAI)val).skinnedMeshRenderers != null && ((EnemyAI)val).skinnedMeshRenderers.Length != 0)
					{
						Material material = ((Renderer)((EnemyAI)val).skinnedMeshRenderers[0]).material;
						if (!((Object)(object)material == (Object)null) && !FrozenFrequency.ContainsKey(material) && material.HasProperty("_Frequency"))
						{
							FrozenFrequency[material] = material.GetFloat("_Frequency");
							material.SetFloat("_Frequency", 0f);
						}
					}
				}
				return;
			}
			foreach (KeyValuePair<Material, float> item in FrozenFrequency)
			{
				if ((Object)(object)item.Key != (Object)null)
				{
					item.Key.SetFloat("_Frequency", item.Value);
				}
			}
			FrozenFrequency.Clear();
		}
	}
	public static class ItemPhysicsFreeze
	{
		private static readonly Dictionary<Rigidbody, (Vector3 velocity, Vector3 angularVelocity)> Frozen = new Dictionary<Rigidbody, (Vector3, Vector3)>();

		public static void Freeze()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
			foreach (GrabbableObject val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.propBody == (Object)null) && (!val.isHeld || !((Object)(object)val.playerHeldBy != (Object)null) || val.playerHeldBy.playerClientId != PauseState.CasterClientId) && !val.propBody.isKinematic)
				{
					Frozen[val.propBody] = (val.propBody.velocity, val.propBody.angularVelocity);
					val.propBody.velocity = Vector3.zero;
					val.propBody.angularVelocity = Vector3.zero;
					val.propBody.isKinematic = true;
				}
			}
		}

		public static void Unfreeze()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			foreach (var (val2, tuple2) in Frozen)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.isKinematic = false;
					val2.velocity = tuple2.Item1;
					val2.angularVelocity = tuple2.Item2;
				}
			}
			Frozen.Clear();
		}
	}
	public static class MineFreeze
	{
		public static readonly List<Landmine> Active = new List<Landmine>();

		public static void Freeze()
		{
			SetFrozen(frozen: true);
		}

		public static void Unfreeze()
		{
			SetFrozen(frozen: false);
		}

		private static void SetFrozen(bool frozen)
		{
			foreach (Landmine item in Active)
			{
				if (!((Object)(object)item == (Object)null))
				{
					if ((Object)(object)item.mineAnimator != (Object)null)
					{
						item.mineAnimator.speed = (frozen ? 0f : 1f);
					}
					AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren<AudioSource>(true);
					foreach (AudioSource val in componentsInChildren)
					{
						val.mute = frozen;
					}
				}
			}
		}
	}
	public static class MineQueue
	{
		private static readonly MethodInfo TriggerMethod = AccessTools.Method(typeof(Landmine), "TriggerMineOnLocalClientByExiting", (Type[])null, (Type[])null);

		private static readonly List<Landmine> Pending = new List<Landmine>();

		public static void Enqueue(Landmine mine)
		{
			Pending.Add(mine);
		}

		public static void ReplayAndClear()
		{
			if (Pending.Count == 0)
			{
				return;
			}
			List<Landmine> list = new List<Landmine>(Pending);
			Pending.Clear();
			foreach (Landmine item in list)
			{
				if (!((Object)(object)item == (Object)null))
				{
					TriggerMethod?.Invoke(item, null);
				}
			}
		}
	}
	public static class ModTick
	{
		public static void Tick()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current != null && ((ButtonControl)current[Plugin.PauseKey.Value]).wasPressedThisFrame)
			{
				PauseController.LocalKeyPressed();
			}
			if (PauseState.IsPaused && (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsHost && Time.realtimeSinceStartup >= PauseState.PauseEndsAtRealtime)
			{
				PauseController.ResumeFromHost();
			}
			PauseEffects.Tick();
			PauseAudio.Tick();
			ScanPulse.Tick();
		}
	}
	public static class PauseAudio
	{
		private class PendingLoad
		{
			public UnityWebRequest Request;

			public UnityWebRequestAsyncOperation Operation;

			public Action<AudioClip> OnLoaded;
		}

		private static readonly List<PendingLoad> Pending = new List<PendingLoad>();

		private static AudioClip _pauseClip;

		private static AudioClip _resumeClip;

		private static bool _loadStarted;

		public static void LoadClips()
		{
			if (!_loadStarted)
			{
				_loadStarted = true;
				StartLoad("DioCompany.Resources.pause_sfx.mp3", delegate(AudioClip clip)
				{
					_pauseClip = clip;
				});
				StartLoad("DioCompany.Resources.resume_sfx.mp3", delegate(AudioClip clip)
				{
					_resumeClip = clip;
				});
			}
		}

		public static void Tick()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			if (Pending.Count == 0)
			{
				return;
			}
			for (int num = Pending.Count - 1; num >= 0; num--)
			{
				PendingLoad pendingLoad = Pending[num];
				if (((AsyncOperation)pendingLoad.Operation).isDone)
				{
					if ((int)pendingLoad.Request.result == 1)
					{
						pendingLoad.OnLoaded(DownloadHandlerAudioClip.GetContent(pendingLoad.Request));
					}
					pendingLoad.Request.Dispose();
					Pending.RemoveAt(num);
				}
			}
		}

		public static void PlayPause()
		{
			PlayOneShot(_pauseClip);
		}

		public static void PlayResume()
		{
			PlayOneShot(_resumeClip);
		}

		private static void PlayOneShot(AudioClip clip)
		{
			if (!((Object)(object)clip == (Object)null))
			{
				AudioSource val = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.UIAudio : null);
				if ((Object)(object)val != (Object)null)
				{
					val.PlayOneShot(clip);
				}
			}
		}

		private static void StartLoad(string resourceName, Action<AudioClip> onLoaded)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
			if (stream != null)
			{
				string text = Path.Combine(Path.GetTempPath(), Path.GetFileName(resourceName));
				using (FileStream destination = File.Create(text))
				{
					stream.CopyTo(destination);
				}
				UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip("file://" + text, (AudioType)13);
				UnityWebRequestAsyncOperation operation = audioClip.SendWebRequest();
				Pending.Add(new PendingLoad
				{
					Request = audioClip,
					Operation = operation,
					OnLoaded = onLoaded
				});
			}
		}
	}
	public static class PauseController
	{
		public static void LocalKeyPressed()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (PauseState.IsPaused)
			{
				if (PauseState.CasterClientId == val.playerClientId)
				{
					PauseNetworking.RequestToggle();
				}
			}
			else
			{
				PauseNetworking.RequestToggle();
			}
		}

		public static void HostHandleToggleRequest(ulong senderClientId)
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array != null)
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append($"[DioDiag] HostHandleToggleRequest senderClientId={senderClientId}, IsPaused={PauseState.IsPaused}. Roster: ");
				for (int i = 0; i < array.Length; i++)
				{
					PlayerControllerB val = array[i];
					if (!((Object)(object)val == (Object)null))
					{
						stringBuilder.Append($"[idx={i} name={val.playerUsername} playerClientId={val.playerClientId} isPlayerControlled={val.isPlayerControlled} isOwner={((NetworkBehaviour)val).IsOwner}] ");
					}
				}
				Plugin.Log.LogInfo((object)stringBuilder.ToString());
			}
			if (!PauseState.IsPaused)
			{
				if (HostPermissions.IsAllowed(senderClientId) && (!PauseState.CooldownEndsAtRealtime.TryGetValue(senderClientId, out var value) || !(Time.realtimeSinceStartup < value)))
				{
					PlayerControllerB val2 = FindPlayerByClientId(senderClientId);
					if (!((Object)(object)val2 == (Object)null))
					{
						PauseStateData data = PauseStateData.Paused(senderClientId, ((Component)val2).transform.position, Plugin.PauseTimeLimitSeconds.Value);
						PauseState.PauseEndsAtRealtime = Time.realtimeSinceStartup + data.TimeLimit;
						PauseNetworking.BroadcastState(data);
						ApplyStateChange(data);
					}
				}
			}
			else if (senderClientId == PauseState.CasterClientId)
			{
				ResumeFromHost();
			}
		}

		public static void ResumeFromHost()
		{
			PauseStateData data = PauseStateData.Resumed();
			PauseState.CooldownEndsAtRealtime[PauseState.CasterClientId] = Time.realtimeSinceStartup + Plugin.PauseCooldownSeconds.Value;
			PauseNetworking.BroadcastState(data);
			ApplyStateChange(data);
		}

		public static void ApplyStateChange(PauseStateData data)
		{
			//IL_0093: 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)
			PauseState.IsPaused = data.IsPaused;
			PauseState.CasterClientId = data.CasterClientId;
			if (data.IsPaused)
			{
				PlayerFreeze.ApplyIfNotExempt(data.CasterClientId);
				EnemyFreeze.Freeze();
				TurretFreeze.Freeze();
				SpikeTrapFreeze.Freeze();
				ElevatorFreeze.Freeze();
				MineFreeze.Freeze();
				ItemPhysicsFreeze.Freeze();
				AmbientAudioFreeze.Freeze(data.CasterClientId);
				GlobalEffectsFreeze.Freeze();
				ShipFreeze.SetFrozen(frozen: true);
				CompanyMonsterFreeze.SetFrozen(frozen: true);
				FanFreeze.SetFrozen(frozen: true);
				FlameEffectFreeze.SetFrozen(frozen: true);
				RadMechFreeze.SetFrozen(frozen: true);
				HygrodereFreeze.SetFrozen(frozen: true);
				PauseEffects.StartPauseEffect(data.CasterPosition);
				ScanPulse.PlayAt(data.CasterPosition);
			}
			else
			{
				PlayerFreeze.RemoveFreeze();
				EnemyFreeze.Unfreeze();
				TurretFreeze.Unfreeze();
				SpikeTrapFreeze.Unfreeze();
				ElevatorFreeze.Unfreeze();
				MineFreeze.Unfreeze();
				ItemPhysicsFreeze.Unfreeze();
				AmbientAudioFreeze.Unfreeze();
				GlobalEffectsFreeze.Unfreeze();
				ShipFreeze.SetFrozen(frozen: false);
				CompanyMonsterFreeze.SetFrozen(frozen: false);
				FanFreeze.SetFrozen(frozen: false);
				FlameEffectFreeze.SetFrozen(frozen: false);
				RadMechFreeze.SetFrozen(frozen: false);
				HygrodereFreeze.SetFrozen(frozen: false);
				PauseEffects.EndPauseEffect();
				DamageQueue.ReplayAndClear();
				MineQueue.ReplayAndClear();
				PlayerDamageQueue.ReplayAndClear();
				PlayerKillQueue.ReplayAndClear();
			}
		}

		private static PlayerControllerB FindPlayerByClientId(ulong clientId)
		{
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array == null)
			{
				return null;
			}
			PlayerControllerB[] array2 = array;
			foreach (PlayerControllerB val in array2)
			{
				if ((Object)(object)val != (Object)null && val.playerClientId == clientId)
				{
					return val;
				}
			}
			return null;
		}
	}
	public static class PauseEffects
	{
		private const float TransitionDuration = 0.6f;

		private static Volume _volume;

		private static ChromaticAberration _chromaticAberration;

		private static ColorAdjustments _colorAdjustments;

		private static bool _transitioning;

		private static float _transitionStart;

		private static float _startSaturation;

		private static float _endSaturation;

		private static float _startAberration;

		private static float _endAberration;

		public static void StartPauseEffect(Vector3 casterWorldPosition)
		{
			PauseAudio.PlayPause();
			EnsureVolume();
			BeginTransition(toGrey: true);
		}

		public static void EndPauseEffect()
		{
			PauseAudio.PlayResume();
			EnsureVolume();
			BeginTransition(toGrey: false);
		}

		public static void Tick()
		{
			if (_transitioning)
			{
				float num = Time.unscaledTime - _transitionStart;
				float num2 = Mathf.Clamp01(num / 0.6f);
				((VolumeParameter<float>)(object)_colorAdjustments.saturation).value = Mathf.Lerp(_startSaturation, _endSaturation, num2);
				((VolumeParameter<float>)(object)_chromaticAberration.intensity).value = Mathf.Lerp(_startAberration, _endAberration, num2);
				if (num2 >= 1f)
				{
					_transitioning = false;
				}
			}
		}

		private static void BeginTransition(bool toGrey)
		{
			_transitionStart = Time.unscaledTime;
			_startSaturation = ((VolumeParameter<float>)(object)_colorAdjustments.saturation).value;
			_endSaturation = (toGrey ? (-100f) : 0f);
			_startAberration = ((VolumeParameter<float>)(object)_chromaticAberration.intensity).value;
			_endAberration = (toGrey ? 1f : 0f);
			_transitioning = true;
		}

		private static void EnsureVolume()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (!((Object)(object)_volume != (Object)null))
			{
				GameObject val = new GameObject("DioCompany_TimeStopVolume");
				Object.DontDestroyOnLoad((Object)(object)val);
				_volume = val.AddComponent<Volume>();
				_volume.isGlobal = true;
				_volume.priority = 1000f;
				_volume.weight = 1f;
				VolumeProfile val2 = ScriptableObject.CreateInstance<VolumeProfile>();
				_chromaticAberration = val2.Add<ChromaticAberration>(false);
				((VolumeParameter<float>)(object)_chromaticAberration.intensity).value = 0f;
				((VolumeParameter)_chromaticAberration.intensity).overrideState = true;
				_colorAdjustments = val2.Add<ColorAdjustments>(false);
				((VolumeParameter<float>)(object)_colorAdjustments.saturation).value = 0f;
				((VolumeParameter)_colorAdjustments.saturation).overrideState = true;
				_volume.profile = val2;
				Plugin.Log.LogInfo((object)"[PauseEffects] Created dedicated time-stop Volume.");
			}
		}
	}
	public static class PauseState
	{
		public static bool IsPaused;

		public static ulong CasterClientId;

		public static float PauseEndsAtRealtime;

		public static readonly Dictionary<ulong, float> CooldownEndsAtRealtime = new Dictionary<ulong, float>();
	}
	public static class PlayerDamageQueue
	{
		private class Entry
		{
			public PlayerControllerB Target;

			public int Force;

			public Vector3 HitDirection;

			public PlayerControllerB PlayerWhoHit;

			public bool PlayHitSFX;

			public int HitId;
		}

		private static readonly MethodInfo HitMethod = ResolveHitMethod();

		private static readonly List<Entry> Pending = new List<Entry>();

		private static MethodInfo ResolveHitMethod()
		{
			InterfaceMapping interfaceMap = typeof(PlayerControllerB).GetInterfaceMap(typeof(IHittable));
			int num = Array.IndexOf<MethodInfo>(interfaceMap.InterfaceMethods, typeof(IHittable).GetMethod("Hit"));
			return (num >= 0) ? interfaceMap.TargetMethods[num] : null;
		}

		public static void Enqueue(PlayerControllerB target, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitId)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Pending.Add(new Entry
			{
				Target = target,
				Force = force,
				HitDirection = hitDirection,
				PlayerWhoHit = playerWhoHit,
				PlayHitSFX = playHitSFX,
				HitId = hitId
			});
		}

		public static void ReplayAndClear()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (Pending.Count == 0 || HitMethod == null)
			{
				return;
			}
			List<Entry> list = new List<Entry>(Pending);
			Pending.Clear();
			foreach (Entry item in list)
			{
				if (!((Object)(object)item.Target == (Object)null))
				{
					HitMethod.Invoke(item.Target, new object[5] { item.Force, item.HitDirection, item.PlayerWhoHit, item.PlayHitSFX, item.HitId });
				}
			}
		}
	}
	public static class PlayerFreeze
	{
		public static bool IsLocalPlayerFrozen()
		{
			if (!PauseState.IsPaused)
			{
				return false;
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			return (Object)(object)val != (Object)null && val.playerClientId != PauseState.CasterClientId;
		}

		public static void ApplyIfNotExempt(ulong casterClientId)
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if (!((Object)(object)val == (Object)null) && val.playerClientId != casterClientId)
			{
				val.disableMoveInput = true;
				val.disableLookInput = true;
			}
		}

		public static void RemoveFreeze()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if (!((Object)(object)val == (Object)null))
			{
				val.disableMoveInput = false;
				val.disableLookInput = false;
			}
		}
	}
	public static class PlayerKillQueue
	{
		private class QueuedKill
		{
			public PlayerControllerB Player;

			public Vector3 BodyVelocity;

			public bool SpawnBody;

			public CauseOfDeath CauseOfDeath;

			public int DeathAnimation;

			public Vector3 PositionOffset;

			public bool SetOverrideDropItems;
		}

		private static readonly List<QueuedKill> Queue = new List<QueuedKill>();

		public static void Enqueue(PlayerControllerB player, Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation, Vector3 positionOffset, bool setOverrideDropItems)
		{
			//IL_0013: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			Queue.Add(new QueuedKill
			{
				Player = player,
				BodyVelocity = bodyVelocity,
				SpawnBody = spawnBody,
				CauseOfDeath = causeOfDeath,
				DeathAnimation = deathAnimation,
				PositionOffset = positionOffset,
				SetOverrideDropItems = setOverrideDropItems
			});
		}

		public static void ReplayAndClear()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			List<QueuedKill> list = new List<QueuedKill>(Queue);
			Queue.Clear();
			foreach (QueuedKill item in list)
			{
				if (!((Object)(object)item.Player == (Object)null))
				{
					item.Player.KillPlayer(item.BodyVelocity, item.SpawnBody, item.CauseOfDeath, item.DeathAnimation, item.PositionOffset, item.SetOverrideDropItems);
				}
			}
		}
	}
	[BepInPlugin("com.paul.diocompany.timestop", "Dio Company - Time Stop", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.paul.diocompany.timestop";

		public const string Name = "Dio Company - Time Stop";

		public const string Version = "1.0.0";

		public static ConfigEntry<Key> PauseKey;

		public static ConfigEntry<float> PauseTimeLimitSeconds;

		public static ConfigEntry<float> PauseCooldownSeconds;

		public static ConfigEntry<string> ScanPulseColorHex;

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PauseKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Keybinds", "PauseKey", (Key)24, "Requests a time-stop. Usable by the host, or by anyone the host has granted permission to (host types '/allow PlayerName' or '/deny PlayerName' in chat). Pressing it again while your own time-stop is active resumes it early.");
			PauseTimeLimitSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PauseTimeLimitSeconds", 30f, "Maximum duration, in seconds, a time-stop lasts before automatically resuming.");
			PauseCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PauseCooldownSeconds", 5f, "How long, in seconds, a given player must wait after ending their own time-stop before starting another. Per-player -- doesn't affect anyone else's cooldown.");
			ScanPulseColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Effects", "ScanPulseColorHex", "#FF33D9", "Hex color (e.g. #FF33D9) for the scan-pulse flash on time-stop cast. This is purely a local display preference -- it only changes what YOU see, regardless of who casts it.");
			((BaseUnityPlugin)this).Config.Remove(new ConfigDefinition("Keybinds", "PermissionMenuKey"));
			_harmony = new Harmony("com.paul.diocompany.timestop");
			_harmony.PatchAll();
			PauseNetworking.Init();
			PauseAudio.LoadClips();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Dio Company - Time Stop v1.0.0 loaded.");
		}
	}
	public static class RadMechFreeze
	{
		private static readonly List<ParticleSystem> Stopped = new List<ParticleSystem>();

		public static void SetFrozen(bool frozen)
		{
			if (frozen)
			{
				RadMechAI[] array = Object.FindObjectsOfType<RadMechAI>();
				foreach (RadMechAI val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						TryStop(val.rightFootParticle);
						TryStop(val.leftFootParticle);
						TryStop(val.bothFeetParticle);
						TryStop(val.smokeRightLeg);
						TryStop(val.smokeLeftLeg);
						TryStop(val.gunArmParticle);
						TryStop(val.chargeParticle);
						TryStop(val.blowtorchParticle);
					}
				}
				return;
			}
			foreach (ParticleSystem item in Stopped)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.Play(true);
				}
			}
			Stopped.Clear();
		}

		private static void TryStop(ParticleSystem particle)
		{
			if (!((Object)(object)particle == (Object)null) && particle.isPlaying)
			{
				particle.Stop(true, (ParticleSystemStopBehavior)0);
				Stopped.Add(particle);
			}
		}
	}
	public static class ScanPulse
	{
		private const float PulseLifetime = 1.5f;

		private static readonly Color DefaultPulseColor = new Color(1f, 0.2f, 0.85f, 1f);

		private static readonly int[] ColorPropertyIds = new int[4]
		{
			Shader.PropertyToID("_Color"),
			Shader.PropertyToID("_BaseColor"),
			Shader.PropertyToID("_TintColor"),
			Shader.PropertyToID("_EmissionColor")
		};

		private static Renderer[] _renderers;

		private static bool _tinted;

		private static float _untintAtRealtime;

		public static void PlayAt(Vector3 worldPosition)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			Animator val = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.scanEffectAnimator : null);
			if (!((Object)(object)val == (Object)null))
			{
				if (_renderers == null)
				{
					_renderers = ((Component)val).GetComponentsInChildren<Renderer>(true);
				}
				MaterialPropertyBlock val2 = new MaterialPropertyBlock();
				Color configuredColor = GetConfiguredColor();
				int[] colorPropertyIds = ColorPropertyIds;
				foreach (int num in colorPropertyIds)
				{
					val2.SetColor(num, configuredColor);
				}
				Renderer[] renderers = _renderers;
				foreach (Renderer val3 in renderers)
				{
					val3.SetPropertyBlock(val2);
				}
				((Component)val).transform.position = worldPosition;
				val.SetTrigger("scan");
				_tinted = true;
				_untintAtRealtime = Time.realtimeSinceStartup + 1.5f;
			}
		}

		public static void Tick()
		{
			if (_tinted && !(Time.realtimeSinceStartup < _untintAtRealtime))
			{
				Renderer[] renderers = _renderers;
				foreach (Renderer val in renderers)
				{
					val.SetPropertyBlock((MaterialPropertyBlock)null);
				}
				_tinted = false;
			}
		}

		private static Color GetConfiguredColor()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			string value = Plugin.ScanPulseColorHex.Value;
			Color result = default(Color);
			if (!string.IsNullOrEmpty(value) && ColorUtility.TryParseHtmlString(value, ref result))
			{
				return result;
			}
			return DefaultPulseColor;
		}
	}
	public static class ShipFreeze
	{
		public static void SetFrozen(bool frozen)
		{
			StartOfRound instance = StartOfRound.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				if ((Object)(object)instance.shipAnimator != (Object)null)
				{
					instance.shipAnimator.speed = (frozen ? 0f : 1f);
				}
				if ((Object)(object)instance.shipDoorsAnimator != (Object)null)
				{
					instance.shipDoorsAnimator.speed = (frozen ? 0f : 1f);
				}
				ItemDropship val = Object.FindObjectOfType<ItemDropship>();
				if ((Object)(object)val != (Object)null && (Object)(object)val.shipAnimator != (Object)null)
				{
					val.shipAnimator.speed = (frozen ? 0f : 1f);
				}
			}
		}
	}
	public static class SpikeTrapFreeze
	{
		public static readonly List<SpikeRoofTrap> Active = new List<SpikeRoofTrap>();

		public static void Freeze()
		{
			SetFrozen(frozen: true);
		}

		public static void Unfreeze()
		{
			SetFrozen(frozen: false);
		}

		private static void SetFrozen(bool frozen)
		{
			foreach (SpikeRoofTrap item in Active)
			{
				if (!((Object)(object)item == (Object)null))
				{
					if ((Object)(object)item.spikeTrapAnimator != (Object)null)
					{
						item.spikeTrapAnimator.speed = (frozen ? 0f : 1f);
					}
					AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren<AudioSource>(true);
					foreach (AudioSource val in componentsInChildren)
					{
						val.mute = frozen;
					}
				}
			}
		}
	}
	public static class TurretFreeze
	{
		public static readonly List<Turret> Active = new List<Turret>();

		public static void Freeze()
		{
			SetFrozen(frozen: true);
		}

		public static void Unfreeze()
		{
			SetFrozen(frozen: false);
		}

		private static void SetFrozen(bool frozen)
		{
			foreach (Turret item in Active)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				if ((Object)(object)item.turretAnimator != (Object)null)
				{
					item.turretAnimator.speed = (frozen ? 0f : 1f);
				}
				if ((Object)(object)item.bulletParticles != (Object)null)
				{
					if (frozen)
					{
						item.bulletParticles.Pause(true);
					}
					else
					{
						item.bulletParticles.Play(true);
					}
				}
				AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val in componentsInChildren)
				{
					val.mute = frozen;
				}
			}
		}
	}
}
namespace DioCompany.Patches
{
	[HarmonyPatch(typeof(HUDManager), "AddTextToChatOnServer")]
	public static class ChatCommandPatch
	{
		private const string AllowPrefix = "/allow ";

		private const string DenyPrefix = "/deny ";

		[HarmonyPrefix]
		private static bool Prefix(string chatMessage)
		{
			if (chatMessage == null)
			{
				return true;
			}
			bool allow;
			string targetName;
			if (chatMessage.StartsWith("/allow ", StringComparison.OrdinalIgnoreCase))
			{
				allow = true;
				targetName = chatMessage.Substring("/allow ".Length).Trim();
			}
			else
			{
				if (!chatMessage.StartsWith("/deny ", StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				allow = false;
				targetName = chatMessage.Substring("/deny ".Length).Trim();
			}
			HandleCommand(allow, targetName);
			return false;
		}

		private static void HandleCommand(bool allow, string targetName)
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsHost)
			{
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.DisplayTip("Time Stop", "Only the host can grant time-stop permission.", true, false, "LC_Tip1");
				}
				return;
			}
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array == null)
			{
				return;
			}
			PlayerControllerB[] array2 = array;
			foreach (PlayerControllerB val in array2)
			{
				if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && string.Equals(val.playerUsername, targetName, StringComparison.OrdinalIgnoreCase))
				{
					if (allow)
					{
						HostPermissions.AllowedClientIds.Add(val.playerClientId);
					}
					else
					{
						HostPermissions.AllowedClientIds.Remove(val.playerClientId);
					}
					HUDManager instance2 = HUDManager.Instance;
					if (instance2 != null)
					{
						instance2.DisplayTip("Time Stop", allow ? (val.playerUsername + " can now use time-stop.") : (val.playerUsername + "'s time-stop permission was revoked."), false, false, "LC_Tip1");
					}
					return;
				}
			}
			HUDManager instance3 = HUDManager.Instance;
			if (instance3 != null)
			{
				instance3.DisplayTip("Time Stop", "No connected player found named '" + targetName + "'.", true, false, "LC_Tip1");
			}
		}
	}
	[HarmonyPatch(typeof(DepositItemsDesk), "Update")]
	public static class CompanyMonsterFreezePatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch(typeof(MineshaftElevatorController))]
	public static class ElevatorFreezePatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool UpdatePrefix()
		{
			return !PauseState.IsPaused;
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		private static bool LateUpdatePrefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch]
	public static class EnemyContactPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type[] types = typeof(EnemyAI).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (typeof(EnemyAI).IsAssignableFrom(type))
				{
					MethodInfo method = type.GetMethod("OnCollideWithPlayer", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (method != null)
					{
						yield return method;
					}
				}
			}
		}

		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "HitEnemyOnLocalClient")]
	public static class EnemyDamagePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyAI __instance, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!PauseState.IsPaused)
			{
				return true;
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null || val.playerClientId != PauseState.CasterClientId)
			{
				return true;
			}
			DamageQueue.Enqueue(__instance, force, hitDirection, playerWhoHit, playHitSFX, hitID);
			return false;
		}
	}
	[HarmonyPatch]
	public static class EnemyLogicFreezePatch
	{
		private static readonly string[] MethodNames = new string[3] { "Update", "FixedUpdate", "LateUpdate" };

		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type[] types = typeof(EnemyAI).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (!typeof(EnemyAI).IsAssignableFrom(type))
				{
					continue;
				}
				string[] methodNames = MethodNames;
				foreach (string name in methodNames)
				{
					MethodInfo method = type.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (method != null)
					{
						yield return method;
					}
				}
			}
		}

		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch(typeof(ItemDropship), "Update")]
	public static class ItemDropshipFreezePatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch]
	public static class ItemFreezePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type[] types = typeof(GrabbableObject).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (typeof(GrabbableObject).IsAssignableFrom(type))
				{
					MethodInfo method = type.GetMethod("Update", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (method != null)
					{
						yield return method;
					}
				}
			}
		}

		[HarmonyPrefix]
		private static bool Prefix(GrabbableObject __instance)
		{
			if (!PauseState.IsPaused)
			{
				return true;
			}
			if (__instance.isHeld && (Object)(object)__instance.playerHeldBy != (Object)null && __instance.playerHeldBy.playerClientId == PauseState.CasterClientId)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Landmine), "TriggerMineOnLocalClientByExiting")]
	public static class MinePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Landmine __instance)
		{
			if (!PauseState.IsPaused)
			{
				return true;
			}
			MineQueue.Enqueue(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(Landmine), "Start")]
	public static class MineRegistrationPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Landmine __instance)
		{
			if (!MineFreeze.Active.Contains(__instance))
			{
				MineFreeze.Active.Add(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "Update")]
	public static class PlayerUpdateFullFreezePatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PlayerFreeze.IsLocalPlayerFrozen();
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
	public static class PlayerLateUpdateFullFreezePatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PlayerFreeze.IsLocalPlayerFrozen();
		}
	}
	[HarmonyPatch]
	public static class PlayerHitPatch
	{
		private static MethodBase TargetMethod()
		{
			InterfaceMapping interfaceMap = typeof(PlayerControllerB).GetInterfaceMap(typeof(IHittable));
			int num = Array.IndexOf<MethodInfo>(interfaceMap.InterfaceMethods, typeof(IHittable).GetMethod("Hit"));
			return (num >= 0) ? interfaceMap.TargetMethods[num] : null;
		}

		[HarmonyPrefix]
		private static bool Prefix(PlayerControllerB __instance, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID, ref bool __result)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!PauseState.IsPaused)
			{
				return true;
			}
			PlayerDamageQueue.Enqueue(__instance, force, hitDirection, playerWhoHit, playHitSFX, hitID);
			__result = true;
			return false;
		}
	}
	[HarmonyPatch]
	public static class PlayerInputFreezePatch
	{
		private static readonly HashSet<string> Excluded = new HashSet<string> { "OpenMenu_performed" };

		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(PlayerControllerB).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo method in methods)
			{
				if (!Excluded.Contains(method.Name) && (method.Name.EndsWith("_performed") || method.Name.EndsWith("_started") || method.Name.EndsWith("_canceled")))
				{
					yield return method;
				}
			}
		}

		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PlayerFreeze.IsLocalPlayerFrozen();
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
	public static class PlayerKillDeferPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PlayerControllerB __instance, Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation, Vector3 positionOffset, bool setOverrideDropItems)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!PauseState.IsPaused)
			{
				return true;
			}
			if (__instance.playerClientId == PauseState.CasterClientId)
			{
				return true;
			}
			PlayerKillQueue.Enqueue(__instance, bodyVelocity, spawnBody, causeOfDeath, deathAnimation, positionOffset, setOverrideDropItems);
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "Update")]
	public static class PlayerTickPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerControllerB __instance)
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if (!((Object)(object)val == (Object)null) && !((Object)(object)__instance != (Object)(object)val))
			{
				ModTick.Tick();
			}
		}
	}
	[HarmonyPatch(typeof(RadMechMissile), "FixedUpdate")]
	public static class RadMechMissileFreezePatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch(typeof(SpikeRoofTrap))]
	public static class SpikeTrapFreezePatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool UpdatePrefix()
		{
			return !PauseState.IsPaused;
		}

		[HarmonyPatch("OnTriggerStay")]
		[HarmonyPrefix]
		private static bool OnTriggerStayPrefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch(typeof(SpikeRoofTrap), "Start")]
	public static class SpikeTrapRegistrationPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SpikeRoofTrap __instance)
		{
			if (!SpikeTrapFreeze.Active.Contains(__instance))
			{
				SpikeTrapFreeze.Active.Add(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(TimeOfDay), "MoveTimeOfDay")]
	public static class TimeOfDayPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch(typeof(Turret), "Update")]
	public static class TurretFreezePatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !PauseState.IsPaused;
		}
	}
	[HarmonyPatch(typeof(Turret), "Start")]
	public static class TurretRegistrationPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Turret __instance)
		{
			if (!TurretFreeze.Active.Contains(__instance))
			{
				TurretFreeze.Active.Add(__instance);
			}
		}
	}
}
namespace DioCompany.Networking
{
	[Serializable]
	public struct PauseStateData
	{
		public bool IsPaused;

		public ulong CasterClientId;

		public float CasterPosX;

		public float CasterPosY;

		public float CasterPosZ;

		public float TimeLimit;

		public Vector3 CasterPosition => new Vector3(CasterPosX, CasterPosY, CasterPosZ);

		public static PauseStateData Paused(ulong casterClientId, Vector3 casterPosition, float timeLimit)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			return new PauseStateData
			{
				IsPaused = true,
				CasterClientId = casterClientId,
				CasterPosX = casterPosition.x,
				CasterPosY = casterPosition.y,
				CasterPosZ = casterPosition.z,
				TimeLimit = timeLimit
			};
		}

		public static PauseStateData Resumed()
		{
			return new PauseStateData
			{
				IsPaused = false
			};
		}
	}
	public static class PauseNetworking
	{
		private static LNetworkMessage<bool> _toggleRequest;

		private static LNetworkMessage<PauseStateData> _stateChanged;

		private static bool _initialized;

		public static void Init()
		{
			if (!_initialized)
			{
				_initialized = true;
				_toggleRequest = LNetworkMessage<bool>.Connect("ToggleRequest", (Action<bool, ulong>)delegate(bool _, ulong senderClientId)
				{
					PauseController.HostHandleToggleRequest(senderClientId);
				}, (Action<bool>)null, (Action<bool, ulong>)null);
				_stateChanged = LNetworkMessage<PauseStateData>.Connect("PauseStateChanged", (Action<PauseStateData, ulong>)null, (Action<PauseStateData>)PauseController.ApplyStateChange, (Action<PauseStateData, ulong>)null);
			}
		}

		public static void RequestToggle()
		{
			_toggleRequest.SendServer(true);
		}

		public static void BroadcastState(PauseStateData data)
		{
			_stateChanged.SendClients(data);
		}
	}
}