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 ScrollableChat v1.0.0
plugins/ScrollableChat.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using ScrollableChat.Patches; using TMPro; using UnityEngine; using UnityEngine.InputSystem; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ScrollableChat")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Makes the in-game chat scrollable")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ScrollableChat")] [assembly: AssemblyTitle("ScrollableChat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 ScrollableChat { public static class PluginInfo { public const string PLUGIN_GUID = "com.psyko.scrollablechat"; public const string PLUGIN_NAME = "ScrollableChat"; public const string PLUGIN_VERSION = "1.0.0"; } [BepInPlugin("com.psyko.scrollablechat", "ScrollableChat", "1.0.0")] public class ScrollableChatPlugin : BaseUnityPlugin { internal static ManualLogSource Logger; private readonly Harmony harmony = new Harmony("com.psyko.scrollablechat"); public static ConfigEntry<int> MaxMessages; public static ConfigEntry<int> MaxVisibleCharacters; private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; MaxMessages = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxMessages", 50, "Maximum number of messages to keep in chat history (default: 50)"); MaxVisibleCharacters = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxVisibleCharacters", 5000, "Maximum number of visible characters in chat (default: 5000)"); harmony.PatchAll(typeof(ChatPatches)); Logger.LogInfo((object)"Plugin com.psyko.scrollablechat is loaded!"); } } } namespace ScrollableChat.Patches { [HarmonyPatch(typeof(HUDManager))] internal class ChatPatches { private static bool isInitialized = false; private static ScrollRect scrollRect; private static RectTransform contentRect; private static TMP_InputField chatInputField; private static string lastMessage = ""; private static float lastMessageTime = 0f; private static List<string> messageHistory = new List<string>(); [HarmonyPatch("Start")] [HarmonyPostfix] private static void InitializeScrollableChat(HUDManager __instance) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_0104: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) Transform val = ((TMP_Text)__instance.chatText).transform.parent.Find("ChatViewport"); if ((Object)(object)val != (Object)null) { isInitialized = true; return; } isInitialized = false; messageHistory.Clear(); if (isInitialized) { return; } try { TextMeshProUGUI chatText = __instance.chatText; if (!((Object)(object)chatText == (Object)null)) { chatInputField = __instance.chatTextField; contentRect = ((Component)chatText).GetComponent<RectTransform>(); Transform parent = ((TMP_Text)chatText).transform.parent; ((TMP_Text)chatText).maxVisibleCharacters = ScrollableChatPlugin.MaxVisibleCharacters.Value; Vector2 anchorMin = contentRect.anchorMin; Vector2 anchorMax = contentRect.anchorMax; Vector2 pivot = contentRect.pivot; Vector2 anchoredPosition = contentRect.anchoredPosition; Vector2 sizeDelta = contentRect.sizeDelta; GameObject val2 = new GameObject("ChatViewport"); val2.transform.SetParent(parent, false); RectTransform val3 = val2.AddComponent<RectTransform>(); val3.anchorMin = anchorMin; val3.anchorMax = anchorMax; val3.pivot = pivot; val3.anchoredPosition = anchoredPosition; val3.sizeDelta = sizeDelta; val2.AddComponent<RectMask2D>(); ((TMP_Text)chatText).transform.SetParent(val2.transform, false); contentRect.anchorMin = new Vector2(0f, 0f); contentRect.anchorMax = new Vector2(1f, 0f); contentRect.pivot = new Vector2(0.5f, 0f); contentRect.anchoredPosition = Vector2.zero; contentRect.sizeDelta = new Vector2(0f, 100f); ((TMP_Text)chatText).enableWordWrapping = true; ((TMP_Text)chatText).overflowMode = (TextOverflowModes)0; ContentSizeFitter val4 = ((Component)chatText).GetComponent<ContentSizeFitter>(); if ((Object)(object)val4 == (Object)null) { val4 = ((Component)chatText).gameObject.AddComponent<ContentSizeFitter>(); } val4.verticalFit = (FitMode)2; val4.horizontalFit = (FitMode)0; GameObject gameObject = ((Component)parent).gameObject; scrollRect = gameObject.AddComponent<ScrollRect>(); scrollRect.content = contentRect; scrollRect.viewport = val3; scrollRect.horizontal = false; scrollRect.vertical = true; scrollRect.movementType = (MovementType)2; scrollRect.scrollSensitivity = 30f; scrollRect.inertia = false; scrollRect.verticalNormalizedPosition = 0f; isInitialized = true; } } catch (Exception arg) { ScrollableChatPlugin.Logger.LogError((object)$"Error: {arg}"); } } [HarmonyPatch("AddChatMessage")] [HarmonyPrefix] private static bool PreventChatTrimming(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped) { string text = nameOfUserWhoTyped + ": " + chatMessage; float time = Time.time; if (text == lastMessage && time - lastMessageTime < 0.5f) { return false; } lastMessage = text; lastMessageTime = time; string item = ((!string.IsNullOrEmpty(nameOfUserWhoTyped) && !chatMessage.Contains("joined the ship") && !chatMessage.Contains("disconnected") && !chatMessage.Contains("left")) ? ("<color=#FF0000>" + nameOfUserWhoTyped + "</color>: <color=#D8D837>'" + chatMessage + "'</color>") : chatMessage); messageHistory.Add(item); if (messageHistory.Count > ScrollableChatPlugin.MaxMessages.Value) { messageHistory.RemoveAt(0); } ((TMP_Text)__instance.chatText).text = string.Join("\n", messageHistory); if ((Object)(object)scrollRect != (Object)null) { LayoutRebuilder.ForceRebuildLayoutImmediate(contentRect); Canvas.ForceUpdateCanvases(); scrollRect.verticalNormalizedPosition = 0f; } return false; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void HandleScrollInput() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)scrollRect == (Object)null || !isInitialized) { return; } if ((Object)(object)chatInputField != (Object)null && !chatInputField.isFocused) { scrollRect.verticalNormalizedPosition = 0f; } else { if (!((Object)(object)chatInputField != (Object)null) || !chatInputField.isFocused) { return; } Mouse current = Mouse.current; if (current != null) { float y = ((InputControl<Vector2>)(object)current.scroll).ReadValue().y; if (y != 0f) { float verticalNormalizedPosition = scrollRect.verticalNormalizedPosition; scrollRect.verticalNormalizedPosition = Mathf.Clamp01(verticalNormalizedPosition + y / 120f * 0.15f); } } } } } }