Decompiled source of SimpleInGameChat v1.0.1

BepInEx/plugins/SimpleInGameChat.dll

Decompiled 7 hours 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.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SimpleInGameChat.Commands;
using SimpleInGameChat.Configuration;
using SimpleInGameChat.Localization;
using SimpleInGameChat.Network;
using SimpleInGameChat.UI;
using SimpleInGameChat.Utils;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SimpleInGameChat")]
[assembly: AssemblyDescription("Simple In-Game Chat mod for Old Market Simulator by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("SimpleInGameChat")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("A7C8D92B-4E56-4F3A-B123-9876543210AB")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace SimpleInGameChat
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.SimpleInGameChat";

		public const string PLUGIN_NAME = "SimpleInGameChat";

		public const string PLUGIN_VERSION = "1.0.1";

		public const string PLUGIN_AUTHOR = "Ice Box Studio";

		public const string PLUGIN_DESCRIPTION = "一个简单的游戏内聊天模组。";
	}
	[BepInPlugin("IceBoxStudio.SimpleInGameChat", "SimpleInGameChat", "1.0.1")]
	public class SimpleInGameChat : BaseUnityPlugin
	{
		public static SimpleInGameChat _Instance;

		private Harmony _harmony;

		private bool patchesApplied;

		public static SimpleInGameChat Instance => _Instance;

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			_Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			try
			{
				Logger.LogInfo((object)"=============================================");
				Logger.LogInfo((object)("SimpleInGameChat " + LocalizationManager.Instance.GetLocalizedText("plugin.initializing")));
				Logger.LogInfo((object)(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
				ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
				ApplyPatches();
				Logger.LogInfo((object)("SimpleInGameChat " + LocalizationManager.Instance.GetLocalizedText("plugin.initialized")));
				Logger.LogInfo((object)"=============================================");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("SimpleInGameChat 初始化错误: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void ApplyPatches()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (!patchesApplied)
			{
				try
				{
					_harmony = new Harmony("IceBoxStudio.SimpleInGameChat");
					_harmony.PatchAll();
					patchesApplied = true;
					return;
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("SimpleInGameChat 应用补丁错误: " + ex.Message + "\n" + ex.StackTrace));
					return;
				}
			}
			Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped"));
		}
	}
}
namespace SimpleInGameChat.Utils
{
	public static class InputActionBindingHelper
	{
		public static InputAction CreateButtonAction(string actionName, string hotkey, Action onPerformed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			string text = BuildBindingPath(hotkey);
			if (string.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			InputAction val = new InputAction(actionName, (InputActionType)1, text, (string)null, (string)null, (string)null);
			if (onPerformed != null)
			{
				val.performed += delegate
				{
					onPerformed();
				};
			}
			val.Enable();
			return val;
		}

		public static string BuildBindingPath(string hotkey)
		{
			if (string.IsNullOrWhiteSpace(hotkey))
			{
				return null;
			}
			string text = hotkey.Trim();
			if (text.Contains("<") && text.Contains(">"))
			{
				return text;
			}
			string text2 = text.ToLowerInvariant();
			return text2 switch
			{
				"leftbutton" => "<Mouse>/leftButton", 
				"rightbutton" => "<Mouse>/rightButton", 
				"middlebutton" => "<Mouse>/middleButton", 
				"backbutton" => "<Mouse>/backButton", 
				"forwardbutton" => "<Mouse>/forwardButton", 
				"buttonsouth" => "<Gamepad>/buttonSouth", 
				"buttoneast" => "<Gamepad>/buttonEast", 
				"buttonwest" => "<Gamepad>/buttonWest", 
				"buttonnorth" => "<Gamepad>/buttonNorth", 
				"leftshoulder" => "<Gamepad>/leftShoulder", 
				"rightshoulder" => "<Gamepad>/rightShoulder", 
				"lefttrigger" => "<Gamepad>/leftTrigger", 
				"righttrigger" => "<Gamepad>/rightTrigger", 
				"dpadup" => "<Gamepad>/dpad/up", 
				"dpaddown" => "<Gamepad>/dpad/down", 
				"dpadleft" => "<Gamepad>/dpad/left", 
				"dpadright" => "<Gamepad>/dpad/right", 
				"startbutton" => "<Gamepad>/start", 
				"selectbutton" => "<Gamepad>/select", 
				"leftstickpress" => "<Gamepad>/leftStickPress", 
				"rightstickpress" => "<Gamepad>/rightStickPress", 
				_ => "<Keyboard>/" + text2, 
			};
		}

		public static string FormatHotkeyForDisplay(string s)
		{
			if (string.IsNullOrWhiteSpace(s))
			{
				return string.Empty;
			}
			s = s.Trim();
			if (s.Length == 1)
			{
				return s.ToUpperInvariant();
			}
			if (s[0] == 'f' || s[0] == 'F')
			{
				bool flag = true;
				for (int i = 1; i < s.Length; i++)
				{
					if (!char.IsDigit(s[i]))
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					return ("F" + s.Substring(1)).ToUpperInvariant();
				}
			}
			string text = s.ToLowerInvariant();
			switch (text)
			{
			case "leftbutton":
				return "Mouse Left";
			case "rightbutton":
				return "Mouse Right";
			case "middlebutton":
				return "Mouse Middle";
			case "backbutton":
				return "Mouse Back";
			case "forwardbutton":
				return "Mouse Forward";
			case "buttonsouth":
				return "Gamepad A";
			case "buttoneast":
				return "Gamepad B";
			case "buttonwest":
				return "Gamepad X";
			case "buttonnorth":
				return "Gamepad Y";
			case "leftshoulder":
				return "Gamepad LB";
			case "rightshoulder":
				return "Gamepad RB";
			case "lefttrigger":
				return "Gamepad LT";
			case "righttrigger":
				return "Gamepad RT";
			case "dpadup":
				return "D-Pad Up";
			case "dpaddown":
				return "D-Pad Down";
			case "dpadleft":
				return "D-Pad Left";
			case "dpadright":
				return "D-Pad Right";
			case "startbutton":
				return "Gamepad Start";
			case "selectbutton":
				return "Gamepad Select";
			case "leftstickpress":
				return "Left Stick Press";
			case "rightstickpress":
				return "Right Stick Press";
			default:
				switch (text.Length)
				{
				case 5:
					switch (text[0])
					{
					case 's':
						if (!(text == "slash"))
						{
							break;
						}
						return "/";
					case 'm':
						if (!(text == "minus"))
						{
							break;
						}
						return "-";
					case 'c':
						if (!(text == "comma"))
						{
							break;
						}
						return ",";
					case 'q':
						if (!(text == "quote"))
						{
							break;
						}
						return "'";
					}
					break;
				case 9:
					switch (text[4])
					{
					case 's':
						if (!(text == "backslash"))
						{
							break;
						}
						return "\\";
					case 'c':
						if (!(text == "semicolon"))
						{
							break;
						}
						return ";";
					case 'q':
						if (!(text == "backquote"))
						{
							break;
						}
						return "`";
					}
					break;
				case 6:
					switch (text[0])
					{
					case 'e':
						if (!(text == "equals"))
						{
							break;
						}
						return "=";
					case 'p':
						if (!(text == "period"))
						{
							break;
						}
						return ".";
					}
					break;
				case 4:
					if (!(text == "plus"))
					{
						break;
					}
					return "+";
				case 11:
					if (!(text == "leftbracket"))
					{
						break;
					}
					return "[";
				case 12:
					if (!(text == "rightbracket"))
					{
						break;
					}
					return "]";
				}
				break;
			case null:
				break;
			}
			switch (text)
			{
			case "alt":
			case "ctrl":
			case "shift":
			case "enter":
			case "space":
			case "escape":
			case "esc":
			case "tab":
			case "backspace":
			case "capslock":
				return char.ToUpper(s[0]) + s.Substring(1).ToLowerInvariant();
			case "leftalt":
				return "LeftAlt";
			case "rightalt":
				return "RightAlt";
			case "leftctrl":
				return "LeftCtrl";
			case "rightctrl":
				return "RightCtrl";
			case "leftshift":
				return "LeftShift";
			case "rightshift":
				return "RightShift";
			default:
				return char.ToUpper(s[0]) + s.Substring(1).ToLowerInvariant();
			}
		}
	}
}
namespace SimpleInGameChat.UI
{
	public class ChatUI : MonoBehaviour
	{
		private class ChatMessage
		{
			public string Text;

			public float Time;

			public string Sender = "";
		}

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

			private object <>2__current;

			public ChatUI <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				ChatUI chatUI = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)chatUI._scrollRect != (Object)null)
					{
						chatUI._scrollRect.verticalNormalizedPosition = 0f;
					}
					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 bool _showChat;

		private readonly List<ChatMessage> _chatHistory = new List<ChatMessage>();

		private bool _inputBlockActive;

		private readonly List<InputAction> _disabledActions = new List<InputAction>();

		private InputAction _chatHotkeyAction;

		private int _lastOpenFrame;

		private GameObject _canvasObj;

		private CanvasGroup _canvasGroup;

		private TMP_InputField _inputField;

		private TextMeshProUGUI _chatHistoryText;

		private ScrollRect _scrollRect;

		private RectTransform _scrollRectTrans;

		private Image _panelBackground;

		private GameObject _scrollbarObj;

		private GameObject _suggestionPanelObj;

		private readonly List<TextMeshProUGUI> _suggestionLines = new List<TextMeshProUGUI>();

		private readonly List<ChatAutoCompleteItem> _suggestions = new List<ChatAutoCompleteItem>();

		private int _suggestionIndex;

		private bool _suppressSuggestionRefresh;

		private const float FADE_TIME = 10f;

		private bool _uiInitialized;

		public static bool IsChatInputActive { get; private set; }

		private void Start()
		{
			if ((Object)(object)ChatNetworkManager.Instance != (Object)null)
			{
				ChatNetworkManager.Instance.OnMessageReceived += OnMessageReceived;
				ChatNetworkManager.Instance.OnPlayerNameCacheUpdated += OnPlayerNameCacheUpdated;
			}
			((MonoBehaviour)this).Invoke("InitializeUI", 1f);
		}

		private void InitializeUI()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: 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_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Expected O, but got Unknown
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Expected O, but got Unknown
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Expected O, but got Unknown
			//IL_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Expected O, but got Unknown
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_065c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_0686: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0727: Unknown result type (might be due to invalid IL or missing references)
			//IL_072c: Unknown result type (might be due to invalid IL or missing references)
			//IL_073f: Unknown result type (might be due to invalid IL or missing references)
			//IL_074d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0758: Unknown result type (might be due to invalid IL or missing references)
			//IL_0763: Unknown result type (might be due to invalid IL or missing references)
			//IL_076d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0814: Unknown result type (might be due to invalid IL or missing references)
			//IL_081e: Expected O, but got Unknown
			//IL_0854: Unknown result type (might be due to invalid IL or missing references)
			//IL_0874: Unknown result type (might be due to invalid IL or missing references)
			//IL_0889: Unknown result type (might be due to invalid IL or missing references)
			//IL_089e: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0909: Unknown result type (might be due to invalid IL or missing references)
			//IL_0913: Expected O, but got Unknown
			//IL_093d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0942: Unknown result type (might be due to invalid IL or missing references)
			//IL_0959: Unknown result type (might be due to invalid IL or missing references)
			//IL_0983: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f8: Unknown result type (might be due to invalid IL or missing references)
			if (_uiInitialized)
			{
				return;
			}
			_canvasObj = new GameObject("SimpleChatCanvas");
			Object.DontDestroyOnLoad((Object)(object)_canvasObj);
			_canvasObj.AddComponent<Canvas>().renderMode = (RenderMode)0;
			CanvasScaler obj = _canvasObj.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.matchWidthOrHeight = 0.5f;
			_canvasObj.AddComponent<GraphicRaycaster>();
			GameObject val = new GameObject("ChatPanel");
			val.transform.SetParent(_canvasObj.transform, false);
			_panelBackground = val.AddComponent<Image>();
			((Graphic)_panelBackground).color = new Color(0f, 0f, 0f, 0.5f);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 0.5f);
			component.anchorMax = new Vector2(1f, 0.5f);
			component.pivot = new Vector2(1f, 0.5f);
			component.sizeDelta = new Vector2(400f, 500f);
			component.anchoredPosition = new Vector2(-20f, 0f);
			_canvasGroup = val.AddComponent<CanvasGroup>();
			_canvasGroup.alpha = 1f;
			GameObject val2 = new GameObject("ScrollArea");
			val2.transform.SetParent(val.transform, false);
			_scrollRect = val2.AddComponent<ScrollRect>();
			_scrollRectTrans = val2.GetComponent<RectTransform>();
			_scrollRectTrans.anchorMin = Vector2.zero;
			_scrollRectTrans.anchorMax = Vector2.one;
			_scrollRectTrans.offsetMin = new Vector2(10f, 10f);
			_scrollRectTrans.offsetMax = new Vector2(-10f, -10f);
			GameObject val3 = new GameObject("Viewport");
			val3.transform.SetParent(val2.transform, false);
			val3.AddComponent<RectMask2D>();
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			GameObject val4 = new GameObject("Content");
			val4.transform.SetParent(val3.transform, false);
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.anchorMin = new Vector2(0f, 0f);
			val5.anchorMax = new Vector2(1f, 0f);
			val5.pivot = new Vector2(0.5f, 0f);
			val5.sizeDelta = new Vector2(0f, 0f);
			val4.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			VerticalLayoutGroup obj2 = val4.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((LayoutGroup)obj2).padding = new RectOffset(0, 0, 10, 10);
			_scrollRect.viewport = component2;
			_scrollRect.content = val5;
			_scrollRect.horizontal = false;
			_scrollRect.vertical = true;
			_scrollRect.scrollSensitivity = 0.1f;
			_scrollbarObj = new GameObject("Scrollbar");
			_scrollbarObj.transform.SetParent(val.transform, false);
			((Graphic)_scrollbarObj.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.5f);
			RectTransform component3 = _scrollbarObj.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(1f, 0f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(1f, 0.5f);
			component3.sizeDelta = new Vector2(10f, 0f);
			component3.anchoredPosition = new Vector2(0f, 0f);
			component3.offsetMin = new Vector2(-10f, 10f);
			component3.offsetMax = new Vector2(0f, -10f);
			Scrollbar val6 = _scrollbarObj.AddComponent<Scrollbar>();
			val6.direction = (Direction)2;
			GameObject val7 = new GameObject("Handle");
			val7.transform.SetParent(_scrollbarObj.transform, false);
			Image val8 = val7.AddComponent<Image>();
			((Graphic)val8).color = new Color(1f, 1f, 1f, 0.5f);
			RectTransform component4 = val7.GetComponent<RectTransform>();
			component4.offsetMin = Vector2.zero;
			component4.offsetMax = Vector2.zero;
			((Selectable)val6).targetGraphic = (Graphic)(object)val8;
			val6.handleRect = component4;
			_scrollRect.verticalScrollbar = val6;
			_scrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			GameObject val9 = new GameObject("HistoryText");
			val9.transform.SetParent(((Component)val5).transform, false);
			_chatHistoryText = val9.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_chatHistoryText).fontSize = 20f;
			((TMP_Text)_chatHistoryText).alignment = (TextAlignmentOptions)1025;
			((TMP_Text)_chatHistoryText).enableWordWrapping = true;
			((Graphic)_chatHistoryText).color = Color.white;
			TMP_FontAsset gameFont = GetGameFont();
			((TMP_Text)_chatHistoryText).font = gameFont;
			GameObject val10 = new GameObject("InputField");
			val10.transform.SetParent(val.transform, false);
			((Graphic)val10.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.8f);
			RectTransform component5 = val10.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 0f);
			component5.anchorMax = new Vector2(1f, 0f);
			component5.pivot = new Vector2(0.5f, 0f);
			component5.anchoredPosition = new Vector2(0f, 10f);
			component5.sizeDelta = new Vector2(-20f, 40f);
			_inputField = val10.AddComponent<TMP_InputField>();
			_inputField.lineType = (LineType)0;
			GameObject val11 = new GameObject("Text Area");
			val11.transform.SetParent(val10.transform, false);
			RectTransform val12 = val11.AddComponent<RectTransform>();
			val11.AddComponent<RectMask2D>();
			val12.anchorMin = Vector2.zero;
			val12.anchorMax = Vector2.one;
			val12.offsetMin = new Vector2(10f, 5f);
			val12.offsetMax = new Vector2(-10f, -5f);
			GameObject val13 = new GameObject("Text");
			val13.transform.SetParent(val11.transform, false);
			TextMeshProUGUI val14 = val13.AddComponent<TextMeshProUGUI>();
			RectTransform component6 = val13.GetComponent<RectTransform>();
			component6.anchorMin = Vector2.zero;
			component6.anchorMax = Vector2.one;
			component6.offsetMin = Vector2.zero;
			component6.offsetMax = Vector2.zero;
			((TMP_Text)val14).fontSize = 20f;
			((TMP_Text)val14).alignment = (TextAlignmentOptions)4097;
			((Graphic)val14).color = Color.white;
			if ((Object)(object)gameFont != (Object)null)
			{
				((TMP_Text)val14).font = gameFont;
			}
			_inputField.textViewport = val12;
			_inputField.textComponent = (TMP_Text)(object)val14;
			GameObject val15 = new GameObject("Placeholder");
			val15.transform.SetParent(val11.transform, false);
			TextMeshProUGUI val16 = val15.AddComponent<TextMeshProUGUI>();
			RectTransform component7 = val15.GetComponent<RectTransform>();
			component7.anchorMin = Vector2.zero;
			component7.anchorMax = Vector2.one;
			component7.offsetMin = Vector2.zero;
			component7.offsetMax = Vector2.zero;
			((TMP_Text)val16).fontSize = 20f;
			((TMP_Text)val16).alignment = (TextAlignmentOptions)4097;
			((Graphic)val16).color = new Color(1f, 1f, 1f, 0.5f);
			((TMP_Text)val16).fontStyle = (FontStyles)2;
			if ((Object)(object)gameFont != (Object)null)
			{
				((TMP_Text)val16).font = gameFont;
			}
			((TMP_Text)val16).text = LocalizationManager.Instance.GetLocalizedText("ui.chat_placeholder");
			_inputField.placeholder = (Graphic)(object)val16;
			((UnityEvent<string>)(object)_inputField.onValueChanged).AddListener((UnityAction<string>)OnInputValueChanged);
			_suggestionPanelObj = new GameObject("SuggestionPanel");
			_suggestionPanelObj.transform.SetParent(val.transform, false);
			((Graphic)_suggestionPanelObj.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.85f);
			RectTransform component8 = _suggestionPanelObj.GetComponent<RectTransform>();
			component8.anchorMin = new Vector2(0f, 0f);
			component8.anchorMax = new Vector2(1f, 0f);
			component8.pivot = new Vector2(0.5f, 0f);
			component8.anchoredPosition = new Vector2(0f, 58f);
			component8.sizeDelta = new Vector2(-20f, 0f);
			VerticalLayoutGroup obj3 = _suggestionPanelObj.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).spacing = 2f;
			((LayoutGroup)obj3).padding = new RectOffset(10, 10, 8, 8);
			_suggestionPanelObj.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			for (int i = 0; i < 6; i++)
			{
				GameObject val17 = new GameObject($"SuggestionLine{i}");
				val17.transform.SetParent(_suggestionPanelObj.transform, false);
				TextMeshProUGUI val18 = val17.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val18).fontSize = 18f;
				((TMP_Text)val18).alignment = (TextAlignmentOptions)4097;
				((TMP_Text)val18).enableWordWrapping = false;
				((Graphic)val18).color = Color.white;
				if ((Object)(object)gameFont != (Object)null)
				{
					((TMP_Text)val18).font = gameFont;
				}
				val17.SetActive(false);
				_suggestionLines.Add(val18);
			}
			_suggestionPanelObj.SetActive(false);
			((Component)_inputField).gameObject.SetActive(false);
			((Graphic)_panelBackground).color = new Color(0f, 0f, 0f, 0f);
			if (_chatHotkeyAction == null)
			{
				_chatHotkeyAction = InputActionBindingHelper.CreateButtonAction("ToggleChat", ConfigManager.ChatHotkey.Value, OnChatHotkeyPerformed);
			}
			_uiInitialized = true;
		}

		private void OnChatHotkeyPerformed()
		{
			if (!_showChat)
			{
				OpenChat();
				_lastOpenFrame = Time.frameCount;
			}
		}

		private void Update()
		{
			if (!_uiInitialized)
			{
				return;
			}
			if (_showChat && ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame)
			{
				CloseChat();
			}
			else
			{
				if (_showChat && ((ButtonControl)Keyboard.current.tabKey).wasPressedThisFrame && TryCycleSuggestion())
				{
					return;
				}
				if (_showChat && Time.frameCount > _lastOpenFrame && ((ButtonControl)Keyboard.current.enterKey).wasPressedThisFrame)
				{
					if (!string.IsNullOrWhiteSpace(_inputField.text))
					{
						SendMessage();
					}
					else
					{
						CloseChat();
					}
				}
				UpdateVisuals();
			}
		}

		private void UpdateVisuals()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_panelBackground == (Object)null) && !((Object)(object)_chatHistoryText == (Object)null))
			{
				if (_showChat)
				{
					((Graphic)_panelBackground).color = new Color(0f, 0f, 0f, 0.5f);
					UpdateHistoryText(showAll: true);
				}
				else
				{
					((Graphic)_panelBackground).color = new Color(0f, 0f, 0f, 0f);
					UpdateHistoryText(showAll: false);
				}
			}
		}

		private void UpdateHistoryText(bool showAll)
		{
			StringBuilder stringBuilder = new StringBuilder();
			float time = Time.time;
			foreach (ChatMessage item in _chatHistory)
			{
				if (showAll)
				{
					stringBuilder.AppendLine(item.Text);
					continue;
				}
				float num = time - item.Time;
				if (num < 10f)
				{
					string text = "FF";
					if (num > 9f)
					{
						text = ((int)((10f - num) * 255f)).ToString("X2");
					}
					stringBuilder.AppendLine("<alpha=#" + text + ">" + item.Text);
				}
			}
			((TMP_Text)_chatHistoryText).text = stringBuilder.ToString();
		}

		private void OpenChat()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_inputField == (Object)null)
			{
				return;
			}
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
			_showChat = true;
			_inputField.text = "";
			((Component)_inputField).gameObject.SetActive(true);
			if ((Object)(object)_scrollRectTrans != (Object)null)
			{
				_scrollRectTrans.offsetMin = new Vector2(10f, 58f);
				_scrollRectTrans.offsetMax = new Vector2(-10f, -10f);
			}
			if ((Object)(object)_scrollbarObj != (Object)null)
			{
				_scrollbarObj.SetActive(true);
				RectTransform component = _scrollbarObj.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.offsetMin = new Vector2(-10f, 58f);
					component.offsetMax = new Vector2(0f, -10f);
				}
			}
			_inputField.ActivateInputField();
			((Selectable)_inputField).Select();
			RefreshSuggestions(_inputField.text);
			EnableInputBlock();
			((MonoBehaviour)this).StartCoroutine(ScrollToBottom());
		}

		private void CloseChat()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_inputField == (Object)null))
			{
				Cursor.visible = false;
				Cursor.lockState = (CursorLockMode)1;
				_showChat = false;
				_inputField.text = "";
				_inputField.DeactivateInputField(false);
				((Component)_inputField).gameObject.SetActive(false);
				_suggestions.Clear();
				GameObject suggestionPanelObj = _suggestionPanelObj;
				if (suggestionPanelObj != null)
				{
					suggestionPanelObj.SetActive(false);
				}
				if ((Object)(object)_scrollRectTrans != (Object)null)
				{
					_scrollRectTrans.offsetMin = new Vector2(10f, 10f);
					_scrollRectTrans.offsetMax = new Vector2(-10f, -10f);
				}
				GameObject scrollbarObj = _scrollbarObj;
				if (scrollbarObj != null)
				{
					scrollbarObj.SetActive(false);
				}
				DisableInputBlock();
				((MonoBehaviour)this).StartCoroutine(ScrollToBottom());
			}
		}

		private void OnInputValueChanged(string value)
		{
			if (!_suppressSuggestionRefresh)
			{
				RefreshSuggestions(value);
			}
		}

		private void OnPlayerNameCacheUpdated()
		{
			if (_showChat && !((Object)(object)_inputField == (Object)null) && !_suppressSuggestionRefresh)
			{
				RefreshSuggestions(_inputField.text);
			}
		}

		private void RefreshSuggestions(string value)
		{
			if (!_showChat)
			{
				GameObject suggestionPanelObj = _suggestionPanelObj;
				if (suggestionPanelObj != null)
				{
					suggestionPanelObj.SetActive(false);
				}
				_suggestions.Clear();
				return;
			}
			_suggestions.Clear();
			if ((Object)(object)ChatNetworkManager.Instance == (Object)null)
			{
				UpdateSuggestionUi();
				return;
			}
			string input = value ?? string.Empty;
			ulong senderClientId = (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.LocalClientId : 0);
			_suggestions.AddRange(ChatCommandManager.GetAutoCompleteItems(input, senderClientId, ChatNetworkManager.Instance));
			if (_suggestionIndex < 0 || _suggestionIndex >= _suggestions.Count)
			{
				_suggestionIndex = 0;
			}
			UpdateSuggestionUi();
		}

		private void UpdateSuggestionUi()
		{
			//IL_00b4: 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)
			if ((Object)(object)_suggestionPanelObj == (Object)null)
			{
				return;
			}
			bool flag = _showChat && _suggestions.Count > 0;
			_suggestionPanelObj.SetActive(flag);
			if (!flag)
			{
				return;
			}
			for (int i = 0; i < _suggestionLines.Count; i++)
			{
				bool flag2 = i < _suggestions.Count;
				TextMeshProUGUI val = _suggestionLines[i];
				if (!((Object)(object)val == (Object)null))
				{
					((Component)val).gameObject.SetActive(flag2);
					if (flag2)
					{
						((TMP_Text)val).text = _suggestions[i].DisplayText;
						((Graphic)val).color = (Color)((i == _suggestionIndex) ? new Color(1f, 0.92f, 0.3f, 1f) : Color.white);
					}
				}
			}
		}

		private bool TryCycleSuggestion()
		{
			if (_suggestions.Count == 0)
			{
				return false;
			}
			if ((Object)(object)_inputField == (Object)null)
			{
				return false;
			}
			ChatAutoCompleteItem chatAutoCompleteItem = _suggestions[_suggestionIndex];
			if (string.IsNullOrWhiteSpace(chatAutoCompleteItem.ApplyText))
			{
				return false;
			}
			_suppressSuggestionRefresh = true;
			_inputField.text = chatAutoCompleteItem.ApplyText;
			_suppressSuggestionRefresh = false;
			_inputField.caretPosition = _inputField.text.Length;
			_inputField.stringPosition = _inputField.text.Length;
			_inputField.ActivateInputField();
			((Selectable)_inputField).Select();
			_suggestionIndex = (_suggestionIndex + 1) % _suggestions.Count;
			UpdateSuggestionUi();
			return true;
		}

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

		private TMP_FontAsset GetGameFont()
		{
			TextMeshProUGUI[] array = Object.FindObjectsOfType<TextMeshProUGUI>();
			foreach (TextMeshProUGUI val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null && ((Component)val).gameObject.activeInHierarchy && !(((Object)((Component)val).gameObject).name == "HistoryText") && !(((Object)((Component)val).gameObject).name == "Placeholder"))
				{
					return ((TMP_Text)val).font;
				}
			}
			return null;
		}

		private void EnableInputBlock()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			if (_inputBlockActive)
			{
				return;
			}
			_inputBlockActive = true;
			IsChatInputActive = true;
			InputManager instance = InputManager.Instance;
			if (instance == null)
			{
				return;
			}
			InputMaster inputMaster = instance.inputMaster;
			if (inputMaster != null)
			{
				_ = inputMaster.Player;
				if (true)
				{
					PlayerActions player = InputManager.Instance.inputMaster.Player;
					((PlayerActions)(ref player)).Disable();
				}
			}
		}

		private void DisableInputBlock()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			if (!_inputBlockActive)
			{
				return;
			}
			_inputBlockActive = false;
			IsChatInputActive = false;
			InputManager instance = InputManager.Instance;
			if (instance != null)
			{
				InputMaster inputMaster = instance.inputMaster;
				if (inputMaster != null)
				{
					_ = inputMaster.Player;
					if (true)
					{
						PlayerActions player = InputManager.Instance.inputMaster.Player;
						((PlayerActions)(ref player)).Enable();
					}
				}
			}
			foreach (InputAction disabledAction in _disabledActions)
			{
				if (disabledAction != null)
				{
					disabledAction.Enable();
				}
			}
			_disabledActions.Clear();
		}

		private void SendMessage()
		{
			if (!string.IsNullOrWhiteSpace(_inputField.text))
			{
				string text = _inputField.text;
				ChatNetworkManager.Instance.SendChatMessage(text);
				CloseChat();
			}
		}

		private void OnMessageReceived(string message)
		{
			_chatHistory.Add(new ChatMessage
			{
				Text = message,
				Time = Time.time
			});
			if (_chatHistory.Count > ConfigManager.MaxChatHistory.Value)
			{
				_chatHistory.RemoveAt(0);
			}
			if (_showChat)
			{
				((MonoBehaviour)this).StartCoroutine(ScrollToBottom());
			}
			UpdateVisuals();
		}

		private void OnDestroy()
		{
			if ((Object)(object)ChatNetworkManager.Instance != (Object)null)
			{
				ChatNetworkManager.Instance.OnMessageReceived -= OnMessageReceived;
				ChatNetworkManager.Instance.OnPlayerNameCacheUpdated -= OnPlayerNameCacheUpdated;
			}
			DisableInputBlock();
			if (_chatHotkeyAction != null)
			{
				_chatHotkeyAction.Dispose();
				_chatHotkeyAction = null;
			}
			TMP_InputField inputField = _inputField;
			if (inputField != null)
			{
				((UnityEvent<string>)(object)inputField.onValueChanged).RemoveListener((UnityAction<string>)OnInputValueChanged);
			}
			if ((Object)(object)_canvasObj != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasObj);
				_canvasObj = null;
			}
			_chatHistory.Clear();
			_uiInitialized = false;
			IsChatInputActive = false;
		}
	}
}
namespace SimpleInGameChat.Patches
{
	[HarmonyPatch(typeof(GameManager))]
	public static class GameManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start_Postfix(GameManager __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				if ((Object)(object)((Component)__instance).gameObject.GetComponent<ChatNetworkManager>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<ChatNetworkManager>();
				}
				if ((Object)(object)((Component)__instance).gameObject.GetComponent<ChatUI>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<ChatUI>();
				}
			}
		}
	}
	[HarmonyPatch]
	public static class InputSystemInputGatePatch
	{
		[HarmonyPatch(typeof(ButtonControl), "get_wasPressedThisFrame")]
		[HarmonyPrefix]
		private static bool WasPressedThisFrame_Prefix(ButtonControl __instance, ref bool __result)
		{
			if (!ChatUI.IsChatInputActive)
			{
				return true;
			}
			if (__instance == null)
			{
				return true;
			}
			InputDevice device = ((InputControl)__instance).device;
			Keyboard val = (Keyboard)(object)((device is Keyboard) ? device : null);
			if (val == null)
			{
				return true;
			}
			if (__instance == val.enterKey || __instance == val.numpadEnterKey || __instance == val.backspaceKey || __instance == val.deleteKey || __instance == val.tabKey || __instance == val.escapeKey || __instance == val.leftArrowKey || __instance == val.rightArrowKey || __instance == val.upArrowKey || __instance == val.downArrowKey || __instance == val.homeKey || __instance == val.endKey)
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(ButtonControl), "get_isPressed")]
		[HarmonyPrefix]
		private static bool IsPressed_Prefix(ButtonControl __instance, ref bool __result)
		{
			if (!ChatUI.IsChatInputActive)
			{
				return true;
			}
			if (__instance == null)
			{
				return true;
			}
			InputDevice device = ((InputControl)__instance).device;
			Keyboard val = (Keyboard)(object)((device is Keyboard) ? device : null);
			if (val == null)
			{
				return true;
			}
			if (__instance == val.enterKey || __instance == val.numpadEnterKey || __instance == val.backspaceKey || __instance == val.deleteKey || __instance == val.tabKey || __instance == val.escapeKey || __instance == val.leftArrowKey || __instance == val.rightArrowKey || __instance == val.upArrowKey || __instance == val.downArrowKey || __instance == val.homeKey || __instance == val.endKey)
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(ButtonControl), "get_wasReleasedThisFrame")]
		[HarmonyPrefix]
		private static bool WasReleasedThisFrame_Prefix(ButtonControl __instance, ref bool __result)
		{
			if (!ChatUI.IsChatInputActive)
			{
				return true;
			}
			if (__instance == null)
			{
				return true;
			}
			InputDevice device = ((InputControl)__instance).device;
			Keyboard val = (Keyboard)(object)((device is Keyboard) ? device : null);
			if (val == null)
			{
				return true;
			}
			if (__instance == val.enterKey || __instance == val.numpadEnterKey || __instance == val.backspaceKey || __instance == val.deleteKey || __instance == val.tabKey || __instance == val.escapeKey || __instance == val.leftArrowKey || __instance == val.rightArrowKey || __instance == val.upArrowKey || __instance == val.downArrowKey || __instance == val.homeKey || __instance == val.endKey)
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(SettingsManager), "Update")]
		[HarmonyPrefix]
		private static bool SettingsManagerUpdate_Prefix()
		{
			return !ChatUI.IsChatInputActive;
		}

		[HarmonyPatch(typeof(UIManager), "Update")]
		[HarmonyPrefix]
		private static bool UIManagerUpdate_Prefix()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!ChatUI.IsChatInputActive)
			{
				return true;
			}
			if ((Object)(object)InputManager.Instance == (Object)null || InputManager.Instance.inputMaster == null)
			{
				return true;
			}
			UIActions uI = InputManager.Instance.inputMaster.UI;
			if (((UIActions)(ref uI)).Tab.WasPerformedThisFrame())
			{
				return false;
			}
			uI = InputManager.Instance.inputMaster.UI;
			if (((UIActions)(ref uI)).Tasks.WasPerformedThisFrame())
			{
				return false;
			}
			return true;
		}
	}
}
namespace SimpleInGameChat.Network
{
	public class ChatNetworkManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <WaitForNetworkManager>d__21 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ChatNetworkManager <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				ChatNetworkManager chatNetworkManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				chatNetworkManager.RegisterHandlers();
				NetworkManager.Singleton.OnClientConnectedCallback += chatNetworkManager.OnClientConnected;
				NetworkManager.Singleton.OnClientDisconnectCallback += chatNetworkManager.OnClientDisconnected;
				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 const string MSG_C2S = "SimpleChat_C2S";

		private const string MSG_S2C = "SimpleChat_S2C";

		private const string MSG_REQ_NAME = "SimpleChat_ReqName";

		private const string MSG_RES_NAME = "SimpleChat_ResName";

		private TpTeleportService _tpTeleportService;

		private FieldInfo _clientIdNicknamesField;

		private readonly Dictionary<ulong, string> _playerNameCache = new Dictionary<ulong, string>();

		private readonly Dictionary<ulong, float> _lastRequestTime = new Dictionary<ulong, float>();

		private const float REQUEST_COOLDOWN = 1f;

		public static ChatNetworkManager Instance { get; private set; }

		public event Action<string> OnMessageReceived;

		public event Action OnPlayerNameCacheUpdated;

		private void Awake()
		{
			Instance = this;
			ChatCommandManager.InitializeBuiltins();
			_tpTeleportService = new TpTeleportService(this);
			_clientIdNicknamesField = AccessTools.Field(typeof(GameManager), "clientIdNicknames");
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(WaitForNetworkManager());
		}

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

		private void OnClientConnected(ulong clientId)
		{
			if (NetworkManager.Singleton.IsClient && NetworkManager.Singleton.LocalClientId == clientId)
			{
				RegisterHandlers();
				RequestNameFromServer(clientId);
			}
		}

