Decompiled source of NecroChat v1.0.1

plugins/NecroChat/NecroChat.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HBS;
using HBS.DebugConsole;
using HBS.Net;
using HBS.Util;
using HarmonyLib;
using Necro;
using Necro.Signaling;
using Necro.UI;
using UnityEngine;
using UnityEngine.UI;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyCopyright("Copyright © KoMiKoZa 2026")]
[assembly: ComVisible(false)]
[assembly: Guid("b9800a51-2b96-4772-b75c-02fb8a64988e")]
[assembly: AssemblyProduct("NecroChat")]
[assembly: AssemblyTitle("NecroChat")]
[assembly: AssemblyCompany("KoMiKoZa")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyDescription("Multiplayer chat mod for Necropolis")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace KoMiKoZa.Necropolis.ChatMod;

public enum ChatDisplayMode
{
	Basic,
	AbovePlayer,
	BasicAndAbovePlayer,
	Smart
}
public enum ChatFontStyle
{
	Basic,
	Necro
}
public enum ChatSoundStyle
{
	None,
	Sound1,
	Sound2,
	Sound3,
	Sound4,
	Sound5
}
[BepInPlugin("komikoza.necropolis.chat", "NecroChat", "1.0.1")]
public class ChatModPlugin : BaseUnityPlugin, ObjectDataReceiver
{
	private const string GUID = "komikoza.necropolis.chat";

	private const string NAME = "NecroChat";

	private const string VERSION = "1.0.1";

	private const int MIN_FONT_SIZE = 20;

	private const int MAX_FONT_SIZE = 40;

	private const int MAX_MESSAGE_LENGTH = 100;

	private const float ABOVE_PLAYER_FADE_IN_TIME = 0.3f;

	private const float CHATBOX_FADE_IN_TIME = 0.5f;

	private const uint NETWORK_ROUTER_ID = 51367u;

	private const byte MSG_CHAT = 1;

	private const float MIN_WIDTH = 300f;

	private const float MIN_HEIGHT = 200f;

	private const float MAX_WIDTH = 800f;

	private const float MAX_HEIGHT = 600f;

	private const float INPUT_HEIGHT = 30f;

	private const float PADDING = 10f;

	private const float HEADER_HEIGHT = 55f;

	private const float RESIZE_HANDLE_SIZE = 24f;

	private const string DEFAULT_NAME_COLOR = "ffcc00";

	private const string EVENT_COLOR_JOIN = "FFFF00";

	private const string EVENT_COLOR_LEAVE = "FFA500";

	private const string EVENT_COLOR_INCAP = "FF4444";

	private const string EVENT_COLOR_REVIVED = "44FF44";

	private const string EVENT_COLOR_RESPAWN = "FFA500";

	private const string EVENT_COLOR_ONEHIT = "FF4444";

	private const float EVENT_DEBOUNCE_TIME = 1f;

	private const float CHAT_REOPEN_DELAY = 0.15f;

	private const string DYE_COLOR_PROPERTY = "_SecondaryColor";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> ModEnabled;

	internal static ConfigEntry<bool> DebugMode;

	internal static ConfigEntry<bool> EnableLogging;

	internal static ConfigEntry<bool> HidePlayerNameOnChat;

	internal static ConfigEntry<bool> UsePlayerDyeColors;

	internal static ConfigEntry<bool> ColorAbovePlayerMessage;

	internal static ConfigEntry<bool> AbovePlayerAnimations;

	internal static ConfigEntry<bool> ChatBoxAnimations;

	internal static ConfigEntry<bool> GameEventMessages;

	internal static ConfigEntry<bool> ShowTimestamps;

	internal static ConfigEntry<ChatSoundStyle> ChatSound;

	internal static ConfigEntry<ChatFontStyle> FontStyle;

	internal static ConfigEntry<ChatDisplayMode> DisplayMode;

	internal static ConfigEntry<KeyCode> ToggleHistoryKey;

	internal static ConfigEntry<KeyCode> OpenChatKey;

	internal static ConfigEntry<int> FontSize;

	internal static ConfigEntry<int> MaxMessages;

	internal static ConfigEntry<int> MaxVisibleMessages;

	internal static ConfigEntry<int> MessageDisplayTime;

	internal static ConfigEntry<int> MessageFadeTime;

	internal static ConfigEntry<int> AbovePlayerDisplayTime;

	internal static ConfigEntry<int> AbovePlayerFadeTime;

	internal static ConfigEntry<int> AbovePlayerFontSize;

	internal static ConfigEntry<int> AbovePlayerWidth;

	internal static ConfigEntry<int> SmartModeDistance;

	internal static ConfigEntry<int> ChatBoxOpacity;

	private static string chatLogPath;

	private static string currentLogFile;

	private static ChatModPlugin instance;

	internal static bool chatOpen = false;

	private static bool showFullHistory = false;

	private static string inputText = "";

	private static bool clearInputNextFrame = false;

	private static List<ChatMessage> messages = new List<ChatMessage>();

	private static Vector2 scrollPosition = Vector2.zero;

	private static GUIStyle labelStyle;

	private static GUIStyle inputStyle;

	private static GUIStyle boxStyle;

	private static GUIStyle headerStyle;

	private static GUIStyle resizeHandleStyle;

	private static GUIStyle abovePlayerStyle;

	private static bool stylesInitialized = false;

	private static bool hasShownDebugMessages = false;

	private static Font fontNecro = null;

	private static bool fontsLoaded = false;

	private static float lastFontCheckTime = 0f;

	private static Texture2D backgroundTex;

	private static Texture2D headerTex;

	private static Texture2D resizeTex;

	private static float chatWidth = 500f;

	private static float chatHeight = 375f;

	private static Vector2 windowPosition = new Vector2(-1f, -1f);

	private static bool isDragging = false;

	private static bool isResizing = false;

	private static Vector2 dragOffset = Vector2.zero;

	private static Vector2 resizeStartPos = Vector2.zero;

	private static Vector2 resizeStartSize = Vector2.zero;

	private static MouseState previousMouseState = (MouseState)1;

	private static FieldInfo trackedObjectsField = null;

	private static int selectedMessageIndex = -1;

	private static GUIStyle selectedLabelStyle;

	private static Texture2D selectionTex;

	private static HashSet<Actor> subscribedActors = new HashSet<Actor>();

	private static Dictionary<Actor, bool> actorHadAutoResurrect = new Dictionary<Actor, bool>();

	private static HashSet<Actor> actorDidSpawnReset = new HashSet<Actor>();

	private static Dictionary<Actor, float> lastReviveTime = new Dictionary<Actor, float>();

	private static Dictionary<string, float> lastJoinLeaveTime = new Dictionary<string, float>();

	internal static Actor lastReviver = null;

	private static int lastKnownPlayerCount = 0;

	private static bool hasAutoOpenedChat = false;

	private static bool gameEventCallbacksRegistered = false;

	private static HashSet<Actor> hiddenHUDIndicators = new HashSet<Actor>();

	private static Dictionary<string, float> senderCornerTransitionTime = new Dictionary<string, float>();

	private static HashSet<string> sendersCurrentlyInCorner = new HashSet<string>();

	private static float lastChatCloseTime = 0f;

	private static readonly uint[] CHAT_SOUND_IDS = new uint[6] { 0u, 3970834679u, 2594522141u, 1594216792u, 3857650026u, 4279107860u };

	private static int lastOpacitySetting = -1;

	private void Awake()
	{
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Expected O, but got Unknown
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Expected O, but got Unknown
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Expected O, but got Unknown
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Expected O, but got Unknown
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Expected O, but got Unknown
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Expected O, but got Unknown
		//IL_036d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0377: Expected O, but got Unknown
		//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ac: Expected O, but got Unknown
		//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ea: Expected O, but got Unknown
		//IL_0415: Unknown result type (might be due to invalid IL or missing references)
		//IL_041f: Expected O, but got Unknown
		//IL_0449: Unknown result type (might be due to invalid IL or missing references)
		//IL_0453: Expected O, but got Unknown
		//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d7: Expected O, but got Unknown
		instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ModEnabled", true, "Enable or disable this mod");
		DebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugMode", false, "Enable debug logging and offline chat testing");
		EnableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableLogging", false, "Save chat messages to a log file in /chatlogs folder");
		HidePlayerNameOnChat = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HidePlayerNameOnChat", true, "Hide player name display when showing chat above them");
		UsePlayerDyeColors = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UsePlayerDyeColors", true, "Color player names using their character dye color");
		ColorAbovePlayerMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ColorAbovePlayerMessage", true, "Color entire above-player message with player's dye color");
		AbovePlayerAnimations = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AbovePlayerAnimations", true, "Enable fade-in and slide-up animations for above-player messages");
		ChatBoxAnimations = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ChatBoxAnimations", true, "Enable fade-in animation for chatbox messages");
		GameEventMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "GameEventMessages", true, "Show game event messages (player join/leave, incap, revive, etc.) in chat");
		ShowTimestamps = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowTimestamps", false, "Show timestamps (HH:mm) on messages in chat box");
		ChatSound = ((BaseUnityPlugin)this).Config.Bind<ChatSoundStyle>("General", "ChatSound", ChatSoundStyle.Sound2, "Sound style for chat messages (None to disable)");
		FontStyle = ((BaseUnityPlugin)this).Config.Bind<ChatFontStyle>("General", "FontStyle", ChatFontStyle.Necro, "Font style to use for chat text");
		DisplayMode = ((BaseUnityPlugin)this).Config.Bind<ChatDisplayMode>("General", "DisplayMode", ChatDisplayMode.Smart, "Chat display mode");
		try
		{
			ChatDisplayMode value = DisplayMode.Value;
		}
		catch
		{
			DisplayMode.Value = ChatDisplayMode.Smart;
		}
		ToggleHistoryKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleHistoryKey", (KeyCode)9, "Key to hold to show chat history");
		OpenChatKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "OpenChatKey", (KeyCode)13, "Key to open chat (send is always Enter)");
		FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("General", "FontSize", 25, new ConfigDescription("Chat font size", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 40), new object[0]));
		MaxMessages = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxMessages", 50, new ConfigDescription("Maximum messages to keep in history", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 100), new object[0]));
		MaxVisibleMessages = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxVisibleMessages", 5, new ConfigDescription("Max messages shown on screen", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 10), new object[0]));
		MessageDisplayTime = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MessageDisplayTime", 5, new ConfigDescription("Seconds before messages start fading", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 12), new object[0]));
		MessageFadeTime = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MessageFadeTime", 2, new ConfigDescription("Fade animation duration in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 8), new object[0]));
		AbovePlayerDisplayTime = ((BaseUnityPlugin)this).Config.Bind<int>("General", "AbovePlayerDisplayTime", 5, new ConfigDescription("Seconds before above-player messages start fading", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 12), new object[0]));
		AbovePlayerFadeTime = ((BaseUnityPlugin)this).Config.Bind<int>("General", "AbovePlayerFadeTime", 2, new ConfigDescription("Above-player fade duration in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 8), new object[0]));
		AbovePlayerFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("General", "AbovePlayerFontSize", 40, new ConfigDescription("Above-player font size", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 50), new object[0]));
		AbovePlayerWidth = ((BaseUnityPlugin)this).Config.Bind<int>("General", "AbovePlayerWidth", 400, new ConfigDescription("Above-player text max width in pixels", (AcceptableValueBase)(object)new AcceptableValueRange<int>(300, 500), new object[0]));
		SmartModeDistance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SmartModeDistance", 30, new ConfigDescription("Smart mode distance threshold", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 100), new object[0]));
		ChatBoxOpacity = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ChatBoxOpacity", 70, new ConfigDescription("Chat box background opacity (0-100%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[0]));
		chatLogPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "chatlogs");
		if (EnableLogging.Value)
		{
			try
			{
				if (!Directory.Exists(chatLogPath))
				{
					Directory.CreateDirectory(chatLogPath);
				}
				string arg = DateTime.Now.ToString("yyyy-MM-dd");
				currentLogFile = Path.Combine(chatLogPath, $"chat_{arg}.txt");
				if (!File.Exists(currentLogFile))
				{
					string contents = "================================================" + Environment.NewLine + string.Format("[NecroChat] v{0} - Chat Log", "1.0.1") + Environment.NewLine + string.Format(" - Generated: {0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) + Environment.NewLine + "================================================" + Environment.NewLine + Environment.NewLine;
					File.WriteAllText(currentLogFile, contents);
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to create chat log folder: " + ex.Message));
			}
		}
		if (!ModEnabled.Value)
		{
			Log.LogInfo((object)"Disabled");
			return;
		}
		try
		{
			Harmony val = new Harmony("komikoza.necropolis.chat");
			val.PatchAll();
			ObjectDataRouter.Singleton.Register(51367u, (ObjectDataReceiver)(object)this);
			RegisterGameEventCallbacks();
			Log.LogInfo((object)"================================================");
			Log.LogInfo((object)string.Format("[{0}] v{1} loaded!", "NecroChat", "1.0.1"));
			Log.LogInfo((object)" - Advanced multiplayer text chat for Necropolis");
			Log.LogInfo((object)"================================================");
		}
		catch (Exception ex)
		{
			Log.LogError((object)string.Format("[{0}] Failed to load: {1}", "NecroChat", ex));
		}
	}

	private bool IsChatAllowed()
	{
		if (DebugMode.Value)
		{
			return true;
		}
		if (!LazySingletonBehavior<NetworkManager>.HasInstance)
		{
			return false;
		}
		return LazySingletonBehavior<NetworkManager>.Instance.IsMultiplayer;
	}

	private int GetCurrentPlayerCount()
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Invalid comparison between Unknown and I4
		//IL_0086: 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)
		//IL_0094: Invalid comparison between Unknown and I4
		try
		{
			if (!LazySingletonBehavior<NetworkManager>.HasInstance)
			{
				return 0;
			}
			NetworkManager val = LazySingletonBehavior<NetworkManager>.Instance;
			if (!val.IsMultiplayer)
			{
				return 0;
			}
			int num = 1;
			if (val.VirtualCouch != null)
			{
				foreach (VirtualCouchSeat item in val.VirtualCouch)
				{
					if (item != null && item.platformHandle != null)
					{
						num++;
					}
					else if (item != null && ((int)item.setupState == 2 || (int)item.setupState == 0 || (int)item.setupState == 1))
					{
						num++;
					}
				}
			}
			return num;
		}
		catch
		{
			return 0;
		}
	}

	private bool IsInLobbyWithPlayers()
	{
		return GetCurrentPlayerCount() >= 2;
	}

	private bool IsInLobby()
	{
		if (!ThirdPersonCameraControl.HasInstance)
		{
			return true;
		}
		if ((Object)(object)ThirdPersonCameraControl.Instance.CharacterActor == (Object)null)
		{
			return true;
		}
		if (!ThirdPersonCameraControl.Instance.CharacterActor.IsAlive)
		{
			return true;
		}
		return false;
	}

	internal static bool IsInMultiplayerLobby()
	{
		if (!LazySingletonBehavior<NetworkManager>.HasInstance)
		{
			return false;
		}
		if (!LazySingletonBehavior<NetworkManager>.Instance.IsMultiplayer)
		{
			return false;
		}
		if (!ThirdPersonCameraControl.HasInstance)
		{
			return true;
		}
		if ((Object)(object)ThirdPersonCameraControl.Instance.CharacterActor == (Object)null)
		{
			return true;
		}
		if (!ThirdPersonCameraControl.Instance.CharacterActor.IsAlive)
		{
			return true;
		}
		return false;
	}

	private bool IsMenuBlockingChat()
	{
		if (Menu_MainMenu.IsShowing)
		{
			return true;
		}
		if (ItemMenuController.IsShowing)
		{
			return true;
		}
		if (ModalDialogController.IsShowing)
		{
			return true;
		}
		return false;
	}

	private void RestoreExpiredHUDIndicators()
	{
		if (hiddenHUDIndicators.Count == 0)
		{
			return;
		}
		if (!HidePlayerNameOnChat.Value)
		{
			RestoreAllHUDIndicators();
			return;
		}
		float num = AbovePlayerDisplayTime.Value;
		float num2 = AbovePlayerFadeTime.Value;
		float num3 = num + num2;
		HashSet<string> hashSet = new HashSet<string>();
		foreach (ChatMessage message in messages)
		{
			float num4 = Time.time - message.Timestamp;
			if (num4 <= num3)
			{
				hashSet.Add(message.Sender);
			}
		}
		List<Actor> list = new List<Actor>();
		foreach (Actor hiddenHUDIndicator in hiddenHUDIndicators)
		{
			if ((Object)(object)hiddenHUDIndicator == (Object)null)
			{
				list.Add(hiddenHUDIndicator);
				continue;
			}
			string actorDisplayName = GetActorDisplayName(hiddenHUDIndicator);
			if (string.IsNullOrEmpty(actorDisplayName) || !hashSet.Contains(actorDisplayName))
			{
				HUDIndicator hUDIndicatorForActor = GetHUDIndicatorForActor(hiddenHUDIndicator);
				if ((Object)(object)hUDIndicatorForActor != (Object)null)
				{
					((Component)hUDIndicatorForActor).gameObject.SetActive(true);
				}
				list.Add(hiddenHUDIndicator);
			}
		}
		foreach (Actor item in list)
		{
			hiddenHUDIndicators.Remove(item);
		}
	}

	private void RestoreAllHUDIndicators()
	{
		foreach (Actor hiddenHUDIndicator in hiddenHUDIndicators)
		{
			if (!((Object)(object)hiddenHUDIndicator == (Object)null))
			{
				HUDIndicator hUDIndicatorForActor = GetHUDIndicatorForActor(hiddenHUDIndicator);
				if ((Object)(object)hUDIndicatorForActor != (Object)null)
				{
					((Component)hUDIndicatorForActor).gameObject.SetActive(true);
				}
			}
		}
		hiddenHUDIndicators.Clear();
	}

	private void Update()
	{
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		if (!ModEnabled.Value || !IsChatAllowed())
		{
			return;
		}
		if (!gameEventCallbacksRegistered)
		{
			RegisterGameEventCallbacks();
		}
		if (!hasShownDebugMessages && !IsInLobby())
		{
			hasShownDebugMessages = true;
			if (DebugMode.Value)
			{
				messages.Add(new ChatMessage("[NecroChat] Debugging is enabled", Time.time, "FFFF00"));
			}
			if (EnableLogging.Value)
			{
				messages.Add(new ChatMessage("[NecroChat] Logging is enabled", Time.time, "FFFF00"));
			}
		}
		int currentPlayerCount = GetCurrentPlayerCount();
		if (IsInLobby() && currentPlayerCount >= 2 && lastKnownPlayerCount < 2 && !hasAutoOpenedChat && !chatOpen && !IsGameUIBlocking(allowLobby: true))
		{
			OpenChat();
			hasAutoOpenedChat = true;
			if (DebugMode.Value)
			{
				Log.LogInfo((object)"LOBBY CHAT auto-opened on player join");
			}
		}
		if (currentPlayerCount < 2)
		{
			hasAutoOpenedChat = false;
		}
		lastKnownPlayerCount = currentPlayerCount;
		if (!chatOpen && !IsGameUIBlocking(allowLobby: true))
		{
			bool key = Input.GetKey(ToggleHistoryKey.Value);
			if (key && !showFullHistory)
			{
				showFullHistory = true;
				if (DebugMode.Value)
				{
					Log.LogInfo((object)"History SHOWN (Tab held)");
				}
			}
			else if (!key && showFullHistory)
			{
				showFullHistory = false;
				if (DebugMode.Value)
				{
					Log.LogInfo((object)"History HIDDEN (Tab released)");
				}
			}
		}
		if (showFullHistory && IsMenuBlockingChat())
		{
			if (DebugMode.Value)
			{
				Log.LogInfo((object)"History HIDDEN (menu opened)");
			}
			showFullHistory = false;
		}
		RestoreExpiredHUDIndicators();
		UpdateActorSubscriptions();
	}

	private bool IsGameUIBlocking(bool allowLobby = false)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		if (LazySingletonBehavior<DebugConsole>.HasInstance && ((Behaviour)LazySingletonBehavior<DebugConsole>.Instance).enabled && (int)LazySingletonBehavior<DebugConsole>.Instance.mode != -1)
		{
			return true;
		}
		if (allowLobby && IsInMultiplayerLobby())
		{
			if (ModalDialogController.IsShowing)
			{
				return true;
			}
			return false;
		}
		if (ItemMenuController.IsShowing)
		{
			return true;
		}
		if (Menu_MainMenu.IsShowing)
		{
			return true;
		}
		if (ModalDialogController.IsShowing)
		{
			return true;
		}
		if (!ThirdPersonCameraControl.HasInstance)
		{
			return true;
		}
		if ((Object)(object)ThirdPersonCameraControl.Instance.CharacterActor == (Object)null)
		{
			return true;
		}
		if (!ThirdPersonCameraControl.Instance.CharacterActor.IsAlive)
		{
			return true;
		}
		return false;
	}

	private void OpenChat()
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if (chatOpen)
		{
			return;
		}
		chatOpen = true;
		if (ThirdPersonCameraControl.HasInstance)
		{
			if (LazySingletonBehavior<EventSystemObjectHandler>.HasInstance)
			{
				LazySingletonBehavior<EventSystemObjectHandler>.Instance.SetInputDisabled(true);
			}
			if (SceneSingletonBehavior<NecroKeyboardManager>.HasInstance)
			{
				previousMouseState = SceneSingletonBehavior<NecroKeyboardManager>.Instance.CurMouseState;
				SceneSingletonBehavior<NecroKeyboardManager>.Instance.SetProfileState((MouseState)0);
			}
			ThirdPersonCameraControl.Instance.StopMainPlayerMovement();
		}
		Cursor.visible = true;
		Cursor.lockState = (CursorLockMode)0;
		if (DebugMode.Value)
		{
			Log.LogInfo((object)"Chat OPENED");
		}
	}

	private void CloseChat()
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		if (!chatOpen)
		{
			return;
		}
		chatOpen = false;
		selectedMessageIndex = -1;
		if (ThirdPersonCameraControl.HasInstance)
		{
			if (LazySingletonBehavior<EventSystemObjectHandler>.HasInstance)
			{
				LazySingletonBehavior<EventSystemObjectHandler>.Instance.SetInputDisabled(false);
			}
			if (SceneSingletonBehavior<NecroKeyboardManager>.HasInstance)
			{
				SceneSingletonBehavior<NecroKeyboardManager>.Instance.SetProfileState(previousMouseState);
			}
		}
		lastChatCloseTime = Time.time;
		if (DebugMode.Value)
		{
			Log.LogInfo((object)"Chat CLOSED");
		}
	}

	private void SendChatMessage(string text)
	{
		string text2 = text.Replace("\n", "").Replace("\r", "").Trim();
		if (text2.Length > 100)
		{
			text2 = text2.Substring(0, 100);
		}
		if (DebugMode.Value)
		{
			Log.LogInfo((object)("SendMessage: '" + text2 + "' (length=" + text2.Length + ")"));
		}
		if (!string.IsNullOrEmpty(text2))
		{
			string localPlayerName = GetLocalPlayerName();
			bool isAction = false;
			string text3 = text2;
			if (text2.StartsWith("/me ", StringComparison.OrdinalIgnoreCase))
			{
				isAction = true;
				text3 = text2.Substring(4);
			}
			else if (text2.Equals("/me", StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
			AddMessage(localPlayerName, text3, isAction, playSound: true);
			BroadcastChatMessage(localPlayerName, text3, isAction);
		}
	}

	private string GetLocalPlayerName()
	{
		try
		{
			if (LazySingletonBehavior<NetworkManager>.HasInstance && LazySingletonBehavior<NetworkManager>.Instance.LocalVirtualCouchSeat != null && LazySingletonBehavior<NetworkManager>.Instance.LocalVirtualCouchSeat.platformHandle != null)
			{
				string name = LazySingletonBehavior<NetworkManager>.Instance.LocalVirtualCouchSeat.platformHandle.Name;
				if (!string.IsNullOrEmpty(name))
				{
					return name;
				}
			}
		}
		catch
		{
		}
		return "Player";
	}

	private void AddMessage(string sender, string text, bool isAction = false, bool playSound = false)
	{
		messages.Add(new ChatMessage(sender, text, Time.time, isAction));
		while (messages.Count > MaxMessages.Value)
		{
			messages.RemoveAt(0);
		}
		scrollPosition.y = float.MaxValue;
		if (playSound && ChatSound.Value != 0)
		{
			PlayChatSound();
		}
		EnsureChatLogInitialized();
		if (!EnableLogging.Value || string.IsNullOrEmpty(currentLogFile))
		{
			return;
		}
		try
		{
			string arg = DateTime.Now.ToString("HH:mm:ss");
			File.AppendAllText(contents: ((!isAction) ? $"[{arg}] {sender}: {text}" : $"[{arg}] * {sender} {text}") + Environment.NewLine, path: currentLogFile);
		}
		catch (Exception ex)
		{
			if (DebugMode.Value)
			{
				Log.LogError((object)("Failed to write chat log: " + ex.Message));
			}
		}
	}

	private void PlayChatSound()
	{
		try
		{
			int value = (int)ChatSound.Value;
			if (value > 0 && value < CHAT_SOUND_IDS.Length)
			{
				AkSoundEngine.PostEvent(CHAT_SOUND_IDS[value], ((Component)this).gameObject);
			}
		}
		catch
		{
		}
	}

	private void AddSystemMessage(string text, string color)
	{
		if (!GameEventMessages.Value)
		{
			return;
		}
		messages.Add(new ChatMessage(text, Time.time, color));
		while (messages.Count > MaxMessages.Value)
		{
			messages.RemoveAt(0);
		}
		scrollPosition.y = float.MaxValue;
		EnsureChatLogInitialized();
		if (EnableLogging.Value && !string.IsNullOrEmpty(currentLogFile))
		{
			try
			{
				string arg = DateTime.Now.ToString("HH:mm:ss");
				string text2 = $"[{arg}] [SYSTEM] {text}";
				File.AppendAllText(currentLogFile, text2 + Environment.NewLine);
			}
			catch
			{
			}
		}
		if (DebugMode.Value)
		{
			Log.LogInfo((object)("System: " + text));
		}
	}

	private void RegisterGameEventCallbacks()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Expected O, but got Unknown
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		if (!gameEventCallbacksRegistered && LazySingletonBehavior<NetworkManager>.HasInstance)
		{
			NetworkManager val = LazySingletonBehavior<NetworkManager>.Instance;
			val.RegisterConnectCallback(new NetworkManagerOnConnect(OnPlayerConnect));
			val.RegisterDisconnectCallback(new NetworkManagerOnDisconnect(OnPlayerDisconnect));
			gameEventCallbacksRegistered = true;
			if (DebugMode.Value)
			{
				Log.LogInfo((object)"Registered game event callbacks");
			}
		}
	}

	private void UnregisterGameEventCallbacks()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		if (LazySingletonBehavior<NetworkManager>.HasInstance)
		{
			NetworkManager val = LazySingletonBehavior<NetworkManager>.Instance;
			val.UnregisterConnectCallback(new NetworkManagerOnConnect(OnPlayerConnect));
			val.UnregisterDisconnectCallback(new NetworkManagerOnDisconnect(OnPlayerDisconnect));
		}
	}

	private void OnPlayerConnect(VirtualCouchSeat seat)
	{
		if (seat == null || seat.platformHandle == null)
		{
			return;
		}
		string name = seat.platformHandle.Name;
		if (!string.IsNullOrEmpty(name))
		{
			string key = "join_" + name;
			float time = Time.time;
			if (!lastJoinLeaveTime.TryGetValue(key, out var value) || !(time - value < 1f))
			{
				lastJoinLeaveTime[key] = time;
				AddSystemMessage(name + " has joined the session", "FFFF00");
			}
		}
	}

	private void OnPlayerDisconnect(VirtualCouchSeat seat)
	{
		if (seat == null || seat.platformHandle == null)
		{
			return;
		}
		string name = seat.platformHandle.Name;
		if (!string.IsNullOrEmpty(name))
		{
			string key = "leave_" + name;
			float time = Time.time;
			if (!lastJoinLeaveTime.TryGetValue(key, out var value) || !(time - value < 1f))
			{
				lastJoinLeaveTime[key] = time;
				AddSystemMessage(name + " has left the session", "FFA500");
			}
		}
	}

	private void SubscribeToActorEvents(Actor actor)
	{
		if (!((Object)(object)actor == (Object)null) && !subscribedActors.Contains(actor))
		{
			actor.OnKilled += delegate
			{
				OnActorKilled(actor);
			};
			actor.OnResurrect += delegate
			{
				OnActorResurrected(actor);
			};
			subscribedActors.Add(actor);
			if (DebugMode.Value)
			{
				Log.LogInfo((object)("Subscribed to actor events: " + GetActorDisplayName(actor)));
			}
		}
	}

	private void OnActorKilled(Actor actor)
	{
		if ((Object)(object)actor == (Object)null || !actor.IsPlayer)
		{
			return;
		}
		string actorDisplayName = GetActorDisplayName(actor);
		if (!string.IsNullOrEmpty(actorDisplayName))
		{
			actorHadAutoResurrect[actor] = actor.WillAutoResurrect;
			if (actor.WillAutoResurrect)
			{
				AddSystemMessage(actorDisplayName + " has cheated death!", "44FF44");
			}
			else
			{
				AddSystemMessage(actorDisplayName + " has fallen!", "FF4444");
			}
		}
	}

	private void OnActorResurrected(Actor actor)
	{
		if ((Object)(object)actor == (Object)null || !actor.IsPlayer)
		{
			return;
		}
		string actorDisplayName = GetActorDisplayName(actor);
		if (string.IsNullOrEmpty(actorDisplayName))
		{
			return;
		}
		if (actorDidSpawnReset.Contains(actor))
		{
			actorDidSpawnReset.Remove(actor);
			return;
		}
		bool value = false;
		if (actorHadAutoResurrect.TryGetValue(actor, out value) && value)
		{
			actorHadAutoResurrect.Remove(actor);
			return;
		}
		actorHadAutoResurrect.Remove(actor);
		float time = Time.time;
		if (lastReviveTime.TryGetValue(actor, out var value2) && time - value2 < 1f)
		{
			return;
		}
		lastReviveTime[actor] = time;
		if ((Object)(object)lastReviver != (Object)null && (Object)(object)lastReviver != (Object)(object)actor)
		{
			string actorDisplayName2 = GetActorDisplayName(lastReviver);
			if (!string.IsNullOrEmpty(actorDisplayName2))
			{
				AddSystemMessage(actorDisplayName + " was revived by " + actorDisplayName2 + "!", "44FF44");
				lastReviver = null;
				return;
			}
		}
		lastReviver = null;
		AddSystemMessage(actorDisplayName + " was revived!", "44FF44");
	}

	internal static void OnActorSpawnReset(Actor actor)
	{
		if (!((Object)(object)instance == (Object)null) && !((Object)(object)actor == (Object)null) && actor.IsPlayer)
		{
			string actorDisplayName = instance.GetActorDisplayName(actor);
			if (!string.IsNullOrEmpty(actorDisplayName))
			{
				actorDidSpawnReset.Add(actor);
				instance.AddSystemMessage(actorDisplayName + " has respawned (lost all gear)", "FFA500");
			}
		}
	}

	internal static void OnOneHitProtection(Actor actor)
	{
		if (!((Object)(object)instance == (Object)null) && !((Object)(object)actor == (Object)null) && actor.IsPlayer)
		{
			string actorDisplayName = instance.GetActorDisplayName(actor);
			if (!string.IsNullOrEmpty(actorDisplayName))
			{
				instance.AddSystemMessage(actorDisplayName + " narrowly escaped death!", "FF4444");
			}
		}
	}

	private void UpdateActorSubscriptions()
	{
		if (!LazySingletonBehavior<NetworkManager>.HasInstance || !GameEventMessages.Value)
		{
			return;
		}
		NetworkManager val = LazySingletonBehavior<NetworkManager>.Instance;
		if (!val.IsMultiplayer)
		{
			return;
		}
		if (ThirdPersonCameraControl.HasInstance && (Object)(object)ThirdPersonCameraControl.Instance.CharacterActor != (Object)null)
		{
			SubscribeToActorEvents(ThirdPersonCameraControl.Instance.CharacterActor);
		}
		if (val.VirtualCouch == null)
		{
			return;
		}
		foreach (VirtualCouchSeat item in val.VirtualCouch)
		{
			if (item != null && (Object)(object)item.actor != (Object)null)
			{
				SubscribeToActorEvents(item.actor);
			}
		}
	}

	private void BroadcastChatMessage(string sender, string text, bool isAction = false)
	{
		try
		{
			if (!LazySingletonBehavior<NetworkManager>.HasInstance)
			{
				return;
			}
			if (!LazySingletonBehavior<NetworkManager>.Instance.IsMultiplayer)
			{
				if (DebugMode.Value)
				{
					Log.LogInfo((object)"Not in multiplayer, skipping broadcast");
				}
				return;
			}
			int num = Serialization.STORAGE_SPACE_BYTE + Serialization.StorageSpaceString(sender) + Serialization.StorageSpaceString(text) + Serialization.STORAGE_SPACE_BYTE;
			SerializationStream routedBuffer = ObjectDataRouter.Singleton.GetRoutedBuffer((ObjectDataReceiver)(object)this, num);
			if (routedBuffer != null)
			{
				routedBuffer.PutByte((byte)1);
				routedBuffer.PutString(sender);
				routedBuffer.PutString(text);
				routedBuffer.PutByte((byte)(isAction ? 1 : 0));
				LazySingletonBehavior<NetworkManager>.Instance.SendReliable(routedBuffer);
				if (DebugMode.Value)
				{
					Log.LogInfo((object)"Broadcast sent");
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Broadcast error: " + ex));
		}
	}

	public void Receive(SerializationStream stream)
	{
		try
		{
			byte @byte = stream.GetByte();
			if (@byte == 1)
			{
				string @string = stream.GetString();
				string string2 = stream.GetString();
				bool flag = false;
				try
				{
					flag = stream.GetByte() == 1;
				}
				catch
				{
				}
				if (DebugMode.Value)
				{
					Log.LogInfo((object)$"Received: {@string}: {string2} (action={flag})");
				}
				AddMessage(@string, string2, flag, playSound: true);
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Receive error: " + ex));
		}
	}

	private float GetInputHeight()
	{
		return Mathf.Max(30f, (float)FontSize.Value + 16f);
	}

	private float GetMessageHeight(ChatMessage msg, float width)
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Expected O, but got Unknown
		string text = (ShowTimestamps.Value ? "[00:00] " : "");
		string text2 = (msg.IsSystemMessage ? (text + msg.Text) : ((!msg.IsAction) ? $"{text}{msg.Sender}: {msg.Text}" : $"{text}*{msg.Sender} {msg.Text}*"));
		if (labelStyle != null)
		{
			GUIContent val = new GUIContent(text2);
			float num = labelStyle.CalcHeight(val, width);
			return num + 4f;
		}
		float num2 = (float)FontSize.Value + 10f;
		float num3 = width / ((float)FontSize.Value * 0.55f);
		if (num3 < 10f)
		{
			num3 = 10f;
		}
		int num4 = Mathf.CeilToInt((float)text2.Length / num3);
		if (num4 < 1)
		{
			num4 = 1;
		}
		return num2 * (float)num4;
	}

	private void EnsureChatLogInitialized()
	{
		if (!EnableLogging.Value || !string.IsNullOrEmpty(currentLogFile))
		{
			return;
		}
		try
		{
			if (string.IsNullOrEmpty(chatLogPath))
			{
				chatLogPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "chatlogs");
			}
			if (!Directory.Exists(chatLogPath))
			{
				Directory.CreateDirectory(chatLogPath);
			}
			string arg = DateTime.Now.ToString("yyyy-MM-dd");
			currentLogFile = Path.Combine(chatLogPath, $"chat_{arg}.txt");
			if (!File.Exists(currentLogFile))
			{
				string contents = "================================================" + Environment.NewLine + string.Format("[NecroChat] v{0} - Chat Log", "1.0.1") + Environment.NewLine + string.Format(" - Generated: {0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) + Environment.NewLine + "================================================" + Environment.NewLine + Environment.NewLine;
				File.WriteAllText(currentLogFile, contents);
			}
		}
		catch (Exception ex)
		{
			if (DebugMode.Value)
			{
				Log.LogError((object)("Failed to initialize chat log: " + ex.Message));
			}
		}
	}

	private void OnGUI()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Invalid comparison between Unknown and I4
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: 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_00cf: Invalid comparison between Unknown and I4
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Invalid comparison between Unknown and I4
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Invalid comparison between Unknown and I4
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Invalid comparison between Unknown and I4
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Invalid comparison between Unknown and I4
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Invalid comparison between Unknown and I4
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Invalid comparison between Unknown and I4
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Invalid comparison between Unknown and I4
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Invalid comparison between Unknown and I4
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Invalid comparison between Unknown and I4
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Invalid comparison between Unknown and I4
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Invalid comparison between Unknown and I4
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03df: Invalid comparison between Unknown and I4
		//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Invalid comparison between Unknown and I4
		//IL_043e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0444: Invalid comparison between Unknown and I4
		//IL_0447: Unknown result type (might be due to invalid IL or missing references)
		//IL_044e: Invalid comparison between Unknown and I4
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Invalid comparison between Unknown and I4
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b0: Invalid comparison between Unknown and I4
		if (!ModEnabled.Value)
		{
			return;
		}
		if (clearInputNextFrame && (int)Event.current.type == 7)
		{
			inputText = "";
			clearInputNextFrame = false;
		}
		InitializeStyles();
		if (windowPosition.x < -0.5f)
		{
			chatWidth = 500f;
			chatHeight = 375f;
			windowPosition = new Vector2(10f, ((float)Screen.height - chatHeight) / 2f);
		}
		Event current = Event.current;
		if (!Input.GetMouseButton(0))
		{
			isDragging = false;
			isResizing = false;
		}
		if (isDragging && (int)current.type == 3)
		{
			windowPosition = current.mousePosition - dragOffset;
			current.Use();
		}
		else if (isResizing && (int)current.type == 3)
		{
			Vector2 val = current.mousePosition - resizeStartPos;
			chatWidth = Mathf.Clamp(resizeStartSize.x + val.x, 300f, 800f);
			chatHeight = Mathf.Clamp(resizeStartSize.y + val.y, 200f, 600f);
			current.Use();
		}
		if ((isDragging || isResizing) && (int)current.type == 1)
		{
			isDragging = false;
			isResizing = false;
			current.Use();
		}
		if (chatOpen && (current.isMouse || (int)current.type == 6))
		{
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(windowPosition.x, windowPosition.y, chatWidth, chatHeight);
			if (!((Rect)(ref val2)).Contains(current.mousePosition))
			{
				current.Use();
			}
		}
		if (!chatOpen || !current.isKey || (int)current.keyCode == 13 || (int)current.keyCode == 271 || (int)current.keyCode == 27 || (int)current.keyCode == 9 || (int)current.keyCode != 99 || !current.control)
		{
		}
		bool flag = current.keyCode == OpenChatKey.Value;
		bool flag2 = (int)current.keyCode == 13 || (int)current.keyCode == 271;
		bool flag3 = Time.time - lastChatCloseTime > 0.15f;
		if ((int)current.type == 4 && (flag || flag2))
		{
			if (chatOpen && flag2)
			{
				if (DebugMode.Value)
				{
					Log.LogInfo((object)"Sending message, closing chat");
				}
				string text = inputText;
				SendChatMessage(text);
				inputText = "";
				CloseChat();
				current.Use();
				return;
			}
			if (!chatOpen && flag && flag3 && !showFullHistory && IsChatAllowed() && !IsGameUIBlocking(allowLobby: true))
			{
				if ((int)OpenChatKey.Value != 13 && (int)OpenChatKey.Value != 271)
				{
					clearInputNextFrame = true;
				}
				OpenChat();
				current.Use();
				return;
			}
		}
		if ((int)current.type == 4 && (int)current.keyCode == 27 && chatOpen)
		{
			if (selectedMessageIndex >= 0)
			{
				selectedMessageIndex = -1;
				current.Use();
			}
			else
			{
				CloseChat();
				current.Use();
			}
		}
		else if ((int)current.type == 4 && (int)current.keyCode == 99 && current.control && (chatOpen || showFullHistory) && selectedMessageIndex >= 0 && selectedMessageIndex < messages.Count)
		{
			ChatMessage chatMessage = messages[selectedMessageIndex];
			string text3 = (GUIUtility.systemCopyBuffer = (chatMessage.IsSystemMessage ? ("[SYSTEM] " + chatMessage.Text) : ((!chatMessage.IsAction) ? $"{chatMessage.Sender}: {chatMessage.Text}" : $"* {chatMessage.Sender} {chatMessage.Text}")));
			if (DebugMode.Value)
			{
				Log.LogInfo((object)("Copied to clipboard: " + text3));
			}
			current.Use();
		}
		else
		{
			if (!IsChatAllowed())
			{
				return;
			}
			bool flag4 = IsMenuBlockingChat();
			if (!chatOpen && !showFullHistory && (!HasRecentMessages() || flag4))
			{
				return;
			}
			windowPosition.x = Mathf.Clamp(windowPosition.x, 0f, (float)Screen.width - chatWidth);
			windowPosition.y = Mathf.Clamp(windowPosition.y, 0f, (float)Screen.height - chatHeight);
			float x = windowPosition.x;
			float y = windowPosition.y;
			bool flag5 = IsInMultiplayerLobby();
			ChatDisplayMode value = DisplayMode.Value;
			if (!flag5 && (value == ChatDisplayMode.AbovePlayer || value == ChatDisplayMode.BasicAndAbovePlayer || value == ChatDisplayMode.Smart))
			{
				DrawAbovePlayerMessages();
			}
			bool flag6 = true;
			if (!chatOpen && !showFullHistory && value == ChatDisplayMode.AbovePlayer && !flag5)
			{
				flag6 = false;
			}
			if (chatOpen || showFullHistory)
			{
				DrawChatWindow(x, y);
			}
			else if (flag6)
			{
				if (value == ChatDisplayMode.Smart && !flag5)
				{
					DrawRecentMessagesFiltered(x, y, onlyFarPlayers: true);
				}
				else
				{
					DrawRecentMessages(x, y);
				}
			}
			if (chatOpen && current.isKey)
			{
				current.Use();
			}
		}
	}

	private void InitializeStyles()
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_00d0: Expected O, but got Unknown
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected O, but got Unknown
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Expected O, but got Unknown
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Expected O, but got Unknown
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Expected O, but got Unknown
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Expected O, but got Unknown
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Expected O, but got Unknown
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Expected O, but got Unknown
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Expected O, but got Unknown
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Expected O, but got Unknown
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Expected O, but got Unknown
		//IL_0334: Unknown result type (might be due to invalid IL or missing references)
		//IL_0378: Unknown result type (might be due to invalid IL or missing references)
		//IL_0382: Expected O, but got Unknown
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		int value = ChatBoxOpacity.Value;
		if ((Object)(object)backgroundTex != (Object)null && value != lastOpacitySetting)
		{
			float num = (float)value / 100f;
			backgroundTex.SetPixel(0, 0, new Color(0f, 0f, 0f, num));
			backgroundTex.Apply();
			headerTex.SetPixel(0, 0, new Color(0.2f, 0.2f, 0.3f, Mathf.Min(1f, num + 0.2f)));
			headerTex.Apply();
			lastOpacitySetting = value;
		}
		if (!stylesInitialized)
		{
			float num = (float)value / 100f;
			lastOpacitySetting = value;
			backgroundTex = new Texture2D(1, 1);
			backgroundTex.SetPixel(0, 0, new Color(0f, 0f, 0f, num));
			backgroundTex.Apply();
			headerTex = new Texture2D(1, 1);
			headerTex.SetPixel(0, 0, new Color(0.2f, 0.2f, 0.3f, Mathf.Min(1f, num + 0.2f)));
			headerTex.Apply();
			resizeTex = new Texture2D(1, 1);
			resizeTex.SetPixel(0, 0, new Color(1f, 0.9f, 0f, 0.9f));
			resizeTex.Apply();
			labelStyle = new GUIStyle(GUI.skin.label);
			labelStyle.normal.textColor = Color.white;
			labelStyle.wordWrap = true;
			labelStyle.richText = true;
			labelStyle.clipping = (TextClipping)0;
			inputStyle = new GUIStyle(GUI.skin.textField);
			inputStyle.normal.textColor = Color.white;
			inputStyle.focused.textColor = Color.white;
			inputStyle.wordWrap = false;
			inputStyle.clipping = (TextClipping)1;
			boxStyle = new GUIStyle(GUI.skin.box);
			boxStyle.normal.background = backgroundTex;
			headerStyle = new GUIStyle(GUI.skin.box);
			headerStyle.normal.background = headerTex;
			headerStyle.normal.textColor = Color.white;
			headerStyle.alignment = (TextAnchor)3;
			headerStyle.fontSize = 12;
			headerStyle.padding = new RectOffset(8, 8, 0, 0);
			resizeHandleStyle = new GUIStyle();
			resizeHandleStyle.normal.background = resizeTex;
			selectionTex = new Texture2D(1, 1);
			selectionTex.SetPixel(0, 0, new Color(0.3f, 0.5f, 0.8f, 0.5f));
			selectionTex.Apply();
			selectedLabelStyle = new GUIStyle(GUI.skin.label);
			selectedLabelStyle.normal.textColor = Color.white;
			selectedLabelStyle.normal.background = selectionTex;
			selectedLabelStyle.wordWrap = true;
			selectedLabelStyle.richText = true;
			selectedLabelStyle.clipping = (TextClipping)0;
			abovePlayerStyle = new GUIStyle();
			abovePlayerStyle.normal.textColor = Color.white;
			abovePlayerStyle.alignment = (TextAnchor)1;
			abovePlayerStyle.wordWrap = true;
			abovePlayerStyle.richText = true;
			stylesInitialized = true;
		}
		if (!fontsLoaded && Time.time - lastFontCheckTime > 1f)
		{
			lastFontCheckTime = Time.time;
			LoadFontsByName();
		}
		Font font = ((FontStyle.Value == ChatFontStyle.Necro) ? fontNecro : null);
		labelStyle.font = font;
		inputStyle.font = font;
		selectedLabelStyle.font = font;
		abovePlayerStyle.font = font;
		int fontSize = Mathf.Clamp(FontSize.Value, 20, 40);
		labelStyle.fontSize = fontSize;
		inputStyle.fontSize = fontSize;
		selectedLabelStyle.fontSize = fontSize;
	}

	private void LoadFontsByName()
	{
		try
		{
			Text[] array = Resources.FindObjectsOfTypeAll<Text>();
			Text[] array2 = array;
			foreach (Text val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.font == (Object)null) && (Object)(object)fontNecro == (Object)null && ((Object)val.font).name == "Nexa Slab Regular")
				{
					fontNecro = val.font;
					fontsLoaded = true;
					break;
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Error loading fonts: " + ex.Message));
		}
	}

	private bool HasRecentMessages()
	{
		if (messages.Count == 0)
		{
			return false;
		}
		if (MessageDisplayTime.Value <= 0 && MessageFadeTime.Value <= 0)
		{
			return true;
		}
		float num = MessageDisplayTime.Value + MessageFadeTime.Value;
		float num2 = Time.time - num;
		foreach (ChatMessage message in messages)
		{
			if (message.Timestamp >= num2)
			{
				return true;
			}
		}
		return false;
	}

	private void DrawChatWindow(float x, float y)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: 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_012a: Expected O, but got Unknown
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: 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_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Expected O, but got Unknown
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Expected O, but got Unknown
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_028d: Expected O, but got Unknown
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_051b: Unknown result type (might be due to invalid IL or missing references)
		//IL_052d: Unknown result type (might be due to invalid IL or missing references)
		//IL_053c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0541: Unknown result type (might be due to invalid IL or missing references)
		//IL_0546: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0474: Unknown result type (might be due to invalid IL or missing references)
		//IL_0486: Unknown result type (might be due to invalid IL or missing references)
		Event current = Event.current;
		float inputHeight = GetInputHeight();
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(x, y, chatWidth, 55f);
		Rect val2 = default(Rect);
		((Rect)(ref val2))..ctor(x + chatWidth - 24f, y + chatHeight - 24f, 24f, 24f);
		if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition) && !isResizing)
		{
			isDragging = true;
			dragOffset = current.mousePosition - windowPosition;
			current.Use();
		}
		if ((int)current.type == 0 && ((Rect)(ref val2)).Contains(current.mousePosition) && !isDragging)
		{
			isResizing = true;
			resizeStartPos = current.mousePosition;
			resizeStartSize = new Vector2(chatWidth, chatHeight);
			current.Use();
		}
		GUI.Box(new Rect(x, y, chatWidth, chatHeight), "", boxStyle);
		GUI.Box(val, "", headerStyle);
		GUIStyle val3 = new GUIStyle(headerStyle);
		val3.alignment = (TextAnchor)4;
		val3.fontSize = headerStyle.fontSize + 2;
		GUIStyle val4 = new GUIStyle(headerStyle);
		val4.alignment = (TextAnchor)1;
		val4.fontSize = headerStyle.fontSize;
		val4.wordWrap = true;
		if (showFullHistory)
		{
			GUI.Label(val, "<b>NECROCHAT HISTORY</b>", val3);
		}
		else if (IsInMultiplayerLobby())
		{
			GUI.Label(val, "<b>NECROCHAT LOBBY</b>", val3);
		}
		else
		{
			float num = 20f;
			Rect val5 = default(Rect);
			((Rect)(ref val5))..ctor(x, y, chatWidth, num);
			Rect val6 = default(Rect);
			((Rect)(ref val6))..ctor(x + 5f, y + num, chatWidth - 10f, 55f - num);
			GUI.Label(val5, string.Format("<b>NECROCHAT</b> v{0}", "1.0.1"), val3);
			GUI.Label(val6, "ENTER=Send, ESC=Close, Click=Select, Mouse-drag to resize/reposition", val4);
		}
		Color color = GUI.color;
		GUI.color = new Color(1f, 0.9f, 0f, 0.9f);
		GUIStyle val7 = new GUIStyle(GUI.skin.label);
		val7.fontSize = 20;
		val7.alignment = (TextAnchor)8;
		val7.padding = new RectOffset(0, 0, 0, 0);
		val7.margin = new RectOffset(0, 0, 0, 0);
		val7.normal.textColor = new Color(1f, 0.9f, 0f, 0.9f);
		Rect val8 = default(Rect);
		((Rect)(ref val8))..ctor(((Rect)(ref val2)).x + 2f, ((Rect)(ref val2)).y + 7f, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height);
		GUI.Label(val8, "◢", val7);
		GUI.color = color;
		float num2 = y + 55f + 5f;
		float num3 = (chatOpen ? (inputHeight + 20f) : 10f);
		float num4 = chatHeight - 55f - num3 - 5f;
		num4 = Mathf.Max(num4, 50f);
		float num5 = chatWidth - 30f - 20f;
		Rect val9 = default(Rect);
		((Rect)(ref val9))..ctor(x + 10f, num2, chatWidth - 20f, num4);
		float num6 = 0f;
		for (int i = 0; i < messages.Count; i++)
		{
			num6 += GetMessageHeight(messages[i], num5);
		}
		Rect val10 = default(Rect);
		((Rect)(ref val10))..ctor(0f, 0f, num5, num6);
		scrollPosition = GUI.BeginScrollView(val9, scrollPosition, val10);
		float num7 = 0f;
		Rect val11 = default(Rect);
		for (int i = 0; i < messages.Count; i++)
		{
			ChatMessage msg = messages[i];
			float messageHeight = GetMessageHeight(msg, num5);
			float messageAlpha = GetMessageAlpha(msg);
			if (messageAlpha > 0f || showFullHistory || chatOpen)
			{
				float alpha = ((showFullHistory || chatOpen) ? 1f : messageAlpha);
				bool isSelected = i == selectedMessageIndex;
				((Rect)(ref val11))..ctor(0f, num7, num5, messageHeight);
				if ((int)current.type == 0 && current.button == 0 && ((Rect)(ref val11)).Contains(current.mousePosition))
				{
					selectedMessageIndex = ((selectedMessageIndex == i) ? (-1) : i);
					current.Use();
				}
				DrawMessageLine(0f, num7, num5, messageHeight, msg, alpha, isSelected);
			}
			num7 += messageHeight;
		}
		GUI.EndScrollView();
		Rect val12 = default(Rect);
		((Rect)(ref val12))..ctor(0f, 0f, chatWidth, chatHeight);
		if ((int)current.type == 0 && current.button == 0 && !((Rect)(ref val9)).Contains(current.mousePosition) && ((Rect)(ref val12)).Contains(current.mousePosition - windowPosition))
		{
			selectedMessageIndex = -1;
		}
		if (chatOpen)
		{
			float num8 = y + chatHeight - inputHeight - 10f;
			GUI.SetNextControlName("ChatInputField");
			inputText = GUI.TextField(new Rect(x + 10f, num8, chatWidth - 20f, inputHeight), inputText, 100, inputStyle);
			if (inputText.IndexOf('\n') >= 0 || inputText.IndexOf('\r') >= 0)
			{
				inputText = inputText.Replace("\n", "").Replace("\r", "");
			}
			if (inputText.Length > 100)
			{
				inputText = inputText.Substring(0, 100);
			}
			GUI.FocusControl("ChatInputField");
		}
	}

	private void DrawRecentMessages(float x, float y)
	{
		DrawRecentMessagesFiltered(x, y, onlyFarPlayers: false);
	}

	private void DrawRecentMessagesFiltered(float x, float y, bool onlyFarPlayers)
	{
		List<ChatMessage> list = new List<ChatMessage>();
		float num = MessageDisplayTime.Value + MessageFadeTime.Value;
		float num2 = Time.time - num;
		foreach (ChatMessage message in messages)
		{
			if (message.Timestamp >= num2)
			{
				list.Add(message);
			}
		}
		if (list.Count == 0)
		{
			return;
		}
		HashSet<string> hashSet = new HashSet<string>();
		int num3 = Mathf.Clamp(MaxVisibleMessages.Value, 1, 20);
		float width = chatWidth - 20f;
		int num4 = Math.Max(0, list.Count - num3);
		float num5 = y + chatHeight - 10f;
		for (int num6 = list.Count - 1; num6 >= num4; num6--)
		{
			ChatMessage current = list[num6];
			if (onlyFarPlayers)
			{
				Actor val = FindActorByPlayerName(current.Sender);
				if ((Object)(object)val != (Object)null)
				{
					float distanceToCamera = GetDistanceToCamera(val);
					if (distanceToCamera <= (float)SmartModeDistance.Value)
					{
						sendersCurrentlyInCorner.Remove(current.Sender);
						senderCornerTransitionTime.Remove(current.Sender);
						continue;
					}
					hashSet.Add(current.Sender);
					if (!sendersCurrentlyInCorner.Contains(current.Sender))
					{
						sendersCurrentlyInCorner.Add(current.Sender);
						senderCornerTransitionTime[current.Sender] = Time.time;
					}
				}
			}
			float messageHeight = GetMessageHeight(current, width);
			float num7 = GetMessageAlpha(current);
			if (onlyFarPlayers && ChatBoxAnimations.Value && !string.IsNullOrEmpty(current.Sender) && senderCornerTransitionTime.TryGetValue(current.Sender, out var value))
			{
				float num8 = Time.time - value;
				if (num8 < 0.5f)
				{
					float num9 = num8 / 0.5f;
					num7 = Mathf.Min(num7, num9);
				}
			}
			if (num7 > 0f)
			{
				num5 -= messageHeight;
				DrawMessageWithShadow(x + 10f, num5, width, messageHeight, current, num7);
			}
		}
	}

	private void DrawMessageLine(float x, float y, float width, float height, ChatMessage msg, float alpha, bool isSelected = false)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		Color color = GUI.color;
		GUI.color = new Color(1f, 1f, 1f, alpha);
		string text = ((int)(alpha * 255f)).ToString("X2");
		string text2 = "";
		if (ShowTimestamps.Value)
		{
			text2 = string.Format("<color=#888888{0}>[{1}]</color> ", text, msg.RealTime.ToString("HH:mm"));
		}
		string text3;
		if (msg.IsSystemMessage)
		{
			text3 = $"{text2}<color=#{msg.SystemColor}{text}><b>{msg.Text}</b></color>";
		}
		else
		{
			string playerDyeColorHex = GetPlayerDyeColorHex(msg.Sender);
			text3 = ((!msg.IsAction) ? string.Format("{0}<color=#{1}{2}><b>{3}</b></color><color=#FFFFFF{2}>: {4}</color>", text2, playerDyeColorHex, text, msg.Sender, msg.Text) : $"{text2}<color=#7EC8E3{text}><b><i>*{msg.Sender} {msg.Text}*</i></b></color>");
		}
		GUIStyle val = (isSelected ? selectedLabelStyle : labelStyle);
		GUI.Label(new Rect(x, y, width, height), text3, val);
		GUI.color = color;
	}

	private void DrawMessageWithShadow(float x, float y, float width, float height, ChatMessage msg, float alpha)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: 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_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		Color color = GUI.color;
		string text = ((int)(alpha * 255f)).ToString("X2");
		string text2 = ((int)(alpha * 0.8f * 255f)).ToString("X2");
		string text3 = "";
		string text4 = "";
		if (ShowTimestamps.Value)
		{
			string arg = msg.RealTime.ToString("HH:mm");
			text3 = $"<color=#888888{text}>[{arg}]</color> ";
			text4 = $"<color=#000000{text2}>[{arg}]</color> ";
		}
		string text5;
		string text6;
		if (msg.IsSystemMessage)
		{
			text5 = $"{text4}<color=#000000{text2}><b>{msg.Text}</b></color>";
			text6 = $"{text3}<color=#{msg.SystemColor}{text}><b>{msg.Text}</b></color>";
		}
		else
		{
			string playerDyeColorHex = GetPlayerDyeColorHex(msg.Sender);
			if (msg.IsAction)
			{
				text5 = $"{text4}<color=#000000{text2}><b><i>*{msg.Sender} {msg.Text}*</i></b></color>";
				text6 = $"{text3}<color=#7EC8E3{text}><b><i>*{msg.Sender} {msg.Text}*</i></b></color>";
			}
			else
			{
				text5 = $"{text4}<color=#000000{text2}><b>{msg.Sender}</b>: {msg.Text}</color>";
				text6 = string.Format("{0}<color=#{1}{2}><b>{3}</b></color><color=#FFFFFF{2}>: {4}</color>", text3, playerDyeColorHex, text, msg.Sender, msg.Text);
			}
		}
		GUI.color = new Color(0f, 0f, 0f, alpha * 0.8f);
		GUI.Label(new Rect(x + 1f, y + 1f, width, height), text5, labelStyle);
		GUI.color = new Color(1f, 1f, 1f, alpha);
		GUI.Label(new Rect(x, y, width, height), text6, labelStyle);
		GUI.color = color;
	}

	private Actor FindActorByPlayerName(string playerName)
	{
		try
		{
			if (!LazySingletonBehavior<NetworkManager>.HasInstance)
			{
				return null;
			}
			NetworkManager val = LazySingletonBehavior<NetworkManager>.Instance;
			if (val.LocalVirtualCouchSeat != null && val.LocalVirtualCouchSeat.platformHandle != null && val.LocalVirtualCouchSeat.platformHandle.Name == playerName && ThirdPersonCameraControl.HasInstance && (Object)(object)ThirdPersonCameraControl.Instance.CharacterActor != (Object)null)
			{
				return ThirdPersonCameraControl.Instance.CharacterActor;
			}
			if (val.VirtualCouch != null)
			{
				foreach (VirtualCouchSeat item in val.VirtualCouch)
				{
					if (item != null && item.platformHandle != null && item.platformHandle.Name == playerName && (Object)(object)item.actor != (Object)null)
					{
						return item.actor;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private float GetDistanceToCamera(Actor actor)
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)actor == (Object)null || (Object)(object)actor.Body == (Object)null)
		{
			return float.MaxValue;
		}
		if (!ThirdPersonCameraControl.HasInstance)
		{
			return float.MaxValue;
		}
		Camera component = ((Component)ThirdPersonCameraControl.Instance).GetComponent<Camera>();
		if ((Object)(object)component == (Object)null)
		{
			return float.MaxValue;
		}
		return Vector3.Distance(((Component)component).transform.position, ((Component)actor.Body).transform.position);
	}

	private void DrawAbovePlayerMessages()
	{
		//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_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: 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)
		if (!ThirdPersonCameraControl.HasInstance)
		{
			return;
		}
		Camera component = ((Component)ThirdPersonCameraControl.Instance).GetComponent<Camera>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		ChatDisplayMode value = DisplayMode.Value;
		if (value == ChatDisplayMode.Basic)
		{
			return;
		}
		float num = AbovePlayerDisplayTime.Value;
		float num2 = AbovePlayerFadeTime.Value;
		float num3 = num + num2;
		Dictionary<string, List<ChatMessage>> dictionary = new Dictionary<string, List<ChatMessage>>();
		foreach (ChatMessage message in messages)
		{
			float num4 = Time.time - message.Timestamp;
			if (!(num4 > num3))
			{
				if (!dictionary.ContainsKey(message.Sender))
				{
					dictionary[message.Sender] = new List<ChatMessage>();
				}
				dictionary[message.Sender].Add(message);
			}
		}
		foreach (KeyValuePair<string, List<ChatMessage>> item in dictionary)
		{
			string key = item.Key;
			List<ChatMessage> value2 = item.Value;
			Actor val = FindActorByPlayerName(key);
			if ((Object)(object)val == (Object)null || (Object)(object)val.Body == (Object)null)
			{
				continue;
			}
			float distanceToCamera = GetDistanceToCamera(val);
			float num5 = 1f;
			if (value == ChatDisplayMode.Smart)
			{
				float num6 = SmartModeDistance.Value;
				float num7 = 5f;
				if (distanceToCamera > num6)
				{
					continue;
				}
				if (distanceToCamera > num6 - num7 && ChatBoxAnimations.Value)
				{
					num5 = (num6 - distanceToCamera) / num7;
				}
			}
			float num8 = 0f;
			if ((Object)(object)val.Body.thisController != (Object)null)
			{
				float num9 = ((val.actorDefId != null && val.actorDefId.StartsWith("Brute")) ? 1.1f : 0.95f);
				num8 = val.Body.thisController.height * num9;
			}
			Vector3 val2 = ((Component)val.Body).transform.position + new Vector3(0f, num8, 0f);
			Vector3 val3 = component.WorldToScreenPoint(val2);
			bool flag = val3.z < 0f;
			if (flag)
			{
				val3.x = (float)Screen.width - val3.x;
				val3.y = (float)Screen.height - val3.y;
			}
			bool flag2 = flag || val3.x < 50f || val3.x > (float)(Screen.width - 50) || val3.y < 50f || val3.y > (float)(Screen.height - 50);
			if (flag2 && distanceToCamera > (float)SmartModeDistance.Value)
			{
				continue;
			}
			if (flag2)
			{
				float num10 = (float)Screen.width / 2f;
				float num11 = (float)Screen.height / 2f;
				float num12 = val3.x - num10;
				float num13 = val3.y - num11;
				float num14 = Mathf.Abs(num12);
				float num15 = Mathf.Abs(num13);
				float num16 = 60f;
				if (num14 / ((float)Screen.width / 2f) > num15 / ((float)Screen.height / 2f))
				{
					float num17 = ((float)Screen.width / 2f - num16) / num14;
					val3.x = num10 + num12 * num17;
					val3.y = Mathf.Clamp(num11 + num13 * num17, num16, (float)Screen.height - num16);
				}
				else
				{
					float num17 = ((float)Screen.height / 2f - num16) / num15;
					val3.y = num11 + num13 * num17;
					val3.x = Mathf.Clamp(num10 + num12 * num17, num16, (float)Screen.width - num16);
				}
			}
			float num18 = (float)Screen.height - val3.y;
			if (HidePlayerNameOnChat.Value && (Object)(object)val.Body != (Object)null && SceneSingletonBehavior<HUDManager>.HasInstance)
			{
				HUDIndicator hUDIndicatorForActor = GetHUDIndicatorForActor(val);
				if ((Object)(object)hUDIndicatorForActor != (Object)null)
				{
					((Component)hUDIndicatorForActor).gameObject.SetActive(false);
					hiddenHUDIndicators.Add(val);
				}
			}
			float num19 = num18;
			for (int num20 = value2.Count - 1; num20 >= 0; num20--)
			{
				ChatMessage current = value2[num20];
				float num4 = Time.time - current.Timestamp;
				float num21 = 1f;
				float num22 = 1f;
				bool value3 = AbovePlayerAnimations.Value;
				if (value3 && num4 < 0.3f)
				{
					num21 = num4 / 0.3f;
					num22 = num21;
				}
				else if (num4 > num && num2 > 0f)
				{
					float num23 = (num4 - num) / num2;
					num21 = 1f - num23;
				}
				num21 *= num5;
				float num24 = (value3 ? ((1f - num22) * 25f) : 0f);
				float num25 = DrawAbovePlayerText(val3.x, num19 + num24, current, num21, flag2);
				float num26 = (value3 ? (num25 * num22) : num25);
				num19 -= num26 + (value3 ? (5f * num22) : 5f);
				if (num19 < 0f)
				{
					break;
				}
			}
		}
	}

	private HUDIndicator GetHUDIndicatorForActor(Actor actor)
	{
		try
		{
			if (!SceneSingletonBehavior<HUDManager>.HasInstance)
			{
				return null;
			}
			if ((Object)(object)actor == (Object)null || (Object)(object)actor.Body == (Object)null)
			{
				return null;
			}
			if ((object)trackedObjectsField == null)
			{
				trackedObjectsField = typeof(HUDManager).GetField("trackedObjects", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if ((object)trackedObjectsField == null)
			{
				return null;
			}
			HUDManager obj = SceneSingletonBehavior<HUDManager>.Instance;
			if (!(trackedObjectsField.GetValue(obj) is Dictionary<GameObject, HUDIndicator> dictionary))
			{
				return null;
			}
			if (dictionary.TryGetValue(((Component)actor.Body).gameObject, out var value))
			{
				return value;
			}
		}
		catch
		{
		}
		return null;
	}

	private string GetPlayerDyeColorHex(string playerName)
	{
		if (!UsePlayerDyeColors.Value)
		{
			return "ffcc00";
		}
		try
		{
			Actor val = FindActorByPlayerName(playerName);
			if ((Object)(object)val != (Object)null)
			{
				return GetActorDyeColor(val);
			}
		}
		catch
		{
		}
		return "ffcc00";
	}

	private Color GetPlayerDyeColor(Actor actor)
	{
		//IL_0105: 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)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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_00d1: 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)
		Color result = default(Color);
		((Color)(ref result))..ctor(1f, 0.84f, 0f);
		if ((Object)(object)actor == (Object)null || (Object)(object)actor.Body == (Object)null)
		{
			return result;
		}
		try
		{
			if (actor.Body.bodyRenderers != null && actor.Body.bodyRenderers.Count > 0)
			{
				foreach (Renderer bodyRenderer in actor.Body.bodyRenderers)
				{
					if ((Object)(object)bodyRenderer != (Object)null && (Object)(object)bodyRenderer.material != (Object)null && bodyRenderer.material.HasProperty("_SecondaryColor"))
					{
						return bodyRenderer.material.GetColor("_SecondaryColor");
					}
				}
			}
		}
		catch
		{
		}
		return result;
	}

	private string GetActorDyeColor(Actor actor)
	{
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)actor == (Object)null || (Object)(object)actor.Body == (Object)null)
			{
				return "ffcc00";
			}
			if (actor.Body.bodyRenderers != null && actor.Body.bodyRenderers.Count > 0)
			{
				foreach (Renderer bodyRenderer in actor.Body.bodyRenderers)
				{
					if ((Object)(object)bodyRenderer != (Object)null && (Object)(object)bodyRenderer.material != (Object)null && bodyRenderer.material.HasProperty("_SecondaryColor"))
					{
						Color color = bodyRenderer.material.GetColor("_SecondaryColor");
						return ColorToHex(color);
					}
				}
			}
			Inventory val = Inventory.Get(((Component)actor.Body).gameObject, true);
			if ((Object)(object)val != (Object)null && val.HasColorSet)
			{
				string activeColorSet = val.ActiveColorSet;
				if (!string.IsNullOrEmpty(activeColorSet))
				{
					ColorPaletteDef palette = ColorPaletteApplicator.GetPalette(activeColorSet);
					if (palette != null && palette.colors != null && palette.colorPropertyNames != null)
					{
						for (int i = 0; i < palette.colorPropertyNames.Length; i++)
						{
							if (palette.colorPropertyNames[i] == "_SecondaryColor")
							{
								return ColorToHex(palette.colors[i]);
							}
						}
					}
				}
			}
		}
		catch
		{
		}
		return "ffcc00";
	}

	private string ColorToHex(Color color)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		float num = default(float);
		float num2 = default(float);
		float num3 = default(float);
		Color.RGBToHSV(color, ref num, ref num2, ref num3);
		if (num3 < 0.75f)
		{
			num3 = 0.75f + num3 * 0.25f;
		}
		if (num2 > 0.7f)
		{
			num2 *= 0.8f;
		}
		Color val = Color.HSVToRGB(num, num2, num3);
		int num4 = (int)(val.r * 255f);
		int num5 = (int)(val.g * 255f);
		int num6 = (int)(val.b * 255f);
		return $"{num4:X2}{num5:X2}{num6:X2}";
	}

	private string GetActorDisplayName(Actor actor)
	{
		try
		{
			if ((Object)(object)actor == (Object)null)
			{
				return "";
			}
			if (actor.Possessor != null && actor.Possessor.platformHandle != null && !string.IsNullOrEmpty(actor.Possessor.platformHandle.Name))
			{
				return actor.Possessor.platformHandle.Name;
			}
		}
		catch
		{
		}
		return "";
	}

	private float DrawAbovePlayerText(float x, float y, ChatMessage msg, float alpha, bool showSender = false)
	{
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Expected O, but got Unknown
		//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0409: Unknown result type (might be due to invalid IL or missing references)
		//IL_0418: Unknown result type (might be due to invalid IL or missing references)
		string text = ((int)(alpha * 255f)).ToString("X2");
		string arg = ((int)(alpha * 0.8f * 255f)).ToString("X2");
		float num = AbovePlayerWidth.Value;
		int num2 = 0;
		bool value = ColorAbovePlayerMessage.Value;
		string text2 = ((!showSender || value) ? (msg.IsAction ? $"*{msg.Text}*" : msg.Text) : (msg.IsAction ? $"*{msg.Sender} {msg.Text}*" : $"{msg.Sender}: {msg.Text}"));
		int value2 = AbovePlayerFontSize.Value;
		int num3 = 10;
		int num4 = value2;
		GUIStyle val = abovePlayerStyle;
		float num5 = num;
		float num6 = 0f;
		int num7 = ((num2 > 0) ? Mathf.Max(1, num2 / (value2 + 4)) : 6);
		GUIContent val2 = new GUIContent(text2);
		while (num4 >= num3)
		{
			val.fontSize = num4;
			num6 = val.CalcHeight(val2, num);
			float num8 = (float)num4 + 4f;
			int num9 = Mathf.CeilToInt(num6 / num8);
			bool flag = num2 <= 0 || num6 <= (float)num2;
			bool flag2 = num9 <= num7;
			if (flag && flag2)
			{
				break;
			}
			num4 -= 2;
		}
		if (num4 < num3)
		{
			num4 = num3;
		}
		val.fontSize = num4;
		num6 = val.CalcHeight(val2, num);
		if (num2 > 0)
		{
			num6 = Mathf.Min(num6, (float)num2);
		}
		string playerDyeColorHex = GetPlayerDyeColorHex(msg.Sender);
		string text3;
		string text4;
		if (msg.IsAction)
		{
			if (value)
			{
				text3 = $"<color=#{playerDyeColorHex}{text}><b><i>*{msg.Text}*</i></b></color>";
				text4 = $"<color=#000000{arg}><b><i>*{msg.Text}*</i></b></color>";
			}
			else if (showSender)
			{
				text3 = $"<color=#7EC8E3{text}><b><i>*{msg.Sender} {msg.Text}*</i></b></color>";
				text4 = $"<color=#000000{arg}><b><i>*{msg.Sender} {msg.Text}*</i></b></color>";
			}
			else
			{
				text3 = $"<color=#7EC8E3{text}><b><i>*{msg.Text}*</i></b></color>";
				text4 = $"<color=#000000{arg}><b><i>*{msg.Text}*</i></b></color>";
			}
		}
		else if (value)
		{
			text3 = $"<color=#{playerDyeColorHex}{text}>{msg.Text}</color>";
			text4 = $"<color=#000000{arg}>{msg.Text}</color>";
		}
		else if (showSender)
		{
			text3 = string.Format("<color=#{0}{1}><b>{2}</b></color><color=#FFFFFF{1}>: {3}</color>", playerDyeColorHex, text, msg.Sender, msg.Text);
			text4 = $"<color=#000000{arg}><b>{msg.Sender}</b>: {msg.Text}</color>";
		}
		else
		{
			text3 = $"<color=#FFFFFF{text}>{msg.Text}</color>";
			text4 = $"<color=#000000{arg}>{msg.Text}</color>";
		}
		float num10 = x - num5 / 2f;
		float num11 = y - num6;
		if (num10 < 5f)
		{
			num10 = 5f;
		}
		if (num10 + num5 > (float)(Screen.width - 5))
		{
			num10 = (float)Screen.width - num5 - 5f;
		}
		GUI.color = new Color(0f, 0f, 0f, alpha * 0.8f);
		GUI.Label(new Rect(num10 + 1f, num11 + 1f, num5, num6), text4, val);
		GUI.color = new Color(1f, 1f, 1f, alpha);
		GUI.Label(new Rect(num10, num11, num5, num6), text3, val);
		GUI.color = Color.white;
		return num6;
	}

	private float GetMessageAlpha(ChatMessage msg)
	{
		int value = MessageDisplayTime.Value;
		int value2 = MessageFadeTime.Value;
		if (value <= 0 && value2 <= 0)
		{
			return 1f;
		}
		float num = Time.time - msg.Timestamp;
		if (ChatBoxAnimations.Value && num < 0.5f)
		{
			return num / 0.5f;
		}
		if (num < (float)value)
		{
			return 1f;
		}
		if (value2 > 0 && num < (float)(value + value2))
		{
			float num2 = (num - (float)value) / (float)value2;
			return 1f - num2;
		}
		return 0f;
	}

	private void OnDestroy()
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		RestoreAllHUDIndicators();
		UnregisterGameEventCallbacks();
		subscribedActors.Clear();
		actorHadAutoResurrect.Clear();
		actorDidSpawnReset.Clear();
		lastReviveTime.Clear();
		lastJoinLeaveTime.Clear();
		if (chatOpen)
		{
			if (LazySingletonBehavior<EventSystemObjectHandler>.HasInstance)
			{
				LazySingletonBehavior<EventSystemObjectHandler>.Instance.SetInputDisabled(false);
			}
			if (SceneSingletonBehavior<NecroKeyboardManager>.HasInstance)
			{
				SceneSingletonBehavior<NecroKeyboardManager>.Instance.SetProfileState(previousMouseState);
			}
		}
		if (ObjectDataRouter.Singleton != null)
		{
			ObjectDataRouter.Singleton.Unregister((ObjectDataReceiver)(object)this);
		}
		instance = null;
		if ((Object)(object)backgroundTex != (Object)null)
		{
			Object.Destroy((Object)(object)backgroundTex);
		}
		if ((Object)(object)headerTex != (Object)null)
		{
			Object.Destroy((Object)(object)headerTex);
		}
		if ((Object)(object)resizeTex != (Object)null)
		{
			Object.Destroy((Object)(object)resizeTex);
		}
		if ((Object)(object)selectionTex != (Object)null)
		{
			Object.Destroy((Object)(object)selectionTex);
		}
	}
}
public class ChatMessage
{
	public string Sender { get; private set; }

