Decompiled source of Dio Company v1.0.1

BepInEx/plugins/Dio_Company/Dio_Company.dll

Decompiled 9 hours 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.IgnoreSymbolStoreSequencePoints)]
[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 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_004c: 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);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].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;
				}
				if ((Object)(object)item.creatureAnimator != (Object)null)
				{
					item.creatureAnimator.speed = (frozen ? 0f : 1f);
				}
				AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren<AudioSource>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].mute = frozen;
				}
				VisualEffect[] componentsInChildren2 = ((Component)item).GetComponentsInChildren<VisualEffect>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					componentsInChildren2[i].pause = frozen;
				}
				ParticleSystem[] componentsInChildren3 = ((Component)item).GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val in componentsInChildren3)
				{
					if (frozen)
					{
						val.Pause(true);
					}
					else
					{
						val.Play(true);
					}
				}
			}
		}
	}
	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 == 0L)
			{
				return true;
			}
			return AllowedClientIds.Contains(clientId);
		}
	}
	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);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].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_000f: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
		{
			using Stream stream = Assembly.GetExecutingAssembly().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_0101: 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_0044: 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)
			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();
				PauseEffects.StartPauseEffect(data.CasterPosition);
				ScanPulse.PlayAt(data.CasterPosition);
			}
			else
			{
				PlayerFreeze.RemoveFreeze();
				EnemyFreeze.Unfreeze();
				TurretFreeze.Unfreeze();
				SpikeTrapFreeze.Unfreeze();
				ElevatorFreeze.Unfreeze();
				MineFreeze.Unfreeze();
				PauseEffects.EndPauseEffect();
				DamageQueue.ReplayAndClear();
				MineQueue.ReplayAndClear();
				PlayerDamageQueue.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 = Mathf.Clamp01((Time.unscaledTime - _transitionStart) / 0.6f);
				((VolumeParameter<float>)(object)_colorAdjustments.saturation).value = Mathf.Lerp(_startSaturation, _endSaturation, num);
				((VolumeParameter<float>)(object)_chromaticAberration.intensity).value = Mathf.Lerp(_startAberration, _endAberration, num);
				if (num >= 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)_volume != (Object)null))
			{
				GameObject val = new GameObject("DioCompany_TimeStopVolume");
				Object.DontDestroyOnLoad((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"));
			if (num < 0)
			{
				return null;
			}
			return interfaceMap.TargetMethods[num];
		}

		public static void Enqueue(PlayerControllerB target, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitId)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_006e: 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 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;
			}
		}
	}
	[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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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.");
			_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 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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;
				for (int i = 0; i < renderers.Length; i++)
				{
					renderers[i].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;
				for (int i = 0; i < renderers.Length; i++)
				{
					renderers[i].SetPropertyBlock((MaterialPropertyBlock)null);
				}
				_tinted = false;
			}
		}

		private static Color GetConfiguredColor()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			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 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);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].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))
				{
					if ((Object)(object)item.turretAnimator != (Object)null)
					{
						item.turretAnimator.speed = (frozen ? 0f : 1f);
					}
					AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren<AudioSource>(true);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].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(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_0035: 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(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]
	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"));
			if (num < 0)
			{
				return null;
			}
			return interfaceMap.TargetMethods[num];
		}

		[HarmonyPrefix]
		private static bool Prefix(PlayerControllerB __instance, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID, ref bool __result)
		{
			//IL_000b: 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(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(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);
		}
	}
}