Decompiled source of SimpleInGameChat v1.0.1
BepInEx/plugins/SimpleInGameChat.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
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