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);
}
}
}
}
}
}