Decompiled source of MonsterHotkeys v3.2.0

BepInEx/plugins/com.github.zehsteam.MonsterHotkeys.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepinControl;
using ControlValley;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Steamworks;
using TMPro;
using TwitchChatAPI;
using TwitchChatAPI.Enums;
using TwitchChatAPI.Objects;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using Zeekerss.Core.Singletons;
using com.github.zehsteam.ImmersiveEntrance.MonoBehaviours;
using com.github.zehsteam.MonsterHotkeys.Dependencies;
using com.github.zehsteam.MonsterHotkeys.Dependencies.CrowdControlMod;
using com.github.zehsteam.MonsterHotkeys.Dependencies.CrowdControlMod.Patches;
using com.github.zehsteam.MonsterHotkeys.Dependencies.ImmersiveEntranceMod;
using com.github.zehsteam.MonsterHotkeys.Enums;
using com.github.zehsteam.MonsterHotkeys.Extensions;
using com.github.zehsteam.MonsterHotkeys.Helpers;
using com.github.zehsteam.MonsterHotkeys.Managers;
using com.github.zehsteam.MonsterHotkeys.MonoBehaviours;
using com.github.zehsteam.MonsterHotkeys.MonoBehaviours.Audio;
using com.github.zehsteam.MonsterHotkeys.MonoBehaviours.UI;
using com.github.zehsteam.MonsterHotkeys.MonoBehaviours.Utils;
using com.github.zehsteam.MonsterHotkeys.NetcodePatcher;
using com.github.zehsteam.MonsterHotkeys.Objects;
using com.github.zehsteam.MonsterHotkeys.Objects.Enemies;
using com.github.zehsteam.MonsterHotkeys.Objects.Network;
using com.github.zehsteam.MonsterHotkeys.Patches;
using com.github.zehsteam.MonsterHotkeys.Twitch;
using com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands;
using com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Developer;
using com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Moderator;
using com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Public;
using com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Special;
using com.github.zehsteam.MonsterHotkeys.Twitch.Managers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Zehs")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2026 Zehs")]
[assembly: AssemblyDescription("Let Twitch chat spawn monsters with subs, bits, raids, and spawn points. Highly configurable, easy to use, no extension or app needed. (Twitch and CrowdControl integration)")]
[assembly: AssemblyFileVersion("3.2.0.0")]
[assembly: AssemblyInformationalVersion("3.2.0+4bae85c51a3e8f63a1762b26436a14cfccb9ca8f")]
[assembly: AssemblyProduct("MonsterHotkeys")]
[assembly: AssemblyTitle("com.github.zehsteam.MonsterHotkeys")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Count;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Count;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Count;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyList(List<T> items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return _items.Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		_items.CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return _items.IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace com.github.zehsteam.MonsterHotkeys
{
	internal static class Assets
	{
		public static readonly string AssetBundleFileName = "monsterhotkeys_assets";

		public static AssetBundle AssetBundle { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static GameObject PluginNetworkHandlerPrefab { get; private set; }

		public static GameObject PluginHUDPrefab { get; private set; }

		public static EnemyDatabase EnemyDatabase { get; private set; }

		public static void Load()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = Path.Combine(directoryName, AssetBundleFileName);
			if (!File.Exists(text))
			{
				Logger.LogFatal("Failed to load assets. AssetBundle file could not be found at path \"" + text + "\". Make sure the \"" + AssetBundleFileName + "\" file is in the same folder as the mod's DLL file.");
			}
			else
			{
				AssetBundle = AssetBundle.LoadFromFile(text);
				if ((Object)(object)AssetBundle == (Object)null)
				{
					Logger.LogFatal("Failed to load assets. AssetBundle is null.");
					return;
				}
				OnAssetBundleLoaded(AssetBundle);
				IsLoaded = true;
			}
		}

		private static void OnAssetBundleLoaded(AssetBundle assetBundle)
		{
			PluginNetworkHandlerPrefab = LoadAsset<GameObject>("PluginNetworkHandler", assetBundle);
			PluginHUDPrefab = LoadAsset<GameObject>("PluginHUD", assetBundle);
			EnemyDatabase = LoadAsset<EnemyDatabase>("EnemyDatabase", assetBundle);
		}

		private static T LoadAsset<T>(string name, AssetBundle assetBundle) where T : Object
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace.");
				return default(T);
			}
			if ((Object)(object)assetBundle == (Object)null)
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null.");
				return default(T);
			}
			T val = assetBundle.LoadAsset<T>(name);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name.");
				return default(T);
			}
			return val;
		}

		private static bool TryLoadAsset<T>(string name, AssetBundle assetBundle, out T asset) where T : Object
		{
			asset = LoadAsset<T>(name, assetBundle);
			return (Object)(object)asset != (Object)null;
		}
	}
	internal class HotkeyInputClass : LcInputActions
	{
		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction MonsterPrefixKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction PlushiePrefixKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnRandomKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnBaboonHawkKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnBarberKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnBlobKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnBrackenKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnBunkerSpiderKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnButlerKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnCoilHeadKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnEarthLeviathanKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnEyelessDogKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnForestGiantKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnGhostGirlKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnHoardingBugKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnJesterKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnKidnapperFoxKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnManeaterKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnManticoilKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnMaskedKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnNutcrackerKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnOldBirdKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnSnareFleaKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnSporeLizardKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnThumperKey { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SpawnTulipSnakeKey { get; set; }
	}
	public static class HotkeyListener
	{
		public static bool DisableHotkeys;

		public static bool IsMonsterPrefixKeyPressed => Plugin.InputActionsInstance.MonsterPrefixKey.IsPressed();

		public static bool IsPlushiePrefixKeyPressed => Plugin.InputActionsInstance.PlushiePrefixKey.IsPressed();

		internal static void SetupKeybindCallbacks()
		{
			Plugin.InputActionsInstance.SpawnRandomKey.performed += OnSpawnRandomKeyPressed;
			Plugin.InputActionsInstance.SpawnBaboonHawkKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnBarberKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnBlobKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnBrackenKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnBunkerSpiderKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnButlerKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnCoilHeadKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnEarthLeviathanKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnEyelessDogKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnForestGiantKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnGhostGirlKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnHoardingBugKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnJesterKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnKidnapperFoxKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnManeaterKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnManticoilKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnMaskedKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnNutcrackerKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnOldBirdKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnSnareFleaKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnSporeLizardKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnThumperKey.performed += OnSpawnKeyPressed;
			Plugin.InputActionsInstance.SpawnTulipSnakeKey.performed += OnSpawnKeyPressed;
			Logger.LogInfo("Setup keybind callbacks.");
		}

		private static void OnSpawnKeyPressed(CallbackContext context)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (!((CallbackContext)(ref context)).performed || !CanPerformHotkeys())
			{
				return;
			}
			string name = ((CallbackContext)(ref context)).action.name;
			Logger.LogInfo(name + " key pressed.", extended: true);
			if (DisableHotkeys && (IsMonsterPrefixKeyPressed || IsPlushiePrefixKeyPressed))
			{
				MessageManger instance = MessageManger.Instance;
				if (instance != null)
				{
					Color? color = Color.red;
					instance.ShowMessage_LocalClient("Hotkeys have been disabled by another mod", new MessageSettings(null, color));
				}
				Logger.LogInfo("Hotkeys have been disabled by another mod.");
				return;
			}
			string name2 = name.Replace("Spawn", "").Replace("Key", "");
			if (!Assets.EnemyDatabase.TryGetDataByName(name2, out var enemyData))
			{
				Logger.LogError("Failed to find EnemyData from key name \"" + name + "\"");
				return;
			}
			if (Plugin.InputActionsInstance.MonsterPrefixKey.IsPressed())
			{
				EnemyHelper.SpawnEnemy(enemyData);
			}
			if (Plugin.InputActionsInstance.PlushiePrefixKey.IsPressed())
			{
				PlushieManager.Instance.SpawnPlushies(enemyData.Name, PlayerUtils.LocalPlayerScript);
			}
		}

		private static void OnSpawnRandomKeyPressed(CallbackContext context)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!((CallbackContext)(ref context)).performed || !CanPerformHotkeys())
			{
				return;
			}
			Logger.LogInfo(((CallbackContext)(ref context)).action.name + " key pressed.", extended: true);
			if (DisableHotkeys && (IsMonsterPrefixKeyPressed || IsPlushiePrefixKeyPressed))
			{
				MessageManger instance = MessageManger.Instance;
				if (instance != null)
				{
					Color? color = Color.red;
					instance.ShowMessage_LocalClient("Hotkeys have been disabled by another mod", new MessageSettings(null, color));
				}
				Logger.LogInfo("Hotkeys have been disabled by another mod.");
			}
			else
			{
				if (IsMonsterPrefixKeyPressed)
				{
					EnemyHelper.SpawnRandomEnemy();
				}
				if (IsPlushiePrefixKeyPressed)
				{
					PlushieManager.Instance?.SpawnRandomPlushies(PlayerUtils.LocalPlayerScript);
				}
			}
		}

		public static bool CanPerformHotkeys()
		{
			PlayerControllerB localPlayerScript = PlayerUtils.LocalPlayerScript;
			if ((Object)(object)localPlayerScript == (Object)null)
			{
				return false;
			}
			if (localPlayerScript.isPlayerDead)
			{
				return false;
			}
			if (localPlayerScript.isTypingChat)
			{
				return false;
			}
			if (localPlayerScript.quickMenuManager.isMenuOpen)
			{
				return false;
			}
			return true;
		}
	}
	internal static class Logger
	{
		public static ManualLogSource ManualLogSource { get; private set; }

		public static bool IsExtendedLoggingEnabled => ConfigManager.Misc_ExtendedLogging?.Value ?? false;

		public static void Initialize(ManualLogSource manualLogSource)
		{
			ManualLogSource = manualLogSource;
		}

		public static void LogDebug(object data)
		{
			Log((LogLevel)32, data);
		}

		public static void LogInfo(object data, bool extended = false)
		{
			Log((LogLevel)16, data, extended);
		}

		public static void LogMessage(object data, bool extended = false)
		{
			Log((LogLevel)8, data, extended);
		}

		public static void LogWarning(object data, bool extended = false)
		{
			Log((LogLevel)4, data, extended);
		}

		public static void LogError(object data, bool extended = false)
		{
			Log((LogLevel)2, data, extended);
		}

		public static void LogFatal(object data, bool extended = false)
		{
			Log((LogLevel)1, data, extended);
		}

		public static void Log(LogLevel logLevel, object data, bool extended = false)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!extended || IsExtendedLoggingEnabled)
			{
				ManualLogSource manualLogSource = ManualLogSource;
				if (manualLogSource != null)
				{
					manualLogSource.Log(logLevel, data);
				}
			}
		}
	}
	[BepInPlugin("com.github.zehsteam.MonsterHotkeys", "MonsterHotkeys", "3.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.zehsteam.MonsterHotkeys");

		internal static Plugin Instance { get; private set; }

		internal static HotkeyInputClass InputActionsInstance { get; private set; }

		internal static JsonSave GlobalSave { get; private set; }

		internal static JsonSave LocalSave { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.MonsterHotkeys"));
			Logger.LogInfo("MonsterHotkeys has awoken!");
			((Object)this).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)this);
			_harmony.PatchAll(typeof(GameNetworkManager_Patches));
			_harmony.PatchAll(typeof(StartOfRound_Patches));
			_harmony.PatchAll(typeof(RoundManager_Patches));
			_harmony.PatchAll(typeof(HUDManager_Patches));
			_harmony.PatchAll(typeof(EnemyAI_Patches));
			_harmony.PatchAll(typeof(RadMechAI_Patches));
			_harmony.PatchAll(typeof(ButlerEnemyAI_Patches));
			_harmony.PatchAll(typeof(Landmine_Patches));
			if (CrowdControlProxy.IsInstalled)
			{
				CrowdControlProxy.PatchAll(_harmony);
			}
			GlobalSave = new JsonSave(Utils.GetPluginPersistentDataPath(), "GlobalSave");
			LocalSave = new JsonSave(Paths.ConfigPath, "MonsterHotkeys_Save.json");
			Assets.Load();
			ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
			InputActionsInstance = new HotkeyInputClass();
			HotkeyListener.SetupKeybindCallbacks();
			TwitchIntegrationManager.Initialize();
			NetworkUtils.NetcodePatcherAwake();
			PluginHelper.OnStart = (Action)Delegate.Combine(PluginHelper.OnStart, (Action)delegate
			{
				PlayerDamagePatcher.PatchAll(_harmony);
			});
			PluginHelper.Spawn();
		}

		private void Start()
		{
			PlayerDamagePatcher.PatchAll(_harmony);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.zehsteam.MonsterHotkeys";

		public const string PLUGIN_NAME = "MonsterHotkeys";

		public const string PLUGIN_VERSION = "3.2.0";
	}
}
namespace com.github.zehsteam.MonsterHotkeys.Twitch
{
	internal static class TwitchIntegrationManager
	{
		public static bool IsEnabled => ConfigManager.TwitchIntegration_Enabled.Value;

