using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Microsoft.Extensions.Logging; using Photon.Pun; using Photon.Realtime; using TMPro; using TwitchLib.Client; using TwitchLib.Client.Enums; using TwitchLib.Client.Events; using TwitchLib.Client.Models; using TwitchLib.Communication.Clients; using TwitchLib.Communication.Interfaces; using TwitchLib.Communication.Models; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using UnityEngine.UI.ProceduralImage; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("V8.TwitchChat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("V8.TwitchChat")] [assembly: AssemblyTitle("TwitchChat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace PeakTextChat { public class BarGroupChildWatcher : MonoBehaviour { public Transform textChatDummyTransform; private void OnTransformChildrenChanged() { if ((Object)(object)textChatDummyTransform != (Object)null && textChatDummyTransform.GetSiblingIndex() > 0) { textChatDummyTransform.SetAsFirstSibling(); } } } public class TextChatDisplay : MonoBehaviour { public class ChatMessage { public string message; public GameObject textObj; public TMP_Text text; private Color textColor; private float hideDelay = 40f; private float hideTime = 10f; private float hideTimer = -1f; private float hide; public void Update() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) hideTimer -= Time.deltaTime; if (hideTimer <= 0f && hide < 1f) { hide += Time.deltaTime / hideTime; ((Graphic)text).color = new Color(textColor.r, textColor.g, textColor.b, 1f - hide); } } public ChatMessage(string message, GameObject textObject, float hideDelay) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) this.message = message; textObj = textObject; text = textObject.GetComponent(); textColor = ((Graphic)text).color; this.hideDelay = hideDelay; hideTimer = hideDelay; } } private int maxMessages = 30; private Vector2 boxSize = new Vector2(500f, 300f); private float fadeInTime = 0.03f; private float fadeOutTime = 5f; private float hideTime = 5f; private float fadeOutDelay = 15f; private float hideDelay = 40f; private float messageHideDelay = 40f; private float fontSize = 25f; private bool usingIMGUI; private TMP_InputField inputField; private RectTransform chatLogViewportTransform; private RectTransform baseTransform; private CanvasGroup canvasGroup; private float fade = 1f; private float fadeTimer = -1f; private float hide; private float hideTimer = -1f; private KeysHelper.KeyCodeInfo keyInfo; private Color offWhite = new Color(0.87f, 0.85f, 0.76f); private Color red = new Color(0.99f, 0.33f, 0f); private List messages = new List(); public bool isBlockingInput; public int framesSinceInputBlocked; public static TextChatDisplay instance; private string imguiFieldString = ""; private bool imguiTyping; private GameObject currentSelection; private void Awake() { instance = this; } private void Start() { //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) keyInfo = KeysHelper.GetKeyCodeShortInfo(PeakTextChatPlugin.configKey.Value); fontSize = ((PeakTextChatPlugin.configFontSize.Value < 0f) ? 1E+09f : PeakTextChatPlugin.configFontSize.Value); hideDelay = ((PeakTextChatPlugin.configHideDelay.Value < 0f) ? float.PositiveInfinity : PeakTextChatPlugin.configHideDelay.Value); fadeOutDelay = Mathf.Min((PeakTextChatPlugin.configFadeDelay.Value < 0f) ? float.PositiveInfinity : PeakTextChatPlugin.configFadeDelay.Value, hideDelay); messageHideDelay = ((PeakTextChatPlugin.configMessageFadeDelay.Value < 0f) ? float.PositiveInfinity : PeakTextChatPlugin.configMessageFadeDelay.Value); usingIMGUI = PeakTextChatPlugin.configIMGUI.Value; string[] array = PeakTextChatPlugin.configChatSize.Value.Split(':'); if (array.Length >= 2) { string s = array[0].Replace(" ", ""); string s2 = array[1].Replace(" ", ""); if (float.TryParse(s, out var result) && float.TryParse(s2, out var result2)) { boxSize = new Vector2(Mathf.Max(result, 10f), Mathf.Max(result2, 10f)); } else { boxSize = new Vector2(500f, 300f); } } ResetTimers(); SetupChatGUI(); } private void Update() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (isBlockingInput) { framesSinceInputBlocked = -1; } else { framesSinceInputBlocked = Mathf.Min(framesSinceInputBlocked + 1, 50); } if (!((Component)this).gameObject.activeInHierarchy) { isBlockingInput = false; return; } if ((Object)(object)currentSelection != (Object)(object)EventSystem.current.currentSelectedGameObject) { currentSelection = EventSystem.current.currentSelectedGameObject; if ((Object)(object)currentSelection != (Object)(object)((Component)inputField).gameObject) { isBlockingInput = false; } } if (!InputBlockingPatches.IsInputBlocked() && Input.GetKeyDown(keyInfo.key) && (Object)(object)inputField != (Object)null && (Object)(object)EventSystem.current != (Object)null) { if (usingIMGUI) { imguiTyping = true; GUI.FocusControl("ptctf"); } else { EventSystem.current.SetSelectedGameObject(((Component)inputField).gameObject, (BaseEventData)null); inputField.ActivateInputField(); } isBlockingInput = true; } if (isBlockingInput) { ResetTimers(); } if (PeakTextChatPlugin.configPos.Value == PeakTextChatPlugin.TextChatPosition.BottomLeft) { UpdatePosition(isBottomLeft: true); } fade = Mathf.Clamp((fadeTimer <= 0f) ? (fade - Time.deltaTime / fadeOutTime) : (fade + Time.deltaTime / fadeInTime), 0f, 1f); hide = Mathf.Clamp((hideTimer <= 0f) ? (hide + Time.deltaTime / hideTime) : (hide - Time.deltaTime / fadeInTime), 0f, 1f); fadeTimer -= Time.deltaTime; hideTimer -= Time.deltaTime; if ((Object)(object)canvasGroup != (Object)null) { canvasGroup.alpha = fade * 0.5f + (1f - hide) * 0.5f; } foreach (ChatMessage message in messages) { message.Update(); } } private void SetupChatGUI() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Expected O, but got Unknown //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) GUIManager val = GUIManager.instance; baseTransform = ((Component)this).gameObject.GetComponent() ?? ((Component)this).gameObject.AddComponent(); ((Transform)baseTransform).SetParent(((Component)this).transform, false); UpdatePosition(); baseTransform.sizeDelta = boxSize; canvasGroup = ((Component)this).gameObject.AddComponent(); canvasGroup.alpha = 1f; canvasGroup.blocksRaycasts = true; canvasGroup.interactable = true; canvasGroup.ignoreParentGroups = false; GameObject val2 = new GameObject("Shadow"); val2.transform.SetParent((Transform)(object)baseTransform, false); RectTransform val3 = val2.AddComponent(); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; ProceduralImage val4 = val2.AddComponent(); ((Graphic)val4).color = new Color(0f, 0f, 0f, PeakTextChatPlugin.configBgOpacity.Value); val4.FalloffDistance = 10f; val4.SetModifierType().Radius = fontSize / 4f + 10f; GameObject val5 = new GameObject("ChatLog"); RectTransform val6 = val5.AddComponent(); ((Transform)val6).SetParent((Transform)(object)baseTransform, false); val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.offsetMin = new Vector2(0f, fontSize * 2f); val6.offsetMax = Vector2.zero; val5.AddComponent(); GameObject val7 = new GameObject("Viewport"); chatLogViewportTransform = val7.AddComponent(); ((Transform)chatLogViewportTransform).SetParent((Transform)(object)val6, false); chatLogViewportTransform.pivot = new Vector2(0.5f, 0f); chatLogViewportTransform.anchorMin = Vector2.zero; chatLogViewportTransform.anchorMax = new Vector2(1f, 0f); chatLogViewportTransform.offsetMin = Vector2.zero; chatLogViewportTransform.offsetMax = new Vector2(0f, 5000f); inputField = CreateInputField(); RectTransform val8 = (RectTransform)((Component)inputField).transform; val8.pivot = new Vector2(0.5f, 0f); val8.anchorMin = new Vector2(0f, 0f); val8.anchorMax = new Vector2(1f, 0f); val8.offsetMin = new Vector2(5f, 5f); val8.offsetMax = new Vector2(-5f, fontSize * 1.75f); ((Transform)val8).SetParent((Transform)(object)baseTransform, false); VerticalLayoutGroup val9 = val7.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val9).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val9).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)val9).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val9).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)val9).childScaleWidth = false; ((HorizontalOrVerticalLayoutGroup)val9).childScaleHeight = false; ((LayoutGroup)val9).childAlignment = (TextAnchor)7; ((LayoutGroup)val9).padding = new RectOffset((int)(fontSize * 0.6f), (int)(fontSize * 0.6f), (int)(fontSize / 20f), (int)(fontSize / 20f)); ((HorizontalOrVerticalLayoutGroup)val9).spacing = (0f - fontSize) / 8f; ((UnityEvent)(object)inputField.onSubmit).AddListener((UnityAction)delegate(string e) { inputField.text = ""; inputField.textComponent.text = ""; TextChatManager.instance?.SendChatMessage(e); }); ((UnityEvent)(object)inputField.onEndEdit).AddListener((UnityAction)delegate { EventSystem.current.SetSelectedGameObject((GameObject)null); isBlockingInput = false; }); if (PeakTextChatPlugin.configFrameVisible.Value) { GameObject val10 = new GameObject("Border"); val10.transform.SetParent((Transform)(object)baseTransform, false); RectTransform val11 = val10.AddComponent(); val11.anchorMin = Vector2.zero; val11.anchorMax = Vector2.one; val11.offsetMin = Vector2.zero; val11.offsetMax = Vector2.zero; ProceduralImage val12 = val10.AddComponent(); ((Graphic)val12).color = offWhite; val12.BorderWidth = 2f; val12.SetModifierType().Radius = fontSize / 4f + 5f; } } private TMP_InputField CreateInputField() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0064: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("InputField"); TMP_InputField val2 = val.AddComponent(); ((Behaviour)val2).enabled = false; ProceduralImage val3 = (ProceduralImage)(object)(((Selectable)val2).targetGraphic = (Graphic)(object)((Component)val2).gameObject.AddComponent()); ((Graphic)val3).color = offWhite; val3.SetModifierType().Radius = fontSize / 4f; GameObject val5 = new GameObject("Text Area"); RectTransform val6 = val5.AddComponent(); val6.anchorMax = Vector2.one; val6.anchorMin = Vector2.zero; val6.offsetMax = new Vector2((0f - fontSize) / 2f, (0f - fontSize) * 0.3f); val6.offsetMin = new Vector2(fontSize / 2f, fontSize * 0.3f); ((Transform)val6).SetParent(((Component)val2).transform, false); RectMask2D val7 = val5.AddComponent(); val7.padding = new Vector4((0f - fontSize) * 0.4f, (0f - fontSize) / 4f, (0f - fontSize) * 0.4f, (0f - fontSize) / 4f); TMP_Text val8 = CreateText((Transform)(object)val6); ((Graphic)val8).color = new Color(0f, 0f, 0f, 0.6f); val8.text = "Press " + keyInfo.keyText + " to chat"; TMP_Text val9 = CreateText((Transform)(object)val6); ((Graphic)val9).color = new Color(0f, 0f, 0f, 1f); val2.textViewport = val6; val2.textComponent = val9; val2.placeholder = (Graphic)(object)val8; val2.richText = false; val2.restoreOriginalTextOnEscape = false; ((Behaviour)val2).enabled = true; return val2; } private TMP_Text CreateText(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0048: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text"); RectTransform val2 = val.AddComponent(); val2.anchorMax = Vector2.one; val2.anchorMin = Vector2.zero; val2.offsetMax = new Vector2(-2f, 0f); val2.offsetMin = new Vector2(2f, 4f); ((Transform)val2).SetParent(parent, false); TextMeshProUGUI val3 = val.AddComponent(); ((TMP_Text)val3).text = "New Text"; if ((Object)(object)GUIManagerPatch.darumaDropOneFont != (Object)null) { ((TMP_Text)val3).font = GUIManagerPatch.darumaDropOneFont; } ((TMP_Text)val3).fontSize = fontSize; ((TMP_Text)val3).horizontalAlignment = (HorizontalAlignmentOptions)1; ((TMP_Text)val3).verticalAlignment = (VerticalAlignmentOptions)512; return (TMP_Text)(object)val3; } public void AddMessage(string message) { //IL_0027: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)chatLogViewportTransform != (Object)null)) { return; } TMP_Text val = CreateText((Transform)(object)chatLogViewportTransform); val.text = message; ((Graphic)val).color = offWhite; val.lineSpacing = (0f - fontSize) * 0.75f; Vector2 preferredValues = val.GetPreferredValues(message, boxSize.x - 24f, 1000f); ((RectTransform)val.transform).sizeDelta = new Vector2(0f, preferredValues.y); ChatMessage item = new ChatMessage(message, ((Component)val).gameObject, messageHideDelay); messages.Add(item); if (messages.Count > maxMessages) { ChatMessage chatMessage = messages[0]; if (chatMessage != null && (Object)(object)chatMessage.textObj != (Object)null) { Object.Destroy((Object)(object)chatMessage.textObj); } messages.RemoveAt(0); } ResetTimers(); } public void AddMessage(TextChatManager.Message messageData) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) if ((Object)(object)chatLogViewportTransform != (Object)null) { Color val = (Color)(((Object)(object)messageData.character != (Object)null) ? messageData.character.refs.customization.PlayerColor : new Color(0.64f, 0.69f, 0.83f)); string[] obj = new string[5] { "[", null, null }; Character character = messageData.character; obj[3] = ((character != null) ? character.characterName : null) ?? "Unknown"; obj[4] = "]"; string text = string.Concat(obj); string text2 = messageData.message; if (!PeakTextChatPlugin.configRichTextEnabled.Value) { text2 = Regex.Replace(text2, "<.*?>", string.Empty); } AddMessage(text + ": " + text2); } } private void ResetTimers() { fadeTimer = fadeOutDelay; hideTimer = hideDelay; } private void UpdatePosition(bool isBottomLeft = false) { //IL_003e: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) if (isBottomLeft || PeakTextChatPlugin.configPos.Value == PeakTextChatPlugin.TextChatPosition.BottomLeft) { if ((Object)(object)baseTransform != (Object)null && (Object)(object)StaminaBarPatch.barGroupChildWatcher.textChatDummyTransform != (Object)null) { baseTransform.pivot = Vector2.zero; baseTransform.anchorMax = Vector2.zero; baseTransform.anchorMin = Vector2.zero; ((Transform)baseTransform).position = StaminaBarPatch.barGroupChildWatcher.textChatDummyTransform.position; RectTransform obj = baseTransform; obj.anchoredPosition += new Vector2(0f, 40f); } } else if (PeakTextChatPlugin.configPos.Value == PeakTextChatPlugin.TextChatPosition.TopLeft) { baseTransform.pivot = new Vector2(0f, 1f); baseTransform.anchorMax = new Vector2(0f, 1f); baseTransform.anchorMin = new Vector2(0f, 1f); baseTransform.anchoredPosition = new Vector2(64f, -62f); } else if (PeakTextChatPlugin.configPos.Value == PeakTextChatPlugin.TextChatPosition.TopRight) { baseTransform.pivot = Vector2.one; baseTransform.anchorMax = Vector2.one; baseTransform.anchorMin = Vector2.one; baseTransform.anchoredPosition = new Vector2(-64f, -62f); } } private void OnGUI() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0076: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Invalid comparison between Unknown and I4 if (imguiTyping) { GUI.SetNextControlName("ptctf"); GUIStyle val = new GUIStyle(); val.fontSize = (int)(fontSize * 0.8f); val.clipping = (TextClipping)1; val.padding = new RectOffset((int)(fontSize * 0.7f), (int)(fontSize * 0.7f), (int)(fontSize * 0.24f), 0); Rect val2 = RectTransformToScreenSpace((RectTransform)((Component)inputField).transform); PeakTextChatPlugin.Logger.LogInfo((object)(((Rect)(ref val2)).xMin + " " + ((Rect)(ref val2)).yMin)); imguiFieldString = GUI.TextArea(val2, imguiFieldString, val); inputField.text = " "; if (GUI.GetNameOfFocusedControl() != "ptctf") { GUI.FocusControl("ptctf"); } if (imguiFieldString.Contains("\n")) { TextChatManager.instance?.SendChatMessage(imguiFieldString.Replace("\n", "")); imguiFieldString = ""; GUI.FocusControl(""); Event.current.Use(); imguiTyping = false; isBlockingInput = false; inputField.text = ""; } else if (Event.current.isKey && (int)Event.current.keyCode == 27) { GUI.FocusControl(""); imguiTyping = false; inputField.text = imguiFieldString; isBlockingInput = false; Event.current.Use(); } } } public static Rect RectTransformToScreenSpace(RectTransform transform) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) Rect rect = transform.rect; Vector2 val = Vector2.Scale(((Rect)(ref rect)).size, Vector2.op_Implicit(((Transform)transform).lossyScale)); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(((Transform)transform).position.x, (float)Screen.height - ((Transform)transform).position.y); return new Rect(val2 - val * new Vector2(0.5f, 1f), val); } } public class TextChatManager : MonoBehaviour { public class Message { public Character character; public string message; public bool isDead; public Message(string userId, string message, bool isDead) { character = Character.AllCharacters.Find(delegate(Character c) { PhotonView photonView = ((MonoBehaviourPun)c).photonView; object obj; if (photonView == null) { obj = null; } else { Player owner = photonView.Owner; obj = ((owner != null) ? owner.UserId : null); } return (string?)obj == userId; }); this.message = message; this.isDead = isDead; } } public static TextChatManager instance; private Character character; private byte chatEventCode = 81; private void Start() { instance = this; character = ((Component)this).GetComponent(); PeakTextChatPlugin.Logger.LogInfo((object)"[TextChatManager] Start()"); } private void OnEnable() { PhotonNetwork.NetworkingClient.EventReceived += OnEventReceived; } private void OnDisable() { PhotonNetwork.NetworkingClient.EventReceived -= OnEventReceived; } private void OnEventReceived(EventData eventData) { if (eventData.Code == chatEventCode) { object[] array = (object[])eventData.CustomData; if (array.Length >= 4) { string text = array[2]?.ToString() ?? ""; string text2 = array[1]?.ToString() ?? ""; bool result; bool isDead = bool.TryParse(array[3]?.ToString(), out result) && result; ReceiveChatMessage(text, text2, isDead); PeakTextChatPlugin.Logger.LogInfo((object)("[TextChatManager] Event received: userId=" + text + ", message='" + text2 + "'")); } } } public void ReceiveChatMessage(string userId, string message, bool isDead) { if ((Object)(object)TextChatDisplay.instance != (Object)null) { TextChatDisplay.instance.AddMessage(new Message(userId, message, isDead)); } } public void SendChatMessage(string message) { //IL_0259: 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_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Expected O, but got Unknown //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: 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_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Expected O, but got Unknown PeakTextChatPlugin.Logger.LogInfo((object)("[TextChatManager] SendChatMessage called: '" + message + "'")); if (string.IsNullOrWhiteSpace(message)) { return; } if (message.StartsWith("!")) { string text = message.Substring(1).Trim(); PeakTextChatPlugin.Logger.LogInfo((object)("[TextChatManager] Command detected: '" + text + "'")); if (string.IsNullOrEmpty(text)) { return; } bool flag = false; if (PhotonNetwork.IsMasterClient) { flag = true; PeakTextChatPlugin.Logger.LogInfo((object)"[TextChatManager] Player is master client."); } else { string value = PeakTextChatPlugin.AllowedSenders.Value; string userId = PhotonNetwork.LocalPlayer.UserId; PeakTextChatPlugin.Logger.LogInfo((object)("[TextChatManager] Non-host. AllowedSenders='" + value + "', UserId='" + userId + "'")); if (!string.IsNullOrEmpty(value)) { List list = (from id in value.Split(',', StringSplitOptions.RemoveEmptyEntries) select id.Trim()).ToList(); if (list.Contains(userId)) { flag = true; PeakTextChatPlugin.Logger.LogInfo((object)"[TextChatManager] User found in allowed list."); } else { PeakTextChatPlugin.Logger.LogInfo((object)"[TextChatManager] User NOT in allowed list."); } } } if (flag) { string value2 = PeakTextChatPlugin.TwitchOAuth.Value; if (string.IsNullOrEmpty(value2) || !(value2 != "oauth:s1o2m3e4t5o6k7e8n9") || value2.Length < 5) { string message2 = "[System] Invalid or missing token. Please set a valid token in the config. You cannot send messages to Twitch chat."; if ((Object)(object)TextChatDisplay.instance != (Object)null) { TextChatDisplay.instance.AddMessage(message2); } PeakTextChatPlugin.Logger.LogInfo((object)"[TextChatManager] Token invalid, message shown."); return; } TwitchIntegration.SendToTwitch(PhotonNetwork.LocalPlayer.NickName, text); string text2 = "[Twitch] " + PhotonNetwork.LocalPlayer.NickName + ": " + text; bool flag2 = false; try { Character localCharacter = Character.localCharacter; bool? obj; if (localCharacter == null) { obj = null; } else { CharacterData data = localCharacter.data; obj = ((data != null) ? new bool?(data.dead) : ((bool?)null)); } bool? flag3 = obj; flag2 = flag3 == true; } catch { } object[] array = new object[4] { PhotonNetwork.LocalPlayer.NickName, text2, PhotonNetwork.LocalPlayer.UserId, flag2 }; PhotonNetwork.RaiseEvent(chatEventCode, (object)array, new RaiseEventOptions { Receivers = (ReceiverGroup)1 }, SendOptions.SendReliable); PeakTextChatPlugin.Logger.LogInfo((object)("[TextChatManager] Duplicate message sent to game chat: '" + text2 + "'")); } else { string message3 = "[System] You don't have permission to send to Twitch."; if ((Object)(object)TextChatDisplay.instance != (Object)null) { TextChatDisplay.instance.AddMessage(message3); } PeakTextChatPlugin.Logger.LogInfo((object)("[TextChatManager] Player " + PhotonNetwork.LocalPlayer.NickName + " has no permission to send.")); } return; } PeakTextChatPlugin.Logger.LogInfo((object)"[TextChatManager] Sending normal game chat message."); bool flag4 = false; try { Character localCharacter2 = Character.localCharacter; bool? obj3; if (localCharacter2 == null) { obj3 = null; } else { CharacterData data2 = localCharacter2.data; obj3 = ((data2 != null) ? new bool?(data2.dead) : ((bool?)null)); } bool? flag3 = obj3; flag4 = flag3 == true; } catch { } object[] array2 = new object[4] { PhotonNetwork.LocalPlayer.NickName, message, PhotonNetwork.LocalPlayer.UserId, flag4 }; PhotonNetwork.RaiseEvent(chatEventCode, (object)array2, new RaiseEventOptions { Receivers = (ReceiverGroup)1 }, SendOptions.SendReliable); } public static void CleanupObjects() { if ((Object)(object)instance != (Object)null) { Object.Destroy((Object)(object)((Component)instance).gameObject); } } } public class TwitchIntegration : MonoBehaviour { private static TwitchIntegration instance = null; private TwitchClient client; private string channelName; private bool isConnected; private static readonly Queue mainThreadActions = new Queue(); private readonly object queueLock = new object(); private void Awake() { instance = this; PeakTextChatPlugin.Logger.LogInfo((object)"[TwitchIntegration] Awake()"); } private void OnEnable() { PeakTextChatPlugin.Logger.LogInfo((object)"[TwitchIntegration] OnEnable()"); } private void Update() { lock (queueLock) { while (mainThreadActions.Count > 0) { Action action = mainThreadActions.Dequeue(); try { action?.Invoke(); } catch (Exception ex) { PeakTextChatPlugin.Logger.LogError((object)("[TwitchIntegration] UI thread error: " + ex.Message)); } } } } private void Start() { PeakTextChatPlugin.Logger.LogInfo((object)"[TwitchIntegration] Start()"); string value = PeakTextChatPlugin.TwitchUsername.Value; string value2 = PeakTextChatPlugin.TwitchOAuth.Value; channelName = value; if (string.IsNullOrEmpty(value) || value == "your_username") { ShowMessageInChat("[System] Please set your Twitch username in the config!"); PeakTextChatPlugin.Logger.LogError((object)"[TwitchIntegration] Username not set."); } else if (string.IsNullOrEmpty(channelName)) { ShowMessageInChat("[System] Channel name is empty. Please set Username in config."); PeakTextChatPlugin.Logger.LogError((object)"[TwitchIntegration] Channel name is empty."); } else if (string.IsNullOrEmpty(value2) || !(value2 != "oauth:s1o2m3e4t5o6k7e8n9") || value2.Length < 5) { ShowMessageInChat("[System] No valid OAuth token. Read-only mode (anonymous). To send messages, set a token in the config."); PeakTextChatPlugin.Logger.LogInfo((object)"[TwitchIntegration] No valid token, falling back to anonymous."); ((MonoBehaviour)this).StartCoroutine(ConnectAnonymous(value, channelName)); } else { PeakTextChatPlugin.Logger.LogInfo((object)"[TwitchIntegration] Token is valid, attempting connection..."); ((MonoBehaviour)this).StartCoroutine(ConnectAndWait(value, value2, channelName, 10f)); } } private void ShowMessageInChat(string message) { if ((Object)(object)TextChatDisplay.instance != (Object)null) { TextChatDisplay.instance.AddMessage(message); } else { ((MonoBehaviour)this).StartCoroutine(WaitForChatAndShow(message)); } } private IEnumerator WaitForChatAndShow(string message) { float timeout = 5f; float elapsed = 0f; while ((Object)(object)TextChatDisplay.instance == (Object)null && elapsed < timeout) { yield return (object)new WaitForSeconds(0.1f); elapsed += 0.1f; } if ((Object)(object)TextChatDisplay.instance != (Object)null) { TextChatDisplay.instance.AddMessage(message); } else { PeakTextChatPlugin.Logger.LogWarning((object)("[TwitchIntegration] Chat not available, message not shown: " + message)); } } private IEnumerator ConnectAnonymous(string username, string channel) { string text = "justinfan12345"; string oauth = ""; PeakTextChatPlugin.Logger.LogInfo((object)("[TwitchIntegration] Trying anonymous connection with nick " + text)); yield return ((MonoBehaviour)this).StartCoroutine(ConnectAndWait(text, oauth, channel, 10f)); if (isConnected) { PeakTextChatPlugin.Logger.LogInfo((object)"[TwitchIntegration] Anonymous connection successful! Chat reading."); ShowMessageInChat("[Twitch] Anonymous mode (read-only)"); } else { PeakTextChatPlugin.Logger.LogError((object)"[TwitchIntegration] Anonymous connection failed. Please provide OAuth token."); ShowMessageInChat("[System] Anonymous connection failed. Please provide OAuth token."); } } private IEnumerator ConnectAndWait(string username, string oauth, string channel, float timeout) { PeakTextChatPlugin.Logger.LogInfo((object)$"[TwitchIntegration] ConnectAndWait started. username={username}, channel={channel}, timeout={timeout}"); isConnected = false; TwitchClient tempClient = null; try { ConnectionCredentials val = new ConnectionCredentials(username, oauth, "wss://irc-ws.chat.twitch.tv:443", false, (Capabilities)null); ClientOptions val2 = new ClientOptions { MessagesAllowedInPeriod = 20, ThrottlingPeriod = TimeSpan.FromSeconds(30.0) }; WebSocketClient val3 = new WebSocketClient((IClientOptions)(object)val2); tempClient = new TwitchClient((IClient)(object)val3, (ClientProtocol)1, (ILogger)null); tempClient.OnConnected += delegate(object s, OnConnectedArgs e) { PeakTextChatPlugin.Logger.LogInfo((object)("[TwitchIntegration] OnConnected: Connected to Twitch! Channel: " + e.AutoJoinChannel)); isConnected = true; }; tempClient.OnJoinedChannel += delegate(object s, OnJoinedChannelArgs e) { PeakTextChatPlugin.Logger.LogInfo((object)("[TwitchIntegration] OnJoinedChannel: Joined channel " + e.Channel)); }; tempClient.OnMessageReceived += OnMessageReceived; tempClient.OnError += OnError; tempClient.Initialize(val, channel, '!', '!', true); tempClient.Connect(); } catch (Exception ex) { PeakTextChatPlugin.Logger.LogError((object)("[TwitchIntegration] Initialization error: " + ex.Message)); TwitchClient obj = tempClient; if (obj != null) { obj.Disconnect(); } yield break; } float elapsed = 0f; while (!isConnected && elapsed < timeout) { yield return (object)new WaitForSeconds(0.1f); elapsed += 0.1f; } if (isConnected) { client = tempClient; PeakTextChatPlugin.Logger.LogInfo((object)$"[TwitchIntegration] Connection established in {elapsed:F1} sec."); ShowMessageInChat("[Twitch] Connected to Twitch!"); yield break; } PeakTextChatPlugin.Logger.LogWarning((object)$"[TwitchIntegration] Timeout {timeout} sec. Failed to connect."); TwitchClient obj2 = tempClient; if (obj2 != null) { obj2.Disconnect(); } ShowMessageInChat("[System] Failed to connect to Twitch. Check your token and internet."); } private void OnMessageReceived(object sender, OnMessageReceivedArgs e) { string displayName = ((TwitchLibMessage)e.ChatMessage).DisplayName; string message = e.ChatMessage.Message; string colorHex = ((TwitchLibMessage)e.ChatMessage).ColorHex ?? "#FFFFFF"; PeakTextChatPlugin.Logger.LogInfo((object)("[TwitchIntegration] " + displayName + ": " + message)); lock (queueLock) { mainThreadActions.Enqueue(delegate { try { string message2 = "[Twitch] " + displayName + ": " + message; if ((Object)(object)TextChatDisplay.instance != (Object)null) { TextChatDisplay.instance.AddMessage(message2); } else { PeakTextChatPlugin.Logger.LogWarning((object)"[TwitchIntegration] TextChatDisplay missing"); } } catch (Exception ex) { PeakTextChatPlugin.Logger.LogError((object)("[TwitchIntegration] Error adding message: " + ex.Message)); } }); } } private void OnError(object sender, EventArgs e) { try { PropertyInfo property = e.GetType().GetProperty("Exception"); if (property != null) { if (property.GetValue(e) is Exception ex) { PeakTextChatPlugin.Logger.LogError((object)("[TwitchIntegration] TwitchLib error: " + ex.Message)); } else { PeakTextChatPlugin.Logger.LogError((object)"[TwitchIntegration] Error, but Exception is null."); } } else { PeakTextChatPlugin.Logger.LogError((object)("[TwitchIntegration] Unknown error. Type: " + e.GetType().Name)); } } catch (Exception ex2) { PeakTextChatPlugin.Logger.LogError((object)("[TwitchIntegration] Error in OnError handler: " + ex2.Message)); } } public static void SendToTwitch(string playerName, string message) { if ((Object)(object)instance == (Object)null) { PeakTextChatPlugin.Logger.LogWarning((object)"[TwitchIntegration] Instance not created!"); } else { instance.SendMessageToTwitch("[" + playerName + "]: " + message); } } public void SendMessageToTwitch(string message) { ManualLogSource logger = PeakTextChatPlugin.Logger; object arg = client != null; TwitchClient obj = client; logger.LogInfo((object)$"[TwitchIntegration] SendMessageToTwitch called. client={arg}, IsConnected={obj != null && obj.IsConnected}, channelName={channelName}"); if (client != null && client.IsConnected && !string.IsNullOrEmpty(channelName)) { if (PeakTextChatPlugin.TwitchOAuth.Value == "oauth:s1o2m3e4t5o6k7e8n9" || string.IsNullOrEmpty(PeakTextChatPlugin.TwitchOAuth.Value)) { PeakTextChatPlugin.Logger.LogWarning((object)"[TwitchIntegration] No rights to send (anonymous mode)"); return; } client.SendMessage(channelName, message, false); PeakTextChatPlugin.Logger.LogInfo((object)("[TwitchIntegration] Sent to Twitch: " + message)); } else { PeakTextChatPlugin.Logger.LogWarning((object)"[TwitchIntegration] Client not ready to send"); } } private void OnDestroy() { PeakTextChatPlugin.Logger.LogInfo((object)"[TwitchIntegration] OnDestroy()"); try { TwitchClient obj = client; if (obj != null) { obj.Disconnect(); } } catch (Exception ex) { PeakTextChatPlugin.Logger.LogError((object)("[TwitchIntegration] Disconnect error: " + ex.Message)); } } } public static class KeysHelper { public class KeyCodeInfo { public KeyCodeShort shortKey; public KeyCode key; public string keyText; public KeyCodeInfo(KeyCodeShort shortKey, KeyCode key, string keyText) { //IL_000e: 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) this.shortKey = shortKey; this.key = key; this.keyText = keyText; } } public static List infos = new List { new KeyCodeInfo(KeyCodeShort.A, (KeyCode)97, "A"), new KeyCodeInfo(KeyCodeShort.B, (KeyCode)98, "B"), new KeyCodeInfo(KeyCodeShort.C, (KeyCode)99, "C"), new KeyCodeInfo(KeyCodeShort.D, (KeyCode)100, "D"), new KeyCodeInfo(KeyCodeShort.E, (KeyCode)101, "E"), new KeyCodeInfo(KeyCodeShort.F, (KeyCode)102, "F"), new KeyCodeInfo(KeyCodeShort.G, (KeyCode)103, "G"), new KeyCodeInfo(KeyCodeShort.H, (KeyCode)104, "H"), new KeyCodeInfo(KeyCodeShort.I, (KeyCode)105, "I"), new KeyCodeInfo(KeyCodeShort.J, (KeyCode)106, "J"), new KeyCodeInfo(KeyCodeShort.K, (KeyCode)107, "K"), new KeyCodeInfo(KeyCodeShort.L, (KeyCode)108, "L"), new KeyCodeInfo(KeyCodeShort.M, (KeyCode)109, "M"), new KeyCodeInfo(KeyCodeShort.N, (KeyCode)110, "N"), new KeyCodeInfo(KeyCodeShort.O, (KeyCode)111, "O"), new KeyCodeInfo(KeyCodeShort.P, (KeyCode)112, "P"), new KeyCodeInfo(KeyCodeShort.Q, (KeyCode)113, "Q"), new KeyCodeInfo(KeyCodeShort.R, (KeyCode)114, "R"), new KeyCodeInfo(KeyCodeShort.S, (KeyCode)115, "S"), new KeyCodeInfo(KeyCodeShort.T, (KeyCode)116, "T"), new KeyCodeInfo(KeyCodeShort.U, (KeyCode)117, "U"), new KeyCodeInfo(KeyCodeShort.V, (KeyCode)118, "V"), new KeyCodeInfo(KeyCodeShort.W, (KeyCode)119, "W"), new KeyCodeInfo(KeyCodeShort.X, (KeyCode)120, "X"), new KeyCodeInfo(KeyCodeShort.Y, (KeyCode)121, "Y"), new KeyCodeInfo(KeyCodeShort.Z, (KeyCode)122, "Z"), new KeyCodeInfo(KeyCodeShort.One, (KeyCode)49, "1"), new KeyCodeInfo(KeyCodeShort.Two, (KeyCode)50, "2"), new KeyCodeInfo(KeyCodeShort.Three, (KeyCode)51, "3"), new KeyCodeInfo(KeyCodeShort.Four, (KeyCode)52, "4"), new KeyCodeInfo(KeyCodeShort.Five, (KeyCode)53, "5"), new KeyCodeInfo(KeyCodeShort.Six, (KeyCode)54, "6"), new KeyCodeInfo(KeyCodeShort.Seven, (KeyCode)55, "7"), new KeyCodeInfo(KeyCodeShort.Eight, (KeyCode)56, "8"), new KeyCodeInfo(KeyCodeShort.Nine, (KeyCode)57, "9"), new KeyCodeInfo(KeyCodeShort.Zero, (KeyCode)48, "0"), new KeyCodeInfo(KeyCodeShort.Minus, (KeyCode)45, "-"), new KeyCodeInfo(KeyCodeShort.Equals, (KeyCode)61, "="), new KeyCodeInfo(KeyCodeShort.Tab, (KeyCode)9, "Tab"), new KeyCodeInfo(KeyCodeShort.LeftBracket, (KeyCode)91, "["), new KeyCodeInfo(KeyCodeShort.RightBracket, (KeyCode)93, "]"), new KeyCodeInfo(KeyCodeShort.Semicolon, (KeyCode)59, ";"), new KeyCodeInfo(KeyCodeShort.Quote, (KeyCode)39, "'"), new KeyCodeInfo(KeyCodeShort.Backslash, (KeyCode)92, "\\"), new KeyCodeInfo(KeyCodeShort.Comma, (KeyCode)44, ","), new KeyCodeInfo(KeyCodeShort.Period, (KeyCode)46, "."), new KeyCodeInfo(KeyCodeShort.Slash, (KeyCode)47, "/"), new KeyCodeInfo(KeyCodeShort.Enter, (KeyCode)13, "Enter"), new KeyCodeInfo(KeyCodeShort.Numpad0, (KeyCode)256, "Num0"), new KeyCodeInfo(KeyCodeShort.Numpad1, (KeyCode)257, "Num1"), new KeyCodeInfo(KeyCodeShort.Numpad2, (KeyCode)258, "Num2"), new KeyCodeInfo(KeyCodeShort.Numpad3, (KeyCode)259, "Num3"), new KeyCodeInfo(KeyCodeShort.Numpad4, (KeyCode)260, "Num4"), new KeyCodeInfo(KeyCodeShort.Numpad5, (KeyCode)261, "Num5"), new KeyCodeInfo(KeyCodeShort.Numpad6, (KeyCode)262, "Num6"), new KeyCodeInfo(KeyCodeShort.Numpad7, (KeyCode)263, "Num7"), new KeyCodeInfo(KeyCodeShort.Numpad8, (KeyCode)264, "Num8"), new KeyCodeInfo(KeyCodeShort.Numpad9, (KeyCode)265, "Num9"), new KeyCodeInfo(KeyCodeShort.NumpadDivide, (KeyCode)267, "Num /"), new KeyCodeInfo(KeyCodeShort.NumpadMultiply, (KeyCode)268, "Num *"), new KeyCodeInfo(KeyCodeShort.NumpadMinus, (KeyCode)269, "Num -"), new KeyCodeInfo(KeyCodeShort.NumpadPlus, (KeyCode)270, "Num +"), new KeyCodeInfo(KeyCodeShort.NumpadEnter, (KeyCode)271, "Num Enter"), new KeyCodeInfo(KeyCodeShort.NumpadPeriod, (KeyCode)266, "Num .") }; public static KeyCodeInfo GetKeyCodeShortInfo(KeyCodeShort key) { return infos.Find((KeyCodeInfo i) => i.shortKey == key); } } public enum KeyCodeShort { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Zero, Tab, Minus, Equals, LeftBracket, RightBracket, Semicolon, Quote, Backslash, Comma, Period, Slash, Enter, Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9, NumpadDivide, NumpadMultiply, NumpadMinus, NumpadPlus, NumpadEnter, NumpadPeriod } public static class ProceduralImageExtensions { public static T SetModifierType(this ProceduralImage image) where T : ProceduralImageModifier { image.ModifierType = typeof(T); return ((Component)image).gameObject.GetComponent() ?? ((Component)image).gameObject.AddComponent(); } } public static class GameUtilsPatch { [HarmonyPatch(typeof(GameUtils), "Awake")] [HarmonyPostfix] public static void AwakePatch(GameUtils __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("TextChatManager"); val.transform.SetParent(((Component)__instance).transform, false); val.AddComponent(); } } [HarmonyPatch(typeof(StaminaBar), "Start")] public static class StaminaBarPatch { public static BarGroupChildWatcher barGroupChildWatcher; [HarmonyPostfix] public static void Postfix(StaminaBar __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002b: 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_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GUIManager.instance != (Object)null) { GameObject val = new GameObject("TextChatPos"); RectTransform val2 = (RectTransform)((Component)__instance).transform.parent; val2.offsetMax = new Vector2(val2.offsetMax.x, 1000f); val.transform.SetParent((Transform)(object)val2); RectTransform val3 = val.AddComponent(); ((Transform)val3).SetAsFirstSibling(); val3.sizeDelta = Vector2.zero; barGroupChildWatcher = ((Component)val2).gameObject.AddComponent(); barGroupChildWatcher.textChatDummyTransform = val.transform; } } public static void CleanupObjects() { Object.Destroy((Object)(object)barGroupChildWatcher.textChatDummyTransform); Object.Destroy((Object)(object)barGroupChildWatcher); } } public static class GUIManagerPatch { public static Canvas textChatCanvas = null; public static TMP_FontAsset darumaDropOneFont = null; private static bool isHUDActive = true; [HarmonyPatch(typeof(GUIManager), "Start")] [HarmonyPostfix] public static void StartPostfix(GUIManager __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown Transform transform = ((Component)__instance).transform; GameObject val = new GameObject("TextChatCanvas"); val.transform.SetParent(transform, false); textChatCanvas = val.AddComponent(); textChatCanvas.renderMode = (RenderMode)1; CanvasScaler val2 = ((Component)textChatCanvas).gameObject.GetComponent() ?? ((Component)textChatCanvas).gameObject.AddComponent(); val2.referencePixelsPerUnit = 100f; val2.matchWidthOrHeight = 1f; val2.referenceResolution = new Vector2(1920f, 1080f); val2.scaleFactor = 1f; val2.screenMatchMode = (ScreenMatchMode)0; val2.uiScaleMode = (ScaleMode)1; GameObject val3 = new GameObject("TextChat"); val3.transform.SetParent(((Component)textChatCanvas).transform, false); val3.AddComponent(); try { GUIManager instance = GUIManager.instance; object obj; if (instance == null) { obj = null; } else { TextMeshProUGUI itemPromptDrop = instance.itemPromptDrop; obj = ((itemPromptDrop != null) ? ((TMP_Text)itemPromptDrop).font : null); } darumaDropOneFont = (TMP_FontAsset)obj; } catch { } } [HarmonyPatch(typeof(GUIManager), "LateUpdate")] [HarmonyPostfix] public static void LateUpdatePostfix(GUIManager __instance) { try { if (isHUDActive != ((Component)__instance.hudCanvas).gameObject.activeInHierarchy) { isHUDActive = ((Component)__instance.hudCanvas).gameObject.activeInHierarchy; ((Component)textChatCanvas).gameObject.SetActive(isHUDActive); } } catch { PeakTextChatPlugin.Logger.LogError((object)"guimanager late update patch failed!! rhwrhrhwhrhwrhwhrawhhrhwhrwhrhrwrh"); } } } public static class InputBlockingPatches { private static MethodInfo windowBlockingInput; [HarmonyPatch(typeof(GUIManager), "UpdateWindowStatus")] [HarmonyPostfix] public static void UpdateWindowStatusPatch() { try { if (windowBlockingInput == null) { windowBlockingInput = AccessTools.PropertySetter(typeof(GUIManager), "windowBlockingInput"); } TextChatDisplay instance = TextChatDisplay.instance; if (instance != null && instance.isBlockingInput) { windowBlockingInput?.Invoke(GUIManager.instance, new object[1] { true }); } } catch { } } [HarmonyPatch(typeof(CinemaCamera), "Update")] [HarmonyPrefix] public static bool UpdateCinemaCamPatch(CinemaCamera __instance) { if (IsInputBlocked() && !__instance.on) { return false; } return true; } [HarmonyPatch(typeof(Character), "UpdateVariablesFixed")] [HarmonyPrefix] public static bool UpdateCharacterVariablesPatch(Character __instance) { try { if (IsInputBlocked()) { __instance.input.interactIsPressed = false; } } catch { PeakTextChatPlugin.Logger.LogError((object)"update character variables patch failed!! YIPPEEEE"); } return true; } public static bool IsInputBlocked() { try { GUIManager instance = GUIManager.instance; return instance != null && instance.windowBlockingInput; } catch { PeakTextChatPlugin.Logger.LogError((object)"window blocking input check failed!! YAY"); } return false; } } [BepInPlugin("V8.TwitchChat", "TwitchChat", "1.1.1")] public class PeakTextChatPlugin : BaseUnityPlugin { public enum TextChatPosition { BottomLeft, TopLeft, TopRight } internal static ManualLogSource Logger; private Harmony harmony; public static ConfigEntry configFontSize; public static ConfigEntry configChatSize; public static ConfigEntry configMessageFadeDelay; public static ConfigEntry configFadeDelay; public static ConfigEntry configHideDelay; public static ConfigEntry configKey; public static ConfigEntry configPos; public static ConfigEntry configRichTextEnabled; public static ConfigEntry configIMGUI; public static ConfigEntry configBgOpacity; public static ConfigEntry configFrameVisible; public static ConfigEntry TwitchUsername; public static ConfigEntry TwitchOAuth; public static ConfigEntry AllowedSenders; private void Awake() { //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"PeakTextChat is loaded!"); configKey = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatKey", KeyCodeShort.Slash, "The key that activates typing in chat"); configIMGUI = ((BaseUnityPlugin)this).Config.Bind("Display", "UseIMGUI", false, "Use IMGUI for the text field"); configPos = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatPosition", TextChatPosition.BottomLeft, "The position of the text chat"); configChatSize = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatSize", "500:300", "The size of the text chat (formatted X:Y)"); configFontSize = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatFontSize", 20f, "Size of the chat's text"); configBgOpacity = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatBackgroundOpacity", 0.3f, "Opacity of the chat's background/shadow"); configFrameVisible = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatFrameVisible", true, "Whether the frame of the chat box is visible"); configRichTextEnabled = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatRichText", true, "Whether rich text tags get parsed in messages"); configFadeDelay = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatFadeDelay", 15f, "How long before the chat fades out"); configHideDelay = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatHideDelay", 40f, "How long before the chat hides completely"); configMessageFadeDelay = ((BaseUnityPlugin)this).Config.Bind("Display", "ChatMessageHideDelay", 40f, "How long before a chat message disappears"); TwitchUsername = ((BaseUnityPlugin)this).Config.Bind("Twitch", "Username", "your_username", "Twitch username (without #)"); TwitchOAuth = ((BaseUnityPlugin)this).Config.Bind("Twitch", "OAuthToken", "oauth:s1o2m3e4t5o6k7e8n9", "OAuth token (get it at twitchtokengenerator.com)"); AllowedSenders = ((BaseUnityPlugin)this).Config.Bind("Twitch", "AllowedSenders", "", "List of Steam IDs (comma separated) allowed to send to Twitch. If empty, only host can send."); TwitchIntegration twitchIntegration = ((Component)this).gameObject.AddComponent(); if ((Object)(object)twitchIntegration != (Object)null) { Logger.LogInfo((object)"[PeakTextChatPlugin] TwitchIntegration component successfully added!"); } else { Logger.LogError((object)"[PeakTextChatPlugin] Failed to add TwitchIntegration!"); } harmony = new Harmony("com.borealityy.peaktextchat"); harmony.PatchAll(typeof(GameUtilsPatch)); harmony.PatchAll(typeof(StaminaBarPatch)); harmony.PatchAll(typeof(GUIManagerPatch)); harmony.PatchAll(typeof(InputBlockingPatches)); } private void OnDestroy() { if ((Object)(object)TextChatDisplay.instance != (Object)null) { Object.Destroy((Object)(object)((Component)TextChatDisplay.instance).gameObject); } if ((Object)(object)GUIManagerPatch.textChatCanvas != (Object)null) { Object.Destroy((Object)(object)GUIManagerPatch.textChatCanvas); } TextChatManager.CleanupObjects(); StaminaBarPatch.CleanupObjects(); harmony.UnpatchSelf(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "V8.TwitchChat"; public const string PLUGIN_NAME = "TwitchChat"; public const string PLUGIN_VERSION = "1.1.1"; } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ConstantExpectedAttribute : Attribute { public object? Min { get; set; } public object? Max { get; set; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class OverloadResolutionPriorityAttribute : Attribute { public int Priority { get; } public OverloadResolutionPriorityAttribute(int priority) { Priority = priority; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class ParamCollectionAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } }