Decompiled source of CozyChat v1.3.1

CozyChat.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CozyChat")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CozyChat")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("63672e51-848e-4583-881d-12ac0f729d94")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TextChatMod;

[BepInPlugin("com.hiccup.textchat", "CozyChat", "1.3.1")]
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>, IDisposable, IEnumerator
		{
			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_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: 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__20 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public TextChatPlugin <>4__this;

		private float <searchTime>5__1;

		private GameObject <go>5__2;

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

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

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

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

		private bool MoveNext()
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<searchTime>5__1 = 0f;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (!Object.op_Implicit((Object)(object)connectionLog) && <searchTime>5__1 < 30f)
			{
				connectionLog = Object.FindFirstObjectByType<PlayerConnectionLog>();
				if (!Object.op_Implicit((Object)(object)connectionLog))
				{
					<go>5__2 = GameObject.Find("PlayerConnectionLog");
					if (Object.op_Implicit((Object)(object)<go>5__2))
					{
						connectionLog = <go>5__2.GetComponent<PlayerConnectionLog>();
					}
					<go>5__2 = null;
				}
				if (Object.op_Implicit((Object)(object)connectionLog))
				{
					((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"Found PlayerConnectionLog via coroutine!");
					<>4__this.CreateChatUI();
					return false;
				}
				<searchTime>5__1 += 0.5f;
				<>2__current = (object)new WaitForSeconds(0.5f);
				<>1__state = 1;
				return true;
			}
			if (!Object.op_Implicit((Object)(object)connectionLog))
			{
				((BaseUnityPlugin)<>4__this).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__31 : IEnumerator<object>, IDisposable, IEnumerator
	{
		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 <ForceFocusInputField>d__31(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__24 : IEnumerator<object>, IDisposable, IEnumerator
	{
		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__24(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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			switch (<>1__state)
			{
			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("[CozyChat]", $"CozyChat v{((BaseUnityPlugin)<>4__this).Info.Metadata.Version} successfully loaded.");
				<>2__current = (object)new WaitForSeconds(0.25f);
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				DisplayChatMessage("[CozyChat]", "Use /help or /commands to change options.");
				((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.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__22 : IEnumerator<object>, IDisposable, IEnumerator
	{
		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__22(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>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
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<>4__this.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__26 : IEnumerator<object>, IDisposable, IEnumerator
	{
		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__26(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

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

		private bool MoveNext()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				goto IL_004f;
			case 1:
				<>1__state = -1;
				goto IL_004f;
			case 2:
				{
					<>1__state = -1;
					<>4__this.SendModPing();
					return false;
				}
				IL_004f:
				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> hideDeadMessages;

	private static ConfigEntry<float> chatProximityRange;

	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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		chatKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ChatKey", (KeyCode)116, "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", 100, "Maximum length of chat messages");
		hideDeadMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideDeadMessages", true, "If enabled, alive players will not see chat from dead/unconscious players.");
		chatProximityRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ChatProximityRange", 0f, "Maximum distance for receiving chat messages. 0 = unlimited range.");
		SceneManager.activeSceneChanged += OnSceneChanged;
		Harmony val = new Harmony("com.yourname.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_0092: 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 '\n':
							continue;
						}
						if (c != '\r' && c != 0 && !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)"[CozyChat] 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__20))]
	private IEnumerator FindConnectionLogCoroutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <FindConnectionLogCoroutine>d__20(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<WaitAndSendPingCoroutine>d__22))]
	private IEnumerator WaitAndSendPingCoroutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <WaitAndSendPingCoroutine>d__22(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 CozyChat startup message...");
			((MonoBehaviour)this).StartCoroutine(ShowStartupMessage());
		}
	}

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

	private void SendModPing()
	{
		//IL_006b: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Expected O, but got Unknown
		//IL_007c: 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)"[CozyChat] 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)$"[CozyChat] Sent mod detection ping to other players (InRoom: {PhotonNetwork.InRoom})");
	}

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

	private void SendModPong()
	{
		//IL_0052: 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)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_0063: 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)"[CozyChat] Sent mod detection pong response");
		}
	}

	private void CreateChatUI()
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Expected O, but got Unknown
		//IL_00ab: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Expected O, but got Unknown
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_028d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Expected O, but got Unknown
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: 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_0312: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Expected O, but got Unknown
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_0346: Unknown result type (might be due to invalid IL or missing references)
		//IL_0353: Unknown result type (might be due to invalid IL or missing references)
		//IL_0360: Unknown result type (might be due to invalid IL or missing references)
		//IL_0378: Unknown result type (might be due to invalid IL or missing references)
		//IL_037f: Expected O, but got Unknown
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Unknown result type (might be due to invalid IL or missing references)
		//IL_041a: Expected O, but got Unknown
		//IL_043a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0447: Unknown result type (might be due to invalid IL or missing references)
		//IL_0454: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bb: 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_0597: 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(500f, 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 = 20f;
			((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 = 20f;
			((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)0;
			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_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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)
		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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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__31))]
	private IEnumerator ForceFocusInputField()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ForceFocusInputField>d__31(0)
		{
			<>4__this = this
		};
	}

	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(new char[1] { ' ' });
		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/chatProximityRange value - Set chat proximity range (0 = unlimited)\n/hideDeadMessages true/false - Show or hide dead/unconscious player chat\n/reset - Reset all configs to default values");
			return true;
		case "/config":
			DisplayChatMessage("[ChatMod]", "Current config:\n" + $"- ChatProximityRange: {chatProximityRange.Value}\n" + $"- HideDeadMessages: {hideDeadMessages.Value}");
			return true;
		case "/chatproximityrange":
		{
			if (array.Length >= 2 && float.TryParse(array[1], out var result2))
			{
				chatProximityRange.Value = result2;
				((BaseUnityPlugin)Instance).Config.Save();
				DisplayChatMessage("[ChatMod]", $"Set chat proximity range to {result2}");
			}
			else
			{
				DisplayChatMessage("[ChatMod]", "Usage: /chatProximityRange value");
			}
			return true;
		}
		case "/hidedeadmessages":
		{
			if (array.Length >= 2 && bool.TryParse(array[1], out var result))
			{
				hideDeadMessages.Value = result;
				((BaseUnityPlugin)Instance).Config.Save();
				DisplayChatMessage("[ChatMod]", $"Set hide dead messages to {result}");
			}
			else
			{
				DisplayChatMessage("[ChatMod]", "Usage: /hideDeadMessages true/false");
			}
			return true;
		}
		case "/reset":
			chatProximityRange.Value = (float)((ConfigEntryBase)chatProximityRange).DefaultValue;
			hideDeadMessages.Value = (bool)((ConfigEntryBase)hideDeadMessages).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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: 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_00c8: Expected O, but got Unknown
		//IL_00cc: 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
		{
			flag = (Character.localCharacter?.data?.dead).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 GetPlayerColorFromCharacter(string playerName)
	{
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
			foreach (Character val in array)
			{
				PhotonView photonView = ((MonoBehaviourPun)val).photonView;
				object obj;
				if (photonView == null)
				{
					obj = null;
				}
				else
				{
					Player owner = photonView.Owner;
					obj = ((owner != null) ? owner.NickName : null);
				}
				string text = (string)obj;
				if (!string.IsNullOrEmpty(text) && text == playerName)
				{
					return val.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)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_0081: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)connectionLog))
		{
			Color playerColorFromCharacter = GetPlayerColorFromCharacter(playerName);
			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] { playerColorFromCharacter });
			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_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_003d: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			_ = character.Head;
			if (true)
			{
				return character.Head;
			}
		}
		catch
		{
		}
		try
		{
			return character.Center;
		}
		catch
		{
		}
		return ((Component)character).transform.position;
	}

	private static void OnEvent(EventData ev)
	{
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: 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 text7 = array3[2]?.ToString() ?? "";
			bool result;
			bool flag = bool.TryParse(array3[3]?.ToString(), out result) && result;
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[ChatMod] Received message from '{text5}' (UserId: {text7}), dead={flag}, message={text6}");
			if (flag)
			{
				text5 = "<color=red>[DEAD]</color> " + text5;
			}
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter != (Object)null && !localCharacter.data.dead && !localCharacter.data.fullyPassedOut)
				{
					if (hideDeadMessages.Value && flag)
					{
						((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Hiding dead message from '" + text5 + "'"));
						break;
					}
					if (chatProximityRange.Value > 0f)
					{
						Character val = FindCharacterByUserId(text7);
						if ((Object)(object)val == (Object)null)
						{
							((BaseUnityPlugin)Instance).Logger.LogWarning((object)("[ChatMod] Could not find Character for UserId '" + text7 + "'"));
						}
						else
						{
							float num = Vector3.Distance(GetCharacterPosition(localCharacter), GetCharacterPosition(val));
							((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[ChatMod] Distance to '{text5}': {num} (limit {chatProximityRange.Value})");
							if ((Object)(object)val != (Object)(object)localCharacter && num > chatProximityRange.Value)
							{
								((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Hiding message from '" + text5 + "' due to distance"));
								break;
							}
						}
					}
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"[ChatMod] Error filtering chat message: {arg}");
			}
			DisplayChatMessage(text5, text6);
			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)("[CozyChat] Received mod ping from '" + text3 + "' (v" + text4 + ")"));
			if (!playersWithMod.Contains(item2))
			{
				playersWithMod.Add(item2);
				DisplayChatMessage("[CozyChat]", text3 + " has CozyChat 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)("[CozyChat] Received mod pong from '" + text + "' (v" + text2 + ")"));
			if (!playersWithMod.Contains(item))
			{
				playersWithMod.Add(item);
				DisplayChatMessage("[CozyChat]", text + " has CozyChat installed! (v" + text2 + ")");
			}
			break;
		}
		case 78:
		case 79:
		case 80:
			break;
		}
	}

	private static Character FindCharacterByUserId(string userId)
	{
		Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
		foreach (Character val in array)
		{
			PhotonView photonView = ((MonoBehaviourPun)val).photonView;
			object obj;
			if (photonView == null)
			{
				obj = null;
			}
			else
			{
				Player owner = photonView.Owner;
				obj = ((owner != null) ? owner.UserId : null);
			}
			if ((string?)obj == userId)
			{
				return val;
			}
		}
		return null;
	}

	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 (TextChatPlugin.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 (TextChatPlugin.isTyping)
			{
				__result = false;
			}
		}
	}

	public static bool IsTyping => TextChatPlugin.isTyping;

	[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;
	}
}