using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using LethalCompanyInputUtils.Api; using LethalCompanyInputUtils.Data; using LethalCompanyInputUtils.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; [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("LethalCompanyInputUtils")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+454418a17b73c2ade80cc578dea969d78d72d114")] [assembly: AssemblyProduct("LethalCompanyInputUtils")] [assembly: AssemblyTitle("LethalCompanyInputUtils")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 LethalCompanyInputUtils { public static class LcInputActionApi { private static readonly Dictionary InputActionsMap = new Dictionary(); private static IReadOnlyCollection InputActions => InputActionsMap.Values; internal static void LoadIntoUI(KepRemapPanel panel) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown List remappableKeys = panel.remappableKeys; int num = remappableKeys.Count((RemappableKey key) => !key.gamepadOnly); foreach (LcInputActions inputAction in InputActions) { if (inputAction.Loaded) { continue; } foreach (InputActionReference actionRef in inputAction.ActionRefs) { InputBinding val = ((IEnumerable)(object)actionRef.action.bindings).First(); string name = ((InputBinding)(ref val)).name; RemappableKey item = new RemappableKey { ControlName = name, currentInput = actionRef, gamepadOnly = false }; remappableKeys.Insert(num++, item); RemappableKey item2 = new RemappableKey { ControlName = name, currentInput = actionRef, rebindingIndex = 1, gamepadOnly = true }; remappableKeys.Add(item2); } inputAction.Loaded = true; } float horizontalOffset = panel.horizontalOffset; Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent().rect; float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset); panel.maxVertical = (float)num / num2; } internal static void CalculateVerticalMaxForGamepad(KepRemapPanel panel) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) int num = panel.remappableKeys.Count((RemappableKey key) => key.gamepadOnly); float horizontalOffset = panel.horizontalOffset; Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent().rect; float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset); panel.maxVertical = (float)num / num2; } internal static void ResetLoadedInputActions() { foreach (LcInputActions inputAction in InputActions) { inputAction.Loaded = false; } } internal static void RegisterInputActions(LcInputActions lcInputActions, InputActionMapBuilder builder) { if (!InputActionsMap.TryAdd(lcInputActions.Id, lcInputActions)) { Logging.Logger.LogWarning((object)("The mod [" + lcInputActions.Plugin.GUID + "] instantiated an Actions class [" + lcInputActions.GetType().Name + "] more than once!\n\t These classes should be treated as singletons!, do not instantiate more than once!")); } else { lcInputActions.CreateInputActions(in builder); InputActionSetupExtensions.AddActionMap(lcInputActions.GetAsset(), builder.Build()); lcInputActions.GetAsset().Enable(); lcInputActions.OnAssetLoaded(); lcInputActions.Load(); lcInputActions.BuildActionRefs(); } } internal static void DisableForRebind() { foreach (LcInputActions inputAction in InputActions) { if (inputAction.Enabled) { inputAction.Disable(); } } } internal static void ReEnableFromRebind() { foreach (LcInputActions inputAction in InputActions) { if (inputAction.WasEnabled) { inputAction.Enable(); } } } internal static void SaveOverrides() { foreach (LcInputActions inputAction in InputActions) { inputAction.Save(); } } } [BepInPlugin("com.rune580.LethalCompanyInputUtils", "Lethal Company Input Utils", "0.4.1")] public class LethalCompanyInputUtilsPlugin : BaseUnityPlugin { public const string ModId = "com.rune580.LethalCompanyInputUtils"; public const string ModName = "Lethal Company Input Utils"; public const string ModVersion = "0.4.1"; private Harmony? _harmony; private void Awake() { Logging.SetLogSource(((BaseUnityPlugin)this).Logger); _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.rune580.LethalCompanyInputUtils"); SceneManager.activeSceneChanged += OnSceneChanged; FsUtils.EnsureControlsDir(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.rune580.LethalCompanyInputUtils is loaded!"); } private static void OnSceneChanged(Scene current, Scene next) { LcInputActionApi.ResetLoadedInputActions(); } } } namespace LethalCompanyInputUtils.Utils { internal static class AssemblyUtils { public static BepInPlugin? GetBepInPlugin(this Assembly assembly) { Type[] exportedTypes = assembly.GetExportedTypes(); for (int i = 0; i < exportedTypes.Length; i++) { BepInPlugin customAttribute = ((MemberInfo)exportedTypes[i]).GetCustomAttribute(); if (customAttribute != null) { return customAttribute; } } return null; } } internal static class FsUtils { public static string SaveDir { get; } = GetSaveDir(); public static string Pre041ControlsDir { get; } = Path.Combine(Paths.BepInExRootPath, "controls"); public static string ControlsDir { get; } = Path.Combine(Paths.ConfigPath, "controls"); private static string GetSaveDir() { string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); return Path.Combine(folderPath, "AppData", "LocalLow", "ZeekerssRBLX", "Lethal Company"); } public static void EnsureControlsDir() { if (!Directory.Exists(ControlsDir)) { Directory.CreateDirectory(ControlsDir); } } } internal static class Logging { private static ManualLogSource? _logSource; internal static ManualLogSource Logger { get; } = _logSource; internal static void SetLogSource(ManualLogSource logSource) { _logSource = logSource; } } } namespace LethalCompanyInputUtils.Patches { public static class KeyRemapPanelPatches { [HarmonyPatch(typeof(KepRemapPanel), "LoadKeybindsUI")] public static class LoadKeybindsUIPatch { public static void Prefix(KepRemapPanel __instance) { LcInputActionApi.DisableForRebind(); LcInputActionApi.LoadIntoUI(__instance); } public static IEnumerable Transpiler(IEnumerable instructions) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); FieldInfo maxVerticalField = AccessTools.Field(typeof(KepRemapPanel), "maxVertical"); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6] { new CodeMatch((Func)((CodeInstruction code) => CodeInstructionExtensions.IsLdarg(code, (int?)0)), (string)null), new CodeMatch((Func)((CodeInstruction code) => CodeInstructionExtensions.LoadsField(code, maxVerticalField, false)), (string)null), new CodeMatch((Func)((CodeInstruction code) => code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 2f), (string)null), new CodeMatch((Func)((CodeInstruction code) => code.opcode == OpCodes.Add), (string)null), new CodeMatch((Func)((CodeInstruction code) => code.opcode == OpCodes.Conv_I4), (string)null), new CodeMatch((Func)((CodeInstruction code) => CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null)), (string)null) }); val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LcInputActionApi), "CalculateVerticalMaxForGamepad", new Type[1] { typeof(KepRemapPanel) }, (Type[])null)) }); return val.InstructionEnumeration(); } } [HarmonyPatch(typeof(KepRemapPanel), "UnloadKeybindsUI")] public static class UnloadKeybindsUIPatch { public static void Prefix() { LcInputActionApi.SaveOverrides(); LcInputActionApi.ReEnableFromRebind(); } } } } namespace LethalCompanyInputUtils.Data { [Serializable] public struct BindingOverride { public string? action; public string? origPath; public string? path; } [Serializable] public class BindingOverrides { public List overrides; private BindingOverrides() { overrides = new List(); } public BindingOverrides(IEnumerable bindings) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) overrides = new List(); foreach (InputBinding binding in bindings) { InputBinding current = binding; if (((InputBinding)(ref current)).hasOverrides) { BindingOverride item = new BindingOverride { action = ((InputBinding)(ref current)).action, origPath = ((InputBinding)(ref current)).path, path = ((InputBinding)(ref current)).overridePath }; overrides.Add(item); } } } public void LoadInto(InputActionAsset asset) { foreach (BindingOverride @override in overrides) { InputAction obj = asset.FindAction(@override.action, false); if (obj != null) { InputActionRebindingExtensions.ApplyBindingOverride(obj, @override.path, (string)null, @override.origPath); } } } public static BindingOverrides FromJson(string json) { BindingOverrides bindingOverrides = new BindingOverrides(); JToken value = JsonConvert.DeserializeObject(json).GetValue("overrides"); bindingOverrides.overrides = value.ToObject>(); return bindingOverrides; } } } namespace LethalCompanyInputUtils.Api { [AttributeUsage(AttributeTargets.Property)] public class InputActionAttribute : Attribute { public readonly string KbmPath; public string? ActionId { get; set; } public string? GamepadPath { get; set; } public InputActionType ActionType { get; set; } = (InputActionType)1; public string? KbmInteractions { get; set; } public string? GamepadInteractions { get; set; } public string? Name { get; set; } [Obsolete("Prefer using the named optional params instead.")] public InputActionAttribute(string action, string kbmPath, string gamepadPath) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ActionId = action; KbmPath = kbmPath; GamepadPath = gamepadPath; } public InputActionAttribute(string kbmPath) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) KbmPath = kbmPath; } } public class InputActionBindingBuilder { private readonly InputActionMapBuilder _mapBuilder; private string? _actionId; private string? _kbmPath; private string? _gamepadPath; private string? _kbmInteractions; private string? _gamepadInteractions; private InputActionType _actionType; private string? _name; internal InputActionBindingBuilder(InputActionMapBuilder mapBuilder) { _mapBuilder = mapBuilder; } public InputActionBindingBuilder WithActionId(string actionId) { _actionId = actionId; return this; } public InputActionBindingBuilder WithKbmPath(string kbmPath) { _kbmPath = kbmPath; return this; } public InputActionBindingBuilder WithGamepadPath(string gamepadPath) { _gamepadPath = gamepadPath; return this; } public InputActionBindingBuilder WithKbmInteractions(string? kbmInteractions) { _kbmInteractions = kbmInteractions; return this; } public InputActionBindingBuilder WithGamepadInteractions(string? gamepadInteractions) { _gamepadInteractions = gamepadInteractions; return this; } public InputActionBindingBuilder WithActionType(InputActionType actionType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _actionType = actionType; return this; } public InputActionBindingBuilder WithBindingName(string? name) { _name = name; return this; } public InputAction Finish() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (_name == null) { _name = _actionId; } InputAction val = new InputAction(_actionId, _actionType, (string)null, (string)null, (string)null, (string)null); _mapBuilder.WithAction(val); if (_kbmPath != null) { _mapBuilder.WithBinding(new InputBinding(_kbmPath, _actionId, (string)null, (string)null, _kbmInteractions, _name)); } if (_gamepadPath != null) { _mapBuilder.WithBinding(new InputBinding(_gamepadPath, _actionId, (string)null, (string)null, _gamepadInteractions, _name)); } return val; } } public class InputActionMapBuilder { private readonly InputActionMap _actionMap = new InputActionMap(mapName); public InputActionMapBuilder(string mapName) { }//IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown public InputActionMapBuilder WithAction(InputAction action) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) InputActionSetupExtensions.AddAction(_actionMap, action.name, action.type, (string)null, (string)null, (string)null, (string)null, (string)null); return this; } public InputActionMapBuilder WithBinding(InputBinding binding) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) InputActionSetupExtensions.AddBinding(_actionMap, binding); return this; } public InputActionBindingBuilder NewActionBinding() { return new InputActionBindingBuilder(this); } internal InputActionMap Build() { return _actionMap; } } public abstract class LcInputActions { private readonly string _jsonPath; private readonly List _actionRefs = new List(); protected readonly InputActionAsset Asset; internal bool Loaded; private readonly Dictionary _inputProps; internal bool WasEnabled { get; private set; } public bool Enabled => Asset.enabled; internal IReadOnlyCollection ActionRefs => _actionRefs; internal string Id => Plugin.GUID + "." + MapName; public BepInPlugin Plugin { get; } protected virtual string MapName => GetType().Name; internal InputActionAsset GetAsset() { return Asset; } protected LcInputActions() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) Asset = ScriptableObject.CreateInstance(); Plugin = Assembly.GetCallingAssembly().GetBepInPlugin() ?? throw new InvalidOperationException(); _jsonPath = Path.Combine(FsUtils.ControlsDir, Id + ".json"); InputActionMapBuilder inputActionMapBuilder = new InputActionMapBuilder(Id); PropertyInfo[] properties = GetType().GetProperties(); _inputProps = new Dictionary(); PropertyInfo[] array = properties; foreach (PropertyInfo propertyInfo in array) { InputActionAttribute customAttribute = propertyInfo.GetCustomAttribute(); if (customAttribute != null && !(propertyInfo.PropertyType != typeof(InputAction))) { InputActionAttribute inputActionAttribute = customAttribute; if (inputActionAttribute.ActionId == null) { string text = (inputActionAttribute.ActionId = propertyInfo.Name); } inputActionAttribute = customAttribute; if (inputActionAttribute.GamepadPath == null) { string text = (inputActionAttribute.GamepadPath = ""); } inputActionMapBuilder.NewActionBinding().WithActionId(customAttribute.ActionId).WithActionType(customAttribute.ActionType) .WithBindingName(customAttribute.Name) .WithKbmPath(customAttribute.KbmPath) .WithGamepadPath(customAttribute.GamepadPath) .WithKbmInteractions(customAttribute.KbmInteractions) .WithGamepadInteractions(customAttribute.GamepadInteractions) .Finish(); _inputProps[propertyInfo] = customAttribute; } } LcInputActionApi.RegisterInputActions(this, inputActionMapBuilder); } public virtual void CreateInputActions(in InputActionMapBuilder builder) { } public virtual void OnAssetLoaded() { } internal void BuildActionRefs() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair inputProp in _inputProps) { inputProp.Deconstruct(out var key, out var value); PropertyInfo propertyInfo = key; InputActionAttribute inputActionAttribute = value; InputAction value2 = Asset.FindAction(inputActionAttribute.ActionId, false); propertyInfo.SetValue(this, value2); } IEnumerable collection = ((IEnumerable)(object)Asset.actionMaps).SelectMany((InputActionMap map) => (IEnumerable)(object)map.actions).Select((Func)InputActionReference.Create); _actionRefs.AddRange(collection); } public void Enable() { WasEnabled = Asset.enabled; Asset.Enable(); } public void Disable() { WasEnabled = Asset.enabled; Asset.Disable(); } internal void Save() { BindingOverrides bindingOverrides = new BindingOverrides(Asset.bindings); File.WriteAllText(_jsonPath, JsonConvert.SerializeObject((object)bindingOverrides)); } internal void Load() { ApplyMigrations(); if (!File.Exists(_jsonPath)) { return; } try { BindingOverrides.FromJson(File.ReadAllText(_jsonPath)).LoadInto(Asset); } catch (Exception ex) { Logging.Logger.LogError((object)ex); } } private void ApplyMigrations() { string text = Path.Combine(FsUtils.Pre041ControlsDir, Id + ".json"); if (File.Exists(text)) { File.Move(text, _jsonPath); } } } }