		private void OnClientDisconnected(ulong clientId)
		{
			if (_playerNameCache.ContainsKey(clientId))
			{
				_playerNameCache.Remove(clientId);
			}
			if (_lastRequestTime.ContainsKey(clientId))
			{
				_lastRequestTime.Remove(clientId);
			}
		}

		private void Update()
		{
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
			{
				ulong localClientId = NetworkManager.Singleton.LocalClientId;
				if (!_playerNameCache.ContainsKey(localClientId))
				{
					RequestNameFromServer(localClientId);
				}
			}
		}

		public void RegisterHandlers()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			if (!((Object)(object)NetworkManager.Singleton == (Object)null))
			{
				CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
				if (customMessagingManager != null)
				{
					customMessagingManager.UnregisterNamedMessageHandler("SimpleChat_C2S");
					customMessagingManager.UnregisterNamedMessageHandler("SimpleChat_S2C");
					customMessagingManager.UnregisterNamedMessageHandler("SimpleChat_ReqName");
					customMessagingManager.UnregisterNamedMessageHandler("SimpleChat_ResName");
					customMessagingManager.RegisterNamedMessageHandler("SimpleChat_C2S", new HandleNamedMessageDelegate(HandleServerMessage));
					customMessagingManager.RegisterNamedMessageHandler("SimpleChat_S2C", new HandleNamedMessageDelegate(HandleClientMessage));
					customMessagingManager.RegisterNamedMessageHandler("SimpleChat_ReqName", new HandleNamedMessageDelegate(HandleNameRequest));
					customMessagingManager.RegisterNamedMessageHandler("SimpleChat_ResName", new HandleNamedMessageDelegate(HandleNameResponse));
					_tpTeleportService?.RegisterHandlers();
				}
			}
		}

		public void SendChatMessage(string message)
		{
			if (string.IsNullOrWhiteSpace(message))
			{
				return;
			}
			ulong senderClientId = (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.LocalClientId : 0);
			if (ChatCommandManager.TryHandleChatInput(message, senderClientId, this))
			{
				return;
			}
			string text = GetPlayerName(NetworkManager.Singleton.LocalClientId) + ": " + message;
			this.OnMessageReceived?.Invoke(text);
			if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsListening)
			{
				if (NetworkManager.Singleton.IsServer)
				{
					BroadcastChatMessage(text, NetworkManager.Singleton.LocalClientId);
				}
				else
				{
					SendToServer(text);
				}
			}
		}

		internal string GetPlayerName(ulong clientId)
		{
			if (_playerNameCache.TryGetValue(clientId, out var value))
			{
				return value;
			}
			if (TryGetResolvedPlayerName(clientId, out var name))
			{
				_playerNameCache[clientId] = name;
				return name;
			}
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
			{
				RequestNameFromServer(clientId);
			}
			return LocalizationManager.Instance.GetLocalizedText("player.default_name", clientId);
		}

		private bool TryGetResolvedPlayerName(ulong clientId, out string name)
		{
			name = null;
			if (_playerNameCache.TryGetValue(clientId, out var value) && !string.IsNullOrWhiteSpace(value))
			{
				name = value;
				return true;
			}
			if ((Object)(object)GameManager.Instance != (Object)null && _clientIdNicknamesField != null)
			{
				try
				{
					if (_clientIdNicknamesField.GetValue(GameManager.Instance) is Dictionary<ulong, string> dictionary && dictionary.TryGetValue(clientId, out var value2) && !string.IsNullOrWhiteSpace(value2))
					{
						name = value2;
						return true;
					}
				}
				catch (Exception)
				{
				}
			}
			return false;
		}

		internal List<string> GetOnlinePlayerNames(ulong excludeClientId)
		{
			List<string> list = new List<string>();
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsListening)
			{
				return list;
			}
			foreach (ulong connectedClientsId in NetworkManager.Singleton.ConnectedClientsIds)
			{
				if (connectedClientsId == excludeClientId)
				{
					continue;
				}
				if (!TryGetResolvedPlayerName(connectedClientsId, out var name))
				{
					if (NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
					{
						RequestNameFromServer(connectedClientsId);
					}
					continue;
				}
				bool flag = false;
				for (int i = 0; i < list.Count; i++)
				{
					if (string.Equals(list[i], name, StringComparison.OrdinalIgnoreCase))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					list.Add(name);
				}
			}
			list.Sort(StringComparer.OrdinalIgnoreCase);
			return list;
		}

		private void RequestNameFromServer(ulong targetClientId)
		{
			//IL_005e: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsClient || (_lastRequestTime.TryGetValue(targetClientId, out var value) && Time.time - value < 1f))
			{
				return;
			}
			_lastRequestTime[targetClientId] = Time.time;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref targetClientId, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SimpleChat_ReqName", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		private void HandleNameRequest(ulong senderClientId, FastBufferReader reader)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			ulong key = default(ulong);
			((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
			string text = null;
			if ((Object)(object)GameManager.Instance != (Object)null && _clientIdNicknamesField != null && _clientIdNicknamesField.GetValue(GameManager.Instance) is Dictionary<ulong, string> dictionary && dictionary.TryGetValue(key, out var value))
			{
				text = value;
			}
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref key, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SimpleChat_ResName", senderClientId, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		private void HandleNameResponse(ulong senderClientId, FastBufferReader reader)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ulong key = default(ulong);
			((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
			string value = default(string);
			((FastBufferReader)(ref reader)).ReadValueSafe(ref value, false);
			if (!string.IsNullOrEmpty(value))
			{
				_playerNameCache[key] = value;
				this.OnPlayerNameCacheUpdated?.Invoke();
			}
		}

		private void SendToServer(string message)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize(message, false), (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(message, false);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SimpleChat_C2S", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		private void BroadcastChatMessage(string message, ulong? excludeClientId = null)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize(message, false), (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(message, false);
				if (NetworkManager.Singleton.ConnectedClientsIds.Count <= 0)
				{
					return;
				}
				foreach (ulong connectedClientsId in NetworkManager.Singleton.ConnectedClientsIds)
				{
					if ((!excludeClientId.HasValue || connectedClientsId != excludeClientId.Value) && connectedClientsId != NetworkManager.Singleton.LocalClientId)
					{
						NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SimpleChat_S2C", connectedClientsId, val, (NetworkDelivery)3);
					}
				}
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		private void HandleServerMessage(ulong senderClientId, FastBufferReader reader)
		{
			string text = default(string);
			((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
			this.OnMessageReceived?.Invoke(text);
			BroadcastChatMessage(text, senderClientId);
		}

		private void HandleClientMessage(ulong senderClientId, FastBufferReader reader)
		{
			string obj = default(string);
			((FastBufferReader)(ref reader)).ReadValueSafe(ref obj, false);
			this.OnMessageReceived?.Invoke(obj);
		}

		public void SendLocalSystemMessage(string message)
		{
			this.OnMessageReceived?.Invoke(FormatSystemMessage(message));
		}

		internal void SendSystemMessageToClient(ulong clientId, string message)
		{
			//IL_0050: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsListening)
			{
				if (clientId == 0L)
				{
					SendLocalSystemMessage(message);
				}
				return;
			}
			if (clientId == NetworkManager.Singleton.LocalClientId)
			{
				SendLocalSystemMessage(message);
				return;
			}
			string text = FormatSystemMessage(message);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize(text, false), (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SimpleChat_S2C", clientId, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		private static string FormatSystemMessage(string message)
		{
			if (string.IsNullOrWhiteSpace(message))
			{
				return LocalizationManager.Instance.GetLocalizedText("ui.system_message_empty");
			}
			return LocalizationManager.Instance.GetLocalizedText("ui.system_message", message);
		}

		public void SendTpRequest(ulong requesterClientId, string targetQuery)
		{
			_tpTeleportService?.SendTpRequest(requesterClientId, targetQuery);
		}

		public void SendTpDecision(ulong targetClientId, bool accept)
		{
			_tpTeleportService?.SendTpDecision(targetClientId, accept);
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			if ((Object)(object)NetworkManager.Singleton != (Object)null)
			{
				if (NetworkManager.Singleton.CustomMessagingManager != null)
				{
					NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_C2S");
					NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_S2C");
					NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_ReqName");
					NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_ResName");
				}
				NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnected;
				NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientDisconnected;
			}
			_tpTeleportService?.UnregisterHandlers();
			_playerNameCache.Clear();
			_lastRequestTime.Clear();
		}
	}
	internal sealed class TpTeleportService
	{
		private struct PendingTpRequest
		{
			public ulong RequesterClientId;

			public string RequesterName;

			public float CreatedAt;
		}

		private const string MSG_TP_C2S = "SimpleChat_TP_C2S";

		private const string MSG_TP_S2C = "SimpleChat_TP_S2C";

		private const float TP_REQUEST_TIMEOUT_SECONDS = 30f;

		private static readonly Dictionary<ulong, PendingTpRequest> PendingTpRequestsByTarget = new Dictionary<ulong, PendingTpRequest>();

		private readonly ChatNetworkManager _owner;

		internal TpTeleportService(ChatNetworkManager owner)
		{
			_owner = owner;
		}

		internal void RegisterHandlers()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			if (!((Object)(object)NetworkManager.Singleton == (Object)null))
			{
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_TP_C2S");
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_TP_S2C");
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("SimpleChat_TP_C2S", new HandleNamedMessageDelegate(HandleTpServerMessage));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("SimpleChat_TP_S2C", new HandleNamedMessageDelegate(HandleTpClientMessage));
			}
		}

		internal void UnregisterHandlers()
		{
			if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.CustomMessagingManager != null)
			{
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_TP_C2S");
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("SimpleChat_TP_S2C");
			}
		}

		private bool CheckTpAvailability()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsListening)
			{
				_owner.SendLocalSystemMessage(LocalizationManager.Instance.GetLocalizedText("tp.error_not_connected"));
				return false;
			}
			if (NetworkManager.Singleton.IsServer && !ConfigManager.EnableTp.Value)
			{
				_owner.SendLocalSystemMessage(LocalizationManager.Instance.GetLocalizedText("tp.error_disabled"));
				return false;
			}
			return true;
		}

		internal void SendTpRequest(ulong requesterClientId, string targetQuery)
		{
			if (CheckTpAvailability())
			{
				if (string.IsNullOrWhiteSpace(targetQuery))
				{
					_owner.SendLocalSystemMessage(LocalizationManager.Instance.GetLocalizedText("tp.usage"));
				}
				else if (NetworkManager.Singleton.IsServer)
				{
					HandleTpRequestServer(requesterClientId, targetQuery);
				}
				else
				{
					SendServerMessage(0, targetQuery);
				}
			}
		}

		internal void SendTpDecision(ulong targetClientId, bool accept)
		{
			if (CheckTpAvailability())
			{
				if (NetworkManager.Singleton.IsServer)
				{
					HandleTpDecisionServer(targetClientId, accept);
				}
				else
				{
					SendServerMessage(1, accept);
				}
			}
		}

		private void SendServerMessage(byte opCode, object data)
		{
			//IL_002e: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			int num = 1;
			if (data is string text)
			{
				num += FastBufferWriter.GetWriteSize(text, false);
			}
			else if (data is bool)
			{
				num++;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref opCode, default(ForPrimitives));
				if (data is string text2)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(text2, false);
				}
				else if (data is bool flag)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				}
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SimpleChat_TP_C2S", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		private void HandleTpServerMessage(ulong senderClientId, FastBufferReader reader)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsServer)
			{
				byte b = default(byte);
				((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
				switch (b)
				{
				case 0:
				{
					string targetQuery = default(string);
					((FastBufferReader)(ref reader)).ReadValueSafe(ref targetQuery, false);
					HandleTpRequestServer(senderClientId, targetQuery);
					break;
				}
				case 1:
				{
					bool accept = default(bool);
					((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref accept, default(ForPrimitives));
					HandleTpDecisionServer(senderClientId, accept);
					break;
				}
				}
			}
		}

		private void HandleTpClientMessage(ulong senderClientId, FastBufferReader reader)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsClient)
			{
				Vector3 destination = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref destination);
				TeleportLocalPlayer(destination);
			}
		}

		private void HandleTpRequestServer(ulong requesterClientId, string targetQuery)
		{
			if (!ConfigManager.EnableTp.Value)
			{
				_owner.SendSystemMessageToClient(requesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_host_disabled"));
				return;
			}
			if (!TryResolveClientIdByName(targetQuery, requesterClientId, out var matchedClientId, out var candidates))
			{
				if (candidates != null && candidates.Count > 0)
				{
					_owner.SendSystemMessageToClient(requesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_multiple_players", targetQuery, string.Join(", ", candidates)));
				}
				else
				{
					_owner.SendSystemMessageToClient(requesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_player_not_found", targetQuery));
				}
				return;
			}
			if (matchedClientId == requesterClientId)
			{
				_owner.SendSystemMessageToClient(requesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_tp_self"));
				return;
			}
			string playerName = _owner.GetPlayerName(requesterClientId);
			string playerName2 = _owner.GetPlayerName(matchedClientId);
			PruneExpiredPendingRequests();
			if (IsClientInAnyPendingRequest(requesterClientId))
			{
				_owner.SendSystemMessageToClient(requesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_requester_busy"));
				return;
			}
			if (IsClientInAnyPendingRequest(matchedClientId))
			{
				_owner.SendSystemMessageToClient(requesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_target_busy", playerName2));
				return;
			}
			PendingTpRequestsByTarget[matchedClientId] = new PendingTpRequest
			{
				RequesterClientId = requesterClientId,
				RequesterName = playerName,
				CreatedAt = Time.realtimeSinceStartup
			};
			_owner.SendSystemMessageToClient(requesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.request_sent", playerName2));
			_owner.SendSystemMessageToClient(matchedClientId, LocalizationManager.Instance.GetLocalizedText("tp.request_received", playerName));
		}

		private void HandleTpDecisionServer(ulong targetClientId, bool accept)
		{
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			if (!ConfigManager.EnableTp.Value)
			{
				_owner.SendSystemMessageToClient(targetClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_host_disabled"));
				return;
			}
			if (!PendingTpRequestsByTarget.TryGetValue(targetClientId, out var value))
			{
				_owner.SendSystemMessageToClient(targetClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_no_request_to_process"));
				return;
			}
			PendingTpRequestsByTarget.Remove(targetClientId);
			if (Time.realtimeSinceStartup - value.CreatedAt > 30f)
			{
				_owner.SendSystemMessageToClient(targetClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_request_expired"));
				return;
			}
			if (!IsClientConnected(value.RequesterClientId))
			{
				_owner.SendSystemMessageToClient(targetClientId, LocalizationManager.Instance.GetLocalizedText("tp.error_requester_offline", value.RequesterName));
				return;
			}
			string playerName = _owner.GetPlayerName(targetClientId);
			string text = value.RequesterName ?? _owner.GetPlayerName(value.RequesterClientId);
			if (!accept)
			{
				_owner.SendSystemMessageToClient(targetClientId, LocalizationManager.Instance.GetLocalizedText("tp.info_you_rejected"));
				_owner.SendSystemMessageToClient(value.RequesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.rejected_request", playerName));
				return;
			}
			if (!TryGetPlayerTransform(targetClientId, out var transform))
			{
				string localizedText = LocalizationManager.Instance.GetLocalizedText("tp.error_teleport_failed");
				_owner.SendSystemMessageToClient(targetClientId, localizedText);
				_owner.SendSystemMessageToClient(value.RequesterClientId, localizedText);
				return;
			}
			Vector3 destination = transform.position + transform.forward * 1.5f + Vector3.up * 0.1f;
			SendTeleportInstructionToClient(value.RequesterClientId, destination);
			_owner.SendSystemMessageToClient(targetClientId, LocalizationManager.Instance.GetLocalizedText("tp.accepted_request", text));
			_owner.SendSystemMessageToClient(value.RequesterClientId, LocalizationManager.Instance.GetLocalizedText("tp.teleported_to", playerName));
		}

		private void PruneExpiredPendingRequests()
		{
			if (PendingTpRequestsByTarget.Count == 0)
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			List<ulong> list = null;
			foreach (KeyValuePair<ulong, PendingTpRequest> item in PendingTpRequestsByTarget)
			{
				if (realtimeSinceStartup - item.Value.CreatedAt > 30f || !IsClientConnected(item.Key) || !IsClientConnected(item.Value.RequesterClientId))
				{
					if (list == null)
					{
						list = new List<ulong>();
					}
					list.Add(item.Key);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					PendingTpRequestsByTarget.Remove(list[i]);
				}
			}
		}

		private bool IsClientInAnyPendingRequest(ulong clientId)
		{
			if (PendingTpRequestsByTarget.ContainsKey(clientId))
			{
				return true;
			}
			foreach (KeyValuePair<ulong, PendingTpRequest> item in PendingTpRequestsByTarget)
			{
				if (item.Value.RequesterClientId == clientId)
				{
					return true;
				}
			}
			return false;
		}

		private void SendTeleportInstructionToClient(ulong clientId, Vector3 destination)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsListening)
			{
				return;
			}
			if (clientId == NetworkManager.Singleton.LocalClientId)
			{
				TeleportLocalPlayer(destination);
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize<Vector3>(ref destination, default(ForStructs)), (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(ref destination);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SimpleChat_TP_S2C", clientId, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		private void TeleportLocalPlayer(Vector3 destination)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			NetworkObject val = ((singleton == null) ? null : singleton.LocalClient?.PlayerObject);
			if (!((Object)(object)val == (Object)null))
			{
				ExampleCharacterSetup component = ((Component)val).GetComponent<ExampleCharacterSetup>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.customCharacterController != (Object)null)
				{
					Quaternion rotation = ((Component)component).transform.rotation;
					component.customCharacterController.Motor.SetPositionAndRotation(destination, rotation, true);
				}
				else
				{
					((Component)val).transform.position = destination;
				}
			}
		}

		private bool IsClientConnected(ulong clientId)
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				return false;
			}
			return NetworkManager.Singleton.ConnectedClientsIds.Contains(clientId);
		}

		private bool TryGetPlayerTransform(ulong clientId, out Transform transform)
		{
			transform = null;
			if ((Object)(object)NetworkManager.Singleton == (Object)null || NetworkManager.Singleton.SpawnManager == null)
			{
				return false;
			}
			foreach (NetworkObject spawnedObjects in NetworkManager.Singleton.SpawnManager.SpawnedObjectsList)
			{
				if (!((Object)(object)spawnedObjects == (Object)null) && spawnedObjects.IsPlayerObject && spawnedObjects.OwnerClientId == clientId)
				{
					transform = ((Component)spawnedObjects).transform;
					return (Object)(object)transform != (Object)null;
				}
			}
			return false;
		}

		private bool TryResolveClientIdByName(string query, ulong requesterClientId, out ulong matchedClientId, out List<string> candidates)
		{
			matchedClientId = 0uL;
			candidates = null;
			if (string.IsNullOrWhiteSpace(query))
			{
				return false;
			}
			string q = query.Trim().ToLowerInvariant();
			List<(ulong, string)> playerList = GetPlayerList(requesterClientId);
			ulong item = playerList.FirstOrDefault<(ulong, string)>(((ulong id, string name) p) => string.Equals(p.name, query.Trim(), StringComparison.OrdinalIgnoreCase)).Item1;
			if (item != 0L)
			{
				matchedClientId = item;
				return true;
			}
			List<(ulong, string)> list = playerList.Where<(ulong, string)>(((ulong id, string name) p) => p.name != null && p.name.Trim().ToLowerInvariant().StartsWith(q)).ToList();
			if (list.Count == 1)
			{
				matchedClientId = list[0].Item1;
				return true;
			}
			List<(ulong, string)> list2 = playerList.Where<(ulong, string)>(((ulong id, string name) p) => p.name != null && p.name.Trim().ToLowerInvariant().Contains(q)).ToList();
			if (list2.Count == 1)
			{
				matchedClientId = list2[0].Item1;
				return true;
			}
			List<(ulong, string)> list3 = ((list.Count > 1) ? list : list2);
			if (list3.Count > 1)
			{
				candidates = list3.Select<(ulong, string), string>(((ulong id, string name) x) => x.name).Distinct().Take(8)
					.ToList();
			}
			return false;
		}

		private List<(ulong id, string name)> GetPlayerList(ulong excludeClientId)
		{
			List<(ulong, string)> list = new List<(ulong, string)>();
			HashSet<ulong> hashSet = null;
			if ((Object)(object)NetworkManager.Singleton != (Object)null)
			{
				hashSet = new HashSet<ulong>(NetworkManager.Singleton.ConnectedClientsIds);
			}
			Dictionary<ulong, string> dictionary = null;
			if ((Object)(object)GameManager.Instance != (Object)null)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(GameManager), "clientIdNicknames");
				if (fieldInfo != null)
				{
					dictionary = fieldInfo.GetValue(GameManager.Instance) as Dictionary<ulong, string>;
				}
			}
			if (dictionary != null && dictionary.Count > 0)
			{
				foreach (KeyValuePair<ulong, string> item in dictionary)
				{
					if (item.Key != excludeClientId && (hashSet == null || hashSet.Contains(item.Key)) && !string.IsNullOrWhiteSpace(item.Value))
					{
						list.Add((item.Key, item.Value));
					}
				}
			}
			else if ((Object)(object)NetworkManager.Singleton != (Object)null)
			{
				foreach (ulong connectedClientsId in NetworkManager.Singleton.ConnectedClientsIds)
				{
					if (connectedClientsId != excludeClientId)
					{
						list.Add((connectedClientsId, _owner.GetPlayerName(connectedClientsId)));
					}
				}
			}
			return list;
		}
	}
}
namespace SimpleInGameChat.Localization
{
	public static class LocalizationHelper
	{
		public static Dictionary<string, string> GetDefaultTranslations(string language)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			switch (language)
			{
			case "zh":
				dictionary.Add("plugin.initializing", "开始初始化...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初始化成功!");
				dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
				dictionary.Add("config.chat_hotkey", "聊天框开关快捷键");
				dictionary.Add("config.max_history", "最大聊天记录行数");
				dictionary.Add("config.enable_tp_desc", "启用传送功能 (/tp 命令)");
				dictionary.Add("ui.chat_placeholder", "输入消息...");
				dictionary.Add("ui.system_message", "[系统] {0}");
				dictionary.Add("ui.system_message_empty", "[系统]");
				dictionary.Add("player.default_name", "玩家 {0}");
				dictionary.Add("cmd.unknown_command", "未知命令:{0}");
				dictionary.Add("tp.usage", "用法:/tp <玩家名> 或 /tp yes/no");
				dictionary.Add("tp.error_not_connected", "当前未连接到联机房间,无法使用传送。");
				dictionary.Add("tp.error_disabled", "传送功能未开启。请在配置文件中启用 EnableTp。");
				dictionary.Add("tp.error_host_disabled", "主机未开启传送功能。");
				dictionary.Add("tp.error_player_not_found", "未找到包含 '{0}' 的玩家。");
				dictionary.Add("tp.error_multiple_players", "找到多个包含 '{0}' 的玩家:{1}");
				dictionary.Add("tp.error_tp_self", "不能向自己发起传送请求。");
				dictionary.Add("tp.error_requester_busy", "你当前已有一个传送请求正在处理中,请先处理完成后再试。");
				dictionary.Add("tp.error_target_busy", "{0} 当前已有一个传送请求正在处理中,请稍后再试。");
				dictionary.Add("tp.error_no_request_to_process", "你当前没有任何传送请求。");
				dictionary.Add("tp.error_request_expired", "传送请求已过期。");
				dictionary.Add("tp.error_requester_offline", "发起请求的玩家 ({0}) 已离线,操作取消。");
				dictionary.Add("tp.error_invalid_command", "无效的传送命令。用法:/tp <玩家名> 或 /tp yes/no");
				dictionary.Add("tp.error_teleport_failed", "传送失败:无法定位玩家位置。");
				dictionary.Add("tp.request_sent", "已向 {0} 发送传送请求。");
				dictionary.Add("tp.request_received", "收到来自 {0} 的传送请求。输入 /tp yes 接受,/tp no 拒绝。");
				dictionary.Add("tp.accepted_request", "已接受 {0} 的传送请求。");
				dictionary.Add("tp.rejected_request", "{0} 拒绝了你的传送请求。");
				dictionary.Add("tp.info_you_rejected", "已拒绝传送请求。");
				dictionary.Add("tp.teleported_to", "已传送到 {0} 身边。");
				break;
			case "zh-Hant":
				dictionary.Add("plugin.initializing", "開始初始化...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初始化成功!");
				dictionary.Add("plugin.patches_skipped", "補丁已應用,跳過...");
				dictionary.Add("config.chat_hotkey", "聊天框開關快捷鍵");
				dictionary.Add("config.max_history", "最大聊天記錄行數");
				dictionary.Add("config.enable_tp_desc", "啟用傳送功能 (/tp 命令)");
				dictionary.Add("ui.chat_placeholder", "輸入消息...");
				dictionary.Add("ui.system_message", "[系統] {0}");
				dictionary.Add("ui.system_message_empty", "[系統]");
				dictionary.Add("player.default_name", "玩家 {0}");
				dictionary.Add("cmd.unknown_command", "未知命令:{0}");
				dictionary.Add("tp.usage", "用法:/tp <玩家名> 或 /tp yes/no");
				dictionary.Add("tp.error_not_connected", "當前未連接到連線房間,無法使用傳送。");
				dictionary.Add("tp.error_disabled", "傳送功能未開啟。請在設定檔中啟用 EnableTp。");
				dictionary.Add("tp.error_host_disabled", "主機未開啟傳送功能。");
				dictionary.Add("tp.error_player_not_found", "未找到包含 '{0}' 的玩家。");
				dictionary.Add("tp.error_multiple_players", "找到多個包含 '{0}' 的玩家:{1}");
				dictionary.Add("tp.error_tp_self", "不能向自己發起傳送請求。");
				dictionary.Add("tp.error_requester_busy", "你當前已有一個傳送請求正在處理中,請先處理完成後再試。");
				dictionary.Add("tp.error_target_busy", "{0} 當前已有一個傳送請求正在處理中,請稍後再試。");
				dictionary.Add("tp.error_invalid_command", "無效的傳送命令。用法:/tp <玩家名> 或 /tp yes/no");
				dictionary.Add("tp.error_no_pending_request", "當前沒有待處理的傳送請求。");
				dictionary.Add("tp.error_no_request_to_process", "你當前沒有任何傳送請求。");
				dictionary.Add("tp.error_request_expired", "傳送請求已過期。");
				dictionary.Add("tp.error_requester_offline", "發起請求的玩家 ({0}) 已離線,操作取消。");
				dictionary.Add("tp.error_teleport_failed", "傳送失敗:無法定位玩家位置。");
				dictionary.Add("tp.request_sent", "已向 {0} 發送傳送請求,等待對方接受...");
				dictionary.Add("tp.request_received", "收到來自 {0} 的傳送請求。輸入 /tp yes 接受,/tp no 拒絕。");
				dictionary.Add("tp.accepted_request", "已接受 {0} 的傳送請求。");
				dictionary.Add("tp.rejected_request", "{0} 拒絕了你的傳送請求。");
				dictionary.Add("tp.info_you_rejected", "已拒絕傳送請求。");
				dictionary.Add("tp.teleported_to", "已傳送到 {0} 身邊。");
				break;
			case "en":
				dictionary.Add("plugin.initializing", "is initializing...");
				dictionary.Add("plugin.author_prefix", "Author: ");
				dictionary.Add("plugin.initialized", "initialized successfully!");
				dictionary.Add("plugin.patches_skipped", "Patches already applied, skipping...");
				dictionary.Add("config.chat_hotkey", "Chat Toggle Hotkey");
				dictionary.Add("config.max_history", "Max Chat History Lines");
				dictionary.Add("config.enable_tp_desc", "Enable Teleport feature (/tp command)");
				dictionary.Add("ui.chat_placeholder", "Enter message...");
				dictionary.Add("ui.system_message", "[System] {0}");
				dictionary.Add("ui.system_message_empty", "[System]");
				dictionary.Add("player.default_name", "Player {0}");
				dictionary.Add("cmd.unknown_command", "Unknown command: {0}");
				dictionary.Add("tp.usage", "Usage: /tp <player> or /tp yes/no");
				dictionary.Add("tp.error_not_connected", "Not connected to a room, cannot use TP.");
				dictionary.Add("tp.error_disabled", "TP feature is disabled. Please enable EnableTp in config.");
				dictionary.Add("tp.error_host_disabled", "Host has disabled TP feature.");
				dictionary.Add("tp.error_player_not_found", "No player found containing '{0}'.");
				dictionary.Add("tp.error_multiple_players", "Multiple players found for '{0}': {1}");
				dictionary.Add("tp.error_tp_self", "Cannot send TP request to yourself.");
				dictionary.Add("tp.error_requester_busy", "You already have a TP request in progress. Please finish it first.");
				dictionary.Add("tp.error_target_busy", "{0} already has a TP request in progress. Please try again later.");
				dictionary.Add("tp.error_invalid_command", "Invalid TP command. Usage: /tp <player> or /tp yes/no");
				dictionary.Add("tp.error_no_request_to_process", "You have no TP requests to process.");
				dictionary.Add("tp.error_request_expired", "TP request expired.");
				dictionary.Add("tp.error_requester_offline", "Requester ({0}) is offline, operation cancelled.");
				dictionary.Add("tp.error_no_pending_request", "No pending TP requests.");
				dictionary.Add("tp.error_teleport_failed", "Teleport failed: Cannot locate player position.");
				dictionary.Add("tp.request_sent", "Sent TP request to {0}, waiting for acceptance...");
				dictionary.Add("tp.request_received", "Received TP request from {0}. Type /tp yes to accept, /tp no to deny.");
				dictionary.Add("tp.accepted_request", "Accepted TP request from {0}.");
				dictionary.Add("tp.rejected_request", "{0} rejected your TP request.");
				dictionary.Add("tp.info_you_rejected", "You rejected the TP request.");
				dictionary.Add("tp.teleported_to", "Teleported to {0}.");
				break;
			case "ja":
				dictionary.Add("plugin.initializing", "初期化を開始します...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初期化が完了しました!");
				dictionary.Add("plugin.patches_skipped", "パッチは既に適用されています。スキップします...");
				dictionary.Add("config.chat_hotkey", "チャット開閉ホットキー");
				dictionary.Add("config.max_history", "チャット履歴の最大行数");
				dictionary.Add("config.enable_tp_desc", "テレポート機能を有効にする (/tp コマンド)");
				dictionary.Add("ui.chat_placeholder", "メッセージを入力...");
				dictionary.Add("ui.system_message", "[システム] {0}");
				dictionary.Add("ui.system_message_empty", "[システム]");
				dictionary.Add("player.default_name", "プレイヤー {0}");
				dictionary.Add("cmd.unknown_command", "不明なコマンド:{0}");
				dictionary.Add("tp.usage", "使い方:/tp <プレイヤー名> または /tp yes/no");
				dictionary.Add("tp.error_not_connected", "マルチプレイの部屋に接続されていないため、テレポートは使用できません。");
				dictionary.Add("tp.error_disabled", "テレポート機能が無効です。設定ファイルで EnableTp を有効にしてください。");
				dictionary.Add("tp.error_host_disabled", "ホストがテレポート機能を無効にしています。");
				dictionary.Add("tp.error_player_not_found", "'{0}' を含むプレイヤーが見つかりません。");
				dictionary.Add("tp.error_multiple_players", "'{0}' を含むプレイヤーが複数見つかりました:{1}");
				dictionary.Add("tp.error_tp_self", "自分自身にテレポートリクエストを送ることはできません。");
				dictionary.Add("tp.error_requester_busy", "現在、処理中のテレポートリクエストがあります。完了してから再試行してください。");
				dictionary.Add("tp.error_target_busy", "{0} は現在、処理中のテレポートリクエストがあります。後で再試行してください。");
				dictionary.Add("tp.error_invalid_command", "無効なテレポートコマンドです。使い方:/tp <プレイヤー名> または /tp yes/no");
				dictionary.Add("tp.error_no_pending_request", "保留中のテレポートリクエストはありません。");
				dictionary.Add("tp.error_no_request_to_process", "処理対象のテレポートリクエストがありません。");
				dictionary.Add("tp.error_request_expired", "テレポートリクエストの期限が切れました。");
				dictionary.Add("tp.error_requester_offline", "リクエスト送信者 ({0}) がオフラインになったため、操作はキャンセルされました。");
				dictionary.Add("tp.error_teleport_failed", "テレポート失敗:プレイヤーの位置を特定できません。");
				dictionary.Add("tp.request_sent", "{0} にテレポートリクエストを送信しました。承認を待っています...");
				dictionary.Add("tp.request_received", "{0} からテレポートリクエストを受け取りました。/tp yes で承認、/tp no で拒否します。");
				dictionary.Add("tp.accepted_request", "{0} からのテレポートリクエストを承認しました。");
				dictionary.Add("tp.rejected_request", "{0} がテレポートリクエストを拒否しました。");
				dictionary.Add("tp.info_you_rejected", "テレポートリクエストを拒否しました。");
				dictionary.Add("tp.teleported_to", "{0} の場所にテレポートしました。");
				break;
			}
			return dictionary;
		}
	}
	public class LocalizationManager
	{
		private static LocalizationManager _instance;

		private readonly Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();

		private string _currentLocale = "zh";

		public static readonly string[] SupportedLanguages = new string[12]
		{
			"zh", "zh-Hant", "en", "fr", "de", "ja", "ko", "pt", "ru", "es",
			"tr", "uk"
		};

		public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager());

		private LocalizationManager()
		{
			Initialize();
		}

		public void Initialize()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LocalizationSettings.SelectedLocale != (Object)null)
			{
				LocaleIdentifier identifier = LocalizationSettings.SelectedLocale.Identifier;
				_currentLocale = ((LocaleIdentifier)(ref identifier)).Code;
			}
			string[] supportedLanguages = SupportedLanguages;
			foreach (string text in supportedLanguages)
			{
				Dictionary<string, string> defaultTranslations = LocalizationHelper.GetDefaultTranslations(text);
				if (defaultTranslations != null && defaultTranslations.Count > 0)
				{
					_localizations[text] = defaultTranslations;
				}
			}
			LocalizationSettings.SelectedLocaleChanged += OnGameLanguageChanged;
		}

		private void OnGameLanguageChanged(Locale locale)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)locale != (Object)null)
			{
				LocaleIdentifier identifier = locale.Identifier;
				string code = ((LocaleIdentifier)(ref identifier)).Code;
				if (_localizations.ContainsKey(code))
				{
					_currentLocale = code;
				}
				else
				{
					_currentLocale = "en";
				}
			}
		}

		public string GetLocalizedText(string key, params object[] args)
		{
			if (string.IsNullOrEmpty(_currentLocale) || !_localizations.ContainsKey(_currentLocale))
			{
				_currentLocale = "en";
			}
			if (_localizations.ContainsKey(_currentLocale) && _localizations[_currentLocale].TryGetValue(key, out var value))
			{
				if (args.Length == 0)
				{
					return value;
				}
				return string.Format(value, args);
			}
			if (_currentLocale != "en" && _localizations.ContainsKey("en") && _localizations["en"].TryGetValue(key, out var value2))
			{
				if (args.Length == 0)
				{
					return value2;
				}
				return string.Format(value2, args);
			}
			if (_localizations.ContainsKey("zh") && _localizations["zh"].TryGetValue(key, out var value3))
			{
				if (args.Length == 0)
				{
					return value3;
				}
				return string.Format(value3, args);
			}
			return key;
		}
	}
}
namespace SimpleInGameChat.Configuration
{
	public class ConfigManager
	{
		private static ConfigManager _instance;

