using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using KeybindLib.Classes;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("KeybindLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("KeybindLib")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a435cffd-1c69-437a-9daa-52fd5a9b02e6")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace KeybindLib
{
[BepInPlugin("bulletbot.keybindlib", "KeybindLib", "1.0.0")]
internal class Plugin : BaseUnityPlugin
{
private const string modGUID = "bulletbot.keybindlib";
private const string modName = "KeybindLib";
private const string modVer = "1.0.0";
internal static Plugin instance;
internal ManualLogSource logger;
private readonly Harmony harmony = new Harmony("bulletbot.keybindlib");
private bool hasPatched;
internal List<KeybindData> keybindDatas;
private void Awake()
{
instance = this;
logger = Logger.CreateLogSource("KeybindLib");
keybindDatas = new List<KeybindData>();
logger.LogMessage((object)"KeybindLib has started.");
SceneManager.activeSceneChanged += delegate
{
if (!hasPatched)
{
harmony.PatchAll();
hasPatched = true;
}
};
}
}
}
namespace KeybindLib.Patches
{
[HarmonyPatch(typeof(MenuManager))]
internal class MenuManagerPatch
{
private static readonly float _headerOffset = 30f;
private static readonly float _categoryOffset = 26.5f;
private static readonly float _categoryHeaderOffset = 6.5f;
private static readonly float _buttonOffset = 42f;
private static readonly float _buttonHeaderOffset = 15f;
private static readonly float _buttonCategoryOffset = 11.5f;
private static readonly float _boolSettingOffset = 27.25f;
private static readonly float _boolSettingHeaderOffset = 12.5f;
private static readonly float _boolSettingCategoryOffset = 9f;
[HarmonyPatch("Start")]
[HarmonyPrefix]
private static void Start(ref List<MenuPages> ___menuPages)
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: 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_0229: Unknown result type (might be due to invalid IL or missing references)
//IL_037e: Unknown result type (might be due to invalid IL or missing references)
//IL_0383: Unknown result type (might be due to invalid IL or missing references)
//IL_039d: Unknown result type (might be due to invalid IL or missing references)
//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
//IL_0412: Unknown result type (might be due to invalid IL or missing references)
//IL_0417: Unknown result type (might be due to invalid IL or missing references)
//IL_0460: Unknown result type (might be due to invalid IL or missing references)
//IL_0469: Unknown result type (might be due to invalid IL or missing references)
//IL_0470: Unknown result type (might be due to invalid IL or missing references)
if (Plugin.instance.keybindDatas.Count <= 0)
{
return;
}
MenuPages val = ((IEnumerable<MenuPages>)___menuPages).FirstOrDefault((Func<MenuPages, bool>)((MenuPages x) => (int)x.menuPageIndex == 6));
Transform child = val.menuPage.transform.GetChild(3);
MenuScrollBox component = ((Component)child).GetComponent<MenuScrollBox>();
Transform child2 = child.GetChild(1).GetChild(0);
GameObject gameObject = ((Component)child2.Find("Header Expressions")).gameObject;
Vector3 localPosition = gameObject.transform.localPosition;
GameObject gameObject2 = ((Component)child2.Find("Header Grabbing")).gameObject;
Vector3 localPosition2 = gameObject2.transform.localPosition;
GameObject gameObject3 = ((Component)child2.Find("Big Button Map")).gameObject;
Vector3 localPosition3 = gameObject3.transform.localPosition;
GameObject gameObject4 = ((Component)child2.Find("Bool Setting - ")).gameObject;
Vector3 localPosition4 = gameObject4.transform.localPosition;
List<string> list = new List<string>();
List<(string, string)> list2 = new List<(string, string)>();
float num = child2.GetChild(child2.childCount - 1).localPosition.y;
bool flag = false;
foreach (KeybindData keybindData in Plugin.instance.keybindDatas)
{
float num2 = 0f;
bool flag2 = !list.Contains(keybindData.modGuid);
if (flag2 && flag)
{
num2 = 0f - _boolSettingHeaderOffset;
flag = false;
}
bool flag3 = !string.IsNullOrEmpty(keybindData.category) && !list2.Contains((keybindData.modGuid, keybindData.category));
if (flag3 && flag)
{
num2 = 0f - _boolSettingCategoryOffset;
flag = false;
}
if (flag2)
{
num -= _headerOffset + num2;
GameObject val2 = Object.Instantiate<GameObject>(gameObject);
((Object)val2).name = "Header " + keybindData.modGuid;
((TMP_Text)val2.GetComponentInChildren<TextMeshProUGUI>()).text = keybindData.modGuid;
val2.transform.SetParent(child2);
val2.transform.localPosition = new Vector3(localPosition.x, num, localPosition.z);
list.Add(keybindData.modGuid);
num2 = (flag3 ? _categoryHeaderOffset : _buttonHeaderOffset);
}
if (flag3)
{
num -= _categoryOffset + num2;
GameObject val3 = Object.Instantiate<GameObject>(gameObject2);
((Object)val3).name = "Category " + keybindData.modGuid + " " + keybindData.category;
((TMP_Text)val3.GetComponentInChildren<TextMeshProUGUI>()).text = keybindData.category;
val3.transform.SetParent(child2);
val3.transform.localPosition = new Vector3(localPosition2.x, num, localPosition2.z);
list2.Add((keybindData.modGuid, keybindData.category));
num2 = _buttonCategoryOffset;
}
num -= _buttonOffset + num2;
GameObject val4 = Object.Instantiate<GameObject>(gameObject3);
((Object)val4).name = "Big Button " + keybindData.modGuid + " " + keybindData.inputAction.name;
val4.GetComponent<MenuBigButton>().buttonTitle = keybindData.inputAction.name;
((TMP_Text)val4.GetComponentInChildren<TextMeshProUGUI>()).text = keybindData.inputAction.name;
val4.GetComponent<MenuKeybind>().inputKey = keybindData.inputKey;
val4.transform.SetParent(child2);
val4.transform.localPosition = new Vector3(localPosition3.x, num, localPosition3.z);
if (keybindData.toggleData != null)
{
num -= _boolSettingOffset;
GameObject val5 = Object.Instantiate<GameObject>(gameObject4);
((Object)val5).name = "Toggle " + keybindData.modGuid + " " + keybindData.inputAction.name;
val5.GetComponent<MenuKeybindToggle>().inputKey = keybindData.inputKey;
MenuTwoOptions component2 = val5.GetComponent<MenuTwoOptions>();
component2.option2Text = keybindData.toggleData.falseText;
component2.option1Text = keybindData.toggleData.trueText;
val5.transform.SetParent(child2);
val5.transform.localPosition = new Vector3(localPosition4.x, num, localPosition4.z);
flag = true;
}
component.heightPadding += 4f;
}
}
}
[HarmonyPatch(typeof(InputManager))]
internal class InputManagerPatch
{
[HarmonyPatch("Start")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> StartTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Expected O, but got Unknown
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"DefaultKeyBindings.es3", (string)null)
});
val.Insert((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldflda, (object)AccessTools.Field(typeof(InputManager), "tagDictionary")),
new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InputManagerPatch), "Start", (Type[])null, (Type[])null))
});
return val.InstructionEnumeration();
}
private static void Start(ref Dictionary<string, InputKey> tagDictionary)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
foreach (KeybindData keybindData in Plugin.instance.keybindDatas)
{
tagDictionary.Add(keybindData.tag, keybindData.inputKey);
}
}
[HarmonyPatch("InitializeInputs")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> InitializeInputsTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Expected O, but got Unknown
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Expected O, but got Unknown
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Expected O, but got Unknown
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Expected O, but got Unknown
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Expected O, but got Unknown
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
int num = -1;
while (true)
{
val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Dictionary<InputKey, InputAction>), "set_Item", (Type[])null, (Type[])null), (string)null)
});
if (!val.IsValid)
{
break;
}
num = val.Pos;
val.Advance(1);
}
if (num != -1)
{
val.Start();
val.Advance(num + 1);
val.Insert((CodeInstruction[])(object)new CodeInstruction[5]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldflda, (object)AccessTools.Field(typeof(InputManager), "inputActions")),
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldflda, (object)AccessTools.Field(typeof(InputManager), "inputToggle")),
new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InputManagerPatch), "InitializeInputs", (Type[])null, (Type[])null))
});
}
return val.InstructionEnumeration();
}
private static void InitializeInputs(ref Dictionary<InputKey, InputAction> inputActions, ref Dictionary<InputKey, bool> inputToggle)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
foreach (KeybindData keybindData in Plugin.instance.keybindDatas)
{
inputActions[keybindData.inputKey] = keybindData.inputAction;
if (keybindData.toggleData != null)
{
inputToggle.Add(keybindData.inputKey, keybindData.toggleData.defaultValue);
}
}
}
}
}
namespace KeybindLib.Classes
{
public class KeybindToggleData
{
public bool defaultValue;
public string falseText = "hold";
public string trueText = "toggle";
}
public class KeybindData
{
public KeybindToggleData toggleData;
internal int modOrderIndex;
internal int registerIndex;
public string modGuid { get; internal set; }
public string modName { get; internal set; }
public string category { get; internal set; }
public string tag { get; internal set; }
public InputKey inputKey { get; internal set; }
public InputAction inputAction { get; internal set; }
}
public static class Keybinds
{
internal static readonly Dictionary<string, int> _modOrder = new Dictionary<string, int>();
internal static int _nextRegisterIndex = 0;
internal static int _nextModOrderIndex = 0;
public static KeybindData Register(string name, string binding)
{
BepInPlugin plugin = (from x in Assembly.GetCallingAssembly().GetTypes()
select ((MemberInfo)x).GetCustomAttribute<BepInPlugin>()).FirstOrDefault();
return Register(plugin, null, name, binding);
}
public static KeybindData Register(string category, string name, string binding)
{
BepInPlugin plugin = (from x in Assembly.GetCallingAssembly().GetTypes()
select ((MemberInfo)x).GetCustomAttribute<BepInPlugin>()).FirstOrDefault();
return Register(plugin, category, name, binding);
}
internal static KeybindData Register(BepInPlugin plugin, string category, string name, string binding)
{
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Expected O, but got Unknown
if (plugin == null || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(binding) || Plugin.instance.keybindDatas.Any((KeybindData x) => x.modGuid == plugin.GUID && ((string.IsNullOrEmpty(x.category) && string.IsNullOrEmpty(category)) || (!string.IsNullOrEmpty(x.category) && !string.IsNullOrEmpty(category) && x.category.Equals(category, StringComparison.OrdinalIgnoreCase))) && x.inputAction.name.Equals(name, StringComparison.OrdinalIgnoreCase)))
{
Plugin.instance.logger.LogMessage((object)("Failed to register keybind \"" + name + "\"" + ((!string.IsNullOrEmpty(category)) ? (" in category \"" + category + "\"") : "") + " from mod \"" + plugin.GUID + "\"."));
return null;
}
KeybindData keybindData = new KeybindData();
keybindData.modGuid = plugin.GUID;
keybindData.modName = plugin.Name;
keybindData.category = category;
int num = Hash(keybindData.modGuid) & 0x3FF;
int num2 = Hash(category) & 0x3FF;
int num3 = Hash(name) & 0x7FF;
uint num4 = 0x40000000u | (uint)(num << 21) | (uint)(num2 << 11) | (uint)num3;
num4 &= 0x7FFFFFFFu;
keybindData.tag = $"[{(int)num4}]";
keybindData.inputKey = (InputKey)num4;
keybindData.inputAction = new InputAction(name, (InputActionType)0, binding, (string)null, (string)null, (string)null);
if (!_modOrder.TryGetValue(keybindData.modGuid, out var value2))
{
value2 = _nextModOrderIndex++;
_modOrder[keybindData.modGuid] = value2;
}
keybindData.modOrderIndex = value2;
keybindData.registerIndex = _nextRegisterIndex++;
Plugin.instance.keybindDatas.Add(keybindData);
Plugin.instance.keybindDatas.Sort(delegate(KeybindData a, KeybindData b)
{
int num6 = a.modOrderIndex.CompareTo(b.modOrderIndex);
if (num6 != 0)
{
return num6;
}
bool flag = !string.IsNullOrEmpty(a.category);
bool flag2 = !string.IsNullOrEmpty(b.category);
return (flag != flag2) ? flag.CompareTo(flag2) : a.registerIndex.CompareTo(b.registerIndex);
});
Plugin.instance.logger.LogMessage((object)("Registered keybind \"" + name + "\"" + ((!string.IsNullOrEmpty(category)) ? (" in category \"" + category + "\"") : "") + " from mod \"" + keybindData.modGuid + "\"."));
return keybindData;
static int Hash(string value)
{
if (string.IsNullOrEmpty(value))
{
return 0;
}
int num5 = 23;
for (int i = 0; i < value.Length; i++)
{
num5 = num5 * 31 + value[i];
}
return num5;
}
}
}
}