	public string Text { get; private set; }

	public float Timestamp { get; private set; }

	public DateTime RealTime { get; private set; }

	public bool IsAction { get; private set; }

	public bool IsSystemMessage { get; private set; }

	public string SystemColor { get; private set; }

	public ChatMessage(string sender, string text, float timestamp, bool isAction = false)
	{
		Sender = sender;
		Text = text;
		Timestamp = timestamp;
		RealTime = DateTime.Now;
		IsAction = isAction;
		IsSystemMessage = false;
		SystemColor = null;
	}

	public ChatMessage(string text, float timestamp, string color)
	{
		Sender = "";
		Text = text;
		Timestamp = timestamp;
		RealTime = DateTime.Now;
		IsAction = false;
		IsSystemMessage = true;
		SystemColor = color;
	}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class ModalDialogController_IsShowing_Patch
{
	private static void Postfix(ref bool __result)
	{
		if (ChatModPlugin.chatOpen)
		{
			__result = true;
		}
	}
}
[HarmonyPatch(typeof(Platform), "GetKeyDown")]
internal static class Platform_GetKeyDown_Patch
{
	private static bool Prefix(KeyCode code, ref bool __result)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Invalid comparison between Unknown and I4
		if (ChatModPlugin.chatOpen)
		{
			__result = false;
			return false;
		}
		if (ChatModPlugin.IsInMultiplayerLobby() && ((int)code == 13 || (int)code == 271))
		{
			__result = false;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Input), "GetKeyDown", new Type[] { typeof(KeyCode) })]
