Decompiled source of TwitchChat v1.5.3

TwitchChat.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Photon.Pun;
using REPOLib.Modules;
using TMPro;
using TwitchChatAPI;
using TwitchChatAPI.Enums;
using TwitchChatAPI.Objects;
using TwitchIntegration.Commands;
using TwitchIntegration.Core;
using TwitchIntegration.Core.Utils;
using TwitchIntegration.Game;
using TwitchIntegration.Game.Commands;
using TwitchIntegration.Game.Utils;
using TwitchIntegration.Twitch;
using TwitchIntegration.Twitch.ChannelPoints.Commands;
using TwitchIntegration.UI;
using TwitchRepoIntegration.Core;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TwitchChat")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Twitch chat integration for REPO Game")]
[assembly: AssemblyFileVersion("1.5.3.0")]
[assembly: AssemblyInformationalVersion("1.5.3-alpha.0.3+1a317d6c56219e06e8399799fc4d8814b7b5d784")]
[assembly: AssemblyProduct("TwitchRepoIntegration")]
[assembly: AssemblyTitle("TwitchChat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TwitchRepoIntegration
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TwitchChat";

		public const string PLUGIN_NAME = "TwitchRepoIntegration";

		public const string PLUGIN_VERSION = "1.5.1";
	}
}
namespace TwitchRepoIntegration.Core
{
	[HarmonyPatch(typeof(RunManager))]
	public static class RunManagerPatch
	{
		[HarmonyPatch("ChangeLevel")]
		[HarmonyPostfix]
		public static void ChangeLevel_Postfix()
		{
			EnemyUtil.Init();
		}
	}
	[HarmonyPatch(typeof(EnemyParent))]
	public static class EnemyParentPatch
	{
		public static bool spawning;

		[HarmonyPatch("Despawn")]
		[HarmonyPrefix]
		private static bool Despawn_Prefix(float ___SpawnedTimeMin, float ___SpawnedTimeMax, ref float ___SpawnedTimer)
		{
			if (spawning)
			{
				spawning = false;
				___SpawnedTimer = Random.Range(___SpawnedTimeMin, ___SpawnedTimeMax);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ChatManager), "MessageSend")]
	public static class ChatMessageSendPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ChatManager __instance, bool _possessed = false)
		{
			try
			{
				string chatMessage = __instance.chatMessage;
				GameChatMessage gameChatMessage = new GameChatMessage("", chatMessage);
				if (gameChatMessage.IsValidCommand && GameCommandProcessor.Instance.ProcessCommand(gameChatMessage))
				{
					__instance.chatMessage = "";
				}
				return true;
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Error processing chat command: " + ex.Message);
				return true;
			}
		}
	}
}
namespace TwitchIntegration
{
	public static class ConfigManager
	{
		public delegate void ConfigValueChangedHandler<T>(T oldValue, T newValue);

		public delegate void ConfigChangedHandler();

		public enum PositionPreset
		{
			TopRight,
			TopLeft,
			MiddleRight,
			MiddleLeft,
			BottomLeft,
			BottomRight,
			Manual
		}

		public const float DEFAULT_FONT_SIZE = 8f;

		public const float DEFAULT_OPACITY = 1f;

		public const PositionPreset DEFAULT_POSITION_PRESET = PositionPreset.BottomRight;

		public static readonly Vector2 DEFAULT_MANUAL_POSITION = new Vector2(0f, 0f);

		public const float DEFAULT_WIDTH = 200f;

		public const float DEFAULT_HEIGHT = 300f;

		public const float DEFAULT_BUFFER = 20f;

		public const bool DEFAULT_CHAT_WINDOW_VISIBLE = true;

		public const bool DEFAULT_SHOW_LABELS = true;

		public const float DEFAULT_BACKGROUND_OPACITY = 0.2f;

		public const float DEFAULT_MESSAGE_TTL = 0f;

		public const bool DEFAULT_ENABLE_LOGGER = false;

		public const bool DEFAULT_SHOW_TELEMETRY_UI = false;

		public const bool DEFAULT_CHANNEL_POINTS_TTS = true;

		public const bool DEFAULT_SUBSCRIBER_TTS = true;

		public const bool DEFAULT_CHATCOMMAND_ENABLED = true;

		public const string DEFAULT_TWITCH_USERNAME = "justinfan3102";

		public const string DEFAULT_TWITCH_OAUTH = "SCHMOOPIIE";

		public const string DEFAULT_TWITCH_CHANNEL = "";

		public const KeyCode DEFAULT_SETTINGS_MENU_KEY = 292;

		public const KeyCode DEFAULT_MANUAL_POSITION_KEY = 290;

		public const bool DEFAULT_REQUIRE_CHANNEL_POINTS = false;

		public const bool DEFAULT_SE_COMMAND_ENABLED = true;

		public const bool DEFAULT_REVIVE_COMMAND_ENABLED = true;

		internal static ConfigEntry<float> FontSizeConfig;

		internal static ConfigEntry<float> OpacityConfig;

		internal static ConfigEntry<PositionPreset> PresetConfig;

		internal static ConfigEntry<Vector2> ManualPositionConfig;

		internal static ConfigEntry<float> WidthConfig;

		internal static ConfigEntry<float> HeightConfig;

		internal static ConfigEntry<float> BufferConfig;

		internal static ConfigEntry<KeyCode> SettingsMenuKeyConfig;

		internal static ConfigEntry<KeyCode> ManualPositionKeyConfig;

		internal static ConfigEntry<bool> ChatWindowVisibleConfig;

		internal static ConfigEntry<bool> ShowLabelsConfig;

		internal static ConfigEntry<float> BackgroundOpacityConfig;

		internal static ConfigEntry<float> MessageTTLConfig;

		internal static ConfigEntry<bool> EnableLoggerConfig;

		internal static ConfigEntry<bool> ShowTelemetryUIConfig;

		internal static ConfigEntry<bool> ChannelPointsTTSConfig;

		internal static ConfigEntry<bool> SubscriberTTSConfig;

		internal static ConfigEntry<bool> ChatCommandsEnabledConfig;

		internal static ConfigEntry<string> TwitchUsernameConfig;

		internal static ConfigEntry<string> TwitchOAuthConfig;

		internal static ConfigEntry<string> TwitchChannelConfig;

		internal static ConfigEntry<bool> RequireChannelPointsConfig;

		internal static ConfigEntry<bool> SECommandEnabledConfig;

		internal static ConfigEntry<bool> ReviveCommandEnabledConfig;

		public static Dictionary<string, float> ttlOptions = new Dictionary<string, float>
		{
			{ "Disabled", 0f },
			{ "5 seconds", 5f },
			{ "15 seconds", 15f },
			{ "30 seconds", 30f },
			{ "1 minute", 60f },
			{ "3 minute", 180f }
		};

		public static float FontSize
		{
			get
			{
				return FontSizeConfig?.Value ?? 8f;
			}
			set
			{
				if (FontSizeConfig != null)
				{
					float value2 = FontSizeConfig.Value;
					FontSizeConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnFontSizeChanged, value2, value);
				}
			}
		}