		public static bool IsCheerEventEnabled
		{
			get
			{
				if (IsEnabled)
				{
					return ConfigManager.TwitchCheerEvent_Enabled.Value;
				}
				return false;
			}
		}

		public static bool IsSubEventEnabled
		{
			get
			{
				if (IsEnabled)
				{
					return ConfigManager.TwitchSubEvent_Enabled.Value;
				}
				return false;
			}
		}

		public static bool IsRaidEventEnabled
		{
			get
			{
				if (IsEnabled)
				{
					return ConfigManager.TwitchRaidEvent_Enabled.Value;
				}
				return false;
			}
		}

		public static string[] TwitchBotUsernames { get; private set; } = new string[24]
		{
			"streamelements", "nightbot", "sery_bot", "wizebot", "kofistreambot", "botrixoficial", "tangiabot", "moobot", "fyow", "creatisbot",
			"frostytoolsdotcom", "own3d", "streamlabs", "pokemoncommunitygame", "fossabot", "lurxx", "blerp", "streamstickers", "wzbot", "botbandera",
			"soundalerts", "overlayexpert", "trackerggbot", "lumiastream"
		};


		public static void Initialize()
		{
			TwitchEventHandler.Initialize();
			TwitchEventQueue.Initialize();
			AccumulatedBitManger.Initialize();
			SpawnPointManager.Initialize();
			TwitchCommandManager.Initialize();
		}

		public static void OnDayEnded()
		{
			SpawnPointManager.OnDayEnded();
		}

		public static void OnLocalDisconnect()
		{
			SpawnPointManager.OnLocalDisconnect();
		}

		public static bool IsBotUser(TwitchUser twitchUser)
		{
			return TwitchBotUsernames.Contains(((TwitchUser)(ref twitchUser)).Username);
		}
	}
}
namespace com.github.zehsteam.MonsterHotkeys.Twitch.Managers
{
	internal static class AccumulatedBitManger
	{
		private static Dictionary<string, int> _accumulatedBits = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

		public static IReadOnlyDictionary<string, int> AccumulatedBits => _accumulatedBits;

		public static void Initialize()
		{
			LoadData();
			Application.quitting += SaveData;
		}

		private static void LoadData()
		{
			try
			{
				if (Plugin.GlobalSave.TryLoad<string>("AccumulatedBits", out var value))
				{
					Logger.LogInfo("[AccumulatedBitManger] Loaded JSON data:\n\n" + value, extended: true);
					_accumulatedBits = JsonConvert.DeserializeObject<Dictionary<string, int>>(value);
				}
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] Failed to load JSON data: {1}", "AccumulatedBitManger", arg));
			}
		}

		private static void SaveData()
		{
			if (Plugin.GlobalSave.Save("AccumulatedBits", JsonConvert.SerializeObject((object)_accumulatedBits)))
			{
				Logger.LogInfo("[AccumulatedBitManger] Saved JSON data.", extended: true);
			}
			else
			{
				Logger.LogError("[AccumulatedBitManger] Failed to save JSON data.");
			}
		}

		public static int Get(string username)
		{
			return _accumulatedBits.GetValueOrDefault(username.ToLower(), 0);
		}

		public static int Get(ViewerData viewer)
		{
			if (viewer == null)
			{
				return 0;
			}
			return Get(viewer.Username);
		}

		public static void Set(string username, int value)
		{
			if (value <= 0)
			{
				_accumulatedBits.Remove(username.ToLower());
			}
			else
			{
				_accumulatedBits[username.ToLower()] = value;
			}
			SaveData();
		}

		public static void Set(ViewerData viewer, int value)
		{
			if (viewer != null)
			{
				Set(viewer.Username, value);
			}
		}

		public static void Add(string username, int amount)
		{
			int num = Get(username);
			int value = num + amount;
			Set(username, value);
		}

		public static void Add(ViewerData viewer, int amount)
		{
			if (viewer != null)
			{
				Add(viewer.Username, amount);
			}
		}

		public static void Remove(string username, int amount)
		{
			Add(username, -amount);
		}