internal static class Input_GetKeyDown_Patch
{
	private static bool Prefix(KeyCode key, ref bool __result)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Invalid comparison between Unknown and I4
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Invalid comparison between Unknown and I4
		if (ChatModPlugin.IsInMultiplayerLobby() && ((int)key == 13 || (int)key == 271))
		{
			__result = false;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Input), "GetKey", new Type[] { typeof(KeyCode) })]
internal static class Input_GetKey_Patch
{
	private static bool Prefix(KeyCode key, ref bool __result)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Invalid comparison between Unknown and I4
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Invalid comparison between Unknown and I4
		if (ChatModPlugin.IsInMultiplayerLobby() && ((int)key == 13 || (int)key == 271))
		{
			__result = false;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Input), "GetKeyDown", new Type[] { typeof(string) })]
internal static class Input_GetKeyDown_String_Patch
{
	private static bool Prefix(string name, ref bool __result)
	{
		if (ChatModPlugin.IsInMultiplayerLobby() && (name == "return" || name == "enter"))
		{
			__result = false;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Input), "GetKey", new Type[] { typeof(string) })]
internal static class Input_GetKey_String_Patch
{
	private static bool Prefix(string name, ref bool __result)
	{
		if (ChatModPlugin.IsInMultiplayerLobby() && (name == "return" || name == "enter"))
		{
			__result = false;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Input), "GetButtonDown", new Type[] { typeof(string) })]