		public static float Opacity
		{
			get
			{
				return OpacityConfig?.Value ?? 1f;
			}
			set
			{
				if (OpacityConfig != null)
				{
					float value2 = OpacityConfig.Value;
					OpacityConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnOpacityChanged, value2, value);
				}
			}
		}

		public static PositionPreset Preset
		{
			get
			{
				return PresetConfig?.Value ?? PositionPreset.BottomRight;
			}
			set
			{
				if (PresetConfig != null)
				{
					PositionPreset value2 = PresetConfig.Value;
					PresetConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnPresetChanged, value2, value);
				}
			}
		}

		public static Vector2 ManualPosition
		{
			get
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: 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)
				return ManualPositionConfig?.Value ?? DEFAULT_MANUAL_POSITION;
			}
			set
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if (ManualPositionConfig != null)
				{
					Vector2 value2 = ManualPositionConfig.Value;
					ManualPositionConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnManualPositionChanged, value2, value);
				}
			}
		}

		public static float Width
		{
			get
			{
				return WidthConfig?.Value ?? 200f;
			}
			set
			{
				if (WidthConfig != null)
				{
					float value2 = WidthConfig.Value;
					WidthConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnWidthChanged, value2, value);
				}
			}
		}

		public static float Height
		{
			get
			{
				return HeightConfig?.Value ?? 300f;
			}
			set
			{
				if (HeightConfig != null)
				{
					float value2 = HeightConfig.Value;
					HeightConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnHeightChanged, value2, value);
				}
			}
		}

		public static float Buffer
		{
			get
			{
				return BufferConfig?.Value ?? 20f;
			}
			set
			{
				if (BufferConfig != null)
				{
					float value2 = BufferConfig.Value;
					BufferConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnBufferChanged, value2, value);
				}
			}
		}

		public static KeyCode SettingsMenuKey
		{
			get
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				ConfigEntry<KeyCode> settingsMenuKeyConfig = SettingsMenuKeyConfig;
				return (KeyCode)((settingsMenuKeyConfig == null) ? 292 : ((int)settingsMenuKeyConfig.Value));
			}
			set
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if (SettingsMenuKeyConfig != null)
				{
					KeyCode value2 = SettingsMenuKeyConfig.Value;
					SettingsMenuKeyConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnSettingsMenuKeyChanged, value2, value);
				}
			}
		}

		public static KeyCode ManualPositionKey
		{
			get
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				ConfigEntry<KeyCode> manualPositionKeyConfig = ManualPositionKeyConfig;
				return (KeyCode)((manualPositionKeyConfig == null) ? 290 : ((int)manualPositionKeyConfig.Value));
			}
			set
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if (ManualPositionKeyConfig != null)
				{
					KeyCode value2 = ManualPositionKeyConfig.Value;
					ManualPositionKeyConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnManualPositionKeyChanged, value2, value);
				}
			}
		}

		public static bool ChatWindowVisible
		{
			get
			{
				return ChatWindowVisibleConfig?.Value ?? true;
			}
			set
			{
				if (ChatWindowVisibleConfig != null)
				{
					bool value2 = ChatWindowVisibleConfig.Value;
					ChatWindowVisibleConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnChatWindowVisibleChanged, value2, value);
				}
			}
		}

		public static bool ShowLabels
		{
			get
			{
				return ShowLabelsConfig?.Value ?? true;
			}
			set
			{
				if (ShowLabelsConfig != null)
				{
					bool value2 = ShowLabelsConfig.Value;
					ShowLabelsConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnShowLabelsChanged, value2, value);
				}
			}
		}

		public static float BackgroundOpacity
		{
			get
			{
				return BackgroundOpacityConfig?.Value ?? 0.2f;
			}
			set
			{
				if (BackgroundOpacityConfig != null)
				{
					float value2 = BackgroundOpacityConfig.Value;
					BackgroundOpacityConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnBackgroundOpacityChanged, value2, value);
				}
			}
		}

		public static float MessageTTL
		{
			get
			{
				return MessageTTLConfig?.Value ?? 0f;
			}
			set
			{
				if (MessageTTLConfig != null)
				{
					float value2 = MessageTTLConfig.Value;
					MessageTTLConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnMessageTTLChanged, value2, value);
				}
			}
		}

		public static bool EnableLogger
		{
			get
			{
				return EnableLoggerConfig?.Value ?? false;
			}
			set
			{
				if (EnableLoggerConfig != null)
				{
					bool value2 = EnableLoggerConfig.Value;
					EnableLoggerConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnEnableLoggerChanged, value2, value);
					LogManagerWrapper.enableLogger = value;
				}
			}
		}

		public static bool ShowTelemetryUI
		{
			get
			{
				return ShowTelemetryUIConfig?.Value ?? false;
			}
			set
			{
				if (ShowTelemetryUIConfig != null)
				{
					bool value2 = ShowTelemetryUIConfig.Value;
					ShowTelemetryUIConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnShowTelemetryUIChanged, value2, value);
				}
			}
		}

		public static bool ChannelPointsTTS
		{
			get
			{
				return ChannelPointsTTSConfig?.Value ?? true;
			}
			set
			{
				if (ChannelPointsTTSConfig != null)
				{
					bool value2 = ChannelPointsTTSConfig.Value;
					ChannelPointsTTSConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnChannelPointsTTSChanged, value2, value);
				}
			}
		}

		public static bool SubscriberTTS
		{
			get
			{
				return SubscriberTTSConfig?.Value ?? true;
			}
			set
			{
				if (SubscriberTTSConfig != null)
				{
					bool value2 = SubscriberTTSConfig.Value;
					SubscriberTTSConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnSubscriberTTSChanged, value2, value);
				}
			}
		}

		public static bool ChatCommandsEnabled
		{
			get
			{
				return ChatCommandsEnabledConfig?.Value ?? true;
			}
			set
			{
				if (ChatCommandsEnabledConfig != null)
				{
					bool value2 = ChatCommandsEnabledConfig.Value;
					ChatCommandsEnabledConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnChatCommandsEnabledChanged, value2, value);
				}
			}
		}

		public static string TwitchUsername
		{
			get
			{
				return TwitchUsernameConfig?.Value ?? "justinfan3102";
			}
			set
			{
				if (TwitchUsernameConfig != null)
				{
					string value2 = TwitchUsernameConfig.Value;
					TwitchUsernameConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnTwitchUsernameChanged, value2, value);
				}
			}
		}

		public static string TwitchOAuth
		{
			get
			{
				return TwitchOAuthConfig?.Value ?? "SCHMOOPIIE";
			}
			set
			{
				if (TwitchOAuthConfig != null)
				{
					string value2 = TwitchOAuthConfig.Value;
					TwitchOAuthConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnTwitchOAuthChanged, value2, value);
				}
			}
		}

		public static string TwitchChannel
		{
			get
			{
				return TwitchChannelConfig?.Value ?? "";
			}
			set
			{
				if (TwitchChannelConfig != null)
				{
					string value2 = TwitchChannelConfig.Value;
					TwitchChannelConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnTwitchChannelChanged, value2, value);
				}
			}
		}

		public static bool RequireChannelPoints
		{
			get
			{
				return RequireChannelPointsConfig?.Value ?? false;
			}
			set
			{
				if (RequireChannelPointsConfig != null)
				{
					bool value2 = RequireChannelPointsConfig.Value;
					RequireChannelPointsConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnRequireChannelPointsChanged, value2, value);
				}
			}
		}

		public static bool SECommandEnabled
		{
			get
			{
				return SECommandEnabledConfig?.Value ?? true;
			}
			set
			{
				if (SECommandEnabledConfig != null)
				{
					bool value2 = SECommandEnabledConfig.Value;
					SECommandEnabledConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnSECommandEnabledChanged, value2, value);
				}
			}
		}

		public static bool ReviveCommandEnabled
		{
			get
			{
				return ReviveCommandEnabledConfig?.Value ?? true;
			}
			set
			{
				if (ReviveCommandEnabledConfig != null)
				{
					bool value2 = ReviveCommandEnabledConfig.Value;
					ReviveCommandEnabledConfig.Value = value;
					NotifyValueChanged(ConfigManager.OnReviveCommandEnabledChanged, value2, value);
				}
			}
		}

		public static event ConfigChangedHandler OnAnyConfigChanged;

		public static event ConfigValueChangedHandler<float> OnFontSizeChanged;

		public static event ConfigValueChangedHandler<float> OnOpacityChanged;

		public static event ConfigValueChangedHandler<PositionPreset> OnPresetChanged;

		public static event ConfigValueChangedHandler<Vector2> OnManualPositionChanged;

		public static event ConfigValueChangedHandler<float> OnWidthChanged;

		public static event ConfigValueChangedHandler<float> OnHeightChanged;

		public static event ConfigValueChangedHandler<float> OnBufferChanged;

		public static event ConfigValueChangedHandler<KeyCode> OnSettingsMenuKeyChanged;

		public static event ConfigValueChangedHandler<KeyCode> OnManualPositionKeyChanged;

		public static event ConfigValueChangedHandler<bool> OnChatWindowVisibleChanged;

		public static event ConfigValueChangedHandler<bool> OnShowLabelsChanged;

		public static event ConfigValueChangedHandler<float> OnBackgroundOpacityChanged;

		public static event ConfigValueChangedHandler<float> OnMessageTTLChanged;

		public static event ConfigValueChangedHandler<bool> OnEnableLoggerChanged;

		public static event ConfigValueChangedHandler<bool> OnShowTelemetryUIChanged;

		public static event ConfigValueChangedHandler<bool> OnChannelPointsTTSChanged;

		public static event ConfigValueChangedHandler<bool> OnSubscriberTTSChanged;

		public static event ConfigValueChangedHandler<bool> OnChatCommandsEnabledChanged;

		public static event ConfigValueChangedHandler<string> OnTwitchUsernameChanged;

		public static event ConfigValueChangedHandler<string> OnTwitchOAuthChanged;

		public static event ConfigValueChangedHandler<string> OnTwitchChannelChanged;

		public static event ConfigValueChangedHandler<bool> OnRequireChannelPointsChanged;

		public static event ConfigValueChangedHandler<bool> OnSECommandEnabledChanged;

		public static event ConfigValueChangedHandler<bool> OnReviveCommandEnabledChanged;

		internal static void Configure(BaseUnityPlugin plugin)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Expected O, but got Unknown
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Expected O, but got Unknown
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Expected O, but got Unknown
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Expected O, but got Unknown
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Expected O, but got Unknown
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Expected O, but got Unknown
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Expected O, but got Unknown
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Expected O, but got Unknown
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Expected O, but got Unknown
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Expected O, but got Unknown
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Expected O, but got Unknown
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Expected O, but got Unknown
			//IL_05db: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Expected O, but got Unknown
			//IL_062e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0638: Expected O, but got Unknown
			//IL_067d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0687: Expected O, but got Unknown
			//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d6: Expected O, but got Unknown
			//IL_071b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0725: Expected O, but got Unknown
			FontSizeConfig = CreateConfigEntry(plugin.Config.Bind<float>("General", "FontSize", 8f, new ConfigDescription("The font size for chat messages in pixels. (Range: 6-24 pixels)", (AcceptableValueBase)null, Array.Empty<object>())), delegate(float oldValue, float newValue)
			{
				ConfigManager.OnFontSizeChanged?.Invoke(oldValue, newValue);
			});
			OpacityConfig = CreateConfigEntry(plugin.Config.Bind<float>("General", "Opacity", 1f, new ConfigDescription("The twitch chat opacity. (Recommended value = 0.85)", (AcceptableValueBase)null, Array.Empty<object>())), delegate(float oldValue, float newValue)
			{
				ConfigManager.OnOpacityChanged?.Invoke(oldValue, newValue);
			});
			PresetConfig = CreateConfigEntry(plugin.Config.Bind<PositionPreset>("Position", "Preset", PositionPreset.BottomRight, new ConfigDescription("The twitch chat position preset. (Recommended value = TopRight)", (AcceptableValueBase)null, Array.Empty<object>())), delegate(PositionPreset oldValue, PositionPreset newValue)
			{
				ConfigManager.OnPresetChanged?.Invoke(oldValue, newValue);
			});
			ManualPositionConfig = CreateConfigEntry(plugin.Config.Bind<Vector2>("Position", "Manual Position", DEFAULT_MANUAL_POSITION, new ConfigDescription("The position of the twitch chat as X, Y coordinates when using Manual position preset.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(Vector2 oldValue, Vector2 newValue)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				ConfigManager.OnManualPositionChanged?.Invoke(oldValue, newValue);
			});
			WidthConfig = CreateConfigEntry(plugin.Config.Bind<float>("Dimensions", "Width", 200f, new ConfigDescription("The width of the twitch chat window. (Recommended value = 375)", (AcceptableValueBase)null, Array.Empty<object>())), delegate(float oldValue, float newValue)
			{
				ConfigManager.OnWidthChanged?.Invoke(oldValue, newValue);
			});
			HeightConfig = CreateConfigEntry(plugin.Config.Bind<float>("Dimensions", "Height", 300f, new ConfigDescription("The height of the twitch chat window. (Recommended value = 375)", (AcceptableValueBase)null, Array.Empty<object>())), delegate(float oldValue, float newValue)
			{
				ConfigManager.OnHeightChanged?.Invoke(oldValue, newValue);
			});
			BufferConfig = CreateConfigEntry(plugin.Config.Bind<float>("Dimensions", "Buffer", 20f, new ConfigDescription("The buffer between edge of screen added to presets. (Recommended value = 20)", (AcceptableValueBase)null, Array.Empty<object>())), delegate(float oldValue, float newValue)
			{
				ConfigManager.OnBufferChanged?.Invoke(oldValue, newValue);
			});
			SettingsMenuKeyConfig = CreateConfigEntry(plugin.Config.Bind<KeyCode>("Key Bindings", "SettingsMenu", (KeyCode)292, new ConfigDescription("The key to toggle the Twitch settings menu", (AcceptableValueBase)null, Array.Empty<object>())), delegate(KeyCode oldValue, KeyCode newValue)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				ConfigManager.OnSettingsMenuKeyChanged?.Invoke(oldValue, newValue);
			});
			ManualPositionKeyConfig = CreateConfigEntry(plugin.Config.Bind<KeyCode>("Key Bindings", "ManualPosition", (KeyCode)290, new ConfigDescription("The key to enable manual positioning of the chat window", (AcceptableValueBase)null, Array.Empty<object>())), delegate(KeyCode oldValue, KeyCode newValue)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				ConfigManager.OnManualPositionKeyChanged?.Invoke(oldValue, newValue);
			});
			ChatWindowVisibleConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Chat Window", "Visible", true, new ConfigDescription("Whether the chat window is visible", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnChatWindowVisibleChanged?.Invoke(oldValue, newValue);
			});
			ShowLabelsConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Chat Window", "Show Labels", true, new ConfigDescription("Whether to show the channel and toggle key labels", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnShowLabelsChanged?.Invoke(oldValue, newValue);
			});
			BackgroundOpacityConfig = CreateConfigEntry(plugin.Config.Bind<float>("Chat Window", "Background Opacity", 0.2f, new ConfigDescription("The opacity of the chat window background (range: 0-1)", (AcceptableValueBase)null, Array.Empty<object>())), delegate(float oldValue, float newValue)
			{
				ConfigManager.OnBackgroundOpacityChanged?.Invoke(oldValue, newValue);
			});
			EnableLoggerConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Logger", "Enable Logger", false, new ConfigDescription("Whether to enable logging functionality", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnEnableLoggerChanged?.Invoke(oldValue, newValue);
			});
			ChannelPointsTTSConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Twitch Connection", "Channel Points TTS", true, new ConfigDescription("Whether to play TTS for Channel Points messages", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnChannelPointsTTSChanged?.Invoke(oldValue, newValue);
			});
			SubscriberTTSConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Twitch Connection", "Subscriber TTS", true, new ConfigDescription("Whether to play TTS for Subscriber messages", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnSubscriberTTSChanged?.Invoke(oldValue, newValue);
			});
			ChatCommandsEnabledConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Twitch Connection", "Chat Commands", true, new ConfigDescription("Whether to allow chat to send in-game commands", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnChatCommandsEnabledChanged?.Invoke(oldValue, newValue);
			});
			TwitchUsernameConfig = CreateConfigEntry(plugin.Config.Bind<string>("Twitch Connection", "Username", "justinfan3102", new ConfigDescription("Your Twitch username. Use 'justinfan3102' for anonymous viewing. Can be changed via config file.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(string oldValue, string newValue)
			{
				ConfigManager.OnTwitchUsernameChanged?.Invoke(oldValue, newValue);
			});
			TwitchOAuthConfig = CreateConfigEntry(plugin.Config.Bind<string>("Twitch Connection", "OAuth Token", "SCHMOOPIIE", new ConfigDescription("Your Twitch OAuth token. Use 'SCHMOOPIIE' for anonymous viewing. Can be changed via config file.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(string oldValue, string newValue)
			{
				ConfigManager.OnTwitchOAuthChanged?.Invoke(oldValue, newValue);
			});
			TwitchChannelConfig = CreateConfigEntry(plugin.Config.Bind<string>("Twitch Connection", "Channel", "", new ConfigDescription("The Twitch channel to connect to. Can be changed in-game with the /channel command.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(string oldValue, string newValue)
			{
				ConfigManager.OnTwitchChannelChanged?.Invoke(oldValue, newValue);
			});
			MessageTTLConfig = CreateConfigEntry(plugin.Config.Bind<float>("Chat Window", "Message TTL", 0f, new ConfigDescription("The time in seconds that messages should be displayed before fading out. Set to 0 to disable message fading.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(float oldValue, float newValue)
			{
				ConfigManager.OnMessageTTLChanged?.Invoke(oldValue, newValue);
			});
			RequireChannelPointsConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Twitch Connection", "Require Channel Points", false, new ConfigDescription("Whether channel points are required for commands.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnRequireChannelPointsChanged?.Invoke(oldValue, newValue);
			});
			SECommandEnabledConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Commands", "SE Command Enabled", true, new ConfigDescription("Whether the '!se' command is enabled.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnSECommandEnabledChanged?.Invoke(oldValue, newValue);
			});
			ReviveCommandEnabledConfig = CreateConfigEntry(plugin.Config.Bind<bool>("Commands", "Revive Command Enabled", true, new ConfigDescription("Whether the '!revive' command is enabled.", (AcceptableValueBase)null, Array.Empty<object>())), delegate(bool oldValue, bool newValue)
			{
				ConfigManager.OnReviveCommandEnabledChanged?.Invoke(oldValue, newValue);
			});
		}

		private static ConfigEntry<T> CreateConfigEntry<T>(ConfigEntry<T> entry, Action<T, T> changeCallback)
		{
			entry.SettingChanged += delegate
			{
				changeCallback?.Invoke(default(T), entry.Value);
				ConfigManager.OnAnyConfigChanged?.Invoke();
			};
			return entry;
		}

		internal static void ResetDefaultValues()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			bool flag = ConfigManager.OnAnyConfigChanged != null;
			ConfigChangedHandler onAnyConfigChanged = ConfigManager.OnAnyConfigChanged;
			ConfigManager.OnAnyConfigChanged = null;
			try
			{
				FontSize = 8f;
				Opacity = 1f;
				Preset = PositionPreset.BottomRight;
				ManualPosition = DEFAULT_MANUAL_POSITION;
				Width = 200f;
				Height = 300f;
				Buffer = 20f;
				SettingsMenuKey = (KeyCode)292;
				ManualPositionKey = (KeyCode)290;
				ChatWindowVisible = true;
				ShowLabels = true;
				BackgroundOpacity = 0.2f;
				EnableLogger = false;
				TwitchUsername = "justinfan3102";
				TwitchOAuth = "SCHMOOPIIE";
				MessageTTL = 0f;
				RequireChannelPoints = false;
				SECommandEnabled = true;
				ReviveCommandEnabled = true;
			}
			finally
			{
				ConfigManager.OnAnyConfigChanged = onAnyConfigChanged;
				if (flag)
				{
					ConfigManager.OnAnyConfigChanged?.Invoke();
				}
			}
		}

		private static void NotifyValueChanged<T>(ConfigValueChangedHandler<T> handler, T oldValue, T newValue)
		{
			if (handler != null)
			{
				try
				{
					handler(oldValue, newValue);
				}
				catch (Exception ex)
				{
					LogManagerWrapper.LogError("Error in config change handler: " + ex.Message);
				}
			}
		}
	}
	internal static class StateUtil
	{
		internal static bool HasLocalMapToolActive()
		{
			PlayerAvatar instance = PlayerAvatar.instance;
			return (Object)(object)instance != (Object)null && (Object)(object)instance.playerAvatarVisuals.playerAvatarRightArm.mapToolController != (Object)null && instance.playerAvatarVisuals.playerAvatarRightArm.mapToolController.Active;
		}

		internal static bool IsInLevel()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			return SemiFunc.RunIsLevel() && (Object)(object)GameDirector.instance != (Object)null && (int)GameDirector.instance.currentState == 2;
		}

		internal static bool IsChatActive()
		{
			return (Object)(object)ChatManager.instance != (Object)null && ChatManager.instance.chatActive;
		}

		internal static bool IsSpectating()
		{
			return (Object)(object)PlayerAvatar.instance != (Object)null && PlayerAvatar.instance.spectating && (Object)(object)SpectateCamera.instance != (Object)null;
		}

		internal static bool IsInMainMenu()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			return (Object)(object)GameDirector.instance != (Object)null && (int)GameDirector.instance.currentState == 2;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TwitchChat";

		public const string PLUGIN_NAME = "TwitchChat";

		public const string PLUGIN_VERSION = "1.5.3";
	}
	[BepInPlugin("TwitchChat", "TwitchChat", "1.5.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony harmony;

		public ChatWindow chatWindow;

		private bool isInitialized = false;

		internal TelemetryUI telemetryUI;

		internal static List<TwitchChatMessage> messages = new List<TwitchChatMessage>(25);

		private const int MaxStoredMessages = 25;

		internal static Plugin Instance { get; private set; }

		public static int MessageCount => messages.Count;

		private void Awake()
		{
			try
			{
				Instance = this;
				ConfigManager.Configure((BaseUnityPlugin)(object)this);
				LogManagerWrapper.Initialize(((BaseUnityPlugin)this).Logger);
				((Component)this).gameObject.transform.parent = null;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				SceneManager.sceneLoaded += OnSceneLoaded;
				API.OnMessage += API_OnMessageReceived;
				API.OnConnect += API_OnConnect;
				API.OnDisconnect += API_OnDisconnect;
				InitializePatches();
				InitializeTelemetryUI();
				InitializeChatWindow();
				SettingsMenu.Initialize();
				Task.Run((Func<Task?>)TwitchBadges.LoadAllBadges);
				LogManagerWrapper.LogInfo("Twitch Chat Window initialized successfully!!");
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Error during plugin initialization: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		private void API_OnMessageReceived(TwitchMessage e)
		{
			//IL_0003: 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)
			try
			{
				PostChannelMessageInMemory(Mappers.ToTwitchChatMessage(e));
				TwitchCommandProcessor.ProcessCommand(Mappers.ToTwitchChatMessage(e));
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Error processing message: " + ex.Message);
			}
		}

		private void API_OnDisconnect()
		{
			PostChannelMessageInMemory(new TwitchChatMessage("", "Disconnected from channel: " + API.Channel));
		}

		private void API_OnConnect()
		{
			PostChannelMessageInMemory(new TwitchChatMessage("", "Joined channel: " + API.Channel));
		}

		private void PostChannelMessageInMemory(TwitchChatMessage chatMessage)
		{
			if (!string.IsNullOrEmpty(chatMessage.FullText))
			{
				messages.Add(chatMessage);
				if (messages.Count > 25)
				{
					messages.RemoveAt(0);
				}
			}
		}

		private void Update()
		{
			SettingsMenu.Update();
		}

		private void InitializePatches()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			try
			{
				harmony = new Harmony("0cahlo.TwitchIntegration");
				harmony.PatchAll();
				LogManagerWrapper.LogInfo("Harmony patches applied successfully");
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Error applying Harmony patches: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		private bool InitializeChatWindow()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			try
			{
				ChatWindow obj = chatWindow;
				if ((Object)(object)((obj != null) ? ((Component)obj).gameObject : null) != (Object)null)
				{
					return true;
				}
				Canvas[] source = Object.FindObjectsOfType<Canvas>();
				Canvas val = ((IEnumerable<Canvas>)source).FirstOrDefault((Func<Canvas, bool>)((Canvas w) => ((Object)w).name == "HUD Canvas"));
				if ((Object)(object)val == (Object)null)
				{
					GameObject val2 = new GameObject("TwitchChatCanvas");
					val = val2.AddComponent<Canvas>();
					val.renderMode = (RenderMode)0;
					CanvasScaler val3 = val2.AddComponent<CanvasScaler>();
					val3.uiScaleMode = (ScaleMode)1;
					val3.referenceResolution = new Vector2(1920f, 1080f);
					val3.screenMatchMode = (ScreenMatchMode)0;
					val2.AddComponent<GraphicRaycaster>();
					Object.DontDestroyOnLoad((Object)(object)val2);
					LogManagerWrapper.LogInfo("Canvas marked with DontDestroyOnLoad");
				}
				else
				{
					Object.DontDestroyOnLoad((Object)(object)((Component)val).gameObject);
					LogManagerWrapper.LogInfo("Using existing canvas and marking with DontDestroyOnLoad");
				}
				GameObject val4 = new GameObject("TwitchChatWindow");
				val4.transform.SetParent(((Component)val).transform, false);
				chatWindow = val4.AddComponent<ChatWindow>();
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null)
				{
					Object.DontDestroyOnLoad((Object)(object)((Component)val).gameObject);
				}
				ChatWindow obj2 = chatWindow;
				isInitialized = (Object)(object)((obj2 != null) ? ((Component)obj2).gameObject : null) != (Object)null;
				if (isInitialized)
				{
					LogManagerWrapper.LogInfo("Chat window initialized successfully");
				}
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogWarning("Error initializing chat window: " + ex.Message + "\n" + ex.StackTrace);
				isInitialized = false;
			}
			return isInitialized;
		}

		private void OnErrorOccurred(object sender, string error)
		{
			LogManagerWrapper.LogError("Twitch error occurred: " + error);
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			LogManagerWrapper.LogInfo($"Scene changed to: {((Scene)(ref scene)).name}, Load mode: {mode}");
			try
			{
				InitializeChatWindow();
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogWarning("Error handling scene change: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		private void OnDisable()
		{
			try
			{
				SceneManager.sceneLoaded -= OnSceneLoaded;
				API.OnMessage -= API_OnMessageReceived;
				LogManagerWrapper.LogInfo("Plugin OnDestroy called - plugin is being destroyed");
				LogManagerWrapper.LogWarning("Plugin OnDestroy called - plugin is being DESTROYED");
				if ((Object)(object)telemetryUI != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)telemetryUI).gameObject);
					telemetryUI = null;
				}
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Error during plugin cleanup: " + ex.Message);
			}
		}

		public void OnChatWindowDestroyed()
		{
			LogManagerWrapper.LogWarning("Plugin notified that ChatWindow was destroyed");
			chatWindow = null;
		}

		private void InitializeTelemetryUI()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject("TelemetryUI");
				val.transform.SetParent(((Component)this).gameObject.transform, false);
				telemetryUI = val.AddComponent<TelemetryUI>();
				Object.DontDestroyOnLoad((Object)(object)val);
				LogManagerWrapper.LogInfo("Telemetry UI initialized successfully");
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Error initializing telemetry UI: " + ex.Message + "\n" + ex.StackTrace);
			}
		}
	}
}
namespace TwitchIntegration.Game
{
	public class GameChatMessage : IChatMessage
	{
		private static readonly Regex CommandRegex = new Regex("^\\/([\\w\\d]+) (.*)");

