Decompiled source of QuanChat v1.0.0

QuanChat.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("QuanChat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+065c1e499a8ab8dc4198c756eb4d05518660929d")]
[assembly: AssemblyProduct("QuanChat")]
[assembly: AssemblyTitle("QuanChat")]
[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 QuanChat
{
	internal static class Channels
	{
		[HarmonyPatch(typeof(Chat), "Awake")]
		private static class ResetOnLogin
		{
			private static void Postfix()
			{
				Current = Settings.StartingChannel.Value;
			}
		}

		[HarmonyPatch(typeof(Chat), "InputText")]
		private static class RouteInput
		{
			private static bool Prefix(Chat __instance)
			{
				string text = ((TMP_InputField)((Terminal)__instance).m_input).text;
				string text2 = text.Trim();
				if (text2.Equals("/s", StringComparison.OrdinalIgnoreCase) || text2.Equals("/shout", StringComparison.OrdinalIgnoreCase))
				{
					return Switch(__instance, Channel.Shout);
				}
				if (text2.StartsWith("/shout ", StringComparison.OrdinalIgnoreCase))
				{
					((Terminal)__instance).TryRunCommand("s " + text2.Substring("/shout ".Length).TrimStart(Array.Empty<char>()), false, false);
					return false;
				}
				if (text2.Equals("/say", StringComparison.OrdinalIgnoreCase))
				{
					return Switch(__instance, Channel.Say);
				}
				if (text.Length > 0 && text[0] != '/' && Current == Channel.Shout)
				{
					((Terminal)__instance).TryRunCommand("s " + text, false, false);
					return false;
				}
				return true;
			}

			private static bool Switch(Chat chat, Channel channel)
			{
				Current = channel;
				((Terminal)chat).AddString((channel == Channel.Shout) ? "<color=#B0B0B0>Channel: Shout. Your messages reach everyone. /say to talk nearby.</color>" : "<color=#B0B0B0>Channel: Say. Your messages reach players within 15 m. /s or /shout to shout.</color>");
				return false;
			}
		}

		internal static Channel Current;

		private static string _placeholderOriginal;

		private static string _placeholderSet;

		internal static void UpdatePlaceholder(Chat chat)
		{
			Graphic placeholder = ((TMP_InputField)((Terminal)chat).m_input).placeholder;
			TMP_Text val = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null);
			if (val != null)
			{
				string text = val.text;
				if (text != _placeholderSet)
				{
					_placeholderOriginal = text;
				}
				string text2 = "[" + Current.ToString() + "] " + (string.IsNullOrEmpty(_placeholderOriginal) ? "..." : _placeholderOriginal);
				if (text != text2)
				{
					val.text = text2;
					_placeholderSet = text2;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Chat), "Update")]
	internal static class ChatWindow
	{
		private const float FadeSeconds = 1f;

		private static readonly FieldRef<Chat, float> HideTimer = AccessTools.FieldRefAccess<Chat, float>("m_hideTimer");

		private static readonly FieldRef<Terminal, int> ScrollHeight = AccessTools.FieldRefAccess<Terminal, int>("m_scrollHeight");

		private static readonly FieldRef<Terminal, List<string>> ChatBuffer = AccessTools.FieldRefAccess<Terminal, List<string>>("m_chatBuffer");

		private static readonly MethodInfo UpdateChat = AccessTools.Method(typeof(Terminal), "UpdateChat", (Type[])null, (Type[])null);

		private const int ScrollStep = 3;

		private const string ConfigurationManagerGuid = "com.bepis.bepinex.configurationmanager";

		private static bool _lookedForSettingsWindow;

		private static object _configurationManager;

		private static PropertyInfo _displayingWindow;

		private static void Prefix(Chat __instance, out int __state)
		{
			__state = ScrollHeight.Invoke((Terminal)(object)__instance);
		}

		private static void Postfix(Chat __instance, int __state)
		{
			RectTransform chatWindow = ((Terminal)__instance).m_chatWindow;
			if (!((Object)(object)chatWindow == (Object)null))
			{
				WindowLayout.KeepInPlace(__instance);
				bool flag = (Object)(object)((Terminal)__instance).m_input != (Object)null && ((Component)((Terminal)__instance).m_input).gameObject.activeSelf;
				if (flag)
				{
					Channels.UpdatePlaceholder(__instance);
				}
				bool flag2 = IsHidden(flag);
				if (flag || !flag2)
				{
					Scroll(__instance, __state, flag);
				}
				float num = (flag ? 1f : IdleAlpha(HideTimer.Invoke(__instance)));
				bool flag3 = !flag2 && num > 0.001f;
				if (((Component)chatWindow).gameObject.activeSelf != flag3)
				{
					((Component)chatWindow).gameObject.SetActive(flag3);
				}
				if (flag3)
				{
					CanvasGroup obj = ((Component)chatWindow).GetComponent<CanvasGroup>() ?? ((Component)chatWindow).gameObject.AddComponent<CanvasGroup>();
					obj.alpha = num;
					obj.blocksRaycasts = flag || !Settings.ClickThrough.Value;
				}
			}
		}

		private static float IdleAlpha(float secondsSinceLastMessage)
		{
			float num = Settings.SecondsUntilIdle.Value;
			if (secondsSinceLastMessage <= num)
			{
				return 1f;
			}
			float num2 = (Settings.AlwaysShow.Value ? ((float)Settings.IdleOpacity.Value / 100f) : 0f);
			float num3 = Mathf.Clamp01((secondsSinceLastMessage - num) / 1f);
			return Mathf.Lerp(1f, num2, num3);
		}

		private static bool IsHidden(bool typing)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).InIntro())
			{
				return true;
			}
			if (typing || SettingsWindowOpen())
			{
				return false;
			}
			if (Menu.IsVisible())
			{
				return true;
			}
			if ((Object)(object)Hud.instance != (Object)null && Hud.instance.m_userHidden)
			{
				return true;
			}
			if (!((Character)localPlayer).InCutscene())
			{
				return Minimap.IsOpen();
			}
			return true;
		}

		private static bool SettingsWindowOpen()
		{
			if (!_lookedForSettingsWindow)
			{
				_lookedForSettingsWindow = true;
				if (Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.configurationmanager", out var value) && (Object)(object)value.Instance != (Object)null)
				{
					_configurationManager = value.Instance;
					_displayingWindow = AccessTools.Property(((object)value.Instance).GetType(), "DisplayingWindow");
				}
			}
			bool flag = default(bool);
			int num;
			if (_displayingWindow != null)
			{
				object value2 = _displayingWindow.GetValue(_configurationManager);
				if (value2 is bool)
				{
					flag = (bool)value2;
					num = 1;
				}
				else
				{
					num = 0;
				}
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static void Scroll(Chat chat, int before, bool typing)
		{
			if (!typing && (Console.IsVisible() || TextInput.IsVisible() || Minimap.InTextInput()))
			{
				return;
			}
			int num = 0;
			if (ZInput.GetButtonDown("ScrollChatUp") || ZInput.GetButtonDown("JoyScrollChatUp"))
			{
				num = 1;
			}
			else if (ZInput.GetButtonDown("ScrollChatDown") || ZInput.GetButtonDown("JoyScrollChatDown"))
			{
				num = -1;
			}
			if (num != 0)
			{
				ref int reference = ref ScrollHeight.Invoke((Terminal)(object)chat);
				int num2 = Mathf.Max(0, ChatBuffer.Invoke((Terminal)(object)chat).Count - 5);
				int num3 = Mathf.Clamp(before + num * 3, 0, num2);
				HideTimer.Invoke(chat) = 0f;
				if (num3 != reference)
				{
					reference = num3;
					UpdateChat.Invoke(chat, null);
				}
			}
		}

		internal static void ScrollToBottom(Terminal terminal)
		{
			ScrollHeight.Invoke(terminal) = 0;
		}
	}
	[HarmonyPatch(typeof(Terminal), "UpdateChat")]
	internal static class MessageLayout
	{
		private const string HangingIndentTags = "<indent=2em><line-indent=-2em>";

		private const float MessageGap = 60f;

		private static readonly MethodInfo UpdateChatMethod = AccessTools.Method(typeof(Terminal), "UpdateChat", (Type[])null, (Type[])null);

		private static float? _vanillaParagraphSpacing;

		private static void Postfix(Terminal __instance)
		{
			if (__instance is Chat && !((Object)(object)__instance.m_output == (Object)null))
			{
				TextMeshProUGUI output = __instance.m_output;
				if (!_vanillaParagraphSpacing.HasValue)
				{
					_vanillaParagraphSpacing = ((TMP_Text)output).paragraphSpacing;
				}
				((TMP_Text)output).paragraphSpacing = (Settings.SpaceBetweenMessages.Value ? 60f : _vanillaParagraphSpacing.Value);
				string text = (Settings.HangingIndent.Value ? "<indent=2em><line-indent=-2em>" : "");
				string[] lines = ((TMP_Text)output).text.TrimEnd(new char[1] { '\n' }).Split(new char[1] { '\n' });
				((TMP_Text)output).text = text + FitToWindow(output, text, lines);
			}
		}

		private static string FitToWindow(TextMeshProUGUI output, string prefix, string[] lines)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = ((TMP_Text)output).rectTransform.rect;
			if (((Rect)(ref rect)).width <= 0f || ((Rect)(ref rect)).height <= 0f)
			{
				return string.Join("\n", lines);
			}
			int num = 0;
			int num2 = lines.Length - 1;
			while (num < num2)
			{
				int num3 = (num + num2) / 2;
				string text = prefix + string.Join("\n", lines, num3, lines.Length - num3);
				if (((TMP_Text)output).GetPreferredValues(text, ((Rect)(ref rect)).width, 0f).y <= ((Rect)(ref rect)).height)
				{
					num2 = num3;
				}
				else
				{
					num = num3 + 1;
				}
			}
			return string.Join("\n", lines, num, lines.Length - num);
		}

		internal static void Refresh()
		{
			if ((Object)(object)Chat.instance != (Object)null)
			{
				UpdateChatMethod.Invoke(Chat.instance, null);
			}
		}
	}
	[HarmonyPatch]
	internal static class MessagesAsTyped
	{
		internal static MethodBase AddStringFromPlayer()
		{
			return AccessTools.GetDeclaredMethods(typeof(Terminal)).First((MethodInfo m) => m.Name == "AddString" && m.GetParameters().Length == 4);
		}

		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AddStringFromPlayer();
			yield return AccessTools.Method(typeof(Chat), "AddInworldText", (Type[])null, (Type[])null);
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
		{
			MethodInfo toUpper = AccessTools.Method(typeof(string), "ToUpper", Type.EmptyTypes, (Type[])null);
			MethodInfo toLower = AccessTools.Method(typeof(string), "ToLowerInvariant", Type.EmptyTypes, (Type[])null);
			MethodInfo keep = AccessTools.Method(typeof(MessagesAsTyped), "Keep", (Type[])null, (Type[])null);
			int replaced = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, toUpper) || CodeInstructionExtensions.Calls(instruction, toLower))
				{
					CodeInstruction val = new CodeInstruction(OpCodes.Call, (object)keep);
					val.labels.AddRange(instruction.labels);
					val.blocks.AddRange(instruction.blocks);
					replaced++;
					yield return val;
				}
				else
				{
					yield return instruction;
				}
			}
			if (replaced != 2)
			{
				Plugin.Log.LogWarning((object)("Messages as typed: expected 2 forced-case calls in " + original.DeclaringType?.Name + "." + $"{original.Name}, found {replaced}. A game update may have changed it."));
			}
		}

		private static string Keep(string text)
		{
			return text;
		}
	}
	[HarmonyPatch]
	internal static class ScrollToNewest
	{
		private static MethodBase TargetMethod()
		{
			return MessagesAsTyped.AddStringFromPlayer();
		}

		private static void Prefix(Terminal __instance)
		{
			if (__instance is Chat)
			{
				ChatWindow.ScrollToBottom(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Chat), "GetShoutWorldTexts")]
	internal static class HideShoutMapPings
	{
		private static bool Prefix()
		{
			return !Settings.HideShoutMapPings.Value;
		}
	}
	[BepInPlugin("quandru.QuanChat", "QuanChat", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "quandru.QuanChat";

		public const string PluginName = "QuanChat";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			if (IsDedicatedServer())
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"QuanChat 1.0.0 loaded on a dedicated server: its features are all client-side, so they're disabled here and no config file is written. It's installed on the server so every player's version matches.");
				return;
			}
			Settings.Bind(((BaseUnityPlugin)this).Config);
			new Harmony("quandru.QuanChat").PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"QuanChat 1.0.0 loaded.");
		}

		private static bool IsDedicatedServer()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				return Application.isBatchMode;
			}
			return true;
		}
	}
	internal enum Channel
	{
		Shout,
		Say
	}
	internal static class Settings
	{
		internal static ConfigEntry<Channel> StartingChannel;

		internal static ConfigEntry<bool> AlwaysShow;

		internal static ConfigEntry<int> SecondsUntilIdle;

		internal static ConfigEntry<int> IdleOpacity;

		internal static ConfigEntry<bool> ClickThrough;

		internal static ConfigEntry<int> Width;

		internal static ConfigEntry<int> Height;

		internal static ConfigEntry<bool> HangingIndent;

		internal static ConfigEntry<bool> SpaceBetweenMessages;

		internal static ConfigEntry<bool> HideShoutMapPings;

		internal static ConfigEntry<int> FontSize;

		internal static void Bind(ConfigFile config)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			StartingChannel = config.Bind<Channel>("0 - General (personal)", "Starting channel", Channel.Shout, "The channel you start in each time you log in. Shout reaches everyone on the server; Say reaches players within 15 m. Switch during play by typing /s or /say on its own. Personal.");
			AlwaysShow = config.Bind<bool>("1 - Window (personal)", "Always show", true, "Off: the chat window fades out entirely once it's idle, and comes back with the next message. On: it stays on screen at the idle opacity. Personal.");
			SecondsUntilIdle = config.Bind<int>("1 - Window (personal)", "Seconds until idle", 30, new ConfigDescription("How long the chat window stays at full opacity after the newest message before it fades. Personal.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 300), Array.Empty<object>()));
			IdleOpacity = config.Bind<int>("1 - Window (personal)", "Idle opacity", 36, new ConfigDescription("How visible the chat window stays once idle, in percent, when Always show is on. Personal.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>()));
			ClickThrough = config.Bind<bool>("1 - Window (personal)", "Click-through", true, "The chat window ignores mouse clicks while you aren't typing, so it never gets in the way of what's behind it. Personal.");
			Width = config.Bind<int>("1 - Window (personal)", "Width", 130, new ConfigDescription("Width of the chat window, in percent of the game's own. It stays anchored at the bottom right. Personal.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 300), Array.Empty<object>()));
			Height = config.Bind<int>("1 - Window (personal)", "Height", 115, new ConfigDescription("Height of the chat window, in percent of the game's own. It grows upwards, and shows as many messages as fit. Personal.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 300), Array.Empty<object>()));
			HangingIndent = config.Bind<bool>("2 - Messages (personal)", "Hanging indent", true, "Indent the wrapped lines of each message, so every new message visibly starts at the margin. Personal.");
			SpaceBetweenMessages = config.Bind<bool>("2 - Messages (personal)", "Space between messages", false, "Leave a small gap, about half a line, between messages. Personal.");
			HideShoutMapPings = config.Bind<bool>("2 - Messages (personal)", "Hide shout map pings", true, "Shouts don't flash a pin on your map. The text over a nearby speaker's head still shows. Personal.");
			FontSize = config.Bind<int>("2 - Messages (personal)", "Font size", 18, new ConfigDescription("Size of the chat text, in points (the game's own is 18). The input box grows with it. Personal.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 40), Array.Empty<object>()));
			HangingIndent.SettingChanged += delegate
			{
				MessageLayout.Refresh();
			};
			SpaceBetweenMessages.SettingChanged += delegate
			{
				MessageLayout.Refresh();
			};
			Width.SettingChanged += delegate
			{
				WindowLayout.Refresh();
			};
			Height.SettingChanged += delegate
			{
				WindowLayout.Refresh();
			};
			FontSize.SettingChanged += delegate
			{
				WindowLayout.Refresh();
			};
		}
	}
	[HarmonyPatch(typeof(Chat), "Awake")]
	internal static class WindowLayout
	{
		private const int MaxMessages = 100;

		private const float TextPadding = 6f;

		private const int MaxMessageLength = 200;

		private static Vector2 _vanillaSize;

		private static float _vanillaBottom;

		private static float _vanillaFontSize;

		private static float _vanillaInputHeight;

		private static float _vanillaInputFontSize;

		private static Vector2Int _laidOutFor;

		private static bool _loggedSettled;

		private static void Postfix(Chat __instance)
		{
			//IL_002e: 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_0039: 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_0068: 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)
			RectTransform chatWindow = ((Terminal)__instance).m_chatWindow;
			if (!((Object)(object)chatWindow == (Object)null) && !((Object)(object)((Terminal)__instance).m_output == (Object)null) && !((Object)(object)((Terminal)__instance).m_input == (Object)null))
			{
				_vanillaSize = chatWindow.sizeDelta;
				_vanillaBottom = chatWindow.anchoredPosition.y;
				_vanillaFontSize = ((TMP_Text)((Terminal)__instance).m_output).fontSize;
				_vanillaInputHeight = ((RectTransform)((Component)((Terminal)__instance).m_input).transform).sizeDelta.y;
				_vanillaInputFontSize = ((TMP_InputField)((Terminal)__instance).m_input).pointSize;
				((Terminal)__instance).m_maxVisibleBufferLength = 100;
				((TMP_InputField)((Terminal)__instance).m_input).characterLimit = 200;
				Apply(__instance, log: false);
				_laidOutFor = default(Vector2Int);
				_loggedSettled = false;
			}
		}

		internal static void Refresh()
		{
			if ((Object)(object)Chat.instance != (Object)null && _vanillaFontSize > 0f)
			{
				Apply(Chat.instance, log: false);
			}
		}

		internal static void KeepInPlace(Chat chat)
		{
			if (!(_vanillaFontSize <= 0f) && (((Vector2Int)(ref _laidOutFor)).x != Screen.width || ((Vector2Int)(ref _laidOutFor)).y != Screen.height))
			{
				Apply(chat, !_loggedSettled);
				_loggedSettled = true;
			}
		}

		private static void Apply(Chat chat, bool log)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00be: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Settings.FontSize.Value / _vanillaFontSize;
			float num2 = _vanillaInputHeight * num;
			float num3 = _vanillaBottom / 2f;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(_vanillaSize.x * (float)Settings.Width.Value / 100f, _vanillaSize.y * (float)Settings.Height.Value / 100f);
			RectTransform chatWindow = ((Terminal)chat).m_chatWindow;
			Transform obj = ((Transform)chatWindow).Find("root");
			RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(1f, 0f);
				val2.pivot = val3;
				Vector2 anchorMin = (val2.anchorMax = val3);
				val2.anchorMin = anchorMin;
				val2.anchoredPosition = new Vector2(0f - num3, num3);
				val2.sizeDelta = val;
				if ((Object)(object)((Component)val2).GetComponent<RectMask2D>() == (Object)null)
				{
					((Component)val2).gameObject.AddComponent<RectMask2D>();
				}
			}
			_laidOutFor = new Vector2Int(Screen.width, Screen.height);
			Transform obj2 = ((Transform)(((Object)(object)val2 != (Object)null) ? val2 : chatWindow)).Find("bkg");
			Image val5 = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
			if ((Object)(object)val5 != (Object)null)
			{
				Fill(((Graphic)val5).rectTransform);
				val5.sprite = null;
			}
			RectTransform val6 = (RectTransform)((Component)((Terminal)chat).m_input).transform;
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = new Vector2(1f, 0f);
			val6.pivot = new Vector2(0.5f, 0f);
			val6.anchoredPosition = Vector2.zero;
			val6.sizeDelta = new Vector2(0f, num2);
			((TMP_InputField)((Terminal)chat).m_input).pointSize = _vanillaInputFontSize * num;
			RectTransform textViewport = ((TMP_InputField)((Terminal)chat).m_input).textViewport;
			if ((Object)(object)textViewport != (Object)null)
			{
				textViewport.offsetMin = new Vector2(6f, textViewport.offsetMin.y);
				textViewport.offsetMax = new Vector2(-6f, textViewport.offsetMax.y);
				RectMask2D component = ((Component)textViewport).GetComponent<RectMask2D>();
				if ((Object)(object)component != (Object)null)
				{
					component.padding = Vector4.zero;
				}
			}
			TextMeshProUGUI output = ((Terminal)chat).m_output;
			RectTransform rectTransform = ((TMP_Text)output).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.offsetMin = new Vector2(6f, num2);
			rectTransform.offsetMax = new Vector2(-6f, -6f);
			((TMP_Text)output).margin = Vector4.zero;
			((TMP_Text)output).fontSize = Settings.FontSize.Value;
			MessageLayout.Refresh();
			if (log)
			{
				ManualLogSource log2 = Plugin.Log;
				string[] obj3 = new string[11]
				{
					$"Chat window laid out on a {Screen.width} x {Screen.height} screen: box ",
					$"{val.x:0} x {val.y:0}, {num3:0} in from the bottom-right corner, text area ",
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null
				};
				Rect rect = ((TMP_Text)((Terminal)chat).m_output).rectTransform.rect;
				obj3[2] = $"{((Rect)(ref rect)).width:0} x ";
				rect = ((TMP_Text)((Terminal)chat).m_output).rectTransform.rect;
				obj3[3] = $"{((Rect)(ref rect)).height:0}, input {num2:0} high, ";
				obj3[4] = "root ";
				obj3[5] = (((Object)(object)val2 != (Object)null) ? "found" : "MISSING");
				obj3[6] = ", window (should match the screen in canvas units) ";
				rect = chatWindow.rect;
				object arg = ((Rect)(ref rect)).width;
				rect = chatWindow.rect;
				obj3[7] = $"{arg:0} x {((Rect)(ref rect)).height:0}, ";
				obj3[8] = "background ";
				obj3[9] = (((Object)(object)val5 != (Object)null) ? "made even" : "MISSING");
				obj3[10] = ".";
				log2.LogInfo((object)string.Concat(obj3));
			}
		}

		private static void Fill(RectTransform rect)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.pivot = new Vector2(0.5f, 0.5f);
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}
	}
	internal static class PluginInfo
	{
		public const string Version = "1.0.0";
	}
}