The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of CozyChat v1.3.1
CozyChat.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CozyChat")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CozyChat")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("63672e51-848e-4583-881d-12ac0f729d94")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace TextChatMod; [BepInPlugin("com.hiccup.textchat", "CozyChat", "1.3.1")] public class TextChatPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(PhotonNetwork), "Disconnect")] public static class PhotonNetwork_Disconnect_Patch { private static void Postfix() { playersWithMod.Clear(); } } [HarmonyPatch(typeof(PlayerConnectionLog), "TimeoutMessageRoutine")] private class TimeoutMessagePatch { [CompilerGenerated] private sealed class <CustomTimeoutRoutine>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PlayerConnectionLog instance; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CustomTimeoutRoutine>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(messageTimeout.Value); <>1__state = 1; return true; case 1: <>1__state = -1; RemoveFirstMessage(instance); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static bool Prefix(PlayerConnectionLog __instance, ref IEnumerator __result) { __result = CustomTimeoutRoutine(__instance); return false; } [IteratorStateMachine(typeof(<CustomTimeoutRoutine>d__1))] private static IEnumerator CustomTimeoutRoutine(PlayerConnectionLog instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CustomTimeoutRoutine>d__1(0) { instance = instance }; } } [CompilerGenerated] private sealed class <FindConnectionLogCoroutine>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextChatPlugin <>4__this; private float <searchTime>5__1; private GameObject <go>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FindConnectionLogCoroutine>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <go>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <searchTime>5__1 = 0f; break; case 1: <>1__state = -1; break; } if (!Object.op_Implicit((Object)(object)connectionLog) && <searchTime>5__1 < 30f) { connectionLog = Object.FindFirstObjectByType<PlayerConnectionLog>(); if (!Object.op_Implicit((Object)(object)connectionLog)) { <go>5__2 = GameObject.Find("PlayerConnectionLog"); if (Object.op_Implicit((Object)(object)<go>5__2)) { connectionLog = <go>5__2.GetComponent<PlayerConnectionLog>(); } <go>5__2 = null; } if (Object.op_Implicit((Object)(object)connectionLog)) { ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"Found PlayerConnectionLog via coroutine!"); <>4__this.CreateChatUI(); return false; } <searchTime>5__1 += 0.5f; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } if (!Object.op_Implicit((Object)(object)connectionLog)) { ((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)"Could not find PlayerConnectionLog after 30 seconds!"); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ForceFocusInputField>d__31 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextChatPlugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ForceFocusInputField>d__31(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)chatInputField != (Object)null && isTyping) { ((Selectable)chatInputField).Select(); chatInputField.ActivateInputField(); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ShowStartupMessage>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextChatPlugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ShowStartupMessage>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 1; return true; case 1: <>1__state = -1; DisplayChatMessage("[CozyChat]", $"CozyChat v{((BaseUnityPlugin)<>4__this).Info.Metadata.Version} successfully loaded."); <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 2; return true; case 2: <>1__state = -1; DisplayChatMessage("[CozyChat]", "Use /help or /commands to change options."); ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.WaitForRoomAndSendPing()); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitAndSendPingCoroutine>d__22 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextChatPlugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitAndSendPingCoroutine>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.SendModPing(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForRoomAndSendPing>d__26 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextChatPlugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForRoomAndSendPing>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_004f; case 1: <>1__state = -1; goto IL_004f; case 2: { <>1__state = -1; <>4__this.SendModPing(); return false; } IL_004f: if (!PhotonNetwork.InRoom) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static TextChatPlugin Instance; private static PlayerConnectionLog connectionLog; public static bool isTyping = false; private static GameObject chatInputUI; private static TMP_InputField chatInputField; private static List<MonoBehaviour> disabledControllers = new List<MonoBehaviour>(); private static List<CharacterController> disabledCharacterControllers = new List<CharacterController>(); private static List<Rigidbody> frozenRigidbodies = new List<Rigidbody>(); private static HashSet<string> playersWithMod = new HashSet<string>(); private static bool hasSentPingForCurrentRoom = false; private static ConfigEntry<KeyCode> chatKey; private static ConfigEntry<Color> chatMessageColor; private static ConfigEntry<float> messageTimeout; private static ConfigEntry<int> maxMessageLength; private static ConfigEntry<bool> hideDeadMessages; private static ConfigEntry<float> chatProximityRange; private static bool startupMessageShown = false; private const byte CHAT_EVENT_CODE_LEGACY = 77; private const byte CHAT_EVENT_CODE_PEAK = 81; private const byte CHAT_MOD_PING_EVENT = 82; private const byte CHAT_MOD_PONG_EVENT = 83; private static bool eventHandlerRegistered = false; public static void LogInfo(string message) { TextChatPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)message); } } private void Awake() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) Instance = this; chatKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ChatKey", (KeyCode)116, "Key to open chat"); chatMessageColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "MessageColor", new Color(1f, 1f, 1f, 1f), "Color of chat messages"); messageTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MessageTimeout", 10f, "How long messages stay on screen"); maxMessageLength = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxMessageLength", 100, "Maximum length of chat messages"); hideDeadMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideDeadMessages", true, "If enabled, alive players will not see chat from dead/unconscious players."); chatProximityRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ChatProximityRange", 0f, "Maximum distance for receiving chat messages. 0 = unlimited range."); SceneManager.activeSceneChanged += OnSceneChanged; Harmony val = new Harmony("com.yourname.textchat"); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Text Chat Mod loaded!"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Chat key set to: {chatKey.Value}"); Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private void Update() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)connectionLog)) { connectionLog = Object.FindFirstObjectByType<PlayerConnectionLog>(); if (Object.op_Implicit((Object)(object)connectionLog)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Found PlayerConnectionLog!"); CreateChatUI(); return; } PlayerConnectionLog[] array = Object.FindObjectsByType<PlayerConnectionLog>((FindObjectsSortMode)0); if (array.Length != 0) { connectionLog = array[0]; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Found PlayerConnectionLog using FindObjectsByType! Count: {array.Length}"); CreateChatUI(); } return; } if (Input.GetKeyDown(chatKey.Value) && !isTyping) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Chat key pressed!"); OpenChat(); } else if (isTyping) { if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)) { SendMessage(); } else if (Input.GetKeyDown((KeyCode)27)) { CloseChat(); } if ((Object)(object)chatInputField != (Object)null && !chatInputField.isFocused) { ((Selectable)chatInputField).Select(); chatInputField.ActivateInputField(); } if ((Object)(object)chatInputField != (Object)null && !chatInputField.isFocused) { string inputString = Input.inputString; if (!string.IsNullOrEmpty(inputString)) { string text = inputString; for (int i = 0; i < text.Length; i++) { char c = text[i]; switch (c) { case '\b': if (chatInputField.text.Length > 0) { chatInputField.text = chatInputField.text.Substring(0, chatInputField.text.Length - 1); } continue; case '\n': continue; } if (c != '\r' && c != 0 && !char.IsControl(c)) { TMP_InputField obj = chatInputField; obj.text += c; } } } } } try { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.data != (Object)null) { if (isTyping) { localCharacter.refs.movement.movementModifier = 0f; localCharacter.data.jumpsRemaining = 0; } else { localCharacter.refs.movement.movementModifier = 1f; if (localCharacter.data.jumpsRemaining == 0) { localCharacter.data.jumpsRemaining = 1; } } } } catch { } if (PhotonNetwork.InRoom && !hasSentPingForCurrentRoom) { hasSentPingForCurrentRoom = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[CozyChat] Detected room join, sending ping"); ((MonoBehaviour)this).StartCoroutine(WaitAndSendPingCoroutine()); } else if (!PhotonNetwork.InRoom && hasSentPingForCurrentRoom) { hasSentPingForCurrentRoom = false; playersWithMod.Clear(); } } private void Start() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"TextChatPlugin Start() called"); ((MonoBehaviour)this).StartCoroutine(FindConnectionLogCoroutine()); if (!eventHandlerRegistered && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived += OnEvent; eventHandlerRegistered = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered Photon event handler"); } } [IteratorStateMachine(typeof(<FindConnectionLogCoroutine>d__20))] private IEnumerator FindConnectionLogCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FindConnectionLogCoroutine>d__20(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<WaitAndSendPingCoroutine>d__22))] private IEnumerator WaitAndSendPingCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitAndSendPingCoroutine>d__22(0) { <>4__this = this }; } private void OnSceneChanged(Scene oldScene, Scene newScene) { if (!startupMessageShown && ((Scene)(ref newScene)).name.ToLower().Contains("airport")) { startupMessageShown = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Airport scene detected, showing CozyChat startup message..."); ((MonoBehaviour)this).StartCoroutine(ShowStartupMessage()); } } [IteratorStateMachine(typeof(<ShowStartupMessage>d__24))] private IEnumerator ShowStartupMessage() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ShowStartupMessage>d__24(0) { <>4__this = this }; } private void SendModPing() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom || PhotonNetwork.LocalPlayer == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[CozyChat] Cannot send ping - not in a room yet"); return; } object[] array = new object[3] { PhotonNetwork.LocalPlayer.NickName, PhotonNetwork.LocalPlayer.UserId, ((BaseUnityPlugin)this).Info.Metadata.Version.ToString() }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)82, (object)array, val, SendOptions.SendReliable); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[CozyChat] Sent mod detection ping to other players (InRoom: {PhotonNetwork.InRoom})"); } [IteratorStateMachine(typeof(<WaitForRoomAndSendPing>d__26))] private IEnumerator WaitForRoomAndSendPing() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForRoomAndSendPing>d__26(0) { <>4__this = this }; } private void SendModPong() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer != null) { object[] array = new object[3] { PhotonNetwork.LocalPlayer.NickName, PhotonNetwork.LocalPlayer.UserId, ((BaseUnityPlugin)this).Info.Metadata.Version.ToString() }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)83, (object)array, val, SendOptions.SendReliable); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[CozyChat] Sent mod detection pong response"); } } private void CreateChatUI() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Expected O, but got Unknown //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Expected O, but got Unknown //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Expected O, but got Unknown //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Expected O, but got Unknown //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) try { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Creating chat UI…"); Canvas componentInParent = ((Component)connectionLog).GetComponentInParent<Canvas>(); if (!Object.op_Implicit((Object)(object)componentInParent)) { ((BaseUnityPlugin)this).Logger.LogError((object)"ChatUI: Parent canvas not found!"); return; } GameObject val = GameObject.Find("/GAME/GUIManager/Canvas_HUD/BarGroup/Bar"); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"ChatUI: Health bar not found, falling back to plain box."); } chatInputUI = new GameObject("ChatInputUI"); chatInputUI.transform.SetParent(((Component)componentInParent).transform, false); RectTransform val2 = chatInputUI.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0f, 0f); val2.anchorMax = new Vector2(1f, 1f); val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; GameObject val3; if ((Object)(object)val != (Object)null) { val3 = Object.Instantiate<GameObject>(val, chatInputUI.transform); ((Object)val3).name = "ChatBackground"; StaminaBar component = val3.GetComponent<StaminaBar>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } string[] array = new string[4] { "MoraleBoost", "FullBar", "OutlineOverflowLine", "LayoutGroup" }; string[] array2 = array; foreach (string text in array2) { Transform val4 = val3.transform.Find(text); if ((Object)(object)val4 != (Object)null) { Object.Destroy((Object)(object)((Component)val4).gameObject); } } } else { val3 = new GameObject("ChatBackground"); val3.transform.SetParent(chatInputUI.transform, false); Image val5 = val3.AddComponent<Image>(); ((Graphic)val5).color = new Color(0f, 0f, 0f, 0.75f); } RectTransform val6 = val3.GetComponent<RectTransform>(); if ((Object)(object)val6 == (Object)null) { val6 = val3.AddComponent<RectTransform>(); } val6.anchorMin = new Vector2(0f, 0f); val6.anchorMax = new Vector2(0f, 0f); val6.pivot = new Vector2(0f, 0f); val6.anchoredPosition = new Vector2(69f, 10f); val6.sizeDelta = new Vector2(500f, 40f); GameObject val7 = new GameObject("ChatInputField"); val7.transform.SetParent(val3.transform, false); RectTransform val8 = val7.AddComponent<RectTransform>(); val8.anchorMin = new Vector2(0f, 0f); val8.anchorMax = new Vector2(1f, 1f); val8.offsetMin = new Vector2(8f, 4f); val8.offsetMax = new Vector2(-8f, -4f); GameObject val9 = new GameObject("Viewport"); val9.transform.SetParent(val7.transform, false); RectTransform val10 = val9.AddComponent<RectTransform>(); val10.anchorMin = Vector2.zero; val10.anchorMax = Vector2.one; val10.offsetMin = Vector2.zero; val10.offsetMax = Vector2.zero; val9.AddComponent<RectMask2D>(); GameObject val11 = new GameObject("Text"); val11.transform.SetParent(val9.transform, false); RectTransform val12 = val11.AddComponent<RectTransform>(); val12.anchorMin = Vector2.zero; val12.anchorMax = Vector2.one; val12.offsetMin = Vector2.zero; val12.offsetMax = Vector2.zero; TextMeshProUGUI val13 = val11.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val13).text = string.Empty; ((TMP_Text)val13).fontSize = 20f; ((Graphic)val13).color = Color.white; ((TMP_Text)val13).alignment = (TextAlignmentOptions)257; GameObject val14 = new GameObject("Placeholder"); val14.transform.SetParent(val9.transform, false); RectTransform val15 = val14.AddComponent<RectTransform>(); val15.anchorMin = Vector2.zero; val15.anchorMax = Vector2.one; val15.offsetMin = Vector2.zero; val15.offsetMax = Vector2.zero; TextMeshProUGUI val16 = val14.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val16).text = "Type a message and press Enter to send..."; ((TMP_Text)val16).fontSize = 20f; ((TMP_Text)val16).alignment = (TextAlignmentOptions)257; ((TMP_Text)val16).fontStyle = (FontStyles)2; ((Graphic)val16).color = new Color(1f, 1f, 1f, 0.55f); TextMeshProUGUI componentInChildren = ((Component)connectionLog).GetComponentInChildren<TextMeshProUGUI>(); TMP_FontAsset val17 = ((componentInChildren != null) ? ((TMP_Text)componentInChildren).font : null); if ((Object)(object)val17 != (Object)null) { ((TMP_Text)val13).font = val17; ((TMP_Text)val16).font = val17; } chatInputField = val7.AddComponent<TMP_InputField>(); chatInputField.textViewport = val10; chatInputField.textComponent = (TMP_Text)(object)val13; chatInputField.placeholder = (Graphic)(object)val16; chatInputField.characterLimit = maxMessageLength.Value; chatInputField.contentType = (ContentType)0; chatInputField.lineType = (LineType)0; chatInputField.richText = false; chatInputField.selectionColor = new Color(0.5f, 0.5f, 1f, 0.5f); chatInputField.caretColor = Color.white; chatInputField.caretWidth = 2; chatInputField.caretBlinkRate = 0.85f; chatInputUI.SetActive(false); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Chat UI created successfully!"); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Error creating chat UI: {arg}"); } } private TMP_Text CreatePlaceholder(Transform parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Placeholder"); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val2).text = "Press Enter to send..."; ((Graphic)val2).color = new Color(0.5f, 0.5f, 0.5f, 0.5f); ((TMP_Text)val2).fontSize = 14f; RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = new Vector2(5f, 5f); component.offsetMax = new Vector2(-5f, -5f); return (TMP_Text)(object)val2; } private void OpenChat() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)chatInputUI) || !Object.op_Implicit((Object)(object)chatInputField)) { return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Opening chat UI..."); isTyping = true; chatInputUI.SetActive(true); EventSystem val = EventSystem.current; if ((Object)(object)val == (Object)null) { GameObject val2 = new GameObject("EventSystem"); val = val2.AddComponent<EventSystem>(); val2.AddComponent<StandaloneInputModule>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Created EventSystem"); } chatInputField.text = ""; ((Selectable)chatInputField).interactable = true; ((Selectable)chatInputField).Select(); chatInputField.ActivateInputField(); chatInputField.ForceLabelUpdate(); val.SetSelectedGameObject(((Component)chatInputField).gameObject); ((MonoBehaviour)this).StartCoroutine(ForceFocusInputField()); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Chat UI active: {chatInputUI.activeSelf}, Input field interactable: {((Selectable)chatInputField).interactable}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Input field selected: {chatInputField.isFocused}"); ManualLogSource logger = ((BaseUnityPlugin)this).Logger; GameObject currentSelectedGameObject = val.currentSelectedGameObject; logger.LogInfo((object)("EventSystem selected object: " + ((currentSelectedGameObject != null) ? ((Object)currentSelectedGameObject).name : null))); try { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.data != (Object)null) { localCharacter.refs.movement.movementModifier = 0f; localCharacter.data.jumpsRemaining = 0; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to disable movement: " + ex.Message)); } } [IteratorStateMachine(typeof(<ForceFocusInputField>d__31))] private IEnumerator ForceFocusInputField() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ForceFocusInputField>d__31(0) { <>4__this = this }; } private void CloseChat() { if (!Object.op_Implicit((Object)(object)chatInputUI)) { return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Closing chat UI..."); isTyping = false; chatInputUI.SetActive(false); chatInputField.DeactivateInputField(false); try { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.data != (Object)null) { localCharacter.refs.movement.movementModifier = 1f; localCharacter.data.jumpsRemaining = 1; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to restore movement: " + ex.Message)); } } private static bool HandleChatCommand(string message) { if (!message.StartsWith("/")) { return false; } string[] array = message.Trim().Split(new char[1] { ' ' }); switch (array[0].ToLower()) { case "/help": case "/commands": DisplayChatMessage("[ChatMod]", "Available commands:\n/help or /commands - Show this list\n/config - Show current config values\n/chatProximityRange value - Set chat proximity range (0 = unlimited)\n/hideDeadMessages true/false - Show or hide dead/unconscious player chat\n/reset - Reset all configs to default values"); return true; case "/config": DisplayChatMessage("[ChatMod]", "Current config:\n" + $"- ChatProximityRange: {chatProximityRange.Value}\n" + $"- HideDeadMessages: {hideDeadMessages.Value}"); return true; case "/chatproximityrange": { if (array.Length >= 2 && float.TryParse(array[1], out var result2)) { chatProximityRange.Value = result2; ((BaseUnityPlugin)Instance).Config.Save(); DisplayChatMessage("[ChatMod]", $"Set chat proximity range to {result2}"); } else { DisplayChatMessage("[ChatMod]", "Usage: /chatProximityRange value"); } return true; } case "/hidedeadmessages": { if (array.Length >= 2 && bool.TryParse(array[1], out var result)) { hideDeadMessages.Value = result; ((BaseUnityPlugin)Instance).Config.Save(); DisplayChatMessage("[ChatMod]", $"Set hide dead messages to {result}"); } else { DisplayChatMessage("[ChatMod]", "Usage: /hideDeadMessages true/false"); } return true; } case "/reset": chatProximityRange.Value = (float)((ConfigEntryBase)chatProximityRange).DefaultValue; hideDeadMessages.Value = (bool)((ConfigEntryBase)hideDeadMessages).DefaultValue; ((BaseUnityPlugin)Instance).Config.Save(); DisplayChatMessage("[ChatMod]", "Config reset to default values."); return true; default: DisplayChatMessage("[ChatMod]", "Unknown command: " + array[0]); return true; } } private void SendMessage() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) string text = chatInputField.text.Trim(); if (string.IsNullOrEmpty(text)) { CloseChat(); return; } if (HandleChatCommand(text)) { CloseChat(); return; } bool flag = false; try { flag = (Character.localCharacter?.data?.dead).GetValueOrDefault(); } catch { } object[] array = new object[4] { PhotonNetwork.LocalPlayer.NickName, text, PhotonNetwork.LocalPlayer.UserId, flag.ToString() }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; PhotonNetwork.RaiseEvent((byte)81, (object)array, val, SendOptions.SendReliable); CloseChat(); } private static Color GetPlayerColorFromCharacter(string playerName) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) try { Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0); foreach (Character val in array) { PhotonView photonView = ((MonoBehaviourPun)val).photonView; object obj; if (photonView == null) { obj = null; } else { Player owner = photonView.Owner; obj = ((owner != null) ? owner.NickName : null); } string text = (string)obj; if (!string.IsNullOrEmpty(text) && text == playerName) { return val.refs.customization.PlayerColor; } } } catch (Exception ex) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Failed to find player color for " + playerName + ": " + ex.Message)); } return Color.white; } public static void DisplayChatMessage(string playerName, string message) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)connectionLog)) { Color playerColorFromCharacter = GetPlayerColorFromCharacter(playerName); MethodInfo method = typeof(PlayerConnectionLog).GetMethod("AddMessage", BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo method2 = typeof(PlayerConnectionLog).GetMethod("GetColorTag", BindingFlags.Instance | BindingFlags.NonPublic); string text = (string)method2.Invoke(connectionLog, new object[1] { playerColorFromCharacter }); string text2 = (string)method2.Invoke(connectionLog, new object[1] { chatMessageColor.Value }); string text3 = Regex.Replace(message, "<.*?>", "", RegexOptions.Singleline); string text4 = text + playerName + "</color>" + text2 + ": " + text3 + "</color>"; method.Invoke(connectionLog, new object[1] { text4 }); } } private void OnDestroy() { if (eventHandlerRegistered && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= OnEvent; eventHandlerRegistered = false; } playersWithMod.Clear(); } private static Vector3 GetCharacterPosition(Character character) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) try { _ = character.Head; if (true) { return character.Head; } } catch { } try { return character.Center; } catch { } return ((Component)character).transform.position; } private static void OnEvent(EventData ev) { //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) switch (ev.Code) { case 81: { object[] array3 = (object[])ev.CustomData; string text5 = array3[0]?.ToString() ?? "???"; string text6 = array3[1]?.ToString() ?? ""; string text7 = array3[2]?.ToString() ?? ""; bool result; bool flag = bool.TryParse(array3[3]?.ToString(), out result) && result; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[ChatMod] Received message from '{text5}' (UserId: {text7}), dead={flag}, message={text6}"); if (flag) { text5 = "<color=red>[DEAD]</color> " + text5; } try { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && !localCharacter.data.dead && !localCharacter.data.fullyPassedOut) { if (hideDeadMessages.Value && flag) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Hiding dead message from '" + text5 + "'")); break; } if (chatProximityRange.Value > 0f) { Character val = FindCharacterByUserId(text7); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("[ChatMod] Could not find Character for UserId '" + text7 + "'")); } else { float num = Vector3.Distance(GetCharacterPosition(localCharacter), GetCharacterPosition(val)); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[ChatMod] Distance to '{text5}': {num} (limit {chatProximityRange.Value})"); if ((Object)(object)val != (Object)(object)localCharacter && num > chatProximityRange.Value) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ChatMod] Hiding message from '" + text5 + "' due to distance")); break; } } } } } catch (Exception arg) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"[ChatMod] Error filtering chat message: {arg}"); } DisplayChatMessage(text5, text6); break; } case 77: { object[] array4 = (object[])ev.CustomData; DisplayChatMessage(array4[0]?.ToString() ?? "???", array4[1]?.ToString() ?? ""); break; } case 82: { object[] array2 = (object[])ev.CustomData; string text3 = array2[0]?.ToString() ?? "???"; string item2 = array2[1]?.ToString() ?? ""; string text4 = array2[2]?.ToString() ?? "Unknown"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[CozyChat] Received mod ping from '" + text3 + "' (v" + text4 + ")")); if (!playersWithMod.Contains(item2)) { playersWithMod.Add(item2); DisplayChatMessage("[CozyChat]", text3 + " has CozyChat installed! (v" + text4 + ")"); } Instance.SendModPong(); break; } case 83: { object[] array = (object[])ev.CustomData; string text = array[0]?.ToString() ?? "???"; string item = array[1]?.ToString() ?? ""; string text2 = array[2]?.ToString() ?? "Unknown"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[CozyChat] Received mod pong from '" + text + "' (v" + text2 + ")")); if (!playersWithMod.Contains(item)) { playersWithMod.Add(item); DisplayChatMessage("[CozyChat]", text + " has CozyChat installed! (v" + text2 + ")"); } break; } case 78: case 79: case 80: break; } } private static Character FindCharacterByUserId(string userId) { Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0); foreach (Character val in array) { PhotonView photonView = ((MonoBehaviourPun)val).photonView; object obj; if (photonView == null) { obj = null; } else { Player owner = photonView.Owner; obj = ((owner != null) ? owner.UserId : null); } if ((string?)obj == userId) { return val; } } return null; } private static Character FindCharacterByName(string name) { Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0); foreach (Character val in array) { if ((Object)(object)((MonoBehaviourPun)val).photonView != (Object)null && ((MonoBehaviourPun)val).photonView.Owner != null && ((MonoBehaviourPun)val).photonView.Owner.NickName == name) { return val; } } return null; } private static void RemoveFirstMessage(PlayerConnectionLog instance) { FieldInfo field = typeof(PlayerConnectionLog).GetField("currentLog", BindingFlags.Instance | BindingFlags.NonPublic); List<string> list = (List<string>)field.GetValue(instance); if (list.Count > 0) { list.RemoveAt(0); MethodInfo method = typeof(PlayerConnectionLog).GetMethod("RebuildString", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(instance, null); } } } [HarmonyPatch] public static class InputPatches { [HarmonyPatch(typeof(EmoteWheel), "OnEnable")] public static class EmoteWheel_OnEnable_Patch { private static bool Prefix(EmoteWheel __instance) { if (TextChatPlugin.isTyping) { ((Component)__instance).gameObject.SetActive(false); return false; } return true; } } [HarmonyPatch] public static class CharacterInteractible_CanBeCarried_Patch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(CharacterInteractible), "CanBeCarried", (Type[])null, (Type[])null); } private static void Postfix(ref bool __result) { if (TextChatPlugin.isTyping) { __result = false; } } } public static bool IsTyping => TextChatPlugin.isTyping; [HarmonyPatch(typeof(Input), "GetButton", new Type[] { typeof(string) })] [HarmonyPrefix] private static bool GetButtonPrefix(string buttonName, ref bool __result) { if (IsTyping && (buttonName.Contains("Fire") || buttonName.Contains("Jump") || buttonName.Contains("Crouch"))) { __result = false; return false; } return true; } [HarmonyPatch(typeof(Input), "GetButtonDown", new Type[] { typeof(string) })] [HarmonyPrefix] private static bool GetButtonDownPrefix(string buttonName, ref bool __result) { if (IsTyping && (buttonName.Contains("Fire") || buttonName.Contains("Jump") || buttonName.Contains("Crouch"))) { __result = false; return false; } return true; } [HarmonyPatch(typeof(Input), "GetAxis", new Type[] { typeof(string) })] [HarmonyPrefix] private static bool GetAxisPrefix(string axisName, ref float __result) { if (IsTyping && (axisName == "Horizontal" || axisName == "Vertical" || axisName.Contains("Mouse"))) { __result = 0f; return false; } return true; } [HarmonyPatch(typeof(Input), "GetAxisRaw", new Type[] { typeof(string) })] [HarmonyPrefix] private static bool GetAxisRawPrefix(string axisName, ref float __result) { if (IsTyping && (axisName == "Horizontal" || axisName == "Vertical" || axisName.Contains("Mouse"))) { __result = 0f; return false; } return true; } }