		public string DisplayName { get; private set; }

		public string FullText { get; private set; }

		public bool IsValidCommand { get; private set; }

		public string CommandName { get; private set; }

		public string CommandArgs { get; private set; }

		public GameChatMessage(string username, string text)
		{
			DisplayName = username;
			FullText = text;
			Match match = CommandRegex.Match(text);
			if (match.Groups.Count > 0)
			{
				IsValidCommand = true;
				CommandName = match.Groups[1]?.Value;
				CommandArgs = match.Groups[2]?.Value;
			}
		}
	}
	public class GameCommandProcessor
	{
		private static GameCommandProcessor singleton;

		private List<ICommand> commands;

		public static GameCommandProcessor Instance
		{
			get
			{
				if (singleton == null)
				{
					singleton = new GameCommandProcessor();
				}
				return singleton;
			}
		}

		public GameCommandProcessor()
		{
			commands = new List<ICommand>();
			RegisterCommands();
		}

		private void RegisterCommands()
		{
			commands.Add(new ChannelCommand());
			LogManagerWrapper.LogInfo($"Registered {commands.Count} game chat commands");
			foreach (ICommand command in commands)
			{
				LogManagerWrapper.LogInfo("  - " + command.CommandName);
			}
		}

		public bool ProcessCommand(IChatMessage message)
		{
			LogManagerWrapper.LogInfo("ProcessGameCommand(): " + message.FullText);
			if (!message.IsValidCommand)
			{
				return false;
			}
			ICommand command = commands.FirstOrDefault((ICommand cmd) => cmd.CanHandle(message));
			if (command != null)
			{
				try
				{
					command.Execute(message);
					return true;
				}
				catch (Exception ex)
				{
					LogManagerWrapper.LogError("Error executing command " + command.CommandName + ": " + ex.Message);
				}
			}
			return false;
		}
	}
}
namespace TwitchIntegration.Game.Utils
{
	public class EnemyUtil
	{
		[CompilerGenerated]
		private sealed class <SpawnEnemy>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public EnemySetup enemySetup;

