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