		private readonly ConfigFile _configFile;

		private readonly Dictionary<string, ConfigEntry<bool>> _boolConfigs;

		private readonly Dictionary<string, ConfigEntry<string>> _stringConfigs;

		private readonly Dictionary<string, ConfigEntry<int>> _intConfigs;

		public static ConfigEntry<string> ChatHotkey { get; private set; }

		public static ConfigEntry<int> MaxChatHistory { get; private set; }

		public static ConfigEntry<bool> EnableTp { get; private set; }

		public static ConfigManager Instance => _instance;

		private ConfigManager(ConfigFile configFile)
		{
			_configFile = configFile;
			_boolConfigs = new Dictionary<string, ConfigEntry<bool>>();
			_stringConfigs = new Dictionary<string, ConfigEntry<string>>();
			_intConfigs = new Dictionary<string, ConfigEntry<int>>();
			InitializeDefaultConfigs();
		}

		public static void Initialize(ConfigFile configFile)
		{
			if (_instance == null)
			{
				_instance = new ConfigManager(configFile);
			}
		}

		private void InitializeDefaultConfigs()
		{
			ChatHotkey = RegisterHotkey("聊天 - Chat", "ChatHotkey", GetLocalizedDescription("config.chat_hotkey"), "enter");
			MaxChatHistory = RegisterInt("聊天 - Chat", "MaxChatHistory", GetLocalizedDescription("config.max_history"), 100);
			EnableTp = RegisterBool("命令 - Commands", "EnableTp", GetLocalizedDescription("config.enable_tp_desc"), defaultValue: false);
		}