		public static void Remove(ViewerData viewer, int amount)
		{
			Add(viewer, -amount);
		}
	}
	internal static class SpawnPointManager
	{
		private static Dictionary<string, float> _spawnPoints = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase);

		public static int EnemiesSpawnedUsingPointsThisDay;

		public static bool IsEnabled
		{
			get
			{
				if (TwitchIntegrationManager.IsEnabled)
				{
					return ConfigManager.SpawnPoints_Enabled.Value;
				}
				return false;
			}
		}

		public static IReadOnlyDictionary<string, float> SpawnPoints => _spawnPoints;

		public static string UseSpawnPointText => $"Use !spawn = {PriceForEnemy}, !plushies = {PriceForPlushies}".RichColor("#00FF00");

		public static float PriceForEnemy => ConfigManager.SpawnPoints_PriceForEnemy.Value;

		public static float PriceForPlushies => ConfigManager.SpawnPoints_PriceForPlushies.Value;

		public static int MaxEnemySpawnsPerDay => ConfigManager.SpawnPoints_MaxEnemySpawnsPerDay.Value;

		public static float RewardPointsPerDeath => ConfigManager.SpawnPoints_RewardPointsPerDeath.Value;

		public static float RewardPointsPerCrewmateDeath => ConfigManager.SpawnPoints_RewardPointsPerCrewmateDeath.Value;

		public static void Initialize()
		{
			LoadData();
			Application.quitting += SaveData;
		}

		private static void LoadData()
		{
			try
			{
				if (Plugin.GlobalSave.TryLoad<string>("SpawnPoints", out var value))
				{
					Logger.LogInfo("[SpawnPointManager] Loaded JSON data:\n\n" + value, extended: true);
					_spawnPoints = JsonConvert.DeserializeObject<Dictionary<string, float>>(value);
				}
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] Failed to load JSON data: {1}", "SpawnPointManager", arg));
			}
		}

		private static void SaveData()
		{
			if (Plugin.GlobalSave.Save("SpawnPoints", JsonConvert.SerializeObject((object)_spawnPoints)))
			{
				Logger.LogInfo("[SpawnPointManager] Saved JSON data.", extended: true);
			}
			else
			{
				Logger.LogError("[SpawnPointManager] Failed to save JSON data.");
			}
		}

		public static float Get(string username)
		{
			return _spawnPoints.GetValueOrDefault(username.ToLower(), 0f);
		}

		public static float Get(ViewerData viewer)
		{
			if (viewer == null)
			{
				return 0f;
			}
			return Get(viewer.Username);
		}

		public static void Set(string username, float value, bool saveImmediately = true)
		{
			if (value <= 0f)
			{
				_spawnPoints.Remove(username.ToLower());
			}
			else
			{
				_spawnPoints[username.ToLower()] = value;
			}
			if (saveImmediately)
			{
				SaveData();
			}
		}

		public static void Set(ViewerData viewer, float value, bool saveImmediately = true)
		{
			if (viewer != null)
			{
				Set(viewer.Username, value, saveImmediately);
			}
		}

		public static void Add(string username, float amount, bool saveImmediately = true)
		{
			float num = Get(username);
			float value = num + amount;
			Set(username, value, saveImmediately);
		}

		public static void Add(ViewerData viewer, float amount, bool saveImmediately = true)
		{
			if (viewer != null)
			{
				Add(viewer.Username, amount, saveImmediately);
			}
		}

		public static void Remove(string username, float amount, bool saveImmediately = false)
		{
			Add(username, 0f - amount, saveImmediately);
		}

		public static void Remove(ViewerData viewer, float amount, bool saveImmediately = false)
		{
			Add(viewer, 0f - amount, saveImmediately);
		}

		public static void ResetAllSpawnPoints()
		{
			_spawnPoints.Clear();
			SaveData();
			Logger.LogInfo("Reset all spawn points.");
		}

		public static void OnDayEnded()
		{
			EnemiesSpawnedUsingPointsThisDay = 0;
			SaveData();
		}

		public static void OnLocalDisconnect()
		{
			EnemiesSpawnedUsingPointsThisDay = 0;
			LoadData();
		}

		public static void SpawnEnemiesUsingPoints(ViewerData viewer, int requestedSpawnCount, PlayerControllerB targetPlayerScript)
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || viewer == null || requestedSpawnCount <= 0 || !TwitchEventHandler.CanPlayEventsOnPlayer(targetPlayerScript))
			{
				return;
			}
			float num = Get(viewer);
			if (num <= 0f)
			{
				return;
			}
			int maxEnemySpawnsPerDay = MaxEnemySpawnsPerDay;
			int num2 = maxEnemySpawnsPerDay - EnemiesSpawnedUsingPointsThisDay;
			if (num2 <= 0)
			{
				MessageManger.Instance?.ShowMessage_LocalClient($"The max amount of enemies ({maxEnemySpawnsPerDay}) have been spawned using spawn points for this day");
				return;
			}
			if (requestedSpawnCount > maxEnemySpawnsPerDay)
			{
				requestedSpawnCount = maxEnemySpawnsPerDay;
			}
			if (requestedSpawnCount > num2)
			{
				requestedSpawnCount = num2;
			}
			float num3 = PriceForEnemy * (float)requestedSpawnCount;
			float num4;
			if (num3 > num)
			{
				requestedSpawnCount = (int)Mathf.Floor(num / PriceForEnemy);
				if (requestedSpawnCount <= 1)
				{
					return;
				}
				if (requestedSpawnCount > num2)
				{
					requestedSpawnCount = num2;
				}
				num4 = PriceForEnemy * (float)requestedSpawnCount;
			}
			else
			{
				num4 = num3;
			}
			Remove(viewer, num4);
			EnemiesSpawnedUsingPointsThisDay += requestedSpawnCount;
			float num5 = Get(viewer);
			string arg = ((num4 == 1f) ? "" : "s");
			string spawnReason = $"by redeeming {num4} spawn point{arg} ({num5} remaining)";
			int spawnCount = requestedSpawnCount;
			ulong? spawnedOnClientId = targetPlayerScript.actualClientId;
			SpawnEnemyData spawnEnemyData = new SpawnEnemyData(viewer, SpawnSource.Twitch, spawnCount, spawnReason, "", null, spawnedOnClientId);
			SpawnEventHandler.Instance?.ExecuteSpawnEnemyData_ServerRpc(spawnEnemyData);
		}

		public static void SpawnPlusheisUsingPoints(ViewerData viewer, PlayerControllerB targetPlayerScript)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			if (IsEnabled && viewer != null && !((Object)(object)PlushieManager.Instance == (Object)null) && PlushieManager.Instance.CanSpawnPlushiesOnPlayer(targetPlayerScript))
			{
				float num = Get(viewer);
				if (!(num <= 0f) && !(num < PriceForPlushies))
				{
					Remove(viewer, PriceForPlushies);
					float num2 = Get(viewer);
					string arg = ((PriceForPlushies == 1f) ? "" : "s");
					string spawnReason = $"by redeeming {PriceForPlushies} spawn point{arg} ({num2} remaining)";
					ulong? spawnedOnClientId = targetPlayerScript.actualClientId;
					SpawnPlushiesData spawnPlushiesData = new SpawnPlushiesData(viewer, SpawnSource.Twitch, spawnReason, "", null, spawnedOnClientId);
					SpawnEventHandler.Instance?.ExecuteSpawnPlushiesData_ServerRpc(spawnPlushiesData);
				}
			}
		}

		public static void RewardFromDeath(NametagData nametagData)
		{
			if (!IsEnabled)
			{
				return;
			}
			SpawnEnemyData spawnEnemyData = nametagData.SpawnEnemyData;
			if (!spawnEnemyData.IsFromViewer)
			{
				return;
			}
			bool value = ConfigManager.CrowdControl_RewardSpawnPoints.Value;
			if (spawnEnemyData.SpawnSource != SpawnSource.CrowdControl || value)
			{
				float rewardPointsPerDeath = RewardPointsPerDeath;
				if (!(rewardPointsPerDeath <= 0f))
				{
					ViewerData viewer = spawnEnemyData.Viewer;
					Add(viewer, rewardPointsPerDeath);
					float num = Get(viewer);
					string displayNameWithReadableColor = viewer.GetDisplayNameWithReadableColor();
					string text = ((rewardPointsPerDeath == 1f) ? "" : "s");
					string message = $"{displayNameWithReadableColor} just earned {rewardPointsPerDeath} spawn point{text} ({num} total) {UseSpawnPointText}";
					MessageManger.Instance?.ShowMessage_LocalClient(message);
				}
			}
		}

		public static void RewardFromCrewmateDeath(ulong crewmateClientId, NametagData nametagData)
		{
			if (!IsEnabled)
			{
				return;
			}
			SpawnEnemyData spawnEnemyData = nametagData.SpawnEnemyData;
			if (!spawnEnemyData.IsFromViewer || NetworkUtils.IsLocalClientId(crewmateClientId) || !NetworkUtils.IsLocalClientId(spawnEnemyData.SpawnedFromClientId))
			{
				return;
			}
			bool value = ConfigManager.CrowdControl_RewardSpawnPoints.Value;
			if (spawnEnemyData.SpawnSource == SpawnSource.CrowdControl && !value)
			{
				return;
			}
			float rewardPointsPerCrewmateDeath = RewardPointsPerCrewmateDeath;
			if (!(rewardPointsPerCrewmateDeath <= 0f))
			{
				PlayerControllerB playerScriptByClientId = PlayerUtils.GetPlayerScriptByClientId(crewmateClientId);
				if (!((Object)(object)playerScriptByClientId == (Object)null))
				{
					ViewerData viewer = spawnEnemyData.Viewer;
					Add(viewer, rewardPointsPerCrewmateDeath);
					float num = Get(viewer);
					string displayNameWithReadableColor = viewer.GetDisplayNameWithReadableColor();
					string text = ((rewardPointsPerCrewmateDeath == 1f) ? "" : "s");
					string message = $"{displayNameWithReadableColor} just earned {rewardPointsPerCrewmateDeath} spawn point{text} by killing {playerScriptByClientId.playerUsername} ({num} total) {UseSpawnPointText}";
					MessageManger.Instance?.ShowMessage_LocalClient(message);
				}
			}
		}
	}
	internal static class TargetPlayerManager
	{
		private static readonly Dictionary<string, PlayerControllerB> _targets = new Dictionary<string, PlayerControllerB>(StringComparer.OrdinalIgnoreCase);

		public static IReadOnlyDictionary<string, PlayerControllerB> Targets => _targets;

		public static PlayerControllerB GetTarget(string username)
		{
			return _targets.GetValueOrDefault(username.ToLower());
		}

		public static bool TryGetTarget(string username, out PlayerControllerB playerScript)
		{
			return _targets.TryGetValue(username.ToLower(), out playerScript);
		}

		public static void SetTarget(string username, PlayerControllerB playerScript)
		{
			_targets[username.ToLower()] = playerScript;
		}

		public static void RemoveTarget(string username)
		{
			_targets.Remove(username.ToLower());
		}
	}
	internal static class TwitchCheerHandler
	{
		public static int PriceForEnemy => ConfigManager.TwitchCheerEvent_AmountToSpawnEnemy.Value;

		public static int PriceForPlushies => ConfigManager.TwitchCheerEvent_AmountToSpawnPlushies.Value;

		public static void HandleCheer(TwitchCheerEvent cheerEvent)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!TwitchIntegrationManager.IsCheerEventEnabled)
			{
				return;
			}
			if (cheerEvent == null)
			{
				Logger.LogError("[TwitchCheerHandler] Failed to handle cheer. TwitchCheerEvent is null.");
				return;
			}
			if (!TwitchEventHandler.CanPlayEventsOnLocalPlayer())
			{
				TwitchEventQueue.Enqueue(cheerEvent);
				return;
			}
			int cheerAmount = cheerEvent.CheerAmount;
			ViewerData viewer = new ViewerData(((TwitchEvent)cheerEvent).User);
			if (PriceForEnemy == PriceForPlushies && cheerAmount == PriceForEnemy)
			{
				if (Utils.RollPercentChance(50f))
				{
					SpawnEnemyFromExactAmount(cheerEvent, viewer);
				}
				else
				{
					SpawnPlushiesFromExactAmount(cheerEvent, viewer);
				}
			}
			else if (cheerAmount == PriceForEnemy)
			{
				SpawnEnemyFromExactAmount(cheerEvent, viewer);
			}
			else if (cheerAmount == PriceForPlushies)
			{
				SpawnPlushiesFromExactAmount(cheerEvent, viewer);
			}
			else
			{
				TrySpawnEnemies(cheerEvent, viewer);
			}
		}

		private static void SpawnPlushiesFromExactAmount(TwitchCheerEvent cheerEvent, ViewerData viewer)
		{
			SpawnPlushiesData spawnPlushiesData = new SpawnPlushiesData(viewer, SpawnSource.Twitch, $"by cheering {cheerEvent.CheerAmount} bits");
			PlushieManager.Instance?.SpawnPlushiesFromData(spawnPlushiesData);
		}

		private static void SpawnEnemyFromExactAmount(TwitchCheerEvent cheerEvent, ViewerData viewer)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			string spawnReason = $"by cheering {cheerEvent.CheerAmount} bits";
			SpawnEnemyData spawnEnemyData = new SpawnEnemyData(viewer, SpawnSource.Twitch, 1, spawnReason);
			SpawnEventHandler.Instance?.ExecuteSpawnEnemyData_ServerRpc(spawnEnemyData);
		}

		private static void TrySpawnEnemies(TwitchCheerEvent cheerEvent, ViewerData viewer)
		{
			int cheerAmount = cheerEvent.CheerAmount;
			int num = Mathf.FloorToInt((float)(cheerAmount / PriceForEnemy));
			int num2 = AccumulatedBitManger.Get(viewer);
			int num3 = cheerAmount + num2;
			int num4 = Mathf.FloorToInt((float)(num3 / PriceForEnemy));
			if (num4 > num)
			{
				SpawnEnemiesWithAccumulatedBits(cheerEvent, viewer);
				return;
			}
			if (num >= 1)
			{
				SpawnEnemiesFromExactOrExtraBits(cheerEvent, viewer);
				return;
			}
			AccumulatedBitManger.Add(viewer, cheerAmount);
			num2 = AccumulatedBitManger.Get(viewer);
			MessageManger.Instance?.ShowMessage_LocalClient($"{viewer.GetDisplayNameWithReadableColor()} didn't cheer enough to spawn anything. {cheerAmount} bits have been added to their accumulation pool ({num2} total / {PriceForEnemy})");
		}

		private static void SpawnEnemiesFromExactOrExtraBits(TwitchCheerEvent cheerEvent, ViewerData viewer)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			int cheerAmount = cheerEvent.CheerAmount;
			int spawnCount = Mathf.FloorToInt((float)(cheerAmount / PriceForEnemy));
			int num = cheerAmount % PriceForEnemy;
			int num2 = cheerAmount - num;
			string spawnReason = ((num <= 0) ? $"by cheering {num2} bits" : $"by cheering {num2} bits + {num} extra bits");
			SpawnEnemyData spawnEnemyData = new SpawnEnemyData(viewer, SpawnSource.Twitch, spawnCount, spawnReason);
			SpawnEventHandler.Instance?.ExecuteSpawnEnemyData_ServerRpc(spawnEnemyData);
			if (num > 0)
			{
				AccumulatedBitManger.Add(viewer, num);
				int num3 = AccumulatedBitManger.Get(viewer);
				MessageManger.Instance?.ShowMessage_LocalClient($"{num} extra bits have been added to {viewer.GetDisplayNameWithReadableColor()}'s accumulation pool ({num3} total / {PriceForEnemy})");
			}
		}

		private static void SpawnEnemiesWithAccumulatedBits(TwitchCheerEvent cheerEvent, ViewerData viewer)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			int cheerAmount = cheerEvent.CheerAmount;
			int num = AccumulatedBitManger.Get(viewer);
			int num2 = cheerAmount + num;
			int spawnCount = Mathf.FloorToInt((float)(num2 / PriceForEnemy));
			int num3 = num2 % PriceForEnemy;
			int num4 = Mathf.Max(num - num3, 0);
			string spawnReason = $"by cheering {cheerAmount} bits + {num4} accumulated bits";
			SpawnEnemyData spawnEnemyData = new SpawnEnemyData(viewer, SpawnSource.Twitch, spawnCount, spawnReason);
			SpawnEventHandler.Instance?.ExecuteSpawnEnemyData_ServerRpc(spawnEnemyData);
			AccumulatedBitManger.Remove(viewer, num4);
			int num5 = AccumulatedBitManger.Get(viewer);
			MessageManger.Instance?.ShowMessage_LocalClient($"{viewer.GetDisplayNameWithReadableColor()} has {num5} / {PriceForEnemy} accumulated bits remaining");
		}
	}
	internal static class TwitchEventHandler
	{
		public static void Initialize()
		{
			try
			{
				API.OnMessage += HandleMessage;
				API.OnCheer += HandleCheer;
				API.OnSub += HandleSub;
				API.OnRaid += HandleRaid;
				Application.quitting += delegate
				{
					API.OnMessage -= HandleMessage;
					API.OnCheer -= HandleCheer;
					API.OnSub -= HandleSub;
					API.OnRaid -= HandleRaid;
				};
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] Failed to initialize. {1}", "TwitchEventHandler", arg));
			}
		}

		public static void HandleMessage(TwitchMessage twitchMessage)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (TwitchIntegrationManager.IsEnabled)
			{
				TwitchCommandManager.Dispatch(twitchMessage);
			}
		}

		public static void HandleCheer(TwitchCheerEvent cheerEvent)
		{
			TwitchCheerHandler.HandleCheer(cheerEvent);
		}

		public static void HandleSub(TwitchSubEvent subEvent)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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)
			if (!TwitchIntegrationManager.IsSubEventEnabled)
			{
				return;
			}
			if (subEvent == null)
			{
				Logger.LogError("[TwitchEventHandler] Failed to handle sub. TwitchSubEvent is null.");
				return;
			}
			if (!CanPlayEventsOnLocalPlayer())
			{
				TwitchEventQueue.Enqueue(subEvent);
				return;
			}
			int num = ConfigManager.TwitchSubEvent_EnemiesPerSub.Value;
			if ((int)subEvent.Type == 3)
			{
				num *= subEvent.GiftCount;
			}
			if ((int)subEvent.Tier == 2)
			{
				num *= ConfigManager.TwitchSubEvent_Tier2EnemyMultiplier.Value;
			}
			else if ((int)subEvent.Tier == 3)
			{
				num *= ConfigManager.TwitchSubEvent_Tier3EnemyMultiplier.Value;
			}
			ViewerData viewer = new ViewerData(((TwitchEvent)subEvent).User);
			string spawnReason = GetSpawnReason(subEvent);
			SpawnEnemyData spawnEnemyData = new SpawnEnemyData(viewer, SpawnSource.Twitch, num, spawnReason);
			SpawnEventHandler.Instance?.ExecuteSpawnEnemyData_ServerRpc(spawnEnemyData);
		}

		public static void HandleRaid(TwitchRaidEvent raidEvent)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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)
			if (TwitchIntegrationManager.IsRaidEventEnabled)
			{
				if (raidEvent == null)
				{
					Logger.LogError("[TwitchEventHandler] Failed to handle raid. TwitchRaidEvent is null.");
					return;
				}
				if (!CanPlayEventsOnLocalPlayer())
				{
					TwitchEventQueue.Enqueue(raidEvent);
					return;
				}
				int value = ConfigManager.TwitchRaidEvent_ViewersPerEnemy.Value;
				int value2 = ConfigManager.TwitchRaidEvent_MaxSpawnCount.Value;
				int spawnCount = Mathf.Clamp(raidEvent.ViewerCount / value, 1, value2);
				ViewerData viewer = new ViewerData(((TwitchEvent)raidEvent).User);
				string spawnReason = $"by raiding with {raidEvent.ViewerCount} viewers";
				SpawnEnemyData spawnEnemyData = new SpawnEnemyData(viewer, SpawnSource.Twitch, spawnCount, spawnReason);
				SpawnEventHandler.Instance?.ExecuteSpawnEnemyData_ServerRpc(spawnEnemyData);
			}
		}

		private static string GetSpawnReason(TwitchSubEvent subEvent)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Invalid comparison between Unknown and I4
			//IL_004f: 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_003a: Expected I4, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Invalid comparison between Unknown and I4
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected I4, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected I4, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected I4, but got Unknown
			if (subEvent == null)
			{
				return string.Empty;
			}
			string result = string.Empty;
			if ((int)subEvent.Type == 0)
			{
				result = (((int)subEvent.Tier != 0) ? $"by subbing at tier {(int)subEvent.Tier}" : "by subbing with prime");
			}
			else if ((int)subEvent.Type == 1)
			{
				result = (((int)subEvent.Tier != 0) ? $"by resubbing at tier {(int)subEvent.Tier} for {subEvent.CumulativeMonths} months" : $"by resubbing with prime for {subEvent.CumulativeMonths} months");
			}
			else if ((int)subEvent.Type == 2)
			{
				result = $"by gifting a tier {(int)subEvent.Tier} sub to {subEvent.RecipientUser}";
			}
			else if ((int)subEvent.Type == 3)
			{
				result = $"by gifting {subEvent.GiftCount} tier {(int)subEvent.Tier} subs";
			}
			return result;
		}

		public static bool CanPlayEventsOnPlayer(PlayerControllerB playerScript)
		{
			if (!TwitchIntegrationManager.IsEnabled)
			{
				return false;
			}
			return EnemyHelper.CanSpawnEnemiesOnPlayer(playerScript);
		}

		public static bool CanPlayEventsOnLocalPlayer()
		{
			return CanPlayEventsOnPlayer(PlayerUtils.LocalPlayerScript);
		}
	}
	internal static class TwitchEventQueue
	{
		[CompilerGenerated]
		private sealed class <PlayQueuedEventsCoroutine>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TimeSpan initialDelay;

			private TimeSpan <delayBetweenEvents>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Expected O, but got Unknown
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Expected O, but got Unknown
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Expected O, but got Unknown
				//IL_0193: Unknown result type (might be due to invalid IL or missing references)
				//IL_019d: Expected O, but got Unknown
				TwitchSubEvent result;
				TwitchCheerEvent result2;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Logger.LogInfo(string.Format("[{0}] Playing queued events after {1} seconds.", "TwitchEventQueue", (float)initialDelay.TotalSeconds), extended: true);
					<>2__current = (object)new WaitForSeconds((float)initialDelay.TotalSeconds);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!TwitchEventHandler.CanPlayEventsOnLocalPlayer())
					{
						Logger.LogWarning("[TwitchEventQueue] Failed to play queued events. You are not allowed to play events at this time.");
						return false;
					}
					if (!HasQueuedEvents())
					{
						Logger.LogInfo("[TwitchEventQueue] No events in the queue to play.", extended: true);
						return false;
					}
					MessageManger.Instance?.ShowMessage_LocalClient("Playing Twitch events from the queue");
					<delayBetweenEvents>5__2 = TimeSpan.FromSeconds(0.5);
					goto IL_00c8;
				case 2:
					<>1__state = -1;
					goto IL_00c8;
				case 3:
					<>1__state = -1;
					goto IL_0115;
				case 4:
					{
						<>1__state = -1;
						break;
					}
					IL_0115:
					if (TwitchIntegrationManager.IsSubEventEnabled && _subQueue.TryDequeue(out result))
					{
						if (!TwitchEventHandler.CanPlayEventsOnLocalPlayer())
						{
							return false;
						}
						TwitchEventHandler.HandleSub(result);
						<>2__current = (object)new WaitForSeconds((float)<delayBetweenEvents>5__2.TotalSeconds);
						<>1__state = 3;
						return true;
					}
					break;
					IL_00c8:
					if (TwitchIntegrationManager.IsCheerEventEnabled && _cheerQueue.TryDequeue(out result2))
					{
						if (!TwitchEventHandler.CanPlayEventsOnLocalPlayer())
						{
							return false;
						}
						TwitchEventHandler.HandleCheer(result2);
						<>2__current = (object)new WaitForSeconds((float)<delayBetweenEvents>5__2.TotalSeconds);
						<>1__state = 2;
						return true;
					}
					goto IL_0115;
				}
				if (TwitchIntegrationManager.IsRaidEventEnabled && _raidQueue.TryDequeue(out var result3))
				{
					if (!TwitchEventHandler.CanPlayEventsOnLocalPlayer())
					{
						return false;
					}
					TwitchEventHandler.HandleRaid(result3);
					<>2__current = (object)new WaitForSeconds((float)<delayBetweenEvents>5__2.TotalSeconds);
					<>1__state = 4;
					return true;
				}
				Logger.LogInfo("[TwitchEventQueue] Finished plyaing queued events.", extended: true);
				SaveData();
				_playQueuedEventsCoroutine = null;
				return false;
			}

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

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

		private static Queue<TwitchCheerEvent> _cheerQueue = new Queue<TwitchCheerEvent>();

		private static Queue<TwitchSubEvent> _subQueue = new Queue<TwitchSubEvent>();

		private static Queue<TwitchRaidEvent> _raidQueue = new Queue<TwitchRaidEvent>();

		private static Coroutine _playQueuedEventsCoroutine;

		public static IReadOnlyCollection<TwitchCheerEvent> CheerQueue => _cheerQueue;

		public static IReadOnlyCollection<TwitchSubEvent> SubQueue => _subQueue;

		public static IReadOnlyCollection<TwitchRaidEvent> RaidQueue => _raidQueue;

		public static void Initialize()
		{
			LoadData();
			Application.quitting += SaveData;
		}

		private static void LoadData()
		{
			Logger.LogInfo("[TwitchEventQueue] Loading saved data...");
			try
			{
				if (Plugin.GlobalSave.TryLoad<string>("CheerQueue", out var value))
				{
					_cheerQueue = QueueJsonConverterHelper.DeserializeQueue<TwitchCheerEvent>(value);
					Logger.LogInfo("[TwitchEventQueue] Loaded CheerQueue JSON data:\n\n" + value, extended: true);
				}
				if (Plugin.GlobalSave.TryLoad<string>("SubQueue", out value))
				{
					_subQueue = QueueJsonConverterHelper.DeserializeQueue<TwitchSubEvent>(value);
					Logger.LogInfo("[TwitchEventQueue] Loaded SubQueue JSON data:\n\n" + value, extended: true);
				}
				if (Plugin.GlobalSave.TryLoad<string>("RaidQueue", out value))
				{
					_raidQueue = QueueJsonConverterHelper.DeserializeQueue<TwitchRaidEvent>(value);
					Logger.LogInfo("[TwitchEventQueue] Loaded RaidQueue JSON data:\n\n" + value, extended: true);
				}
				Logger.LogInfo("[TwitchEventQueue] Finished loading saved data.");
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] Failed to load saved data. {1}", "TwitchEventQueue", arg));
			}
		}

		private static void SaveData()
		{
			Logger.LogInfo("[TwitchEventQueue] Saving data...", extended: true);
			try
			{
				SaveCheerQueue();
				SaveSubQueue();
				SaveRaidQueue();
				Logger.LogInfo("[TwitchEventQueue] Saved data.", extended: true);
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] Failed to save data. {1}", "TwitchEventQueue", arg));
			}
		}

		private static void SaveCheerQueue()
		{
			try
			{
				Plugin.GlobalSave.Save("CheerQueue", QueueJsonConverterHelper.SerializeQueue(_cheerQueue));
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] {1}: Failed to save data. {2}", "TwitchEventQueue", "SaveCheerQueue", arg));
			}
		}

		private static void SaveSubQueue()
		{
			try
			{
				Plugin.GlobalSave.Save("SubQueue", QueueJsonConverterHelper.SerializeQueue(_subQueue));
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] {1}: Failed to save data. {2}", "TwitchEventQueue", "SaveSubQueue", arg));
			}
		}

		private static void SaveRaidQueue()
		{
			try
			{
				Plugin.GlobalSave.Save("RaidQueue", QueueJsonConverterHelper.SerializeQueue(_raidQueue));
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] {1}: Failed to save data. {2}", "TwitchEventQueue", "SaveRaidQueue", arg));
			}
		}

		public static void PlayQueuedEvents()
		{
			PlayQueuedEvents(TimeSpan.Zero);
		}

		public static void PlayQueuedEvents(TimeSpan initialDelay)
		{
			if (!TwitchIntegrationManager.IsEnabled)
			{
				Logger.LogWarning("[TwitchEventQueue] Failed to play queued events. Twitch integration is not enabled.");
				return;
			}
			if ((Object)(object)SpawnEventHandler.Instance == (Object)null)
			{
				Logger.LogWarning("[TwitchEventQueue] Failed to play queued events. ViewerSpawnEventHandler instance is null.");
				return;
			}
			if (_playQueuedEventsCoroutine != null)
			{
				CoroutineRunner.Stop(_playQueuedEventsCoroutine);
			}
			_playQueuedEventsCoroutine = CoroutineRunner.Start(PlayQueuedEventsCoroutine(initialDelay));
		}

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

		public static bool HasQueuedEvents()
		{
			if (_cheerQueue.Count <= 0 && _subQueue.Count <= 0)
			{
				return _raidQueue.Count > 0;
			}
			return true;
		}

		public static void Enqueue(TwitchCheerEvent cheerEvent)
		{
			if (!_cheerQueue.Contains(cheerEvent))
			{
				_cheerQueue.Enqueue(cheerEvent);
				SaveCheerQueue();
				ShowEnqueueMessage((TwitchEvent)(object)cheerEvent, "cheer");
			}
		}

		public static void Enqueue(TwitchSubEvent subEvent)
		{
			if (!_subQueue.Contains(subEvent))
			{
				_subQueue.Enqueue(subEvent);
				SaveSubQueue();
				ShowEnqueueMessage((TwitchEvent)(object)subEvent, "sub");
			}
		}

		public static void Enqueue(TwitchRaidEvent raidEvent)
		{
			if (!_raidQueue.Contains(raidEvent))
			{
				_raidQueue.Enqueue(raidEvent);
				SaveRaidQueue();
				ShowEnqueueMessage((TwitchEvent)(object)raidEvent, "raid");
			}
		}

		private static void ShowEnqueueMessage(TwitchEvent twitchEvent, string eventName)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string displayNameWithReadableColor = twitchEvent.User.GetDisplayNameWithReadableColor();
			string message = "Added Twitch " + eventName + " event from " + displayNameWithReadableColor + " to queue";
			MessageManger.Instance?.ShowMessage_LocalClient(message);
		}
	}
}
namespace com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands
{
	public class ParsedArgs
	{
		private readonly Dictionary<string, string> _named;