internal static class Input_GetButtonDown_Patch
{
	private static bool Prefix(string buttonName, ref bool __result)
	{
		if (ChatModPlugin.IsInMultiplayerLobby() && buttonName == "Submit")
		{
			__result = false;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(RxResurrect), "Activate")]
internal static class RxResurrect_Activate_Patch
{
	private static void Prefix(RxResurrect __instance, bool val)
	{
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		if (!val || (Object)(object)__instance.actor == (Object)null || __instance.actor.IsAlive)
		{
			return;
		}
		try
		{
			if (!LazySingletonBehavior<NetworkManager>.HasInstance)
			{
				return;
			}
			NetworkManager instance = LazySingletonBehavior<NetworkManager>.Instance;
			Actor lastReviver = null;
			float num = float.MaxValue;
			if (ThirdPersonCameraControl.HasInstance && (Object)(object)ThirdPersonCameraControl.Instance.CharacterActor != (Object)null)
			{
				Actor characterActor = ThirdPersonCameraControl.Instance.CharacterActor;
				if (characterActor.IsAlive && (Object)(object)characterActor != (Object)(object)__instance.actor)
				{
					float num2 = Vector3.Distance(characterActor.Position, __instance.actor.Position);
					if (num2 < num && num2 < 5f)
					{
						num = num2;
						lastReviver = characterActor;
					}
				}
			}
			if (instance.VirtualCouch != null)
			{
				foreach (VirtualCouchSeat item in instance.VirtualCouch)
				{
					if (item != null && !((Object)(object)item.actor == (Object)null) && item.actor.IsAlive && !((Object)(object)item.actor == (Object)(object)__instance.actor))
					{
						float num2 = Vector3.Distance(item.actor.Position, __instance.actor.Position);
						if (num2 < num && num2 < 5f)
						{
							num = num2;
							lastReviver = item.actor;
						}
					}
				}
			}
			ChatModPlugin.lastReviver = lastReviver;
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Actor), "SpawnReset", new Type[]
{
	typeof(Vector3),
	typeof(Quaternion)
})]
internal static class Actor_SpawnReset_Patch
{
	private static void Prefix(Actor __instance)
	{
		if ((Object)(object)__instance != (Object)null && __instance.IsPlayer)
		{
			ChatModPlugin.OnActorSpawnReset(__instance);
		}
	}
}
[HarmonyPatch(typeof(ConsoleCommands), "ToastRandomConvo")]
internal static class ConsoleCommands_ToastRandomConvo_Patch
{
	private static void Postfix(string convoID)
	{
		if (convoID == "OneHitKillProtection" && ThirdPersonCameraControl.HasInstance && (Object)(object)ThirdPersonCameraControl.Instance.CharacterActor != (Object)null)
		{
			ChatModPlugin.OnOneHitProtection(ThirdPersonCameraControl.Instance.CharacterActor);
		}
	}
}