Decompiled source of FastSwitchPlayerViewInRadar v1.3.2

LethalCompanyMonitorMod.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyMonitorMod.ConfigModel;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalCompanyMonitorMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A plugin that let's you fast switch to a player's cam while using the radar built in the in-game Terminal")]
[assembly: AssemblyFileVersion("1.3.1.0")]
[assembly: AssemblyInformationalVersion("1.3.1+bdf35e35c47b7a9ad5bdf05f759ed0c6f1cc349d")]
[assembly: AssemblyProduct("LethalCompanyMonitorMod")]
[assembly: AssemblyTitle("LethalCompanyMonitorMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalCompanyMonitorMod
{
	public class Configs
	{
		public static readonly ConfigModel<Key> PreviousPlayerCam = new ConfigModel<Key>((Key)61, "Get previous player's cam", "PrevPCam", "HotKeys");

		public static readonly ConfigModel<Key> NextPlayerCam = new ConfigModel<Key>((Key)62, "Get next player's cam", "NextPCam", "HotKeys");

		public static readonly ConfigModel<Key>[] AllBinds = new ConfigModel<Key>[2] { PreviousPlayerCam, NextPlayerCam };
	}
	[BepInPlugin("krystall9.FastSwitchPlayerViewInRadar", "FastSwitchPlayerViewInRadar", "1.3.1")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal static InputActionAsset Asset;

		internal static string keyMappingPath = Application.persistentDataPath + "/switch_radar_cam.txt";

		internal static Dictionary<string, string> defaultKeys = new Dictionary<string, string>();

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static bool ViewMonitorSubmitted { get; set; } = false;


		internal static int CurrentlyViewingPlayer { get; set; } = 0;


		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			defaultKeys.Add("Previous Cam", "/Keyboard/LeftArrow");
			defaultKeys.Add("Next Cam", "/Keyboard/RightArrow");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"krystall9.FastSwitchPlayerViewInRadar plugin has been loaded!");
		}

		public static void SetAsset(string previousCam, string nextCam)
		{
			Asset = InputActionAsset.FromJson("\r\n                {\r\n                    \"maps\" : [\r\n                        {\r\n                            \"name\" : \"FastSwitchPlayerViewInRadar\",\r\n                            \"actions\": [\r\n                                {\"name\": \"Previous Cam\", \"type\" : \"button\"},\r\n                            {\"name\": \"Next Cam\", \"type\" : \"button\"}\r\n                            ],\r\n                            \"bindings\" : [\r\n                                {\"path\" : \"" + previousCam + "\", \"action\": \"Previous Cam\"},\r\n                            {\"path\" : \"" + nextCam + "\", \"action\": \"Next Cam\"}\r\n                            ]\r\n                        }\r\n                    ]\r\n                }");
		}
	}
	public static class PluginStaticInfo
	{
		public const string PLUGIN_GUID = "krystall9.FastSwitchPlayerViewInRadar";

		public const string PLUGIN_NAME = "FastSwitchPlayerViewInRadar";

		public const string PLUGIN_VERSION = "1.3.1";
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalCompanyMonitorMod";

		public const string PLUGIN_NAME = "LethalCompanyMonitorMod";

		public const string PLUGIN_VERSION = "1.3.1";
	}
}
namespace LethalCompanyMonitorMod.Patch
{
	[HarmonyPatch(typeof(IngamePlayerSettings))]
	public class IngamePlayerSettingsPatch
	{
		[HarmonyPatch("CompleteRebind")]
		[HarmonyPrefix]
		public static void Rebind(IngamePlayerSettings __instance)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			string name = __instance.rebindingOperation.action.name;
			Plugin.Log.LogInfo((object)("Method - Rebind | Rebinding " + name));
			if (!(name == "Previous Cam"))
			{
				if (name == "Next Cam")
				{
					string text = File.ReadAllText(Plugin.keyMappingPath);
					string contents = text.Trim().Split('\n')[0] + "\n" + __instance.rebindingOperation.action.controls[0].path;
					File.WriteAllText(Plugin.keyMappingPath, contents);
				}
			}
			else
			{
				string text = File.ReadAllText(Plugin.keyMappingPath);
				string contents = __instance.rebindingOperation.action.controls[0].path + "\n" + text.Trim().Split('\n')[1];
				File.WriteAllText(Plugin.keyMappingPath, contents);
			}
			if (File.Exists(Plugin.keyMappingPath))
			{
				string text = File.ReadAllText(Plugin.keyMappingPath);
				string previousCam = text.Trim().Split('\n')[0];
				string nextCam = text.Trim().Split('\n')[1];
				Plugin.SetAsset(previousCam, nextCam);
			}
			else
			{
				Plugin.SetAsset(Plugin.defaultKeys["Previous Cam"], Plugin.defaultKeys["Next Cam"]);
			}
		}
	}
	[HarmonyPatch(typeof(KepRemapPanel))]
	public class KeyRemapPanelPatch
	{
		[HarmonyPatch("LoadKeybindsUI")]
		[HarmonyPrefix]
		public static void LoadBindings(ref KepRemapPanel __instance)
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			List<string> list = new List<string>();
			if (!File.Exists(Plugin.keyMappingPath))
			{
				string contents = Plugin.defaultKeys["Previous Cam"] + "\n" + Plugin.defaultKeys["Next Cam"];
				File.WriteAllText(Plugin.keyMappingPath, contents);
			}
			else
			{
				string contents = File.ReadAllText(Plugin.keyMappingPath);
				list = contents.Trim().Split('\n').ToList();
			}
			foreach (RemappableKey remappableKey in __instance.remappableKeys)
			{
				if (remappableKey.ControlName == "Radar Previous Cam" || remappableKey.ControlName == "Radar Next Cam")
				{
					return;
				}
			}
			if (list.Count > 0)
			{
				Plugin.SetAsset(list[0], list[1]);
			}
			else
			{
				Plugin.SetAsset(Plugin.defaultKeys["Previous Cam"], Plugin.defaultKeys["Next Cam"]);
			}
			foreach (KeyValuePair<string, string> defaultKey in Plugin.defaultKeys)
			{
				RemappableKey val = new RemappableKey();
				Plugin.Log.LogInfo((object)("Method - LoadBindings | Loading Keybindings for " + defaultKey.Key));
				string key = defaultKey.Key;
				if (!(key == "Previous Cam"))
				{
					if (key == "Next Cam")
					{
						InputActionReference currentInput = InputActionReference.Create(Plugin.Asset.FindAction(defaultKey.Key, false));
						val.ControlName = "Radar Next Cam";
						val.currentInput = currentInput;
					}
				}
				else
				{
					InputActionReference currentInput = InputActionReference.Create(Plugin.Asset.FindAction(defaultKey.Key, false));
					val.ControlName = "Radar Previous Cam";
					val.currentInput = currentInput;
				}
				__instance.remappableKeys.Add(val);
			}
		}
	}
	[HarmonyPatch(typeof(RadarBoosterItem))]
	public class RadarBoosterPatch
	{
		[HarmonyPatch("RemoveBoosterFromRadar")]
		[HarmonyPostfix]
		public static void RemovingUnusedRadar(ref RadarBoosterItem __instance)
		{
			ManualCameraRenderer mapScreen = Object.FindObjectOfType<StartOfRound>().mapScreen;
			Plugin.Log.LogInfo((object)("Method - RemovingUnusedRadar | Current cam target name: " + __instance.radarBoosterName));
			Plugin.Log.LogInfo((object)("Method - RemovingUnusedRadar | " + __instance.radarBoosterName + " removed"));
			Plugin.Log.LogInfo((object)"Method - RemovingUnusedRadar | Updating camera target");
			for (int i = 0; i < mapScreen.radarTargets.Count; i++)
			{
				if (mapScreen.radarTargets.Count <= Plugin.CurrentlyViewingPlayer || mapScreen.radarTargets[Plugin.CurrentlyViewingPlayer] == null)
				{
					Plugin.CurrentlyViewingPlayer = i;
					continue;
				}
				mapScreen.SwitchRadarTargetAndSync(Plugin.CurrentlyViewingPlayer);
				Plugin.Log.LogInfo((object)("Method - RemovingUnusedRadar | Currently targeting " + mapScreen.radarTargets[Plugin.CurrentlyViewingPlayer].name));
				break;
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public class TerminalPatch
	{
		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPostfix]
		private static void HandleSentence(Terminal __instance, TerminalNode __result)
		{
			if (!((Object)(object)__result == (Object)null) && __instance.terminalInUse && !Plugin.ViewMonitorSubmitted && string.Compare(((Object)__result).name, "ViewInsideShipCam 1", ignoreCase: true) == 0)
			{
				Plugin.ViewMonitorSubmitted = true;
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void HandleTerminalCameraNode(Terminal __instance)
		{
			if (!__instance.terminalInUse)
			{
				return;
			}
			List<string> list = new List<string>();
			if (File.Exists(Plugin.keyMappingPath))
			{
				list = File.ReadAllText(Plugin.keyMappingPath).Trim().Split('\n')
					.ToList();
			}
			if ((Object)(object)Plugin.Asset == (Object)null || !Plugin.Asset.enabled)
			{
				if ((Object)(object)Plugin.Asset == (Object)null)
				{
					Plugin.Log.LogInfo((object)"Method - HandleTerminalCameraNode | InputActionAsset not yet created");
					if (File.Exists(Plugin.keyMappingPath))
					{
						Plugin.SetAsset(list[0], list[1]);
					}
					else
					{
						Plugin.SetAsset(Plugin.defaultKeys["Previous Cam"], Plugin.defaultKeys["Next Cam"]);
					}
					Plugin.Log.LogInfo((object)"Method - HandleTerminalCameraNode | InputActionAsset created successfully");
				}
				if ((Object)(object)Plugin.Asset != (Object)null)
				{
					Plugin.Log.LogInfo((object)"Method - HandleTerminalCameraNode | InputActionAsset not yet enabled");
					Plugin.Asset.Enable();
					Plugin.Log.LogInfo((object)"Method - HandleTerminalCameraNode | InputActionAsset enabled successfully");
				}
			}
			if (!Plugin.ViewMonitorSubmitted)
			{
				return;
			}
			try
			{
				InputAction val = ((IEnumerable<InputAction>)Plugin.Asset).Where((InputAction x) => x.WasPressedThisFrame()).FirstOrDefault();
				if (val == null && val == null)
				{
					return;
				}
				int num = Plugin.CurrentlyViewingPlayer;
				ManualCameraRenderer mapScreen = Object.FindObjectOfType<StartOfRound>().mapScreen;
				int count = mapScreen.radarTargets.Count;
				Plugin.Log.LogInfo((object)$"Method - HandleTerminalCameraNode | Currently Max Spectable Players: {count}");
				PlayerControllerB val2 = null;
				RadarBoosterItem val3 = null;
				for (int i = 0; i < mapScreen.radarTargets.Count; i++)
				{
					string name = val.name;
					if (!(name == "Previous Cam"))
					{
						if (name == "Next Cam")
						{
							num = GetRadarTargetIndex(num, mapScreen.radarTargets.Count, isIndexPlusOne: true);
							Plugin.Log.LogInfo((object)$"Method - HandleTerminalCameraNode | Current Index: {num}");
						}
					}
					else
					{
						num = GetRadarTargetIndex(num, mapScreen.radarTargets.Count);
						Plugin.Log.LogInfo((object)$"Method - HandleTerminalCameraNode | Current Index: {num}");
					}
					if (mapScreen.radarTargets[num] == null)
					{
						Plugin.Log.LogInfo((object)$"Method - HandleTerminalCameraNode | The player at the Index: {num} cannot be spectated. Getting the next player");
						continue;
					}
					GameObject gameObject = ((Component)mapScreen.radarTargets[num].transform).gameObject;
					gameObject.TryGetComponent<PlayerControllerB>(ref val2);
					if ((Object)(object)val2 != (Object)null && (val2.isPlayerControlled || val2.isPlayerDead))
					{
						break;
					}
					if ((Object)(object)val2 == (Object)null || !val2.isPlayerControlled)
					{
						gameObject.TryGetComponent<RadarBoosterItem>(ref val3);
						if ((Object)(object)val3 != (Object)null && val3.radarEnabled)
						{
							break;
						}
					}
				}
				if (count > num && mapScreen.radarTargets[num] != null)
				{
					string text = "";
					text = ((!((Object)(object)val3 != (Object)null)) ? val2.playerUsername : val3.radarBoosterName);
					Plugin.Log.LogInfo((object)("Method - HandleTerminalCameraNode | Switching cam to " + text));
					mapScreen.SwitchRadarTargetAndSync(num);
				}
				Plugin.CurrentlyViewingPlayer = num;
				val2 = null;
				val3 = null;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogInfo((object)("Method - HandleTerminalCameraNode| Error: " + ex.Message));
			}
		}

		public static int GetRadarTargetIndex(int index, int loopableItemsCount, bool isIndexPlusOne = false)
		{
			if (isIndexPlusOne)
			{
				return (index < loopableItemsCount - 1) ? (index + 1) : 0;
			}
			return (index > 0) ? (index - 1) : (loopableItemsCount - 1);
		}
	}
}
namespace LethalCompanyMonitorMod.ConfigModel
{
	public class ConfigModel<T>
	{
		public T DefaultValue { get; set; }

		public string Description { get; set; }

		public string Key { get; set; }

		public string Section { get; set; }

		public ConfigEntry<T> ConfigEntry { get; set; }

		public ConfigModel(T defaultValue, string description, string key, string section)
		{
			DefaultValue = defaultValue;
			Description = description;
			Key = key;
			Section = section;
		}
	}
}