			public Vector3 position;

			private GameObject <val>5__1;

			private EnemyParent <component>5__2;

			private List<PlayerAvatar>.Enumerator <>s__3;

			private PlayerAvatar <item>5__4;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<val>5__1 = null;
				<component>5__2 = null;
				<>s__3 = default(List<PlayerAvatar>.Enumerator);
				<item>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: 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_00be: Expected O, but got Unknown
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (SemiFunc.IsMultiplayer())
					{
						Enemies.SpawnEnemy(enemySetup, position, Quaternion.identity, false);
						return false;
					}
					EnemyParentPatch.spawning = true;
					LevelGenerator.Instance.EnemiesSpawned = -1;
					<val>5__1 = Object.Instantiate<GameObject>(enemySetup.spawnObjects[0], position, Quaternion.identity);
					<component>5__2 = <val>5__1.GetComponent<EnemyParent>();
					if (!((Object)<component>5__2 != (Object)null))
					{
						return false;
					}
					<component>5__2.SetupDone = true;
					<val>5__1.GetComponentInChildren<Enemy>().EnemyTeleported(position);
					EnemyDirector.instance.FirstSpawnPointAdd(<component>5__2);
					EnemyDirector.instance.enemiesSpawned.Add(<component>5__2);
					<>s__3 = SemiFunc.PlayerGetAll().GetEnumerator();
					try
					{
						while (<>s__3.MoveNext())
						{
							<item>5__4 = <>s__3.Current;
							<component>5__2.Enemy.PlayerAdded(<item>5__4.photonView.ViewID);
							<item>5__4 = null;
						}
					}
					finally
					{
						((IDisposable)<>s__3).Dispose();
					}
					<>s__3 = default(List<PlayerAvatar>.Enumerator);
					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 SortedDictionary<string, EnemySetup> enemySetups = new SortedDictionary<string, EnemySetup>();

		private static SortedDictionary<string, EnemySetup> modEnemySetups = new SortedDictionary<string, EnemySetup>();

		public static void Init()
		{
			enemySetups.Clear();
			modEnemySetups.Clear();
			List<EnemySetup> list = new List<EnemySetup>();
			LogManagerWrapper.LogInfo("loading all enemies:");
			LogManagerWrapper.LogInfo("difficult1:");
			list.AddRange(EnemyDirector.instance.enemiesDifficulty1);
			LogManagerWrapper.LogInfo("difficult2:");
			list.AddRange(EnemyDirector.instance.enemiesDifficulty2);
			LogManagerWrapper.LogInfo("difficult3:");
			list.AddRange(EnemyDirector.instance.enemiesDifficulty3);
			foreach (EnemySetup item in list)
			{
				LogManagerWrapper.LogInfo($"iterating through enemy list: {item}");
				if (!((Object)item).name.StartsWith("Enemy Group"))
				{
					string text = ((Object)item).name.Replace("Enemy - ", string.Empty);
					switch (text)
					{
					case "Ceiling Eye":
						enemySetups.Add("Peeper", item);
						break;
					case "Thin Man":
						enemySetups.Add("ShadowChild", item);
						break;
					case "Gnome":
						enemySetups.Add("Gnome", item);
						break;
					case "Duck":
						enemySetups.Add("ApexPredator", item);
						break;
					case "Slow Mouth":
						enemySetups.Add("Spewer", item);
						break;
					case "Valuable Thrower":
						enemySetups.Add("Rugrat", item);
						break;
					case "Animal":
						enemySetups.Add("Animal", item);
						break;
					case "Upscream":
						enemySetups.Add("Upscream", item);
						break;
					case "Hidden":
						enemySetups.Add("Hidden", item);
						break;
					case "Tumbler":
						enemySetups.Add("Chef", item);
						break;
					case "Bowtie":
						enemySetups.Add("Bowtie", item);
						break;
					case "Floater":
						enemySetups.Add("Mentalist", item);
						break;
					case "Bang":
						enemySetups.Add("Bang", item);
						break;
					case "Head":
						enemySetups.Add("Headman", item);
						break;
					case "Robe":
						enemySetups.Add("Robe", item);
						break;
					case "Hunter":
						enemySetups.Add("Huntsman", item);
						break;
					case "Runner":
						enemySetups.Add("Reaper", item);
						break;
					case "Beamer":
						enemySetups.Add("Clown", item);
						break;
					case "Slow Walker":
						enemySetups.Add("Trudge", item);
						break;
					default:
						modEnemySetups.Add(text, item);
						break;
					}
				}
			}
		}

		public static SortedDictionary<string, EnemySetup> getEnemies()
		{
			return enemySetups;
		}

		public static SortedDictionary<string, EnemySetup> getModEnemies()
		{
			return modEnemySetups;
		}

		private static EnemySetup getRandomEnemySetup()
		{
			EnemySetup[] array = enemySetups.Select((KeyValuePair<string, EnemySetup> s) => s.Value).ToArray();
			int num = Random.Range(0, array.Length - 1);
			return array[num];
		}

		private static EnemySetup getEnemySetup(string name)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			EnemySetup valueOrDefault = enemySetups.GetValueOrDefault(name, null);
			if ((Object)valueOrDefault == (Object)null)
			{
				valueOrDefault = modEnemySetups.GetValueOrDefault(name, null);
			}
			return valueOrDefault;
		}

		public static void spawnRandomEnemy(IChatMessage message)
		{
			//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)
			if (EnemyParentPatch.spawning)
			{
				MissionUI.instance.MissionText("Already spawning enemy!", Color.red, Color.red, 3f);
				Task.Run(delegate
				{
					Thread.Sleep(1000);
					spawnRandomEnemy(message);
				});
			}
			else
			{
				EnemySetup randomEnemySetup = getRandomEnemySetup();
				spawnEnemyAtCurrentPlayerPosition(message, randomEnemySetup);
			}
		}

		public static void spawnEnemyAtCurrentPlayerPosition(IChatMessage message, EnemySetup enemySetup)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)PlayerAvatar.instance).transform.position;
			((MonoBehaviour)EnemyDirector.instance).StartCoroutine(SpawnEnemy(enemySetup, position));
			MissionUI.instance.MissionText(message.DisplayName + " spawned an enemy... Run...!", Color.red, Color.red, 6f);
		}

		public static void spawnEnemy(IChatMessage message, string enemy)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			if (EnemyParentPatch.spawning)
			{
				MissionUI.instance.MissionText("Already spawning enemy '" + enemy + "'!", Color.red, Color.red, 3f);
				return;
			}
			EnemySetup enemySetup = getEnemySetup(enemy);
			if ((Object)enemySetup != (Object)null)
			{
				spawnEnemyAtCurrentPlayerPosition(message, enemySetup);
			}
			else
			{
				MissionUI.instance.MissionText("Could not find enemy named '" + enemy + "'", Color.red, Color.red, 3f);
			}
		}

		[IteratorStateMachine(typeof(<SpawnEnemy>d__10))]
		private static IEnumerator SpawnEnemy(EnemySetup enemySetup, Vector3 position)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnEnemy>d__10(0)
			{
				enemySetup = enemySetup,
				position = position
			};
		}
	}
	public class PlayerUtil
	{
		public static void killPlayer(PlayerAvatar avatar)
		{
			avatar.PlayerDeath(-1);
			LogManagerWrapper.LogInfo(SemiFunc.PlayerGetName(avatar) + " Killed!");
		}

		public static bool canRevicePlayer(PlayerAvatar avatar)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerAvatar), "deadSet");
			if (fieldInfo != null && (bool)fieldInfo.GetValue(avatar) && (Object)avatar.playerDeathHead != (Object)null)
			{
				PlayerDeathHead playerDeathHead = avatar.playerDeathHead;
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(PlayerDeathHead), "inExtractionPoint");
				if (fieldInfo2 != null)
				{
					return true;
				}
				return false;
			}
			return false;
		}

		public static bool revivePlayer(PlayerAvatar avatar)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerAvatar), "deadSet");
			if (fieldInfo != null && (bool)fieldInfo.GetValue(avatar) && (Object)avatar.playerDeathHead != (Object)null)
			{
				PlayerDeathHead playerDeathHead = avatar.playerDeathHead;
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(PlayerDeathHead), "inExtractionPoint");
				if (fieldInfo2 != null)
				{
					fieldInfo2.SetValue(playerDeathHead, true);
					avatar.Revive(false);
					fieldInfo2.SetValue(playerDeathHead, false);
					LogManagerWrapper.LogInfo(SemiFunc.PlayerGetName(avatar) + " Revived!");
					return true;
				}
				LogManagerWrapper.LogError("Failed to grab field 'PlayerDeathHead->inExtractionPoint'!");
				return false;
			}
			LogManagerWrapper.LogInfo(SemiFunc.PlayerGetName(avatar) + " is not dead. Cannot be revived!");
			return false;
		}

		public static bool reviveRandomPlayer(IChatMessage message)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerAvatar> list = new List<PlayerAvatar>();
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (canRevicePlayer(player))
				{
					list.Add(player);
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			list.ToArray();
			int index = Random.Range(0, list.Count);
			PlayerAvatar val = list[index];
			val.Revive(true);
			MissionUI.instance.MissionText(val.playerName + " was revived by " + message.DisplayName + "!", Color.green, Color.green, 3f);
			return true;
		}

		public static void healPlayer(PlayerAvatar avatar)
		{
			PlayerHealth playerHealth = avatar.playerHealth;
			FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerHealth), "maxHealth");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(PlayerHealth), "health");
			if (fieldInfo != null && fieldInfo2 != null)
			{
				avatar.playerHealth.Heal((int)fieldInfo.GetValue(playerHealth), true);
				StatsManager.instance.SetPlayerHealth(SemiFunc.PlayerGetSteamID(avatar), (int)fieldInfo2.GetValue(playerHealth), false);
				LogManagerWrapper.LogInfo(SemiFunc.PlayerGetName(avatar) + " Healed!");
			}
			else
			{
				LogManagerWrapper.LogError("Failed to grab field 'PlayerHealth->maxHealth' or 'PlayerHealth->health'!");
			}
		}

		public static void HandleTTSCommand(IChatMessage message)
		{
			ChatManager.instance.ForceSendMessage(message.FullText);
			LogManagerWrapper.LogInfo("Handling TTS: " + message.FullText + " requested by " + message.DisplayName);
		}

		public static void giveCrown(PlayerAvatar avatar)
		{
			SessionManager.instance.crownedPlayerSteamID = SemiFunc.PlayerGetSteamID(avatar);
			SessionManager.instance.CrownPlayer();
		}

		public static void teleportTo(PlayerAvatar avatar)
		{
			teleport(PlayerAvatar.instance, avatar);
		}

		public static void summon(PlayerAvatar avatar)
		{
			teleport(avatar, PlayerAvatar.instance);
		}

		private static void teleport(PlayerAvatar from, PlayerAvatar to)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)to).transform.position;
			Quaternion rotation = ((Component)to).transform.rotation;
			if (to.deadSet)
			{
				position = ((Component)to.playerDeathHead.physGrabObject).transform.position;
				rotation = ((Component)to.playerDeathHead.physGrabObject).transform.rotation;
			}
			if (!SemiFunc.IsMultiplayer())
			{
				from.Spawn(position, rotation);
			}
			else if ((Object)from.photonView != (Object)null)
			{
				if (from.deadSet)
				{
					from.playerDeathHead.physGrabObject.Teleport(position, rotation);
					return;
				}
				from.photonView.RPC("SpawnRPC", (RpcTarget)1, new object[2] { position, rotation });
			}
		}
	}
}
namespace TwitchIntegration.Game.Commands
{
	public class ChannelCommand : InGameCommand
	{
		public ChannelCommand()
			: base("channel")
		{
		}

		public override void Execute(IChatMessage message)
		{
			LogManagerWrapper.LogInfo("ChannelCommand(" + string.Join(" ", message.CommandArgs) + ")");
			string text = string.Join(" ", message.CommandArgs);
			Plugin instance = Plugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				LogManagerWrapper.LogError("Plugin instance is null");
				return;
			}
			((BaseUnityPlugin)instance).Config.Save();
			try
			{
				API.Connect(text);
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Error switching Twitch channel: " + ex.Message);
			}
		}
	}
	public abstract class InGameCommand : ICommand
	{
		public string CommandName { get; }

		public InGameCommand(string name)
		{
			CommandName = name;
		}

		public bool CanHandle(IChatMessage message)
		{
			if (!(message is GameChatMessage))
			{
				return false;
			}
			return message.IsValidCommand && message.CommandName.Equals(CommandName, StringComparison.OrdinalIgnoreCase);
		}

		public abstract void Execute(IChatMessage message);
	}
}
namespace TwitchIntegration.UI
{
	public class CoroutineRunner : MonoBehaviour
	{
		private void Awake()
		{
			((Object)this).hideFlags = (HideFlags)61;
		}
	}
	public class MessageUI
	{
		public GameObject container;

		public TextMeshProUGUI text;

		public Image background;

		public bool isVisible = true;

		private float messageFadeAlpha = 1f;

		private CanvasGroup messageCanvasGroup;

		private GameObject badgeContainer;

		private HorizontalLayoutGroup badgeLayout;

		private List<Image> badgeImages = new List<Image>();

		private List<Image> emoteImages = new List<Image>();

		public TwitchChatMessage twitchChatMessage;

		private CoroutineRunner coroutineRunner;

		public DateTime timestamp => twitchChatMessage.Timestamp;

