Decompiled source of ScrollableChat v1.0.0

plugins/ScrollableChat.dll

Decompiled 2 months ago
using 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);
					}
				}
			}
		}
	}
}