Decompiled source of StupidChat v1.0.2

com.chouja.textchat.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.chouja.textchat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+675db819cfbf0500d2c7f955ffc61b63017ec855")]
[assembly: AssemblyProduct("com.chouja.textchat")]
[assembly: AssemblyTitle("StupidChat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace TextChatMod
{
	[BepInPlugin("com.chouja.textchat", "StupidChat", "1.0.2")]
	public class TextChatPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(PhotonNetwork), "Disconnect")]
		public static class PhotonNetwork_Disconnect_Patch
		{
			private static void Postfix()
			{
				playersWithMod.Clear();
			}
		}

		[HarmonyPatch(typeof(PlayerConnectionLog), "TimeoutMessageRoutine")]
		private class TimeoutMessagePatch
		{
			[CompilerGenerated]
			private sealed class <CustomTimeoutRoutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private object <>2__current;

				public PlayerConnectionLog instance;

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

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

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

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

				private bool MoveNext()
				{
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					//IL_002c: Expected O, but got Unknown
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = (object)new WaitForSeconds(messageTimeout.Value);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						RemoveFirstMessage(instance);
						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 bool Prefix(PlayerConnectionLog __instance, ref IEnumerator __result)
			{
				__result = CustomTimeoutRoutine(__instance);
				return false;
			}

			[IteratorStateMachine(typeof(<CustomTimeoutRoutine>d__1))]
			private static IEnumerator CustomTimeoutRoutine(PlayerConnectionLog instance)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <CustomTimeoutRoutine>d__1(0)
				{
					instance = instance
				};
			}
		}

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

			private object <>2__current;

			public TextChatPlugin <>4__this;

			private float <searchTime>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Expected O, but got Unknown
				int num = <>1__state;
				TextChatPlugin textChatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<searchTime>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!Object.op_Implicit((Object)(object)connectionLog) && <searchTime>5__2 < 30f)
				{
					connectionLog = Object.FindFirstObjectByType<PlayerConnectionLog>();
					if (!Object.op_Implicit((Object)(object)connectionLog))
					{
						GameObject val = GameObject.Find("PlayerConnectionLog");
						if (Object.op_Implicit((Object)(object)val))
						{
							connectionLog = val.GetComponent<PlayerConnectionLog>();
						}
					}
					if (Object.op_Implicit((Object)(object)connectionLog))
					{
						((BaseUnityPlugin)textChatPlugin).Logger.LogInfo((object)"Found PlayerConnectionLog via coroutine!");
						textChatPlugin.CreateChatUI();
						return false;
					}
					<searchTime>5__2 += 0.5f;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				}
				if (!Object.op_Implicit((Object)(object)connectionLog))
				{
					((BaseUnityPlugin)textChatPlugin).Logger.LogWarning((object)"Could not find PlayerConnectionLog after 30 seconds!");
				}
				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 <ForceFocusInputField>d__34 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)chatInputField != (Object)null && isTyping)
					{
						((Selectable)chatInputField).Select();
						chatInputField.ActivateInputField();
					}
					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 <ShowStartupMessage>d__27 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextChatPlugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: 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
				int num = <>1__state;
				TextChatPlugin textChatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					DisplayChatMessage("[StupidChat]", $"StupidChat v{((BaseUnityPlugin)textChatPlugin).Info.Metadata.Version} successfully loaded.");
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					DisplayChatMessage("[StupidChat]", "Use /help or /commands to change options.");
					((MonoBehaviour)textChatPlugin).StartCoroutine(textChatPlugin.WaitForRoomAndSendPing());
					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 <WaitAndSendPingCoroutine>d__25 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextChatPlugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				TextChatPlugin textChatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					textChatPlugin.SendModPing();
					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 <WaitForRoomAndSendPing>d__29 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextChatPlugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Expected O, but got Unknown
				int num = <>1__state;
				TextChatPlugin textChatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_004b;
				case 1:
					<>1__state = -1;
					goto IL_004b;
				case 2:
					{
						<>1__state = -1;
						textChatPlugin.SendModPing();
						return false;
					}
					IL_004b:
					if (!PhotonNetwork.InRoom)
					{
						<>2__current = (object)new WaitForSeconds(0.5f);
						<>1__state = 1;
						return true;
					}
					<>2__current = (object)new WaitForSeconds(1f);
					<>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 static TextChatPlugin Instance;

		private static PlayerConnectionLog connectionLog;

		public static bool isTyping = false;

		private static GameObject chatInputUI;

		private static TMP_InputField chatInputField;

		private static List<MonoBehaviour> disabledControllers = new List<MonoBehaviour>();

		private static List<CharacterController> disabledCharacterControllers = new List<CharacterController>();

		private static List<Rigidbody> frozenRigidbodies = new List<Rigidbody>();

		private static HashSet<string> playersWithMod = new HashSet<string>();

		private static bool hasSentPingForCurrentRoom = false;

		private static ConfigEntry<KeyCode> chatKey;

		private static ConfigEntry<Color> chatMessageColor;

		private static ConfigEntry<float> messageTimeout;

		private static ConfigEntry<int> maxMessageLength;

		private static ConfigEntry<bool> hideUnconsciousMessages;

		private static ConfigEntry<bool> showAllMessagesWhenDead;

		private static ConfigEntry<bool> useProximityChat;

		private static ConfigEntry<float> chatFadeDistance;

		private static ConfigEntry<float> chatCutDistance;

		private static bool startupMessageShown = false;

		private const byte CHAT_EVENT_CODE_LEGACY = 77;

		private const byte CHAT_EVENT_CODE_PEAK = 81;

		private const byte CHAT_MOD_PING_EVENT = 82;

		private const byte CHAT_MOD_PONG_EVENT = 83;

		private static bool eventHandlerRegistered = false;

		public static void LogInfo(string message)
		{
			TextChatPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
			}
		}

		private void Awake()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			chatKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ChatKey", (KeyCode)13, "Key to open chat");
			chatMessageColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "MessageColor", new Color(1f, 1f, 1f, 1f), "Color of chat messages");
			messageTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MessageTimeout", 10f, "How long messages stay on screen");
			maxMessageLength = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxMessageLength", 300, "Maximum length of chat messages");
			hideUnconsciousMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideUnconsciousMessages", true, "If enabled, players will not see chat from unconscious players.");
			showAllMessagesWhenDead = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowAllMessagesWhenDead", false, "If enabled, dead players will see all chat messages regardless of proximity.");
			useProximityChat = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseProximityChat", true, "If enabled, chat messages will only be visible within a certain range.");
			chatFadeDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ChatFadeDistance", 100f, "The distance at which chat messages begin to be distorted when proximity chat is enabled.");
			chatCutDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ChatCutDistance", 500f, "The distance at which chat messages are no longer visible when proximity chat is enabled.");
			SceneManager.activeSceneChanged += OnSceneChanged;
			Harmony val = new Harmony("com.chouja.textchat");
			val.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Text Chat Mod loaded!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Chat key set to: {chatKey.Value}");
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}

		private void Update()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)connectionLog))
			{
				connectionLog = Object.FindFirstObjectByType<PlayerConnectionLog>();
				if (Object.op_Implicit((Object)(object)connectionLog))
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Found PlayerConnectionLog!");
					CreateChatUI();
					return;
				}
				PlayerConnectionLog[] array = Object.FindObjectsByType<PlayerConnectionLog>((FindObjectsSortMode)0);
				if (array.Length != 0)
				{
					connectionLog = array[0];
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"Found PlayerConnectionLog using FindObjectsByType! Count: {array.Length}");
					CreateChatUI();
				}
				return;
			}
			if (Input.GetKeyDown(chatKey.Value) && !isTyping)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Chat key pressed!");
				OpenChat();
			}
			else if (isTyping)
			{
				if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271))
				{
					SendMessage();
				}
				else if (Input.GetKeyDown((KeyCode)27))
				{
					CloseChat();
				}
				if ((Object)(object)chatInputField != (Object)null && !chatInputField.isFocused)
				{
					((Selectable)chatInputField).Select();
					chatInputField.ActivateInputField();
				}
				if ((Object)(object)chatInputField != (Object)null && !chatInputField.isFocused)
				{
					string inputString = Input.inputString;
					if (!string.IsNullOrEmpty(inputString))
					{
						string text = inputString;
						for (int i = 0; i < text.Length; i++)
						{
							char c = text[i];
							switch (c)
							{
							case '\b':
								if (chatInputField.text.Length > 0)
								{
									chatInputField.text = chatInputField.text.Substring(0, chatInputField.text.Length - 1);
								}
								continue;
							case '\0':
							case '\n':
							case '\r':
								continue;
							}
							if (!char.IsControl(c))
							{
								TMP_InputField obj = chatInputField;
								obj.text += c;
							}
						}
					}
				}
			}
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.data != (Object)null)
				{
					if (isTyping)
					{
						localCharacter.refs.movement.movementModifier = 0f;
						localCharacter.data.jumpsRemaining = 0;
					}
					else
					{
						localCharacter.refs.movement.movementModifier = 1f;
						if (localCharacter.data.jumpsRemaining == 0)
						{
							localCharacter.data.jumpsRemaining = 1;
						}
					}
				}
			}
			catch
			{
			}
			if (PhotonNetwork.InRoom && !hasSentPingForCurrentRoom)
			{
				hasSentPingForCurrentRoom = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[StupidChat] Detected room join, sending ping");
				((MonoBehaviour)this).StartCoroutine(WaitAndSendPingCoroutine());
			}
			else if (!PhotonNetwork.InRoom && hasSentPingForCurrentRoom)
			{
				hasSentPingForCurrentRoom = false;
				playersWithMod.Clear();
			}
		}

		private void Start()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"TextChatPlugin Start() called");
			((MonoBehaviour)this).StartCoroutine(FindConnectionLogCoroutine());
			if (!eventHandlerRegistered && PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
				eventHandlerRegistered = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered Photon event handler");
			}
		}

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

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

		private void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			if (!startupMessageShown && ((Scene)(ref newScene)).name.ToLower().Contains("airport"))
			{
				startupMessageShown = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Airport scene detected, showing StupidChat startup message...");
				((MonoBehaviour)this).StartCoroutine(ShowStartupMessage());
			}
		}

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

		private void SendModPing()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom || PhotonNetwork.LocalPlayer == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[StupidChat] Cannot send ping - not in a room yet");
				return;
			}
			object[] array = new object[3]
			{
				PhotonNetwork.LocalPlayer.NickName,
				PhotonNetwork.LocalPlayer.UserId,
				((BaseUnityPlugin)this).Info.Metadata.Version.ToString()
			};
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)0
			};
			PhotonNetwork.RaiseEvent((byte)82, (object)array, val, SendOptions.SendReliable);
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[StupidChat] Sent mod detection ping to other players (InRoom: {PhotonNetwork.InRoom})");
		}

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

		private void SendModPong()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer != null)
			{
				object[] array = new object[3]
				{
					PhotonNetwork.LocalPlayer.NickName,
					PhotonNetwork.LocalPlayer.UserId,
					((BaseUnityPlugin)this).Info.Metadata.Version.ToString()
				};
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				};
				PhotonNetwork.RaiseEvent((byte)83, (object)array, val, SendOptions.SendReliable);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[StupidChat] Sent mod detection pong response");
			}
		}

		private void CreateChatUI()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0097: 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)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: 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_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Expected O, but got Unknown
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Expected O, but got Unknown
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Creating chat UI...");
				Canvas componentInParent = ((Component)connectionLog).GetComponentInParent<Canvas>();
				if (!Object.op_Implicit((Object)(object)componentInParent))
				{
					((BaseUnityPlugin)this).Logger.LogError((object)"ChatUI: Parent canvas not found!");
					return;
				}
				GameObject val = GameObject.Find("/GAME/GUIManager/Canvas_HUD/BarGroup/Bar");
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"ChatUI: Health bar not found, falling back to plain box.");
				}
				chatInputUI = new GameObject("ChatInputUI");
				chatInputUI.transform.SetParent(((Component)componentInParent).transform, false);
				RectTransform val2 = chatInputUI.AddComponent<RectTransform>();
				val2.anchorMin = new Vector2(0f, 0f);
				val2.anchorMax = new Vector2(1f, 1f);
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
				GameObject val3;
				if ((Object)(object)val != (Object)null)
				{
					val3 = Object.Instantiate<GameObject>(val, chatInputUI.transform);
					((Object)val3).name = "ChatBackground";
					StaminaBar component = val3.GetComponent<StaminaBar>();
					if ((Object)(object)component != (Object)null)
					{
						Object.Destroy((Object)(object)component);
					}
					string[] array = new string[4] { "MoraleBoost", "FullBar", "OutlineOverflowLine", "LayoutGroup" };
					string[] array2 = array;
					foreach (string text in array2)
					{
						Transform val4 = val3.transform.Find(text);
						if ((Object)(object)val4 != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)val4).gameObject);
						}
					}
				}
				else
				{
					val3 = new GameObject("ChatBackground");
					val3.transform.SetParent(chatInputUI.transform, false);
					Image val5 = val3.AddComponent<Image>();
					((Graphic)val5).color = new Color(0f, 0f, 0f, 0.75f);
				}
				RectTransform val6 = val3.GetComponent<RectTransform>();
				if ((Object)(object)val6 == (Object)null)
				{
					val6 = val3.AddComponent<RectTransform>();
				}
				val6.anchorMin = new Vector2(0f, 0f);
				val6.anchorMax = new Vector2(0f, 0f);
				val6.pivot = new Vector2(0f, 0f);
				val6.anchoredPosition = new Vector2(69f, 10f);
				val6.sizeDelta = new Vector2(600f, 40f);
				GameObject val7 = new GameObject("ChatInputField");
				val7.transform.SetParent(val3.transform, false);
				RectTransform val8 = val7.AddComponent<RectTransform>();
				val8.anchorMin = new Vector2(0f, 0f);
				val8.anchorMax = new Vector2(1f, 1f);
				val8.offsetMin = new Vector2(8f, 4f);
				val8.offsetMax = new Vector2(-8f, -4f);
				GameObject val9 = new GameObject("Viewport");
				val9.transform.SetParent(val7.transform, false);
				RectTransform val10 = val9.AddComponent<RectTransform>();
				val10.anchorMin = Vector2.zero;
				val10.anchorMax = Vector2.one;
				val10.offsetMin = Vector2.zero;
				val10.offsetMax = Vector2.zero;
				val9.AddComponent<RectMask2D>();
				GameObject val11 = new GameObject("Text");
				val11.transform.SetParent(val9.transform, false);
				RectTransform val12 = val11.AddComponent<RectTransform>();
				val12.anchorMin = Vector2.zero;
				val12.anchorMax = Vector2.one;
				val12.offsetMin = Vector2.zero;
				val12.offsetMax = Vector2.zero;
				TextMeshProUGUI val13 = val11.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val13).text = string.Empty;
				((TMP_Text)val13).fontSize = 12f;
				((Graphic)val13).color = Color.white;
				((TMP_Text)val13).alignment = (TextAlignmentOptions)257;
				GameObject val14 = new GameObject("Placeholder");
				val14.transform.SetParent(val9.transform, false);
				RectTransform val15 = val14.AddComponent<RectTransform>();
				val15.anchorMin = Vector2.zero;
				val15.anchorMax = Vector2.one;
				val15.offsetMin = Vector2.zero;
				val15.offsetMax = Vector2.zero;
				TextMeshProUGUI val16 = val14.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val16).text = "Type a message and press Enter to send...";
				((TMP_Text)val16).fontSize = 12f;
				((TMP_Text)val16).alignment = (TextAlignmentOptions)257;
				((TMP_Text)val16).fontStyle = (FontStyles)2;
				((Graphic)val16).color = new Color(1f, 1f, 1f, 0.55f);
				TextMeshProUGUI componentInChildren = ((Component)connectionLog).GetComponentInChildren<TextMeshProUGUI>();
				TMP_FontAsset val17 = ((componentInChildren != null) ? ((TMP_Text)componentInChildren).font : null);
				if ((Object)(object)val17 != (Object)null)
				{
					((TMP_Text)val13).font = val17;
					((TMP_Text)val16).font = val17;
				}
				chatInputField = val7.AddComponent<TMP_InputField>();
				chatInputField.textViewport = val10;
				chatInputField.textComponent = (TMP_Text)(object)val13;
				chatInputField.placeholder = (Graphic)(object)val16;
				chatInputField.characterLimit = maxMessageLength.Value;
				chatInputField.contentType = (ContentType)0;
				chatInputField.lineType = (LineType)1;
				chatInputField.richText = false;
				chatInputField.selectionColor = new Color(0.5f, 0.5f, 1f, 0.5f);
				chatInputField.caretColor = Color.white;
				chatInputField.caretWidth = 2;
				chatInputField.caretBlinkRate = 0.85f;
				chatInputUI.SetActive(false);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Chat UI created successfully!");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Error creating chat UI: {arg}");
			}
		}

		private TMP_Text CreatePlaceholder(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Placeholder");
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val2).text = "Press Enter to send...";
			((Graphic)val2).color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
			((TMP_Text)val2).fontSize = 14f;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = new Vector2(5f, 5f);
			component.offsetMax = new Vector2(-5f, -5f);
			return (TMP_Text)(object)val2;
		}

		private void OpenChat()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)chatInputUI) || !Object.op_Implicit((Object)(object)chatInputField))
			{
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Opening chat UI...");
			isTyping = true;
			chatInputUI.SetActive(true);
			EventSystem val = EventSystem.current;
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = new GameObject("EventSystem");
				val = val2.AddComponent<EventSystem>();
				val2.AddComponent<StandaloneInputModule>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Created EventSystem");
			}
			chatInputField.text = "";
			((Selectable)chatInputField).interactable = true;
			((Selectable)chatInputField).Select();
			chatInputField.ActivateInputField();
			chatInputField.ForceLabelUpdate();
			val.SetSelectedGameObject(((Component)chatInputField).gameObject);
			((MonoBehaviour)this).StartCoroutine(ForceFocusInputField());
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Chat UI active: {chatInputUI.activeSelf}, Input field interactable: {((Selectable)chatInputField).interactable}");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Input field selected: {chatInputField.isFocused}");
			ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
			GameObject currentSelectedGameObject = val.currentSelectedGameObject;
			logger.LogInfo((object)("EventSystem selected object: " + ((currentSelectedGameObject != null) ? ((Object)currentSelectedGameObject).name : null)));
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.data != (Object)null)
				{
					localCharacter.refs.movement.movementModifier = 0f;
					localCharacter.data.jumpsRemaining = 0;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to disable movement: " + ex.Message));
			}
		}

		[IteratorStateMachine(typeof(<ForceFocusInputField>d__34))]
		private IEnumerator ForceFocusInputField()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ForceFocusInputField>d__34(0);
		}

		private void CloseChat()
		{
			if (!Object.op_Implicit((Object)(object)chatInputUI))
			{
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Closing chat UI...");
			isTyping = false;
			chatInputUI.SetActive(false);
			chatInputField.DeactivateInputField(false);
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.data != (Object)null)
				{
					localCharacter.refs.movement.movementModifier = 1f;
					localCharacter.data.jumpsRemaining = 1;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to restore movement: " + ex.Message));
			}
		}

		private static bool HandleChatCommand(string message)
		{
			if (!message.StartsWith("/"))
			{
				return false;
			}
			string[] array = message.Trim().Split(' ');
			switch (array[0].ToLower())
			{
			case "/help":
			case "/commands":
				DisplayChatMessage("[ChatMod]", "Available commands:\n/help or /commands - Show this list\n/config - Show current config values\n/useProximityChat true/false - Enable or disable proximity chat\n/chatFadeDistance value - Set the distance at which chat messages begin to be distorted\n/chatCutDistance value - Set the distance at which chat messages are no longer visible\n/hideUnconsciousMessages true/false - Show or hide unconscious player chat\n/showAllMessagesWhenDead true/false - Show or hide all chat messages when a player is dead\n/reset - Reset all configs to default values");
				return true;
			case "/config":
				DisplayChatMessage("[ChatMod]", "Current config:\n" + $"- UseProximityChat: {useProximityChat.Value}\n" + $"- ChatFadeDistance: {chatFadeDistance.Value}\n" + $"- ChatCutDistance: {chatCutDistance.Value}\n" + $"- HideUnconsciousMessages: {hideUnconsciousMessages.Value}\n" + $"- ShowAllMessagesWhenDead: {showAllMessagesWhenDead.Value}");
				return true;
			case "/useproximitychat":
			{
				if (array.Length >= 2 && bool.TryParse(array[1], out var result3))
				{
					useProximityChat.Value = result3;
					((BaseUnityPlugin)Instance).Config.Save();
					DisplayChatMessage("[ChatMod]", $"Set use proximity chat to {result3}");
				}
				else
				{
					DisplayChatMessage("[ChatMod]", "Usage: /useProximityChat true/false");
				}
				return true;
			}
			case "/chatfadedistance":
			{
				if (array.Length >= 2 && float.TryParse(array[1], out var result4))
				{
					chatFadeDistance.Value = result4;
					((BaseUnityPlugin)Instance).Config.Save();
					DisplayChatMessage("[ChatMod]", $"Set chat fade distance to {result4}");
				}
				else
				{
					DisplayChatMessage("[ChatMod]", "Usage: /chatFadeDistance value");
				}
				return true;
			}
			case "/chatcutdistance":
			{
				if (array.Length >= 2 && float.TryParse(array[1], out var result2))
				{
					chatCutDistance.Value = result2;
					((BaseUnityPlugin)Instance).Config.Save();
					DisplayChatMessage("[ChatMod]", $"Set chat cut distance to {result2}");
				}
				else
				{
					DisplayChatMessage("[ChatMod]", "Usage: /chatCutDistance value");
				}
				return true;
			}
			case "/hideunconsciousmessages":
			{
				if (array.Length >= 2 && bool.TryParse(array[1], out var result5))
				{
					hideUnconsciousMessages.Value = result5;
					((BaseUnityPlugin)Instance).Config.Save();
					DisplayChatMessage("[ChatMod]", $"Set hide unconscious messages to {result5}");
				}
				else
				{
					DisplayChatMessage("[ChatMod]", "Usage: /hideUnconsciousMessages true/false");
				}
				return true;
			}
			case "/showallmessageswhendead":
			{
				if (array.Length >= 2 && bool.TryParse(array[1], out var result))
				{
					showAllMessagesWhenDead.Value = result;
					((BaseUnityPlugin)Instance).Config.Save();
					DisplayChatMessage("[ChatMod]", $"Set show all messages when dead to {result}");
				}
				else
				{
					DisplayChatMessage("[ChatMod]", "Usage: /showAllMessagesWhenDead true/false");
				}
				return true;
			}
			case "/reset":
				useProximityChat.Value = (bool)((ConfigEntryBase)useProximityChat).DefaultValue;
				chatFadeDistance.Value = (float)((ConfigEntryBase)chatFadeDistance).DefaultValue;
				chatCutDistance.Value = (float)((ConfigEntryBase)chatCutDistance).DefaultValue;
				hideUnconsciousMessages.Value = (bool)((ConfigEntryBase)hideUnconsciousMessages).DefaultValue;
				((BaseUnityPlugin)Instance).Config.Save();
				DisplayChatMessage("[ChatMod]", "Config reset to default values.");
				return true;
			default:
				DisplayChatMessage("[ChatMod]", "Unknown command: " + array[0]);
				return true;
			}
		}

		private void SendMessage()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			string text = chatInputField.text.Trim();
			if (string.IsNullOrEmpty(text))
			{
				CloseChat();
				return;
			}
			if (HandleChatCommand(text))
			{
				CloseChat();
				return;
			}
			bool flag = false;
			try
			{
				Character localCharacter = Character.localCharacter;
				bool? obj;
				if (localCharacter == null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = localCharacter.data;
					obj = ((data != null) ? new bool?(data.dead) : null);
				}
				bool? flag2 = obj;
				flag = flag2.GetValueOrDefault();
			}
			catch
			{
			}
			object[] array = new object[4]
			{
				PhotonNetwork.LocalPlayer.NickName,
				text,
				PhotonNetwork.LocalPlayer.UserId,
				flag.ToString()
			};
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			};
			PhotonNetwork.RaiseEvent((byte)81, (object)array, val, SendOptions.SendReliable);
			CloseChat();
		}

		private static Color GetPlayerColorFromNick(string playerName)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00df: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (Character allCharacter in Character.AllCharacters)
				{
					PhotonView photonView = ((MonoBehaviourPun)allCharacter).photonView;
					object obj;
					if (photonView == null)
					{
						obj = null;
					}
					else
					{
						Player owner = photonView.Owner;
						obj = ((owner != null) ? owner.UserId : null);
					}
					string text = (string)obj;
					if (string.IsNullOrEmpty(text) || !(text == playerName))
					{
						continue;
					}
					CharacterRefs refs = allCharacter.refs;
					if (refs != null)
					{
						CharacterCustomization customization = refs.customization;
						if (((customization != null) ? new Color?(customization.PlayerColor) : null).HasValue)
						{
							return allCharacter.refs.customization.PlayerColor;
						}
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Failed to find player color for " + playerName + ": " + ex.Message));
			}
			return Color.white;
		}

		public static void DisplayChatMessage(string playerName, string message, Character? sender = null)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)connectionLog))
			{
				return;
			}
			? val;
			if (!((Object)(object)sender != (Object)null))
			{
				val = GetPlayerColorFromNick(playerName);
			}
			else
			{
				CharacterRefs refs = sender.refs;
				Color? obj;
				if (refs == null)
				{
					obj = null;
				}
				else
				{
					CharacterCustomization customization = refs.customization;
					obj = ((customization != null) ? new Color?(customization.PlayerColor) : null);
				}
				val = ((??)obj) ?? Color.white;
			}
			Color val2 = (Color)val;
			MethodInfo method = typeof(PlayerConnectionLog).GetMethod("AddMessage", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method2 = typeof(PlayerConnectionLog).GetMethod("GetColorTag", BindingFlags.Instance | BindingFlags.NonPublic);
			string text = (string)method2.Invoke(connectionLog, new object[1] { val2 });
			string text2 = (string)method2.Invoke(connectionLog, new object[1] { chatMessageColor.Value });
			string text3 = Regex.Replace(message, "<.*?>", "", RegexOptions.Singleline);
			string text4 = text + playerName + "</color>" + text2 + ": " + text3 + "</color>";
			method.Invoke(connectionLog, new object[1] { text4 });
		}

		private void OnDestroy()
		{
			if (eventHandlerRegistered && PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
				eventHandlerRegistered = false;
			}
			playersWithMod.Clear();
		}

		private static Vector3 GetCharacterPosition(Character character)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (character.IsGhost)
			{
				return ((Component)character.Ghost).transform.position;
			}
			try
			{
				_ = character.Head;
				return character.Head;
			}
			catch
			{
			}
			try
			{
				return character.Center;
			}
			catch
			{
			}
			Bodypart bodypart = character.GetBodypart((BodypartType)18);
			if (bodypart == null)
			{
				return Vector3.zero;
			}
			return ((Component)bodypart).transform.position;
		}

		private static void OnEvent(EventData ev)
		{
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			switch (ev.Code)
			{
			case 81:
			{
				object[] array3 = (object[])ev.CustomData;
				string text5 = array3[0]?.ToString() ?? "???";
				string text6 = array3[1]?.ToString() ?? "";
				string userId = array3[2]?.ToString() ?? "";
				Character localCharacter = Character.localCharacter;
				Character val = Character.AllCharacters.Find((Character c) => ((MonoBehaviourPun)c).photonView.Owner.UserId == userId);
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)Instance).Logger.LogWarning((object)("[ChatMod] Could not find Character for UserId '" + userId + "'"));
				}
				else
				{
					((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Received message from '" + text5 + "' (UserId: " + userId + "), message=" + text6));
				}
				int num;
				if (hideUnconsciousMessages.Value && (val?.data?.fullyPassedOut).GetValueOrDefault())
				{
					bool? obj;
					if (val == null)
					{
						obj = null;
					}
					else
					{
						CharacterData data = val.data;
						obj = ((data != null) ? new bool?(!data.dead) : null);
					}
					bool? flag = obj;
					num = (flag.GetValueOrDefault() ? 1 : 0);
				}
				else
				{
					num = 0;
				}
				bool flag2 = (byte)num != 0;
				if ((Object)(object)val != (Object)(object)localCharacter && flag2)
				{
					((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Hiding unconscious message from '" + text5 + "'"));
					break;
				}
				try
				{
					if ((Object)(object)localCharacter != (Object)null && useProximityChat.Value && (Object)(object)val != (Object)null && (!showAllMessagesWhenDead.Value || !localCharacter.data.dead))
					{
						Character character = (localCharacter.data.dead ? Character.observedCharacter : localCharacter);
						float num2 = Vector3.Distance(GetCharacterPosition(character), GetCharacterPosition(val));
						((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[ChatMod] Distance to '{text5}': {num2} (limit {chatCutDistance.Value})");
						if (num2 > 1000f)
						{
							((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Displaying message from '" + text5 + "' due to extreme distance"));
							num2 = 0f;
						}
						if ((Object)(object)val != (Object)(object)localCharacter)
						{
							if (num2 > chatCutDistance.Value)
							{
								((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Hiding message from '" + text5 + "' due to distance"));
								break;
							}
							if (num2 > chatFadeDistance.Value)
							{
								float distortRatio = Mathf.Clamp01(1f - Mathf.Pow(num2 / chatFadeDistance.Value, -2f));
								int length = text6.Length;
								List<string> source = text6.Split(' ').ToList();
								text6 = string.Join(" ", source.Select((string w) => new string(w.Select(delegate(char c)
								{
									float num4 = ((c == ' ') ? 0f : (w.All((char c) => char.IsUpper(c)) ? (distortRatio / 5f) : distortRatio));
									return (!(Random.value > distortRatio)) ? '.' : c;
								}).ToArray())).ToArray());
								float num3 = (float)text6.Count((char c) => c == '.' || c == ' ') / (float)length;
								if (num3 == 1f)
								{
									((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Hiding message from '" + text5 + "' due to complete distortion"));
									break;
								}
								((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[ChatMod] Distorting message from '{text5}' due to distance (distort ratio: {distortRatio})");
								if (num3 > 0.95f)
								{
									text5 = "???";
									userId = "";
								}
							}
						}
					}
				}
				catch (Exception arg)
				{
					((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"[ChatMod] Error filtering chat message: {arg}");
				}
				DisplayChatMessage(text5, text6, val);
				break;
			}
			case 77:
			{
				object[] array4 = (object[])ev.CustomData;
				DisplayChatMessage(array4[0]?.ToString() ?? "???", array4[1]?.ToString() ?? "");
				break;
			}
			case 82:
			{
				object[] array2 = (object[])ev.CustomData;
				string text3 = array2[0]?.ToString() ?? "???";
				string item2 = array2[1]?.ToString() ?? "";
				string text4 = array2[2]?.ToString() ?? "Unknown";
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[StupidChat] Received mod ping from '" + text3 + "' (v" + text4 + ")"));
				if (!playersWithMod.Contains(item2))
				{
					playersWithMod.Add(item2);
					DisplayChatMessage("[StupidChat]", text3 + " has StupidChat installed! (v" + text4 + ")");
				}
				Instance.SendModPong();
				break;
			}
			case 83:
			{
				object[] array = (object[])ev.CustomData;
				string text = array[0]?.ToString() ?? "???";
				string item = array[1]?.ToString() ?? "";
				string text2 = array[2]?.ToString() ?? "Unknown";
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[StupidChat] Received mod pong from '" + text + "' (v" + text2 + ")"));
				if (!playersWithMod.Contains(item))
				{
					playersWithMod.Add(item);
					DisplayChatMessage("[StupidChat]", text + " has StupidChat installed! (v" + text2 + ")");
				}
				break;
			}
			case 78:
			case 79:
			case 80:
				break;
			}
		}

		private static Character? FindCharacterByName(string name)
		{
			Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
			foreach (Character val in array)
			{
				if ((Object)(object)((MonoBehaviourPun)val).photonView != (Object)null && ((MonoBehaviourPun)val).photonView.Owner != null && ((MonoBehaviourPun)val).photonView.Owner.NickName == name)
				{
					return val;
				}
			}
			return null;
		}

		private static void RemoveFirstMessage(PlayerConnectionLog instance)
		{
			FieldInfo field = typeof(PlayerConnectionLog).GetField("currentLog", BindingFlags.Instance | BindingFlags.NonPublic);
			List<string> list = (List<string>)field.GetValue(instance);
			if (list.Count > 0)
			{
				list.RemoveAt(0);
				MethodInfo method = typeof(PlayerConnectionLog).GetMethod("RebuildString", BindingFlags.Instance | BindingFlags.NonPublic);
				method.Invoke(instance, null);
			}
		}
	}
	[HarmonyPatch]
	public static class InputPatches
	{
		[HarmonyPatch(typeof(EmoteWheel), "OnEnable")]
		public static class EmoteWheel_OnEnable_Patch
		{
			private static bool Prefix(EmoteWheel __instance)
			{
				if (IsTyping)
				{
					((Component)__instance).gameObject.SetActive(false);
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		public static class CharacterInteractible_CanBeCarried_Patch
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(typeof(CharacterInteractible), "CanBeCarried", (Type[])null, (Type[])null);
			}

			private static void Postfix(ref bool __result)
			{
				if (IsTyping)
				{
					__result = false;
				}
			}
		}

		private static MethodInfo? windowBlockingInput;

		public static bool IsTyping => TextChatPlugin.isTyping;

		[HarmonyPatch(typeof(GUIManager), "UpdateWindowStatus")]
		[HarmonyPostfix]
		public static void UpdateWindowStatusPatch()
		{
			try
			{
				if (windowBlockingInput == null)
				{
					windowBlockingInput = AccessTools.PropertySetter(typeof(GUIManager), "windowBlockingInput");
				}
				if (IsTyping)
				{
					windowBlockingInput?.Invoke(GUIManager.instance, new object[1] { true });
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(CinemaCamera), "Update")]
		[HarmonyPrefix]
		public static bool UpdateCinemaCamPatch(CinemaCamera __instance)
		{
			if (IsTyping && !__instance.on)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Character), "UpdateVariablesFixed")]
		[HarmonyPrefix]
		public static bool UpdateCharacterVariablesPatch(Character __instance)
		{
			try
			{
				if (IsTyping)
				{
					__instance.input.interactIsPressed = false;
				}
			}
			catch
			{
			}
			return true;
		}

		public static bool IsInputBlocked()
		{
			try
			{
				GUIManager instance = GUIManager.instance;
				return (Object)(object)instance != (Object)null && instance.windowBlockingInput;
			}
			catch
			{
			}
			return false;
		}

		[HarmonyPatch(typeof(Input), "GetButton", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		private static bool GetButtonPrefix(string buttonName, ref bool __result)
		{
			if (IsTyping && (buttonName.Contains("Fire") || buttonName.Contains("Jump") || buttonName.Contains("Crouch")))
			{
				__result = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Input), "GetButtonDown", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		private static bool GetButtonDownPrefix(string buttonName, ref bool __result)
		{
			if (IsTyping && (buttonName.Contains("Fire") || buttonName.Contains("Jump") || buttonName.Contains("Crouch")))
			{
				__result = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Input), "GetAxis", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		private static bool GetAxisPrefix(string axisName, ref float __result)
		{
			if (IsTyping && (axisName == "Horizontal" || axisName == "Vertical" || axisName.Contains("Mouse")))
			{
				__result = 0f;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Input), "GetAxisRaw", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		private static bool GetAxisRawPrefix(string axisName, ref float __result)
		{
			if (IsTyping && (axisName == "Horizontal" || axisName == "Vertical" || axisName.Contains("Mouse")))
			{
				__result = 0f;
				return false;
			}
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}