		private string GetLocalizedDescription(string key)
		{
			return LocalizationManager.Instance?.GetLocalizedText(key);
		}

		public ConfigEntry<bool> RegisterBool(string section, string key, string description, bool defaultValue)
		{
			ConfigEntry<bool> val = _configFile.Bind<bool>(section, key, defaultValue, description);
			_boolConfigs[key] = val;
			return val;
		}

		public ConfigEntry<string> RegisterHotkey(string section, string key, string description, string defaultValue)
		{
			ConfigEntry<string> val = _configFile.Bind<string>(section, key, defaultValue, description);
			_stringConfigs[key] = val;
			return val;
		}

		public ConfigEntry<int> RegisterInt(string section, string key, string description, int defaultValue)
		{
			ConfigEntry<int> val = _configFile.Bind<int>(section, key, defaultValue, description);
			_intConfigs[key] = val;
			return val;
		}
	}
}
namespace SimpleInGameChat.Commands
{
	public interface IChatCommand
	{
		string Name { get; }

		IEnumerable<string> Aliases { get; }

		bool TryExecute(ChatCommandContext context);
	}
	public interface IChatCommandAutoComplete
	{
		IEnumerable<ChatAutoCompleteItem> GetAutoCompleteItems(ChatAutoCompleteContext context);
	}
	public sealed class ChatCommandContext
	{
		public string RawInput { get; }