		private readonly List<string> _positional;

		public IReadOnlyDictionary<string, string> Named => _named;

		public IReadOnlyList<string> Positional => _positional;

		public ParsedArgs(Dictionary<string, string> named, List<string> positional)
		{
			_named = named;
			_positional = positional;
		}

		public bool HasFlag(string key)
		{
			return _named.ContainsKey(key);
		}

		public bool TryGet(string key, out string value)
		{
			return _named.TryGetValue(key, out value);
		}

		public string Get(string key, string defaultValue = "")
		{
			if (!TryGet(key, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public bool TryGetInt(string key, out int value)
		{
			return int.TryParse(Get(key), out value);
		}

		public int GetInt(string key, int defaultValue = 0)
		{
			if (!TryGetInt(key, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public bool TryGetFloat(string key, out float value)
		{
			return float.TryParse(Get(key), out value);
		}

		public float GetFloat(string key, float defaultValue = 0f)
		{
			if (!TryGetFloat(key, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public bool TryGetPositional(int index, out string value)
		{
			if (index >= _positional.Count)
			{
				value = null;
				return false;
			}
			value = _positional[index];
			return true;
		}

		public string GetPositional(int index, string defaultValue = "")
		{
			if (!TryGetPositional(index, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public bool TryGetPositionalInt(int index, out int value)
		{
			if (!TryGetPositional(index, out var value2))
			{
				value = 0;
				return false;
			}
			return int.TryParse(value2, out value);
		}

		public int GetPositionalInt(int index, int defaultValue = 0)
		{
			if (!TryGetPositionalInt(index, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public bool TryGetPositionalFloat(int index, out float value)
		{
			if (!TryGetPositional(index, out var value2))
			{
				value = 0f;
				return false;
			}
			return float.TryParse(value2, out value);
		}

		public float GetPositionalFloat(int index, float defaultValue = 0f)
		{
			if (!TryGetPositionalFloat(index, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public static ParsedArgs Parse(string[] args)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			List<string> list = new List<string>();
			int num = 0;
			while (num < args.Length)
			{
				string text = args[num];
				if (text.StartsWith("--"))
				{
					string text2 = text;
					string key = text2.Substring(2, text2.Length - 2);
					if (num + 1 >= args.Length || args[num + 1].StartsWith("--"))
					{
						dictionary[key] = "true";
						num++;
					}
					else
					{
						dictionary[key] = args[num + 1];
						num += 2;
					}
				}
				else
				{
					list.Add(text);
					num++;
				}
			}
			return new ParsedArgs(dictionary, list);
		}
	}
	internal abstract class TwitchCommand
	{
		private ConfigEntry<bool> _enabled;

		private bool _boundConfigs;

		public abstract string Name { get; }

		public abstract bool EnabledByDefault { get; }

		public abstract bool EnableConfigs { get; }

		public bool IsEnabled => _enabled?.Value ?? EnabledByDefault;

		public abstract void Execute(TwitchMessage twitchMessage, string[] args);

		public void PreBindConfigs()
		{
			if (!_boundConfigs)
			{
				_boundConfigs = true;
				string section = "Command: " + Name;
				_enabled = ConfigHelper.Bind(section, "Enabled", EnabledByDefault, "Enable " + Name + " Twitch chat command.");
				BindConfigs(section);
			}
		}

		protected virtual void BindConfigs(string section)
		{
		}

		protected string ParseUsername(string input)
		{
			return input.Replace("@", "");
		}
	}
	internal static class TwitchCommandManager
	{
		private static readonly Dictionary<string, TwitchCommand> _commands = new Dictionary<string, TwitchCommand>(StringComparer.OrdinalIgnoreCase);

		public static bool IsEnabled => ConfigManager.TwitchChatCommands_Enabled.Value;

		public static string Prefix => ConfigManager.TwitchChatCommands_Prefix.Value;

		public static IReadOnlyDictionary<string, TwitchCommand> Commands => _commands;

		public static void Initialize()
		{
			Register(new DevSpawnCommand());
			Register(new DevPlushiesCommand());
			Register(new DevCheerCommand());
			Register(new DevSubCommand());
			Register(new DevRaidCommand());
			Register(new PlayQueueCommand());
			Register(new ViewConfigCommand());
			Register(new SetConfigCommand());
			Register(new GiveSpawnCommand());
			Register(new GiveSpawnRandomCommand());
			Register(new InfoCommand());
			Register(new ViewPlayersCommand());
			Register(new ViewAllSpawnCommand());
			Register(new ViewAllBitsCommand());
			Register(new LustySpawnCommand());
			Register(new SpawnCommand());
			Register(new CrewSpawnCommand());
			Register(new PlushiesCommand());
			Register(new CrewPlushiesCommand());
			Register(new ViewSpawnCommand());
			Register(new ViewBitsCommand());
			Register(new TargetCommand());
			Register(new ClearTargetCommand());
			Register(new ViewTargetCommand());
		}

		public static void Register(TwitchCommand command)
		{
			_commands[command.Name] = command;
			if (command.EnableConfigs)
			{
				command.PreBindConfigs();
			}
		}

		public static void Dispatch(TwitchMessage twitchMessage)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled)
			{
				return;
			}
			string message = ((TwitchMessage)(ref twitchMessage)).Message;
			if (string.IsNullOrWhiteSpace(message) || !message.StartsWith(Prefix))
			{
				return;
			}
			string[] array = Tokenize(message.Trim());
			if (array.Length == 0)
			{
				return;
			}
			string key = array[0].Substring(Prefix.Length);
			if (!_commands.TryGetValue(key, out var value) || !value.IsEnabled)
			{
				return;
			}
			string[] subArray = array[1..];
			try
			{
				value.Execute(twitchMessage, subArray);
			}
			catch (Exception arg)
			{
				Logger.LogError(string.Format("[{0}] Error running command \"{1}\". {2}", "TwitchCommandManager", value.GetType().Name, arg));
			}
		}

		private static string[] Tokenize(string input)
		{
			List<string> list = new List<string>();
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = false;
			char c = '"';
			foreach (char c2 in input)
			{
				if (flag)
				{
					if (c2 == c)
					{
						flag = false;
					}
					else
					{
						stringBuilder.Append(c2);
					}
				}
				else if (c2 == '"' || c2 == '\'')
				{
					flag = true;
					c = c2;
				}
				else if (char.IsWhiteSpace(c2))
				{
					if (stringBuilder.Length > 0)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Clear();
					}
				}
				else
				{
					stringBuilder.Append(c2);
				}
			}
			if (stringBuilder.Length > 0)
			{
				list.Add(stringBuilder.ToString());
			}
			return list.ToArray();
		}
	}
}
namespace com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Special
{
	internal class LustySpawnCommand : TwitchCommand
	{
		public override string Name => "lustyspawn";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
			if (((TwitchUser)(ref user)).Username.Equals_OrdinalIgnoreCase("LustStings") || ((TwitchMessage)(ref twitchMessage)).User.IsDeveloper())
			{
				ParsedArgs parsedArgs = ParsedArgs.Parse(args);
				string targetEnemyName = parsedArgs.GetPositional(0, "Blob");
				int spawnCount = parsedArgs.GetPositionalInt(1, 69);
				string targetPlayerUsername = parsedArgs.GetPositional(2);
				string spawnReason = "by being susty";
				if (parsedArgs.TryGet("enemy", out var value))
				{
					targetEnemyName = value;
				}
				if (parsedArgs.TryGetInt("count", out var value2))
				{
					spawnCount = value2;
				}
				if (parsedArgs.TryGetInt("amount", out value2))
				{
					spawnCount = value2;
				}
				if (parsedArgs.TryGet("target", out value))
				{
					targetPlayerUsername = value;
				}
				if (parsedArgs.TryGet("reason", out value))
				{
					spawnReason = value;
				}
				ViewerData viewer = new ViewerData(((TwitchMessage)(ref twitchMessage)).User);
				DevSpawnCommand.SpawnEnemy(viewer, spawnCount, spawnReason, targetEnemyName, targetPlayerUsername, null, 69);
			}
		}
	}
}
namespace com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Public
{
	internal class ClearTargetCommand : TwitchCommand
	{
		public override string Name => "cleartarget";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: 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)
			//IL_0014: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			string displayNameWithReadableColor = ((TwitchMessage)(ref twitchMessage)).User.GetDisplayNameWithReadableColor();
			TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
			PlayerControllerB target = TargetPlayerManager.GetTarget(((TwitchUser)(ref user)).Username);
			if ((Object)(object)target == (Object)null)
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " is not targeting anyone");
				return;
			}
			user = ((TwitchMessage)(ref twitchMessage)).User;
			TargetPlayerManager.RemoveTarget(((TwitchUser)(ref user)).Username);
			MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " has stopped targeting " + target.playerUsername);
		}
	}
	internal class CrewPlushiesCommand : TwitchCommand
	{
		public override string Name => "crewplushies";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => true;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//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_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (!SpawnPointManager.IsEnabled)
			{
				return;
			}
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			string positional = parsedArgs.GetPositional(0);
			string displayNameWithReadableColor = ((TwitchMessage)(ref twitchMessage)).User.GetDisplayNameWithReadableColor();
			PlayerControllerB playerScript;
			if (!string.IsNullOrWhiteSpace(positional))
			{
				if (!PlayerUtils.TryGetPlayerScriptByUsername(positional, out playerScript))
				{
					MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " no player was found with the name \"" + positional + "\"");
					return;
				}
				if (PlayerUtils.IsLocalPlayer(playerScript))
				{
					MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " you can not target the local player");
					return;
				}
			}
			else
			{
				TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
				if (!TargetPlayerManager.TryGetTarget(((TwitchUser)(ref user)).Username, out playerScript))
				{
					playerScript = PlayerUtils.GetRandomPlayerScript(PlayerUtils.AlivePlayerScripts, excludeLocal: true);
				}
			}
			if (!((Object)(object)playerScript == (Object)null))
			{
				ViewerData viewer = new ViewerData(((TwitchMessage)(ref twitchMessage)).User);
				SpawnPointManager.SpawnPlusheisUsingPoints(viewer, playerScript);
			}
		}
	}
	internal class CrewSpawnCommand : TwitchCommand
	{
		public override string Name => "crewspawn";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => true;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0065: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (!SpawnPointManager.IsEnabled)
			{
				return;
			}
			int num = 1;
			string text = string.Empty;
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			if (parsedArgs.TryGetPositionalInt(0, out var value))
			{
				num = value;
			}
			else
			{
				text = ParseUsername(parsedArgs.GetPositional(0));
			}
			string value2;
			if (parsedArgs.TryGetPositionalInt(1, out value))
			{
				num = value;
			}
			else if (string.IsNullOrWhiteSpace(text) && parsedArgs.TryGetPositional(1, out value2))
			{
				text = value2;
			}
			if (num <= 0)
			{
				return;
			}
			string displayNameWithReadableColor = ((TwitchMessage)(ref twitchMessage)).User.GetDisplayNameWithReadableColor();
			PlayerControllerB playerScript;
			if (!string.IsNullOrWhiteSpace(text))
			{
				if (!PlayerUtils.TryGetPlayerScriptByUsername(text, out playerScript))
				{
					MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " no player was found with the name \"" + text + "\"");
					return;
				}
				if (PlayerUtils.IsLocalPlayer(playerScript))
				{
					MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " you can not target the local player");
					return;
				}
			}
			else
			{
				TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
				if (!TargetPlayerManager.TryGetTarget(((TwitchUser)(ref user)).Username, out playerScript))
				{
					playerScript = PlayerUtils.GetRandomPlayerScript(PlayerUtils.AlivePlayerScripts, excludeLocal: true);
				}
			}
			if (!((Object)(object)playerScript == (Object)null))
			{
				ViewerData viewer = new ViewerData(((TwitchMessage)(ref twitchMessage)).User);
				SpawnPointManager.SpawnEnemiesUsingPoints(viewer, num, playerScript);
			}
		}
	}
	internal class PlushiesCommand : TwitchCommand
	{
		public override string Name => "plushies";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => true;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (SpawnPointManager.IsEnabled)
			{
				ViewerData viewer = new ViewerData(((TwitchMessage)(ref twitchMessage)).User);
				SpawnPointManager.SpawnPlusheisUsingPoints(viewer, PlayerUtils.LocalPlayerScript);
			}
		}
	}
	internal class SpawnCommand : TwitchCommand
	{
		public override string Name => "spawn";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => true;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (SpawnPointManager.IsEnabled)
			{
				ParsedArgs parsedArgs = ParsedArgs.Parse(args);
				int positionalInt = parsedArgs.GetPositionalInt(0, 1);
				if (positionalInt > 0)
				{
					ViewerData viewer = new ViewerData(((TwitchMessage)(ref twitchMessage)).User);
					SpawnPointManager.SpawnEnemiesUsingPoints(viewer, positionalInt, PlayerUtils.LocalPlayerScript);
				}
			}
		}
	}
	internal class TargetCommand : TwitchCommand
	{
		private ConfigEntry<string> _excludePlayers;