		public MessageUI(GameObject parent, TwitchChatMessage chatMessage)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Expected O, but got Unknown
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Expected O, but got Unknown
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Expected O, but got Unknown
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Expected O, but got Unknown
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_058e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			container = new GameObject("MessageContainer");
			container.transform.SetParent(parent.transform, false);
			RectTransform val = container.AddComponent<RectTransform>();
			val.anchorMin = new Vector2(0f, 0f);
			val.anchorMax = new Vector2(1f, 0f);
			val.pivot = new Vector2(0.5f, 0f);
			val.sizeDelta = new Vector2(0f, 0f);
			messageCanvasGroup = container.AddComponent<CanvasGroup>();
			messageCanvasGroup.alpha = messageFadeAlpha * ConfigManager.Opacity;
			GameObject val2 = new GameObject("Background");
			val2.transform.SetParent(container.transform, false);
			background = val2.AddComponent<Image>();
			((Graphic)background).color = new Color(0.1f, 0.1f, 0.1f, 0f);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 1f);
			component.sizeDelta = new Vector2(-8f, -2f);
			component.offsetMin = new Vector2(0f, 0f);
			component.offsetMax = new Vector2(0f, 0f);
			badgeContainer = new GameObject("BadgeContainer");
			badgeContainer.transform.SetParent(container.transform, false);
			RectTransform val3 = badgeContainer.AddComponent<RectTransform>();
			val3.anchorMin = new Vector2(0f, 1f);
			val3.anchorMax = new Vector2(0f, 1f);
			val3.pivot = new Vector2(0f, 1f);
			val3.sizeDelta = new Vector2(0f, 0f);
			val3.offsetMin = new Vector2(2f, -2f);
			val3.offsetMax = new Vector2(2f, -2f);
			GameObject val4 = new GameObject("BadgeContainerBackground");
			val4.transform.SetParent(badgeContainer.transform, false);
			Image val5 = val4.AddComponent<Image>();
			((Graphic)val5).color = new Color(0f, 0f, 0f, 0.1f);
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.sizeDelta = Vector2.zero;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			badgeLayout = badgeContainer.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)badgeLayout).spacing = 1f;
			((LayoutGroup)badgeLayout).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)badgeLayout).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)badgeLayout).childForceExpandHeight = false;
			((LayoutGroup)badgeLayout).padding = new RectOffset(0, 0, 0, 0);
			ContentSizeFitter val6 = badgeContainer.AddComponent<ContentSizeFitter>();
			val6.horizontalFit = (FitMode)2;
			val6.verticalFit = (FitMode)2;
			GameObject val7 = new GameObject("Text");
			val7.transform.SetParent(container.transform, false);
			this.text = val7.AddComponent<TextMeshProUGUI>();
			((TMP_Text)this.text).fontSize = ConfigManager.FontSize;
			((Graphic)this.text).color = Color.white;
			((Graphic)this.text).raycastTarget = false;
			((TMP_Text)this.text).richText = true;
			((TMP_Text)this.text).alignment = (TextAlignmentOptions)513;
			((TMP_Text)this.text).overflowMode = (TextOverflowModes)0;
			RectTransform component3 = val7.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.sizeDelta = Vector2.zero;
			component3.offsetMin = new Vector2(5f, 1f);
			component3.offsetMax = new Vector2(-5f, -1f);
			coroutineRunner = container.AddComponent<CoroutineRunner>();
			twitchChatMessage = chatMessage;
			foreach (TwitchChatMessage.Badge badge in chatMessage.Badges)
			{
				AddBadge(badge.Id);
			}
			string text = MessageUtilities.FormatMessageText(chatMessage);
			((TMP_Text)this.text).text = text;
			foreach (TwitchChatMessage.Emote emote in chatMessage.Emotes)
			{
				AddEmote(emote.Code);
			}
			if (chatMessage.IsHighlightedMessage)
			{
				((Graphic)background).color = new Color(0.1f, 0.29f, 0.35f, 0.3f);
			}
			else if (chatMessage.IsUserNotice)
			{
				((Graphic)background).color = new Color(0.54f, 0.17f, 0.89f, 0.3f);
			}
			else if (chatMessage.IsFirstMessage)
			{
				((Graphic)background).color = new Color(0.2f, 0.8f, 0.2f, 0.3f);
			}
			else if (!string.IsNullOrEmpty(chatMessage.CustomRewardId))
			{
				((Graphic)background).color = new Color(1f, 0.84f, 0f, 0.3f);
			}
		}

		private void AddEmote(string emoteCode)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(emoteCode) && TwitchEmotes.TryGetEmoteSprite(ConfigManager.TwitchChannel, emoteCode, out var sprite))
			{
				GameObject val = new GameObject("Emote");
				val.transform.SetParent(((TMP_Text)text).transform.parent, false);
				LayoutElement val2 = val.AddComponent<LayoutElement>();
				float num5 = (val2.minHeight = (val2.minWidth = (val2.preferredHeight = (val2.preferredWidth = ConfigManager.FontSize * 1.2f))));
				Image val3 = val.AddComponent<Image>();
				val3.preserveAspect = true;
				((Graphic)val3).raycastTarget = false;
				val3.sprite = sprite;
				((Behaviour)val3).enabled = true;
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 0f);
				component.anchorMax = new Vector2(0f, 0f);
				component.pivot = new Vector2(0.5f, 0.5f);
				component.sizeDelta = new Vector2(num5, num5);
				emoteImages.Add(val3);
				LayoutRebuilder.ForceRebuildLayoutImmediate(container.GetComponent<RectTransform>());
			}
		}

		public void ClearEmotes()
		{
			foreach (Image emoteImage in emoteImages)
			{
				if ((Object)(object)emoteImage != (Object)null && (Object)(object)((Component)emoteImage).gameObject != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)emoteImage).gameObject);
				}
			}
			emoteImages.Clear();
		}

		public void AddBadge(string badgeId)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(badgeId))
			{
				return;
			}
			Sprite badgeSprite = TwitchBadges.GetBadgeSprite(badgeId);
			if (!((Object)(object)badgeSprite == (Object)null))
			{
				if ((Object)(object)coroutineRunner == (Object)null)
				{
					LogManagerWrapper.LogError("CoroutineRunner is null! Creating new one...");
					coroutineRunner = container.AddComponent<CoroutineRunner>();
				}
				GameObject val = new GameObject("Badge_" + badgeId);
				val.transform.SetParent(badgeContainer.transform, false);
				LayoutElement val2 = val.AddComponent<LayoutElement>();
				float minHeight = (val2.minWidth = (val2.preferredHeight = (val2.preferredWidth = ConfigManager.FontSize * 1.2f)));
				val2.minHeight = minHeight;
				GameObject val3 = new GameObject("BadgeImage");
				val3.transform.SetParent(val.transform, false);
				Image val4 = val3.AddComponent<Image>();
				val4.preserveAspect = true;
				((Graphic)val4).raycastTarget = false;
				val4.sprite = badgeSprite;
				((Behaviour)val4).enabled = true;
				RectTransform component = val3.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.sizeDelta = Vector2.zero;
				component.offsetMin = new Vector2(2f, 0f);
				component.offsetMax = new Vector2(0f, 0f);
				badgeImages.Add(val4);
				LayoutRebuilder.ForceRebuildLayoutImmediate(badgeContainer.GetComponent<RectTransform>());
				LayoutRebuilder.ForceRebuildLayoutImmediate(container.GetComponent<RectTransform>());
			}
		}

		public void ClearBadges()
		{
			foreach (Image badgeImage in badgeImages)
			{
				if ((Object)(object)badgeImage != (Object)null && (Object)(object)((Component)badgeImage).gameObject != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)badgeImage).gameObject);
				}
			}
			badgeImages.Clear();
		}

		public void Destroy()
		{
			if ((Object)(object)container != (Object)null)
			{
				ClearBadges();
				ClearEmotes();
				Object.Destroy((Object)(object)container);
			}
		}

		public void UpdateFontSize()
		{
			((TMP_Text)text).fontSize = ConfigManager.FontSize;
			UpdateOpacity();
		}

		public void UpdateOpacity()
		{
			messageCanvasGroup.alpha = messageFadeAlpha * ConfigManager.Opacity;
		}

		public void SetFadeAlpha(float alpha)
		{
			messageFadeAlpha = alpha;
			UpdateOpacity();
		}
	}
	public static class MessageUtilities
	{
		private static readonly Regex sanitizeRegex = new Regex("[^a-zA-Z0-9\\s.,;:!?\\-()]", RegexOptions.Compiled);

		private static readonly Regex whitespaceRegex = new Regex("\\s+", RegexOptions.Compiled);

		private static readonly Regex colorRegex = new Regex("^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$", RegexOptions.Compiled);

		internal static string FormatMessageText(TwitchChatMessage message)
		{
			if (message == null)
			{
				return "[Message formatting error]";
			}
			string text = message.DisplayName ?? "Anonymous";
			string input = message.FullText ?? "";
			string text2 = Sanitize(input);
			string text3 = FormatColor(message.Color);
			string text4 = "";
			int count = message.Badges.Count;
			text4 = new string(' ', count * 5);
			if (message.IsHighlightedMessage)
			{
				return text4 + "<color=" + text3 + ">" + text + "</color> <color=#FFA500>★</color> " + text2;
			}
			return string.IsNullOrEmpty(text) ? text2 : (text4 + "<color=" + text3 + ">" + text + "</color> " + text2);
		}

		internal static string Sanitize(string input)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				return string.Empty;
			}
			try
			{
				if (input.Length > 500)
				{
					input = input.Substring(0, 500) + "...";
				}
				string text = HttpUtility.HtmlDecode(input).Replace("<", "&lt;").Replace(">", "&gt;");
				string text2 = text.Normalize(NormalizationForm.FormD);
				StringBuilder stringBuilder = new StringBuilder(text2.Length);
				foreach (char c in text2)
				{
					if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
					{
						stringBuilder.Append(c);
					}
				}
				string input2 = Regex.Replace(stringBuilder.ToString(), "[\\p{C}]", "");
				return whitespaceRegex.Replace(input2, " ").Trim();
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("Sanitize error: " + ex.Message);
				return "[Text processing error]";
			}
		}

		internal static string FormatColor(string color)
		{
			if (string.IsNullOrEmpty(color))
			{
				return "#FF6B6B";
			}
			color = color.TrimStart('#');
			Match match = colorRegex.Match(color);
			if (!match.Success)
			{
				return "#FF6B6B";
			}
			string value = match.Groups[1].Value;
			string text = (match.Groups[2].Success ? match.Groups[2].Value : "FF");
			return "#" + value + text;
		}
	}
	public class ChatWindow : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <DelayedInitialization>d__41 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ChatWindow <>4__this;

			private Transform <parent>5__1;

			private GameObject <container>5__2;

			private GameObject <labelsContainer>5__3;

			private RectTransform <labelsRect>5__4;

			private GameObject <toggleKeyObj>5__5;

			private RectTransform <toggleKeyRect>5__6;

			private GameObject <channelObj>5__7;

			private RectTransform <channelRect>5__8;

			private Image <background>5__9;

			private GameObject <scrollView>5__10;

			private RectTransform <scrollViewRect>5__11;

			private GameObject <viewport>5__12;

			private RectTransform <viewportRect>5__13;

			private GameObject <content>5__14;

			private RectTransform <messagesRect>5__15;

			private float <initialWidth>5__16;

			private float <initialHeight>5__17;

			private Exception <ex>5__18;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<parent>5__1 = null;
				<container>5__2 = null;
				<labelsContainer>5__3 = null;
				<labelsRect>5__4 = null;
				<toggleKeyObj>5__5 = null;
				<toggleKeyRect>5__6 = null;
				<channelObj>5__7 = null;
				<channelRect>5__8 = null;
				<background>5__9 = null;
				<scrollView>5__10 = null;
				<scrollViewRect>5__11 = null;
				<viewport>5__12 = null;
				<viewportRect>5__13 = null;
				<content>5__14 = null;
				<messagesRect>5__15 = null;
				<ex>5__18 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Expected O, but got Unknown
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Expected O, but got Unknown
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Expected O, but got Unknown
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0149: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Expected O, but got Unknown
				//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_023a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0255: Unknown result type (might be due to invalid IL or missing references)
				//IL_0270: Unknown result type (might be due to invalid IL or missing references)
				//IL_028b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ec: Expected O, but got Unknown
				//IL_033b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0393: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0460: Unknown result type (might be due to invalid IL or missing references)
				//IL_047e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0488: Expected O, but got Unknown
				//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0505: Unknown result type (might be due to invalid IL or missing references)
				//IL_0516: Unknown result type (might be due to invalid IL or missing references)
				//IL_0527: Unknown result type (might be due to invalid IL or missing references)
				//IL_0531: Expected O, but got Unknown
				//IL_0565: Unknown result type (might be due to invalid IL or missing references)
				//IL_0576: Unknown result type (might be due to invalid IL or missing references)
				//IL_0587: Unknown result type (might be due to invalid IL or missing references)
				//IL_0598: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ec: Expected O, but got Unknown
				//IL_0634: Unknown result type (might be due to invalid IL or missing references)
				//IL_0654: Unknown result type (might be due to invalid IL or missing references)
				//IL_0674: Unknown result type (might be due to invalid IL or missing references)
				//IL_0694: Unknown result type (might be due to invalid IL or missing references)
				//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_06b4: Expected O, but got Unknown
				//IL_06f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0703: Unknown result type (might be due to invalid IL or missing references)
				//IL_0714: Unknown result type (might be due to invalid IL or missing references)
				//IL_072f: Unknown result type (might be due to invalid IL or missing references)
				//IL_074a: Unknown result type (might be due to invalid IL or missing references)
				//IL_07fd: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					try
					{
						LogManagerWrapper.LogInfo("Starting DelayedInitialization");
						<parent>5__1 = ((Component)<>4__this).transform.parent ?? ((Component)<>4__this).transform;
						<container>5__2 = new GameObject("ChatWindowContainer");
						<container>5__2.transform.SetParent(<parent>5__1, false);
						<>4__this.containerRect = <container>5__2.AddComponent<RectTransform>();
						<labelsContainer>5__3 = new GameObject("LabelsContainer");
						<labelsContainer>5__3.transform.SetParent(<container>5__2.transform, false);
						<labelsRect>5__4 = <labelsContainer>5__3.AddComponent<RectTransform>();
						<labelsRect>5__4.anchorMin = new Vector2(0f, 0f);
						<labelsRect>5__4.anchorMax = new Vector2(1f, 0f);
						<labelsRect>5__4.pivot = new Vector2(0.5f, 0f);
						<labelsRect>5__4.sizeDelta = new Vector2(0f, 48f);
						<labelsRect>5__4.anchoredPosition = new Vector2(0f, -30f);
						<toggleKeyObj>5__5 = new GameObject("ToggleKeyLabel");
						<toggleKeyObj>5__5.transform.SetParent((Transform)(object)<labelsRect>5__4, false);
						<>4__this.toggleKeyLabel = <toggleKeyObj>5__5.AddComponent<TextMeshProUGUI>();
						((TMP_Text)<>4__this.toggleKeyLabel).fontSize = 8f;
						((Graphic)<>4__this.toggleKeyLabel).color = Color.white;
						((TMP_Text)<>4__this.toggleKeyLabel).alignment = (TextAlignmentOptions)513;
						((TMP_Text)<>4__this.toggleKeyLabel).text = $"[{ConfigManager.SettingsMenuKey}] Channel: {ConfigManager.TwitchChannel}";
						<toggleKeyRect>5__6 = <toggleKeyObj>5__5.GetComponent<RectTransform>();
						<toggleKeyRect>5__6.anchorMin = new Vector2(0f, 0.5f);
						<toggleKeyRect>5__6.anchorMax = new Vector2(1f, 0.5f);
						<toggleKeyRect>5__6.pivot = new Vector2(0f, 0.5f);
						<toggleKeyRect>5__6.sizeDelta = new Vector2(0f, 24f);
						<toggleKeyRect>5__6.anchoredPosition = new Vector2(10f, 0f);
						LogManagerWrapper.LogInfo($"Setting initial toggleKeyLabel visibility to: {ConfigManager.ShowLabels}");
						<toggleKeyObj>5__5.SetActive(ConfigManager.ShowLabels);
						<channelObj>5__7 = new GameObject("ChannelLabel");
						<channelObj>5__7.transform.SetParent((Transform)(object)<labelsRect>5__4, false);
						<>4__this.channelLabel = <channelObj>5__7.AddComponent<TextMeshProUGUI>();
						((TMP_Text)<>4__this.channelLabel).fontSize = 8f;
						((Graphic)<>4__this.channelLabel).color = Color.white;
						((TMP_Text)<>4__this.channelLabel).alignment = (TextAlignmentOptions)516;
						((TMP_Text)<>4__this.channelLabel).text = "";
						<channelRect>5__8 = <channelObj>5__7.GetComponent<RectTransform>();
						<channelRect>5__8.anchorMin = new Vector2(0f, 0.5f);
						<channelRect>5__8.anchorMax = new Vector2(1f, 0.5f);
						<channelRect>5__8.pivot = new Vector2(1f, 0.5f);
						<channelRect>5__8.sizeDelta = new Vector2(0f, 24f);
						<channelRect>5__8.anchoredPosition = new Vector2(-10f, 0f);
						LogManagerWrapper.LogInfo($"Setting initial channelLabel visibility to: {ConfigManager.ShowLabels}");
						<channelObj>5__7.SetActive(ConfigManager.ShowLabels);
						<background>5__9 = <container>5__2.AddComponent<Image>();
						((Graphic)<background>5__9).color = new Color(0f, 0f, 0f, ConfigManager.BackgroundOpacity);
						((Behaviour)<background>5__9).enabled = true;
						<scrollView>5__10 = new GameObject("ScrollView");
						<scrollView>5__10.transform.SetParent(<container>5__2.transform, false);
						<>4__this.scrollRect = <scrollView>5__10.AddComponent<ScrollRect>();
						<scrollViewRect>5__11 = <scrollView>5__10.GetComponent<RectTransform>();
						<scrollViewRect>5__11.anchorMin = Vector2.zero;
						<scrollViewRect>5__11.anchorMax = Vector2.one;
						<scrollViewRect>5__11.sizeDelta = Vector2.zero;
						<scrollViewRect>5__11.offsetMin = Vector2.zero;
						<scrollViewRect>5__11.offsetMax = Vector2.zero;
						<viewport>5__12 = new GameObject("Viewport");
						<viewport>5__12.transform.SetParent(<scrollView>5__10.transform, false);
						<viewportRect>5__13 = <viewport>5__12.AddComponent<RectTransform>();
						<viewportRect>5__13.anchorMin = Vector2.zero;
						<viewportRect>5__13.anchorMax = Vector2.one;
						<viewportRect>5__13.sizeDelta = Vector2.zero;
						<viewportRect>5__13.offsetMin = Vector2.zero;
						<viewportRect>5__13.offsetMax = Vector2.zero;
						<viewport>5__12.AddComponent<Mask>().showMaskGraphic = false;
						((Graphic)<viewport>5__12.AddComponent<Image>()).color = Color.white;
						<content>5__14 = new GameObject("Content");
						<content>5__14.transform.SetParent(<viewport>5__12.transform, false);
						<>4__this.contentRect = <content>5__14.AddComponent<RectTransform>();
						<>4__this.contentRect.anchorMin = new Vector2(0f, 0f);
						<>4__this.contentRect.anchorMax = new Vector2(1f, 1f);
						<>4__this.contentRect.pivot = new Vector2(0.5f, 0f);
						<>4__this.contentRect.sizeDelta = new Vector2(0f, 0f);
						<>4__this.messagesContainer = new GameObject("MessagesContainer");
						<>4__this.messagesContainer.transform.SetParent(<content>5__14.transform, false);
						<messagesRect>5__15 = <>4__this.messagesContainer.AddComponent<RectTransform>();
						<messagesRect>5__15.anchorMin = Vector2.zero;
						<messagesRect>5__15.anchorMax = Vector2.one;
						<messagesRect>5__15.sizeDelta = Vector2.zero;
						<messagesRect>5__15.offsetMin = new Vector2(5f, 10f);
						<messagesRect>5__15.offsetMax = new Vector2(-5f, -10f);
						<>4__this.scrollRect.viewport = <viewportRect>5__13;
						<>4__this.scrollRect.content = <>4__this.contentRect;
						<>4__this.scrollRect.horizontal = false;
						<>4__this.scrollRect.vertical = true;
						<>4__this.scrollRect.scrollSensitivity = 20f;
						<initialWidth>5__16 = ConfigManager.Width;
						<initialHeight>5__17 = ConfigManager.Height;
						<>4__this.containerRect.sizeDelta = new Vector2(<initialWidth>5__16, ConfigManager.ChatWindowVisible ? <initialHeight>5__17 : 0f);
						<>4__this.originalHeight = <initialHeight>5__17;
						<>4__this.UpdateWindowPosition();
						SceneManager.activeSceneChanged += delegate
						{
							<>4__this.UpdateWindowPosition();
							LogManagerWrapper.LogInfo("Scene changed, updating UI position");
						};
						<>4__this.RegisterConfigListeners();
						<>4__this.isInitialized = true;
						LogManagerWrapper.LogInfo("DelayedInitialization completed successfully");
						<>4__this.RestoreMessages();
						<>4__this.UpdateWindowPosition();
						<parent>5__1 = null;
						<container>5__2 = null;
						<labelsContainer>5__3 = null;
						<labelsRect>5__4 = null;
						<toggleKeyObj>5__5 = null;
						<toggleKeyRect>5__6 = null;
						<channelObj>5__7 = null;
						<channelRect>5__8 = null;
						<background>5__9 = null;
						<scrollView>5__10 = null;
						<scrollViewRect>5__11 = null;
						<viewport>5__12 = null;
						<viewportRect>5__13 = null;
						<content>5__14 = null;
						<messagesRect>5__15 = null;
					}
					catch (Exception ex)
					{
						<ex>5__18 = ex;
						LogManagerWrapper.LogError("DelayedInitialization error: " + <ex>5__18.Message + "\n" + <ex>5__18.StackTrace);
						<>4__this.isInitialized = false;
					}
					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();
			}
		}

		[CompilerGenerated]
		private sealed class <FadeRoutine>d__49 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ChatWindow <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				<>4__this.UpdateFadeAffectOfAllMessages();
				<>2__current = (object)new WaitForSeconds(0.1f);
				<>1__state = 1;
				return true;
			}

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

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

		[CompilerGenerated]
		private sealed class <ProcessMessageQueueRoutine>d__35 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ChatWindow <>4__this;

			private WaitForSeconds <waitTime>5__1;

			private Exception <ex>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<waitTime>5__1 = null;
				<ex>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Expected O, but got Unknown
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					LogManagerWrapper.LogWarning("ProcessMessageQueueRoutine triggered");
					<>2__current = (object)new WaitUntil((Func<bool>)(() => <>4__this.isInitialized));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<waitTime>5__1 = new WaitForSeconds(0.1f);
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				try
				{
					if (<>4__this.messageQueue.Count > 0 && !<>4__this.isProcessingMessages)
					{
						<>4__this.ProcessMessageBatch();
						if ((Object)(object)<>4__this.scrollRect != (Object)null && (Object)(object)<>4__this.contentRect != (Object)null)
						{
							<>4__this.scrollRect.verticalNormalizedPosition = 0f;
						}
					}
				}
				catch (Exception ex)
				{
					<ex>5__2 = ex;
					LogManagerWrapper.LogError("Error in message queue processing: " + <ex>5__2.Message);
				}
				<>4__this.messageProcessedCount = 0;
				<>4__this.messageProcessingTime = 0f;
				<>4__this.lastPerformanceLog = DateTime.Now;
				<>2__current = <waitTime>5__1;
				<>1__state = 2;
				return true;
			}

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

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

		public RectTransform containerRect;

		public ScrollRect scrollRect;

		public RectTransform contentRect;

		private int maxMessages = 25;

		public bool isInitialized = false;

		private const float FadeOutDuration = 5f;

		private float lastFadeUpdate = 0f;

		private const float FadeUpdateInterval = 0.1f;

		public readonly Queue<TwitchChatMessage> messageQueue = new Queue<TwitchChatMessage>(100);

		private const int MaxQueueSize = 100;

		private bool isUpdatingPosition = false;

		private bool isProcessingMessages = false;

		private int lastScreenWidth;

		private int lastScreenHeight;

		private const string MessageTemplate = "<color=#FF6B6B>{0}</color>: {1}";

		public int messageProcessedCount = 0;

		public float messageProcessingTime = 0f;

		public DateTime lastPerformanceLog = DateTime.MinValue;

		private TextMeshProUGUI toggleKeyLabel;

		private TextMeshProUGUI channelLabel;

		private float originalHeight;

		private Coroutine heightAnimationCoroutine;

		internal List<MessageUI> messageUIs = new List<MessageUI>();

		private GameObject messagesContainer;

		private bool updatingFromToggle = false;

		private List<TwitchChatMessage> currentMessages = new List<TwitchChatMessage>();

		private Coroutine fadeCoroutine;

		public int MessageQueueCount => messageQueue.Count;

		private void Awake()
		{
			try
			{
				ConfigManager.ChatWindowVisible = true;
				((MonoBehaviour)this).StartCoroutine(DelayedInitialization());
				lastScreenWidth = Screen.width;
				lastScreenHeight = Screen.height;
				LogManagerWrapper.LogInfo("Starting ProcessMessageQueueRoutine");
				((MonoBehaviour)this).StartCoroutine(ProcessMessageQueueRoutine());
				API.OnMessage += API_OnMessageReceived;
				API.OnDisconnect += API_OnDisconnect;
				API.OnConnect += API_OnConnect;
				UpdateWindowPosition();
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("ChatWindow Awake error: " + ex.Message);
			}
		}

		private void OnDestroy()
		{
			try
			{
				API.OnMessage -= API_OnMessageReceived;
				API.OnDisconnect -= API_OnDisconnect;
				foreach (MessageUI messageUI in messageUIs)
				{
					messageUI.Destroy();
				}
				messageUIs.Clear();
				LogManagerWrapper.LogInfo("ChatWindow OnDestroy called - component is being destroyed");
				LogManagerWrapper.LogWarning("ChatWindow OnDestroy called - component is being DESTROYED");
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					Plugin.Instance.OnChatWindowDestroyed();
				}
				isInitialized = false;
				isUpdatingPosition = false;
				isProcessingMessages = false;
				if (heightAnimationCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(heightAnimationCoroutine);
				}
				toggleKeyLabel = null;
				channelLabel = null;
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("OnDestroy error: " + ex.Message);
			}
		}

		private void OnEnable()
		{
			fadeCoroutine = ((MonoBehaviour)this).StartCoroutine(FadeRoutine());
		}

		private void OnDisable()
		{
			isUpdatingPosition = false;
			isProcessingMessages = false;
			if (fadeCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(fadeCoroutine);
			}
		}

		private void API_OnMessageReceived(TwitchMessage e)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TwitchChatMessage item = Mappers.ToTwitchChatMessage(e);
				if (messageQueue.Count >= 100)
				{
					messageQueue.Dequeue();
				}
				messageQueue.Enqueue(item);
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("OnMessageReceived error: " + ex.Message);
			}
		}

		private void API_OnDisconnect()
		{
			UpdateLabels();
		}

		private void API_OnConnect()
		{
			UpdateLabels();
		}

		[IteratorStateMachine(typeof(<ProcessMessageQueueRoutine>d__35))]
		private IEnumerator ProcessMessageQueueRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ProcessMessageQueueRoutine>d__35(0)
			{
				<>4__this = this
			};
		}

		private void ProcessMessageBatch()
		{
			if (messageQueue.Count == 0 || isProcessingMessages)
			{
				return;
			}
			isProcessingMessages = true;
			DateTime now = DateTime.Now;
			try
			{
				int num = Math.Min(messageQueue.Count, 20);
				List<TwitchChatMessage> list = new List<TwitchChatMessage>();
				for (int i = 0; i < num; i++)
				{
					if (messageQueue.Count == 0)
					{
						break;
					}
					list.Add(messageQueue.Dequeue());
				}
				foreach (TwitchChatMessage item in list)
				{
					CreateMessageUI(item);
					messageProcessedCount++;
				}
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("ProcessMessageBatch error: " + ex.Message);
			}
			finally
			{
				isProcessingMessages = false;
				messageProcessingTime += (float)(DateTime.Now - now).TotalMilliseconds;
			}
		}

		public void AddMessage(TwitchChatMessage message)
		{
			if (message == null)
			{
				return;
			}
			try
			{
				if (messageQueue.Count >= 100)
				{
					messageQueue.Dequeue();
				}
				messageQueue.Enqueue(message);
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("AddMessage error: " + ex.Message);
			}
		}

		private void CreateMessageUI(TwitchChatMessage message)
		{
			try
			{
				if (message != null)
				{
					if (messageUIs.Count >= maxMessages)
					{
						messageUIs[0].Destroy();
						messageUIs.RemoveAt(0);
					}
					messageUIs.Add(new MessageUI(messagesContainer, message));
					LogManagerWrapper.LogInfo("CREATING NEW MESSAGE UI");
					UpdateMessageOrderAndPositions();
				}
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("CreateMessageUI error: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		public void ClearAllMessages()
		{
			try
			{
				messageQueue.Clear();
				foreach (MessageUI messageUI in messageUIs)
				{
					messageUI.Destroy();
				}
				messageUIs.Clear();
				LogManagerWrapper.LogInfo($"Cleared {messageUIs.Count} messages from chat window");
			}
			catch (Exception ex)
			{
				LogManagerWrapper.LogError("ClearAllMessages error: " + ex.Message);
			}
		}

		private void UpdateMessageOrderAndPositions()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			LogManagerWrapper.LogWarning("UpdateMessageOrderAndPositions");
			if (!((Object)(object)contentRect != (Object)null) || messageUIs.Count == 0)
			{
				return;
			}
			float num = 0f;
			for (int num2 = messageUIs.Count - 1; num2 >= 0; num2--)
			{
				MessageUI messageUI = messageUIs[num2];
				if (messageUI.isVisible)
				{
					RectTransform component = messageUI.container.GetComponent<RectTransform>();
					float num3 = ((TMP_Text)messageUI.text).preferredHeight + 4f;
					componen