Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ChatHistory v0.1.2
ChatHistory.dll
Decompiled 11 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ChatHistory")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ChatHistory")] [assembly: AssemblyTitle("ChatHistory")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 ChatHistory { [BepInPlugin("com.chathistory.repo", "ChatHistory", "0.1.2")] [BepInProcess("REPO.exe")] public class ChatHistoryPlugin : BaseUnityPlugin { internal class LobbyState { public bool LastSpeaking; public string LastText; } private Harmony _harmony; private ChatLogUi _ui; private static readonly ConditionalWeakTable<object, LobbyState> _lobbyStates = new ConditionalWeakTable<object, LobbyState>(); private const float DedupeWindow = 2f; private static readonly Dictionary<string, float> _recentKeys = new Dictionary<string, float>(); private static FieldInfo _ttsVoiceField; private static FieldInfo _isSpeakingField; private static FieldInfo _voiceTextField; private static FieldInfo _playerAvatarField; private static FieldInfo _playerNameField; private static FieldInfo _avatarPlayerNameField; private Type _chatManagerType; private FieldInfo _chatActiveField; private object _chatManager; private bool _lastChatActive; private float _nextChatPoll; internal static ChatHistoryPlugin Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; public static ConfigEntry<bool> Enabled { get; private set; } public static ConfigEntry<bool> ToastEnabled { get; private set; } public static ConfigEntry<float> ToastDuration { get; private set; } public static ConfigEntry<float> FadeDuration { get; private set; } public static ConfigEntry<int> HistoryMax { get; private set; } public static ConfigEntry<int> FontSize { get; private set; } public static ConfigEntry<float> PanelAlpha { get; private set; } public static ConfigEntry<bool> DebugLog { get; private set; } private void Awake() { Instance = this; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "总开关"); ToastEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Toast", "Enabled", true, "左侧渐隐提示开关"); ToastDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Toast", "Duration Seconds", 3f, "toast 停留秒数"); FadeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Toast", "Fade Seconds", 1.5f, "toast 渐隐秒数"); HistoryMax = ((BaseUnityPlugin)this).Config.Bind<int>("History", "Max Entries", 200, "历史最大保留条数"); FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Style", "Font Size", 16, "toast/历史字号"); PanelAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "Panel Alpha", 0.2f, "背景透明度 0-1"); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Log Chat Events", false, "记录每条捕获消息到日志"); Patch(); _ui = ((Component)this).gameObject.AddComponent<ChatLogUi>(); _ui.Init(); Logger.LogInfo((object)$"ChatHistory v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded. capture=ChatMessageSpeak+LobbyChatUI, PanelAlpha={PanelAlpha.Value}"); } private void Patch() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown _harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Type type = AccessTools.TypeByName("PlayerAvatar"); if (type == null) { Logger.LogError((object)"Type PlayerAvatar not found, remote chat capture disabled."); return; } MethodInfo methodInfo = AccessTools.Method(type, "ChatMessageSpeak", new Type[3] { typeof(string), typeof(bool), typeof(string) }, (Type[])null); if (methodInfo == null) { Logger.LogError((object)"Method PlayerAvatar.ChatMessageSpeak(string,bool,string) not found, remote chat capture disabled."); return; } _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PlayerAvatarChatPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Type type2 = AccessTools.TypeByName("LobbyChatUI"); if (type2 == null) { Logger.LogError((object)"Type LobbyChatUI not found, fallback capture disabled."); return; } MethodInfo methodInfo2 = AccessTools.Method(type2, "Update", Type.EmptyTypes, (Type[])null); if (methodInfo2 == null) { Logger.LogError((object)"Method LobbyChatUI.Update not found, fallback capture disabled."); } else { _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(LobbyChatUiPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } private static bool TryDedupe(string name, string message) { float unscaledTime = Time.unscaledTime; string key = name + "\u0001" + message; if (_recentKeys.Count > 0) { List<string> list = null; foreach (KeyValuePair<string, float> recentKey in _recentKeys) { if (unscaledTime - recentKey.Value >= 2f) { if (list == null) { list = new List<string>(); } list.Add(recentKey.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { _recentKeys.Remove(list[i]); } } } if (_recentKeys.TryGetValue(key, out var value) && unscaledTime - value < 2f) { return true; } _recentKeys[key] = unscaledTime; return false; } internal void OnChatSpeak(object avatar, string message) { if (!Enabled.Value || avatar == null || string.IsNullOrWhiteSpace(message)) { return; } try { string text = ReadAvatarName(avatar); if (!TryDedupe(text, message)) { ChatEntry entry = new ChatEntry(text, message, Time.unscaledTime); _ui.AddMessage(entry); if (DebugLog.Value) { Logger.LogInfo((object)$"[Chat] {text}: {message}"); } } } catch (Exception ex) { Logger.LogWarning((object)("ChatMessageSpeak capture skipped: " + ex.Message)); } } private static string ReadAvatarName(object avatar) { try { if (_avatarPlayerNameField == null) { _avatarPlayerNameField = AccessTools.Field(avatar.GetType(), "playerName"); } if (_avatarPlayerNameField == null) { return string.Empty; } object value = _avatarPlayerNameField.GetValue(avatar); return (value == null) ? string.Empty : value.ToString(); } catch (Exception) { return string.Empty; } } internal void OnLobbyChatUpdate(object lobby) { if (!Enabled.Value || lobby == null) { return; } try { if (_ttsVoiceField == null) { _ttsVoiceField = AccessTools.Field(lobby.GetType(), "ttsVoice"); } if (_ttsVoiceField == null) { return; } object value = _ttsVoiceField.GetValue(lobby); if (value == null) { return; } if (_isSpeakingField == null) { _isSpeakingField = AccessTools.Field(value.GetType(), "isSpeaking"); } if (_voiceTextField == null) { _voiceTextField = AccessTools.Field(value.GetType(), "voiceText"); } if (_isSpeakingField == null || _voiceTextField == null) { return; } bool flag = (bool)_isSpeakingField.GetValue(value); string text = (string)_voiceTextField.GetValue(value); LobbyState orCreateValue = _lobbyStates.GetOrCreateValue(lobby); if (flag && !orCreateValue.LastSpeaking && !string.IsNullOrEmpty(text)) { string text2 = ReadPlayerName(value); if (TryDedupe(text2, text)) { orCreateValue.LastSpeaking = flag; orCreateValue.LastText = text; return; } ChatEntry entry = new ChatEntry(text2, text, Time.unscaledTime); _ui.AddMessage(entry); if (DebugLog.Value) { Logger.LogInfo((object)$"[Chat] {text2}: {text}"); } } orCreateValue.LastSpeaking = flag; orCreateValue.LastText = text; } catch (Exception ex) { Logger.LogWarning((object)("LobbyChatUI capture skipped: " + ex.Message)); } } private static string ReadPlayerName(object ttsVoice) { try { if (_playerAvatarField == null) { _playerAvatarField = AccessTools.Field(ttsVoice.GetType(), "playerAvatar"); } if (_playerAvatarField == null) { return string.Empty; } object value = _playerAvatarField.GetValue(ttsVoice); if (value == null) { return string.Empty; } if (_playerNameField == null) { _playerNameField = AccessTools.Field(value.GetType(), "playerName"); } if (_playerNameField == null) { return string.Empty; } object value2 = _playerNameField.GetValue(value); return (value2 == null) ? string.Empty : value2.ToString(); } catch (Exception) { return string.Empty; } } private void Update() { if (!Enabled.Value || (Object)(object)_ui == (Object)null || !(Time.unscaledTime >= _nextChatPoll)) { return; } _nextChatPoll = Time.unscaledTime + 0.2f; bool flag = ReadChatActive(); if (flag != _lastChatActive) { _lastChatActive = flag; if (flag) { _ui.ShowHistory(); } else { _ui.HideHistory(); } } } private bool ReadChatActive() { try { if (_chatManagerType == null) { _chatManagerType = AccessTools.TypeByName("ChatManager"); } if (_chatManagerType == null) { return _lastChatActive; } if (_chatManager == null) { Object[] array = Object.FindObjectsOfType(_chatManagerType); _chatManager = ((array != null && array.Length != 0) ? array[0] : null); } if (_chatManager == null) { return _lastChatActive; } if (_chatActiveField == null) { _chatActiveField = AccessTools.Field(_chatManagerType, "chatActive"); } if (_chatActiveField == null) { return _lastChatActive; } object value = _chatActiveField.GetValue(_chatManager); return value is bool && (bool)value; } catch (Exception) { return _lastChatActive; } } } internal class ChatEntry { public string Name; public string Message; public float Time; public ChatEntry(string name, string message, float time) { Name = name; Message = message; Time = time; } } internal class PlayerAvatarChatPatch { public static void Postfix(object __instance, string _message) { try { if ((Object)(object)ChatHistoryPlugin.Instance != (Object)null) { ChatHistoryPlugin.Instance.OnChatSpeak(__instance, _message); } } catch (Exception ex) { ChatHistoryPlugin.Logger.LogError((object)("ChatMessageSpeak postfix error: " + ex)); } } } internal class LobbyChatUiPatch { public static void Postfix(object __instance) { try { if ((Object)(object)ChatHistoryPlugin.Instance != (Object)null) { ChatHistoryPlugin.Instance.OnLobbyChatUpdate(__instance); } } catch (Exception ex) { ChatHistoryPlugin.Logger.LogError((object)("LobbyChatUI postfix error: " + ex)); } } } internal class ChatLogUi : MonoBehaviour { private class ToastItem { public GameObject Root; public CanvasGroup Group; public Image Bg; public float AddedTime; } private readonly List<ChatEntry> _history = new List<ChatEntry>(); private readonly List<ToastItem> _toasts = new List<ToastItem>(); private Canvas _canvas; private GameObject _historyRoot; private GameObject _toastRoot; private Image _historyBg; private ScrollRect _scroll; private RectTransform _content; private Font _font; private Sprite _whiteSprite; private Color _panelColor; private Vector2 _offset = new Vector2(24f, 128f); private const float HistoryPanelHeight = 340f; private const float ToastStackGap = 12f; private RectTransform _toastRt; private bool _toastRaised; private static readonly int HistoryPoolCount = 32; private readonly List<Text> _historyLines = new List<Text>(); public void Init() { _font = LoadFont(); _whiteSprite = CreateWhiteSprite(); BuildCanvas(); BuildToastArea(); BuildHistoryArea(); ApplyStyle(); if ((Object)(object)_font == (Object)null) { ChatHistoryPlugin.Logger.LogWarning((object)"No builtin font found, text may be invisible."); } ChatHistoryPlugin.Logger.LogInfo((object)"ChatHistory UI ready (left side)."); } private static Font LoadFont() { string[] array = new string[3] { "LegacyRuntime.ttf", "Arial.ttf", "LiberationSans.ttf" }; for (int i = 0; i < array.Length; i++) { try { Font builtinResource = Resources.GetBuiltinResource<Font>(array[i]); if ((Object)(object)builtinResource != (Object)null) { return builtinResource; } } catch (Exception) { } } return null; } private static Sprite CreateWhiteSprite() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_002e: 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) //IL_0047: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, Color.white); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); } private void BuildCanvas() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ChatHistoryCanvas"); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 200; CanvasScaler obj = val.AddComponent<CanvasScaler>(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 0.5f; } private Image AddBackground(GameObject parent) { Image obj = parent.AddComponent<Image>(); obj.sprite = _whiteSprite; obj.type = (Type)0; return obj; } private void BuildToastArea() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) _toastRoot = new GameObject("ToastArea"); _toastRoot.transform.SetParent(((Component)_canvas).transform, false); RectTransform val = _toastRoot.AddComponent<RectTransform>(); val.anchorMin = new Vector2(0f, 0f); val.anchorMax = new Vector2(0f, 0f); val.pivot = new Vector2(0f, 0f); val.anchoredPosition = _offset; val.sizeDelta = new Vector2(520f, 0f); _toastRt = val; VerticalLayoutGroup obj = _toastRoot.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj).childAlignment = (TextAnchor)6; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f; _toastRoot.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; } private void BuildHistoryArea() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_00c9: 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_00e5: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_018c: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Expected O, but got Unknown //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) _historyRoot = new GameObject("HistoryPanel"); _historyRoot.transform.SetParent(((Component)_canvas).transform, false); _historyRoot.SetActive(false); RectTransform obj = _historyRoot.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0f, 0f); obj.anchorMax = new Vector2(0f, 0f); obj.pivot = new Vector2(0f, 0f); obj.anchoredPosition = _offset; obj.sizeDelta = new Vector2(560f, 340f); Image val = AddBackground(_historyRoot); ((Graphic)val).color = new Color(0.05f, 0.05f, 0.05f, ChatHistoryPlugin.PanelAlpha.Value); _historyBg = val; GameObject val2 = new GameObject("Scroll"); val2.transform.SetParent(_historyRoot.transform, false); RectTransform obj2 = val2.AddComponent<RectTransform>(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.offsetMin = new Vector2(8f, 8f); obj2.offsetMax = new Vector2(-8f, -8f); _scroll = val2.AddComponent<ScrollRect>(); _scroll.horizontal = false; _scroll.vertical = true; _scroll.movementType = (MovementType)2; _scroll.scrollSensitivity = 24f; GameObject val3 = new GameObject("Viewport"); val3.transform.SetParent(val2.transform, false); RectTransform val4 = val3.AddComponent<RectTransform>(); val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; val3.AddComponent<RectMask2D>(); _scroll.viewport = val4; GameObject val5 = new GameObject("Content"); val5.transform.SetParent(val3.transform, false); _content = val5.AddComponent<RectTransform>(); _content.anchorMin = new Vector2(0f, 1f); _content.anchorMax = new Vector2(1f, 1f); _content.pivot = new Vector2(0f, 1f); _content.sizeDelta = new Vector2(0f, 0f); VerticalLayoutGroup obj3 = val5.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj3).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 2f; val5.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; _scroll.content = _content; for (int i = 0; i < HistoryPoolCount; i++) { GameObject val6 = new GameObject("HistoryLine" + i); val6.transform.SetParent(val5.transform, false); Text val7 = val6.AddComponent<Text>(); val7.font = _font; val7.fontSize = ChatHistoryPlugin.FontSize.Value; ((Graphic)val7).color = new Color(0.95f, 0.95f, 0.95f, 1f); val7.alignment = (TextAnchor)0; val7.horizontalOverflow = (HorizontalWrapMode)0; val7.verticalOverflow = (VerticalWrapMode)1; ((Graphic)val7).raycastTarget = false; LayoutElement obj4 = val6.AddComponent<LayoutElement>(); obj4.preferredWidth = 530f; obj4.preferredHeight = (float)ChatHistoryPlugin.FontSize.Value + 12f; _historyLines.Add(val7); } } public void ApplyStyle() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_007d: Unknown result type (might be due to invalid IL or missing references) float value = ChatHistoryPlugin.PanelAlpha.Value; _panelColor = new Color(0.08f, 0.08f, 0.08f, value); if ((Object)(object)_historyBg != (Object)null) { ((Graphic)_historyBg).color = new Color(0.05f, 0.05f, 0.05f, value); } for (int i = 0; i < _toasts.Count; i++) { ToastItem toastItem = _toasts[i]; if (toastItem != null && (Object)(object)toastItem.Bg != (Object)null) { ((Graphic)toastItem.Bg).color = _panelColor; } } } public void AddMessage(ChatEntry entry) { _history.Add(entry); while (_history.Count > ChatHistoryPlugin.HistoryMax.Value) { _history.RemoveAt(0); } if (ChatHistoryPlugin.ToastEnabled.Value) { SpawnToast(entry); } if ((Object)(object)_historyRoot != (Object)null && _historyRoot.activeSelf) { RebuildHistory(); } } private void SetToastRaised(bool raised) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_toastRt == (Object)null) && _toastRaised != raised) { _toastRaised = raised; _toastRt.anchoredPosition = (Vector2)(raised ? new Vector2(_offset.x, _offset.y + 340f + 12f) : _offset); } } private void SpawnToast(ChatEntry entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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) GameObject val = new GameObject("Toast"); val.transform.SetParent(_toastRoot.transform, false); Image val2 = AddBackground(val); ((Graphic)val2).color = _panelColor; CanvasGroup val3 = val.AddComponent<CanvasGroup>(); val3.alpha = 1f; LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredWidth = 500f; obj.preferredHeight = (float)ChatHistoryPlugin.FontSize.Value + 14f; GameObject val4 = new GameObject("Text"); val4.transform.SetParent(val.transform, false); RectTransform obj2 = val4.AddComponent<RectTransform>(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.offsetMin = new Vector2(10f, 5f); obj2.offsetMax = new Vector2(-10f, -5f); Text obj3 = val4.AddComponent<Text>(); obj3.font = _font; obj3.fontSize = ChatHistoryPlugin.FontSize.Value; ((Graphic)obj3).color = new Color(1f, 1f, 1f, 1f); obj3.alignment = (TextAnchor)3; obj3.horizontalOverflow = (HorizontalWrapMode)0; obj3.verticalOverflow = (VerticalWrapMode)1; ((Graphic)obj3).raycastTarget = false; obj3.text = BuildDisplayLine(entry); ToastItem toastItem = new ToastItem(); toastItem.Root = val; toastItem.Group = val3; toastItem.Bg = val2; toastItem.AddedTime = Time.unscaledTime; _toasts.Add(toastItem); while (_toasts.Count > 6) { Object.Destroy((Object)(object)_toasts[0].Root); _toasts.RemoveAt(0); } } private static string BuildDisplayLine(ChatEntry entry) { if (string.IsNullOrEmpty(entry.Name)) { return entry.Message; } return $"{entry.Name}: {entry.Message}"; } public void ShowHistory() { if (!((Object)(object)_historyRoot == (Object)null)) { SetToastRaised(raised: true); RebuildHistory(); _historyRoot.SetActive(true); } } public void HideHistory() { if (!((Object)(object)_historyRoot == (Object)null)) { _historyRoot.SetActive(false); SetToastRaised(raised: false); } } private void RebuildHistory() { int num = _history.Count; if (num > HistoryPoolCount) { num = HistoryPoolCount; } for (int i = 0; i < _historyLines.Count; i++) { Text val = _historyLines[i]; if (i < num) { ChatEntry entry = _history[_history.Count - num + i]; val.text = BuildDisplayLine(entry); ((Component)val).gameObject.SetActive(true); } else { ((Component)val).gameObject.SetActive(false); } } ((MonoBehaviour)this).StartCoroutine(ScrollToBottomNextFrame()); } private IEnumerator ScrollToBottomNextFrame() { yield return null; if ((Object)(object)_scroll != (Object)null) { _scroll.verticalNormalizedPosition = 0f; } } private void Update() { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if (_toasts.Count > 0) { float unscaledTime = Time.unscaledTime; for (int num = _toasts.Count - 1; num >= 0; num--) { ToastItem toastItem = _toasts[num]; float num2 = unscaledTime - toastItem.AddedTime; float num3 = ChatHistoryPlugin.ToastDuration.Value + ChatHistoryPlugin.FadeDuration.Value; if (num2 >= num3) { Object.Destroy((Object)(object)toastItem.Root); _toasts.RemoveAt(num); } else if (num2 > ChatHistoryPlugin.ToastDuration.Value) { float num4 = (num2 - ChatHistoryPlugin.ToastDuration.Value) / Mathf.Max(0.01f, ChatHistoryPlugin.FadeDuration.Value); toastItem.Group.alpha = Mathf.Clamp01(1f - num4); } } } if ((Object)(object)_historyRoot != (Object)null && _historyRoot.activeSelf && (Object)(object)_scroll != (Object)null) { float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.001f) { float num5 = _scroll.verticalNormalizedPosition + y * 0.08f; _scroll.verticalNormalizedPosition = Mathf.Clamp01(num5); } } } } }