		public override string Name => "target";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => true;

		public string[] ExcludePlayersArray => _excludePlayers.Value.StringToCollection<string>().ToArray();

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			string displayNameWithReadableColor = ((TwitchMessage)(ref twitchMessage)).User.GetDisplayNameWithReadableColor();
			if (args.Length < 1)
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " must specify a target username in the command. Partial usernames will work too. " + TwitchCommandManager.Prefix + Name + " <username>");
				return;
			}
			string text = ParseUsername(args[0]);
			if (!PlayerUtils.TryGetPlayerScriptByUsername(text, out var playerScript))
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " no player was found with the name \"" + text + "\"");
				return;
			}
			if (ExcludePlayersArray.Contains<string>(playerScript.playerUsername, StringComparer.OrdinalIgnoreCase))
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " you are not able to target " + playerScript.playerUsername);
				return;
			}
			if (PlayerUtils.IsLocalPlayer(playerScript))
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " you can not target the local player");
				return;
			}
			TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
			TargetPlayerManager.SetTarget(((TwitchUser)(ref user)).Username, playerScript);
			string message = displayNameWithReadableColor + " is now targeting " + playerScript.playerUsername;
			MessageManger.Instance?.ShowMessage_LocalClient(message);
		}

		protected override void BindConfigs(string section)
		{
			_excludePlayers = ConfigHelper.Bind(section, "ExcludePlayers", "", "List of players to exclude from being targeted. Comma-separated list of player usernames.");
		}
	}
	internal class ViewBitsCommand : TwitchCommand
	{
		public override string Name => "viewbits";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			string text = ParseUsername(parsedArgs.GetPositional(0));
			string text2;
			string colorHex;
			if (!string.IsNullOrWhiteSpace(text) && text.Length >= 4)
			{
				TwitchUser val = default(TwitchUser);
				if (API.TryGetUserByUsername(text, ref val))
				{
					text2 = ((TwitchUser)(ref val)).DisplayName;
					colorHex = ((TwitchUser)(ref val)).Color;
				}
				else
				{
					text2 = text;
					colorHex = "#FFFFFF";
				}
			}
			else
			{
				TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
				text2 = ((TwitchUser)(ref user)).DisplayName;
				user = ((TwitchMessage)(ref twitchMessage)).User;
				colorHex = ((TwitchUser)(ref user)).Color;
			}
			int num = AccumulatedBitManger.Get(text2);
			string arg = ((num == 1) ? "" : "s");
			MessageManger.Instance?.ShowMessage_LocalClient($"{text2.RichReadableColor(colorHex)} has {num} accumulated bit{arg}");
		}
	}
	internal class ViewSpawnCommand : TwitchCommand
	{
		public override string Name => "viewspawn";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			if (!SpawnPointManager.IsEnabled)
			{
				return;
			}
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			string text = ParseUsername(parsedArgs.GetPositional(0));
			string text2;
			string colorHex;
			if (!string.IsNullOrWhiteSpace(text) && text.Length >= 4)
			{
				TwitchUser val = default(TwitchUser);
				if (API.TryGetUserByUsername(text, ref val))
				{
					text2 = ((TwitchUser)(ref val)).DisplayName;
					colorHex = ((TwitchUser)(ref val)).Color;
				}
				else
				{
					text2 = text;
					colorHex = "#FFFFFF";
				}
			}
			else
			{
				TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
				text2 = ((TwitchUser)(ref user)).DisplayName;
				user = ((TwitchMessage)(ref twitchMessage)).User;
				colorHex = ((TwitchUser)(ref user)).Color;
			}
			float num = SpawnPointManager.Get(text2);
			string arg = ((num == 1f) ? "" : "s");
			MessageManger.Instance?.ShowMessage_LocalClient($"{text2.RichReadableColor(colorHex)} has {num} spawn point{arg}");
		}
	}
	internal class ViewTargetCommand : TwitchCommand
	{
		public override string Name => "viewtarget";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0018: 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)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (args.Length > 1)
			{
				ExecuteForViewer(twitchMessage, ParseUsername(args[0]));
				return;
			}
			TwitchMessage twitchMessage2 = twitchMessage;
			TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
			ExecuteForViewer(twitchMessage2, ((TwitchUser)(ref user)).Username);
		}

		private void ExecuteForViewer(TwitchMessage twitchMessage, string targetViewerUsername)
		{
			//IL_000a: 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)
			//IL_0022: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			string s = targetViewerUsername;
			string colorHex = "#FFFFFF";
			TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
			TwitchUser val = default(TwitchUser);
			if (((TwitchUser)(ref user)).Username == targetViewerUsername)
			{
				user = ((TwitchMessage)(ref twitchMessage)).User;
				s = ((TwitchUser)(ref user)).DisplayName;
				user = ((TwitchMessage)(ref twitchMessage)).User;
				colorHex = ((TwitchUser)(ref user)).Color;
			}
			else if (API.TryGetUserByUsername(targetViewerUsername, ref val))
			{
				s = ((TwitchUser)(ref val)).DisplayName;
				colorHex = ((TwitchUser)(ref val)).Color;
			}
			string text = s.RichReadableColor(colorHex);
			PlayerControllerB target = TargetPlayerManager.GetTarget(targetViewerUsername);
			if ((Object)(object)target == (Object)null)
			{
				MessageManger.Instance?.ShowMessage_LocalClient(text + " is not targeting anyone");
			}
			else
			{
				MessageManger.Instance?.ShowMessage_LocalClient(text + " is targeting " + target.playerUsername);
			}
		}
	}
}
namespace com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Moderator
{
	internal class GiveSpawnCommand : TwitchCommand
	{
		public override string Name => "givespawn";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!SpawnPointManager.IsEnabled || !((TwitchMessage)(ref twitchMessage)).User.IsModeratorOrHigher())
			{
				return;
			}
			string displayNameWithReadableColor = ((TwitchMessage)(ref twitchMessage)).User.GetDisplayNameWithReadableColor();
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			string text = ParseUsername(parsedArgs.GetPositional(0));
			if (string.IsNullOrWhiteSpace(text) || text.Length < 4)
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " command usage is " + TwitchCommandManager.Prefix + Name + " <target_username> <amount>");
				return;
			}
			float positionalFloat = parsedArgs.GetPositionalFloat(1, SpawnPointManager.PriceForEnemy);
			string s = text;
			string colorHex = "#FFFFFF";
			TwitchUser val = default(TwitchUser);
			if (API.TryGetUserByUsername(text, ref val))
			{
				s = ((TwitchUser)(ref val)).DisplayName;
				colorHex = ((TwitchUser)(ref val)).Color;
			}
			string text2 = s.RichReadableColor(colorHex);
			SpawnPointManager.Add(text, positionalFloat);
			float num = SpawnPointManager.Get(text);
			string text3 = ((positionalFloat > 0f) ? "gave" : "removed");
			string text4 = ((positionalFloat == 1f) ? "" : "s");
			MessageManger.Instance?.ShowMessage_LocalClient($"{displayNameWithReadableColor} {text3} {text2} {Mathf.Abs(positionalFloat)} spawn point{text4} ({num} total) {SpawnPointManager.UseSpawnPointText}");
		}
	}
	internal class GiveSpawnRandomCommand : TwitchCommand
	{
		public override string Name => "givespawnrandom";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			if (SpawnPointManager.IsEnabled && ((TwitchMessage)(ref twitchMessage)).User.IsModeratorOrHigher())
			{
				string displayNameWithReadableColor = ((TwitchMessage)(ref twitchMessage)).User.GetDisplayNameWithReadableColor();
				ParsedArgs parsedArgs = ParsedArgs.Parse(args);
				float positionalFloat = parsedArgs.GetPositionalFloat(0, SpawnPointManager.PriceForEnemy);
				int positionalInt = parsedArgs.GetPositionalInt(1, 1);
				TwitchUser[] array = (from user in API.GetUsersSeenWithin(TimeSpan.FromMinutes(positionalInt))
					where IsUserAllowedForGiveaway(user, ((TwitchMessage)(ref twitchMessage)).User)
					select user).ToArray();
				if (array.Length == 0)
				{
					string arg = ((positionalInt == 1) ? "" : "s");
					MessageManger.Instance?.ShowMessage_LocalClient($"Could not find any active Twitch users within {positionalInt} minute{arg} for the giveaway");
					return;
				}
				TwitchUser twitchUser = array[Random.Range(0, array.Length)];
				MessageManger.Instance?.ShowMessage_LocalClient(twitchUser.GetDisplayNameWithReadableColor() + " won the spawn points giveaway!");
				SpawnPointManager.Add(((TwitchUser)(ref twitchUser)).Username, positionalFloat);
				float num = SpawnPointManager.Get(((TwitchUser)(ref twitchUser)).Username);
				string text = ((positionalFloat == 1f) ? "" : "s");
				MessageManger.Instance?.ShowMessage_LocalClient($"{twitchUser.GetDisplayNameWithReadableColor()} received {positionalFloat} spawn point{text} ({num} total) {SpawnPointManager.UseSpawnPointText}");
			}
		}

		private static bool IsUserAllowedForGiveaway(TwitchUser twitchUser, TwitchUser executingTwitchUser)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (false && twitchUser == executingTwitchUser)
			{
				return false;
			}
			if (true && ((TwitchUser)(ref twitchUser)).IsBroadcaster)
			{
				return false;
			}
			if (TwitchIntegrationManager.IsBotUser(twitchUser))
			{
				return false;
			}
			return true;
		}
	}
	internal class InfoCommand : TwitchCommand
	{
		public override string Name => "info";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			if (!((TwitchMessage)(ref twitchMessage)).User.IsModeratorOrHigher())
			{
				return;
			}
			bool isSubEventEnabled = TwitchIntegrationManager.IsSubEventEnabled;
			bool isCheerEventEnabled = TwitchIntegrationManager.IsCheerEventEnabled;
			bool isRaidEventEnabled = TwitchIntegrationManager.IsRaidEventEnabled;
			bool isEnabled = SpawnPointManager.IsEnabled;
			MessageSettings messageSettings = new MessageSettings(25f);
			MessageManger.Instance?.ShowMessage_LocalClient("--- MonsterHotkeys v3.2.0 Info ---", messageSettings);
			if (!isSubEventEnabled && !isCheerEventEnabled && !isRaidEventEnabled && !isEnabled)
			{
				MessageManger.Instance?.ShowMessage_LocalClient("subs/cheers/raids/spawn-points are not enabled", messageSettings);
				return;
			}
			if (isSubEventEnabled)
			{
				int num = 1;
				int value = ConfigManager.TwitchSubEvent_Tier2EnemyMultiplier.Value;
				int value2 = ConfigManager.TwitchSubEvent_Tier3EnemyMultiplier.Value;
				MessageManger.Instance?.ShowMessage_LocalClient($"Tier 1 sub/gift = {num} Random Enemy", messageSettings);
				MessageManger.Instance?.ShowMessage_LocalClient($"Tier 2 sub/gift = {num * value} Random Enemy", messageSettings);
				MessageManger.Instance?.ShowMessage_LocalClient($"Tier 3 sub/gift = {num * value2} Random Enemy", messageSettings);
			}
			if (isCheerEventEnabled)
			{
				MessageManger.Instance?.ShowMessage_LocalClient($"{TwitchCheerHandler.PriceForEnemy} bits = Random Enemy", messageSettings);
				MessageManger.Instance?.ShowMessage_LocalClient($"{TwitchCheerHandler.PriceForPlushies} bits = Random Plushies", messageSettings);
			}
			if (isRaidEventEnabled)
			{
				int value3 = ConfigManager.TwitchRaidEvent_ViewersPerEnemy.Value;
				int value4 = ConfigManager.TwitchRaidEvent_MaxSpawnCount.Value;
				MessageManger.Instance?.ShowMessage_LocalClient($"Raids: Every {value3} viewers = Random Enemy ({value4} max)", messageSettings);
			}
			if (SpawnPointManager.IsEnabled)
			{
				MessageManger.Instance?.ShowMessage_LocalClient($"{SpawnPointManager.PriceForEnemy} spawn points = Random Enemy", messageSettings);
				MessageManger.Instance?.ShowMessage_LocalClient($"{SpawnPointManager.PriceForPlushies} spawn points = Random Plushies", messageSettings);
				MessageManger.Instance?.ShowMessage_LocalClient($"Death = {SpawnPointManager.RewardPointsPerDeath} spawn points reward", messageSettings);
				MessageManger.Instance?.ShowMessage_LocalClient($"Crewmate Death = {SpawnPointManager.RewardPointsPerCrewmateDeath} spawn points reward", messageSettings);
				MessageManger.Instance?.ShowMessage_LocalClient($"{SpawnPointManager.MaxEnemySpawnsPerDay} max enemy spawns from spawn points per in-game day", messageSettings);
			}
			MessageManger.Instance?.ShowMessage_LocalClient($"DEBUG: {PlayerDamagePatcher.TranspilersCreated} transpilers created", messageSettings);
		}
	}
	internal class ViewAllBitsCommand : TwitchCommand
	{
		public override string Name => "viewallbits";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			if (!((TwitchMessage)(ref twitchMessage)).User.IsModeratorOrHigher())
			{
				return;
			}
			if (AccumulatedBitManger.AccumulatedBits.Count == 0)
			{
				MessageManger.Instance?.ShowMessage_LocalClient("Nobody has accumulated any bits");
				return;
			}
			int columns = 1;
			if (AccumulatedBitManger.AccumulatedBits.Count >= 20)
			{
				columns = 3;
			}
			else if (AccumulatedBitManger.AccumulatedBits.Count >= 10)
			{
				columns = 2;
			}
			Dictionary<string, int> keyValuePair = AccumulatedBitManger.AccumulatedBits.OrderByDescending((KeyValuePair<string, int> x) => x.Value).ToDictionary((KeyValuePair<string, int> a) => a.Key, (KeyValuePair<string, int> b) => b.Value);
			MessageManger.Instance?.ShowMessage_LocalClient(Utils.GetFormattedKeyValuePairMessage(keyValuePair, columns, "{key} {value} bits"));
		}
	}
	internal class ViewAllSpawnCommand : TwitchCommand
	{
		public override string Name => "viewallspawn";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!SpawnPointManager.IsEnabled || !((TwitchMessage)(ref twitchMessage)).User.IsModeratorOrHigher())
			{
				return;
			}
			if (SpawnPointManager.SpawnPoints.Count == 0)
			{
				MessageManger.Instance?.ShowMessage_LocalClient("Nobody has spawn points");
				return;
			}
			int columns = 1;
			if (SpawnPointManager.SpawnPoints.Count >= 20)
			{
				columns = 3;
			}
			else if (SpawnPointManager.SpawnPoints.Count >= 10)
			{
				columns = 2;
			}
			Dictionary<string, float> keyValuePair = SpawnPointManager.SpawnPoints.OrderByDescending((KeyValuePair<string, float> x) => x.Value).ToDictionary((KeyValuePair<string, float> a) => a.Key, (KeyValuePair<string, float> b) => b.Value);
			MessageManger.Instance?.ShowMessage_LocalClient(Utils.GetFormattedKeyValuePairMessage(keyValuePair, columns, "{key} {value} sp"));
		}
	}
	internal class ViewPlayersCommand : TwitchCommand
	{
		public override string Name => "viewplayers";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			if (!((TwitchMessage)(ref twitchMessage)).User.IsModeratorOrHigher())
			{
				return;
			}
			PlayerControllerB[] connectedPlayerScripts = PlayerUtils.ConnectedPlayerScripts;
			if (connectedPlayerScripts.Length != 0)
			{
				MessageManger.Instance?.ShowMessage_LocalClient("Players in the lobby:");
				PlayerControllerB[] array = connectedPlayerScripts;
				foreach (PlayerControllerB val in array)
				{
					MessageManger.Instance?.ShowMessage_LocalClient(val.playerUsername ?? "");
				}
			}
		}
	}
}
namespace com.github.zehsteam.MonsterHotkeys.Twitch.ChatCommands.Commands.Developer
{
	internal class DevCheerCommand : TwitchCommand
	{
		public override string Name => "devcheer";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: 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)
			//IL_0051: 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_0081: 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)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_0076: 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)
			if (!((TwitchMessage)(ref twitchMessage)).User.IsDeveloper())
			{
				return;
			}
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			int num = parsedArgs.GetPositionalInt(0, TwitchCheerHandler.PriceForEnemy);
			if (parsedArgs.TryGetInt("count", out var value))
			{
				num = value;
			}
			if (parsedArgs.TryGetInt("amount", out value))
			{
				num = value;
			}
			if (num <= 0)
			{
				return;
			}
			TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
			if (parsedArgs.TryGet("viewer", out var value2))
			{
				value2 = ParseUsername(value2);
				TwitchUser val = default(TwitchUser);
				if (!API.TryGetUserByUsername(value2, ref val))
				{
					return;
				}
				user = val;
			}
			TwitchCheerEvent cheerEvent = new TwitchCheerEvent
			{
				Channel = ((TwitchMessage)(ref twitchMessage)).Channel,
				User = user,
				Message = $"cheer{num}",
				Tags = ((TwitchMessage)(ref twitchMessage)).Tags,
				CheerAmount = num
			};
			TwitchEventHandler.HandleCheer(cheerEvent);
		}
	}
	internal class DevPlushiesCommand : TwitchCommand
	{
		public override string Name => "devplushies";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			if (!((TwitchMessage)(ref twitchMessage)).User.IsDeveloper() || (Object)(object)PlushieManager.Instance == (Object)null)
			{
				return;
			}
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			string text = parsedArgs.GetPositional(0);
			string text2 = parsedArgs.GetPositional(1);
			string text3 = "by being the mod developer";
			if (parsedArgs.TryGet("id", out var value))
			{
				text = value;
			}
			if (parsedArgs.TryGet("target", out value))
			{
				text2 = value;
			}
			if (parsedArgs.TryGet("reason", out value))
			{
				text3 = value;
			}
			string displayNameWithReadableColor = ((TwitchMessage)(ref twitchMessage)).User.GetDisplayNameWithReadableColor();
			PlayerControllerB playerScript;
			if (!string.IsNullOrWhiteSpace(text2))
			{
				if (!PlayerUtils.TryGetPlayerScriptByUsername(text2, out playerScript))
				{
					MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " no player was found with the name \"" + text2 + "\"");
					return;
				}
			}
			else
			{
				playerScript = PlayerUtils.LocalPlayerScript;
			}
			if ((Object)(object)playerScript == (Object)null)
			{
				return;
			}
			if (!PlushieManager.Instance.CanSpawnPlushiesOnPlayer(playerScript))
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " cannot spawn plushies on " + playerScript.playerUsername + " right now");
				return;
			}
			if (!string.IsNullOrWhiteSpace(text) && !PlushieManager.Instance.PoolExists(text))
			{
				MessageManger.Instance?.ShowMessage_LocalClient(displayNameWithReadableColor + " there are no plushies with the id of \"" + text + "\"");
				return;
			}
			ViewerData viewerData;
			if (parsedArgs.TryGet("viewer", out var value2))
			{
				value2 = ParseUsername(value2);
				TwitchUser user = default(TwitchUser);
				viewerData = ((!API.TryGetUserByUsername(value2, ref user)) ? new ViewerData(value2, value2, value2, "#FFFFFF") : new ViewerData(user));
			}
			else
			{
				viewerData = new ViewerData(((TwitchMessage)(ref twitchMessage)).User);
			}
			ViewerData viewer = viewerData;
			string spawnReason = text3;
			string targetPoolId = text;
			ulong? spawnedOnClientId = playerScript.actualClientId;
			SpawnPlushiesData spawnPlushiesData = new SpawnPlushiesData(viewer, SpawnSource.Twitch, spawnReason, targetPoolId, null, spawnedOnClientId);
			PlushieManager.Instance?.SpawnPlushiesFromData(spawnPlushiesData);
		}
	}
	internal class DevRaidCommand : TwitchCommand
	{
		public override string Name => "devraid";

		public override bool EnabledByDefault => true;

		public override bool EnableConfigs => false;

		public override void Execute(TwitchMessage twitchMessage, string[] args)
		{
			//IL_0002: 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_004d: 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_007d: 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_008b: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (!((TwitchMessage)(ref twitchMessage)).User.IsDeveloper())
			{
				return;
			}
			ParsedArgs parsedArgs = ParsedArgs.Parse(args);
			int num = parsedArgs.GetPositionalInt(0, 1);
			if (parsedArgs.TryGetInt("count", out var value))
			{
				num = value;
			}
			if (parsedArgs.TryGetInt("amount", out value))
			{
				num = value;
			}
			if (num <= 0)
			{
				return;
			}
			TwitchUser user = ((TwitchMessage)(ref twitchMessage)).User;
			if (parsedArgs.TryGet("viewer", out var value2)