		public string Command { get; }

		public string[] Args { get; }

		public ulong SenderClientId { get; }

		public ChatNetworkManager Network { get; }

		public ChatCommandContext(string rawInput, string command, string[] args, ulong senderClientId, ChatNetworkManager network)
		{
			RawInput = rawInput;
			Command = command;
			Args = args;
			SenderClientId = senderClientId;
			Network = network;
		}
	}
	public readonly struct ChatAutoCompleteItem
	{
		public string DisplayText { get; }

		public string ApplyText { get; }

		public ChatAutoCompleteItem(string displayText, string applyText)
		{
			DisplayText = displayText ?? string.Empty;
			ApplyText = applyText ?? string.Empty;
		}
	}
	public sealed class ChatAutoCompleteContext
	{
		public string RawInput { get; }

		public char Prefix { get; }

		public string CommandToken { get; }

		public string ArgsText { get; }

		public ulong SenderClientId { get; }

		public ChatNetworkManager Network { get; }

		public ChatAutoCompleteContext(string rawInput, char prefix, string commandToken, string argsText, ulong senderClientId, ChatNetworkManager network)
		{
			RawInput = rawInput ?? string.Empty;
			Prefix = prefix;
			CommandToken = commandToken ?? string.Empty;
			ArgsText = argsText ?? string.Empty;
			SenderClientId = senderClientId;
			Network = network;
		}
	}
	public static class ChatCommandManager
	{
		private sealed class TpCommand : IChatCommand, IChatCommandAutoComplete
		{
			[CompilerGenerated]
			private sealed class <>c__DisplayClass5_0
			{
				public string query;

				internal bool <GetAutoCompleteItems>b__0(string p)
				{
					return p.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;
				}

				internal bool <GetAutoCompleteItems>b__1(string p)
				{
					return p.StartsWith(query, StringComparison.OrdinalIgnoreCase);
				}
			}

			[CompilerGenerated]
			private sealed class <GetAutoCompleteItems>d__5 : IEnumerable<ChatAutoCompleteItem>, IEnumerable, IEnumerator<ChatAutoCompleteItem>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private ChatAutoCompleteItem <>2__current;

				private int <>l__initialThreadId;

				private ChatAutoCompleteContext context;

				public ChatAutoCompleteContext <>3__context;

				private IEnumerator<string> <>7__wrap1;

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

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

				[DebuggerHidden]
				public <GetAutoCompleteItems>d__5(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					int num = <>1__state;
					if (num == -3 || num == 1)
					{
						try
						{
						}
						finally
						{
							<>m__Finally1();
						}
					}
					<>7__wrap1 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					try
					{
						switch (<>1__state)
						{
						default:
							return false;
						case 0:
						{
							<>1__state = -1;
							<>c__DisplayClass5_0 CS$<>8__locals0 = new <>c__DisplayClass5_0();
							if ((Object)(object)context.Network == (Object)null)
							{
								return false;
							}
							string text = (context.ArgsText ?? string.Empty).Trim();
							if (text.Equals("yes", StringComparison.OrdinalIgnoreCase) || text.Equals("no", StringComparison.OrdinalIgnoreCase))
							{
								return false;
							}
							List<string> onlinePlayerNames = context.Network.GetOnlinePlayerNames(context.SenderClientId);
							if (onlinePlayerNames == null || onlinePlayerNames.Count == 0)
							{
								return false;
							}
							CS$<>8__locals0.query = text;
							IEnumerable<string> enumerable = ((!string.IsNullOrWhiteSpace(CS$<>8__locals0.query)) ? ((IEnumerable<string>)(from p in onlinePlayerNames