Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ExtraButtonSupport v1.0.0
ExtraButtonSupport.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; 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 GlobalEnums; using GlobalSettings; using HarmonyLib; using HutongGames.PlayMaker; using InControl; using Microsoft.CodeAnalysis; using Steamworks; using UnityEngine; using UnityEngine.UI; [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("ExtraButtonSupport")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+67d4550c2c94ab97d827eb3393fe6c23235a1944")] [assembly: AssemblyProduct("ExtraButtonSupport")] [assembly: AssemblyTitle("ExtraButtonSupport")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace ExtraButtonSupport { [HarmonyPatch] internal static class DeviceInjection { private static bool _pollFailed; [HarmonyPrefix] [HarmonyPatch(typeof(InputManager), "AttachDevice")] private static void AddExtraControls(InputDevice inputDevice) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 12; i++) { inputDevice.AddControl(ExtraButtonSupportPlugin.ControlFor(i), $"Extra {i + 1}"); } ManualLogSource? log = ExtraButtonSupportPlugin.Log; if (log != null) { log.LogInfo((object)$"[extra] added Extra 1-{12} to {inputDevice.Name} ({((object)inputDevice).GetType().Name}, style {inputDevice.DeviceStyle})"); } } [HarmonyPostfix] [HarmonyPatch(typeof(InputManager), "UpdateDevices")] private static void FeedExtraControls(float deltaTime) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) try { ExtraButtonSupportPlugin.Instance?.Poll(); } catch (Exception arg) { Array.Clear(ExtraButtonSupportPlugin.SlotDown, 0, 12); if (!_pollFailed) { ManualLogSource? log = ExtraButtonSupportPlugin.Log; if (log != null) { log.LogError((object)$"[extra] Steam Input poll failed: {arg}"); } } _pollFailed = true; } InputDevice activeDevice = InputManager.ActiveDevice; bool flag = activeDevice == null || !activeDevice.HasControl(ExtraButtonSupportPlugin.ControlFor(0)); ulong currentTick = InputManager.CurrentTick; foreach (InputDevice device in InputManager.Devices) { for (int i = 0; i < 12; i++) { if (device.HasControl(ExtraButtonSupportPlugin.ControlFor(i))) { ((OneAxisInputControl)device.GetControl(ExtraButtonSupportPlugin.ControlFor(i))).UpdateWithState((flag || device == activeDevice) && ExtraButtonSupportPlugin.SlotDown[i], currentTick, deltaTime); } } } } [HarmonyPostfix] [HarmonyPatch(typeof(DeviceBindingSourceListener), "ListenForControl")] private static void AcceptExtraSlots(InputDevice device, ref InputControlType __result) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown if (__result || device == null) { return; } for (int i = 8; i < 12; i++) { if (((OneAxisInputControl)device.GetControl(ExtraButtonSupportPlugin.ControlFor(i))).Value > 0.5f) { __result = (InputControlType)(int)ExtraButtonSupportPlugin.ControlFor(i); break; } } } } [BepInPlugin("io.github.andygobrien.extrabuttonsupport", "ExtraButtonSupport", "1.0.0")] public class ExtraButtonSupportPlugin : BaseUnityPlugin { internal const int Slots = 12; private const string ActionSet = "Default"; internal static ExtraButtonSupportPlugin? Instance; internal static ManualLogSource? Log; internal static readonly bool[] SlotDown = new bool[12]; private bool _initialized; private float _nextInitAttempt; private InputActionSetHandle_t _set; private readonly InputDigitalActionHandle_t[] _actions = (InputDigitalActionHandle_t[])(object)new InputDigitalActionHandle_t[12]; private static readonly string[] ActionNames = BuildActionNames(); private float _nextResolve; private readonly InputHandle_t[] _pads = (InputHandle_t[])(object)new InputHandle_t[16]; private readonly EInputActionOrigin[] _origins = (EInputActionOrigin[])(object)new EInputActionOrigin[8]; private int _padCount = -1; private readonly ulong[] _lastPads = new ulong[16]; private bool _padsChanged; private Callback<SteamInputConfigurationLoaded_t>? _configLoaded; public const string Id = "io.github.andygobrien.extrabuttonsupport"; public static string Name => "ExtraButtonSupport"; public static string Version => "1.0.0"; internal static InputControlType ControlFor(int slot) { if (slot < 8) { return (InputControlType)(23 + slot); } return (InputControlType)(500 + (slot - 8)); } internal static int SlotFor(InputControlType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected I4, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0026: Expected I4, but got Unknown if ((int)type < 23 || (int)type > 30) { if ((int)type < 500 || (int)type > 503) { return -1; } return 8 + (type - 500); } return type - 23; } private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; Harmony val = new Harmony("io.github.andygobrien.extrabuttonsupport"); val.PatchAll(typeof(DeviceInjection)); val.PatchAll(typeof(Glyphs)); val.PatchAll(typeof(ToolActionPatches)); val.PatchAll(typeof(MenuRowPatches)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " (io.github.andygobrien.extrabuttonsupport) has loaded!")); } private void Update() { if (!_initialized) { TryInit(); } else if (_padsChanged) { _padsChanged = false; try { LogPads(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[extra] controller info failed: " + ex.Message)); } } } private void TryInit() { if (Time.unscaledTime < _nextInitAttempt) { return; } _nextInitAttempt = Time.unscaledTime + 1f; try { _configLoaded = Callback<SteamInputConfigurationLoaded_t>.Create((DispatchDelegate<SteamInputConfigurationLoaded_t>)delegate(SteamInputConfigurationLoaded_t e) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[extra] config loaded: app={e.m_unAppID} usesSteamInputAPI={e.m_bUsesSteamInputAPI} usesGamepadAPI={e.m_bUsesGamepadAPI}"); }); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[extra] SteamInput.Init(true) = {SteamInput.Init(true)}"); _initialized = true; } catch (InvalidOperationException) { } } internal void Poll() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_0105: Unknown result type (might be due to invalid IL or missing references) if (!_initialized) { return; } SteamInput.RunFrame(true); if (Time.unscaledTime >= _nextResolve) { _nextResolve = Time.unscaledTime + 1f; ResolveHandles(); } int connectedControllers = SteamInput.GetConnectedControllers(_pads); if (PadsChanged(connectedControllers)) { _padCount = connectedControllers; _padsChanged = true; } if (_set.m_InputActionSetHandle != 0L) { for (int i = 0; i < connectedControllers; i++) { SteamInput.ActivateActionSet(_pads[i], _set); } } for (int j = 0; j < 12; j++) { bool flag = false; for (int k = 0; k < connectedControllers; k++) { if (_actions[j].m_InputDigitalActionHandle == 0L) { break; } InputDigitalActionData_t digitalActionData = SteamInput.GetDigitalActionData(_pads[k], _actions[j]); flag |= digitalActionData.bActive != 0 && digitalActionData.bState != 0; } if (flag && !SlotDown[j]) { LogPress(j, (InputHandle_t)((connectedControllers > 0) ? _pads[0] : default(InputHandle_t))); } SlotDown[j] = flag; } } private bool PadsChanged(int count) { bool flag = count != _padCount; for (int i = 0; i < count; i++) { flag |= _lastPads[i] != _pads[i].m_InputHandle; _lastPads[i] = _pads[i].m_InputHandle; } return flag; } internal EInputActionOrigin? OriginFor(int slot) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) if (!_initialized || _padCount < 1 || _actions[slot].m_InputDigitalActionHandle == 0L) { return null; } if (SteamInput.GetDigitalActionOrigins(_pads[0], _set, _actions[slot], _origins) <= 0) { return null; } return _origins[0]; } private void ResolveHandles() { //IL_0013: 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_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) if (_set.m_InputActionSetHandle == 0L) { _set = SteamInput.GetActionSetHandle("Default"); } for (int i = 0; i < 12; i++) { if (_actions[i].m_InputDigitalActionHandle == 0L) { _actions[i] = SteamInput.GetDigitalActionHandle(ActionNames[i]); } } } private static string[] BuildActionNames() { string[] array = new string[12]; for (int i = 0; i < 12; i++) { array[i] = $"extra_{i + 1}"; } return array; } private void LogPads() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[extra] {_padCount} controller(s) connected"); for (int i = 0; i < _padCount; i++) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[extra] pad{i} handle={_pads[i].m_InputHandle} type={SteamInput.GetInputTypeForHandle(_pads[i])}"); } } private void LogPress(int s, InputHandle_t pad) { //IL_0000: 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) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) int digitalActionOrigins = SteamInput.GetDigitalActionOrigins(pad, _set, _actions[s], _origins); string text = ""; for (int i = 0; i < digitalActionOrigins; i++) { text = text + " '" + SteamInput.GetStringForActionOrigin(_origins[i]) + "'"; } ((BaseUnityPlugin)this).Logger.LogDebug((object)$"[extra] extra_{s + 1} DOWN ->{text} (InControl {ControlFor(s)})"); } } [HarmonyPatch] internal static class Glyphs { private static readonly Dictionary<EInputActionOrigin, Sprite> Cache = new Dictionary<EInputActionOrigin, Sprite>(); private static readonly Dictionary<EInputActionOrigin, float> RetryAt = new Dictionary<EInputActionOrigin, float>(); [HarmonyPostfix] [HarmonyPatch(typeof(UIButtonSkins), "GetButtonSkinFor", new Type[] { typeof(InputControlType) })] private static void UseSteamGlyph(UIButtonSkins __instance, InputControlType inputControlType, ButtonSkin __result) { //IL_0000: 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_003e: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) int num = ExtraButtonSupportPlugin.SlotFor(inputControlType); if (num < 0) { return; } EInputActionOrigin? val; try { val = ExtraButtonSupportPlugin.Instance?.OriginFor(num); } catch (Exception) { return; } if (!val.HasValue) { return; } EInputActionOrigin valueOrDefault = val.GetValueOrDefault(); if (!Cache.TryGetValue(valueOrDefault, out Sprite value)) { if (RetryAt.TryGetValue(valueOrDefault, out var value2) && Time.unscaledTime < value2) { return; } value = GlyphHelpers.Load(valueOrDefault, __instance.blankKey); if ((Object)(object)value == (Object)null) { RetryAt[valueOrDefault] = Time.unscaledTime + 10f; return; } Cache[valueOrDefault] = value; } __result.sprite = value; } } internal static class GlyphHelpers { private static readonly HashSet<EInputActionOrigin> Reported = new HashSet<EInputActionOrigin>(); internal static Sprite? Load(EInputActionOrigin origin, Sprite reference) { //IL_0002: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected I4, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) Texture2D val = null; try { string glyphPNGForActionOrigin = SteamInput.GetGlyphPNGForActionOrigin(origin, (ESteamInputGlyphSize)2, 0u); if (string.IsNullOrEmpty(glyphPNGForActionOrigin) || !File.Exists(glyphPNGForActionOrigin)) { throw new FileNotFoundException("no glyph file '" + glyphPNGForActionOrigin + "'"); } val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(glyphPNGForActionOrigin))) { throw new InvalidDataException("can't decode '" + glyphPNGForActionOrigin + "'"); } return Loaded(origin, glyphPNGForActionOrigin, val, reference); } catch (Exception ex) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } if (Reported.Add(origin)) { ManualLogSource? log = ExtraButtonSupportPlugin.Log; if (log != null) { log.LogWarning((object)$"[extra] glyph for origin {(int)origin} not loaded: {ex.Message}"); } } return null; } } private static Sprite Loaded(EInputActionOrigin origin, string path, Texture2D tex, Sprite reference) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_003f: Expected I4, but got Unknown //IL_006c: 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) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00d5: Unknown result type (might be due to invalid IL or missing references) float num = (float)((Texture)tex).width * reference.pixelsPerUnit; Rect rect = reference.rect; float num2 = num / ((Rect)(ref rect)).width; ManualLogSource? log = ExtraButtonSupportPlugin.Log; if (log != null) { object[] obj = new object[8] { (int)origin, path, ((Texture)tex).width, ((Texture)tex).height, num2, null, null, null }; rect = reference.rect; obj[5] = ((Rect)(ref rect)).width; rect = reference.rect; obj[6] = ((Rect)(ref rect)).height; obj[7] = reference.pixelsPerUnit; log.LogInfo((object)string.Format("[extra] glyph {0} {1} {2}x{3} ppu={4} (ref {5}x{6} ppu={7})", obj)); } return Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), num2); } } [HarmonyPatch] internal static class MenuRowPatches { private static readonly FieldRef<MappableControllerButton, PlayerAction> RowAction = AccessTools.FieldRefAccess<MappableControllerButton, PlayerAction>("playerAction"); private static readonly FieldRef<MappableControllerButton, PlayerAction> ActionToSwap = AccessTools.FieldRefAccess<MappableControllerButton, PlayerAction>("actionToSwap"); private static readonly FieldRef<MappableControllerButton, BindingSource> BindingToSwap = AccessTools.FieldRefAccess<MappableControllerButton, BindingSource>("bindingToSwap"); [HarmonyPrefix] [HarmonyPatch(typeof(UIManager), "UIGoToRemapControllerMenu")] private static void AddToolRows(UIManager __instance) { try { MenuRows.Ensure(__instance.uiButtonSkins.mappableControllerButtons); } catch (Exception arg) { ManualLogSource? log = ExtraButtonSupportPlugin.Log; if (log != null) { log.LogError((object)$"[extra] tool rows not added: {arg}"); } } } [HarmonyPostfix] [HarmonyPatch(typeof(MappableControllerButton), "OnBindingFound")] private static void UnbindInsteadOfSwap(MappableControllerButton __instance) { PlayerAction val = ActionToSwap.Invoke(__instance); if (val != null && (Tools.IsTool(RowAction.Invoke(__instance)) || Tools.IsTool(val))) { BindingToSwap.Invoke(__instance) = null; } } } internal static class MenuRows { private const string Prefix = "ExtraButtonSupport "; private const float RowHeight = 100f; internal static void Ensure(RectTransform rows) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) if ((Object)(object)((Transform)rows).Find("ExtraButtonSupport " + Tools.Names[0]) != (Object)null) { return; } MappableControllerButton val = Find(rows, "CastButton"); MappableControllerButton val2 = Find(rows, "QCastButton"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { ManualLogSource? log = ExtraButtonSupportPlugin.Log; if (log != null) { log.LogError((object)"[extra] remap rows not found; tool rows not added"); } return; } rows.anchoredPosition += new Vector2(0f, 100f); Navigation navigation = ((Selectable)val).navigation; Selectable selectOnDown = ((Navigation)(ref navigation)).selectOnDown; MappableControllerButton val3 = Clone(val, 0, 1); MappableControllerButton val4 = Clone(val, 2, 2); MappableControllerButton val5 = Clone(val2, 1, 1); MappableControllerButton val6 = Clone(val2, 3, 2); Link((Selectable)(object)val, null, (Selectable?)(object)val3); Link((Selectable)(object)val3, (Selectable?)(object)val, (Selectable?)(object)val4, null, (Selectable?)(object)val5); Link((Selectable)(object)val4, (Selectable?)(object)val3, selectOnDown, null, (Selectable?)(object)val6); Link((Selectable)(object)val2, null, (Selectable?)(object)val5); Link((Selectable)(object)val5, (Selectable?)(object)val2, (Selectable?)(object)val6, (Selectable?)(object)val3); Link((Selectable)(object)val6, (Selectable?)(object)val5, selectOnDown, (Selectable?)(object)val4); if ((Object)(object)selectOnDown != (Object)null) { Link(selectOnDown, (Selectable?)(object)val4); } ManualLogSource? log2 = ExtraButtonSupportPlugin.Log; if (log2 != null) { log2.LogInfo((object)"[extra] added tool rows to Remap Controller screen"); } } private static MappableControllerButton? Find(RectTransform rows, string name) { Transform obj = ((Transform)rows).Find(name); if (obj == null) { return null; } return ((Component)obj).GetComponent<MappableControllerButton>(); } private static MappableControllerButton Clone(MappableControllerButton template, int tool, int rowsBelow) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ExtraButtonSupport holder"); val.SetActive(false); MappableControllerButton val2 = Object.Instantiate<MappableControllerButton>(template, val.transform); ((Object)val2).name = "ExtraButtonSupport " + Tools.Names[tool]; val2.actionButtonType = (HeroActionButton)(100 + tool); Transform val3 = ((Component)val2).transform.Find("Input Button Text"); Component[] components = ((Component)val3).GetComponents<Component>(); foreach (Component val4 in components) { if (((object)val4).GetType().Name == "AutoLocalizeTextUI") { Object.DestroyImmediate((Object)(object)val4); } } ((Component)val3).GetComponent<Text>().text = Tools.Names[tool]; RectTransform val5 = (RectTransform)((Component)val2).transform; ((Transform)val5).SetParent(((Component)template).transform.parent, false); val5.anchoredPosition = ((RectTransform)((Component)template).transform).anchoredPosition - new Vector2(0f, 100f * (float)rowsBelow); Object.Destroy((Object)(object)val); return val2; } private static void Link(Selectable s, Selectable? upTo = null, Selectable? down = null, Selectable? left = null, Selectable? right = null) { //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_0056: Unknown result type (might be due to invalid IL or missing references) Navigation navigation = s.navigation; ((Navigation)(ref navigation)).mode = (Mode)4; if ((Object)(object)upTo != (Object)null) { ((Navigation)(ref navigation)).selectOnUp = upTo; } if ((Object)(object)down != (Object)null) { ((Navigation)(ref navigation)).selectOnDown = down; } if ((Object)(object)left != (Object)null) { ((Navigation)(ref navigation)).selectOnLeft = left; } if ((Object)(object)right != (Object)null) { ((Navigation)(ref navigation)).selectOnRight = right; } s.navigation = navigation; } } internal static class Tools { internal static readonly string[] Names = new string[4] { "Tool Up", "Tool Neutral", "Tool Down", "Scuttle" }; internal const int ScuttleIndex = 3; internal static readonly AttackToolBinding[] Slots = (AttackToolBinding[])(object)new AttackToolBinding[3] { (AttackToolBinding)1, default(AttackToolBinding), (AttackToolBinding)2 }; internal const int ButtonBase = 100; private static HeroActions? _owner; private static readonly PlayerAction[] Actions = (PlayerAction[])(object)new PlayerAction[4]; internal static HeroActions? Owner => _owner; internal static PlayerAction[] For(HeroActions heroActions) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (_owner != heroActions) { for (int i = 0; i < Names.Length; i++) { Actions[i] = (PlayerAction)(((object)((PlayerActionSet)heroActions).GetPlayerActionByName("ExtraButtonSupport " + Names[i])) ?? ((object)new PlayerAction("ExtraButtonSupport " + Names[i], (PlayerActionSet)(object)heroActions))); } _owner = heroActions; } return Actions; } internal static bool IsTool(PlayerAction? action) { if (_owner != null && action != null) { return Array.IndexOf(Actions, action) >= 0; } return false; } internal static AttackToolBinding? Held(InputDevice? device) { if (_owner == null || device == null) { return null; } for (int i = 0; i < Slots.Length; i++) { if (IsHeld(Actions[i], device)) { return Slots[i]; } } return null; } internal static bool ScuttleHeld(InputDevice? device) { if (_owner != null && device != null && IsHeld(Actions[3], device)) { return ((ToolBase)Gameplay.ScuttleCharmTool).IsEquipped; } return false; } private static bool IsHeld(PlayerAction action, InputDevice device) { ReadOnlyCollection<BindingSource> bindings = action.Bindings; for (int i = 0; i < bindings.Count; i++) { if (bindings[i].GetState(device)) { return true; } } return false; } internal unsafe static ConfigEntry<InputControlType> Saved(GamepadType pad, int i) { return ((BaseUnityPlugin)ExtraButtonSupportPlugin.Instance).Config.Bind<InputControlType>("Bindings." + ((object)(*(GamepadType*)(&pad))/*cast due to .constrained prefix*/).ToString(), Names[i].Replace(" ", ""), (InputControlType)0, "Controller button for " + Names[i] + " (set from the in-game Controller remap screen)"); } } [HarmonyPatch] internal static class ToolActionPatches { private delegate bool CanThrowToolFn(HeroController hero, ToolItem tool, AttackToolBinding binding, bool reportFailure); private static readonly FieldRef<HeroController, ToolItem> WillThrowTool = AccessTools.FieldRefAccess<HeroController, ToolItem>("willThrowTool"); private static readonly CanThrowToolFn CanThrowTool = AccessTools.MethodDelegate<CanThrowToolFn>(AccessTools.Method(typeof(HeroController), "CanThrowTool", new Type[3] { typeof(ToolItem), typeof(AttackToolBinding), typeof(bool) }, (Type[])null), (object)null, true); private static readonly FieldRef<OneAxisInputControl, InputControlState> ControlState = AccessTools.FieldRefAccess<OneAxisInputControl, InputControlState>("thisState"); private static bool _wasHeld; private static readonly FieldRef<HeroController, bool> IsGameplayScene = AccessTools.FieldRefAccess<HeroController, bool>("isGameplayScene"); [HarmonyPostfix] [HarmonyPatch(typeof(InputHandler), "MapControllerButtons")] private static void ApplyToolBindings(InputHandler __instance, GamepadType gamePadType) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown PlayerAction[] array = Tools.For(__instance.inputActions); for (int i = 0; i < array.Length; i++) { array[i].ClearBindings(); InputControlType value = Tools.Saved(gamePadType, i).Value; if ((int)value != 0) { array[i].AddBinding((BindingSource)new DeviceBindingSource(value)); } } } [HarmonyPostfix] [HarmonyPatch(typeof(InputHandler), "SetupMappableControllerBindingsList")] private static void AddToMappable(InputHandler __instance) { __instance.MappableControllerActions.AddRange(Tools.For(__instance.inputActions)); } [HarmonyPostfix] [HarmonyPatch(typeof(InputHandler), "SendButtonBindingsToGameSettings")] private static void SaveToolBindings(InputHandler __instance) { //IL_0011: 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) PlayerAction[] array = Tools.For(__instance.inputActions); for (int i = 0; i < array.Length; i++) { Tools.Saved(__instance.activeGamepadType, i).Value = __instance.GetButtonBindingForAction(array[i]); } } [HarmonyPrefix] [HarmonyPatch(typeof(InputHandler), "ResetDefaultControllerButtonBindings")] private static void ResetToolBindings(InputHandler __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < Tools.Names.Length; i++) { Tools.Saved(__instance.activeGamepadType, i).Value = (InputControlType)0; } } [HarmonyPrefix] [HarmonyPatch(typeof(InputHandler), "ActionButtonToPlayerAction")] private static bool RowToToolAction(InputHandler __instance, HeroActionButton actionButtonType, ref PlayerAction __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Expected I4, but got Unknown int num = actionButtonType - 100; if (num < 0 || num >= Tools.Names.Length) { return true; } __result = Tools.For(__instance.inputActions)[num]; return false; } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerAction), "UpdateBindings")] private static void DriveVanillaActions(PlayerAction __instance, ulong updateTick, float deltaTime) { HeroActions owner = Tools.Owner; if (owner == null || ((PlayerActionSet)owner).IsListeningForBinding) { return; } bool num; if (__instance != owner.QuickCast) { if (__instance != owner.Dash) { return; } num = Tools.ScuttleHeld(InputManager.ActiveDevice); } else { num = Tools.Held(InputManager.ActiveDevice).HasValue; } if (num) { ((OneAxisInputControl)__instance).UpdateWithValue(1f, updateTick, deltaTime); } } [HarmonyPrefix] [HarmonyPatch(typeof(HeroController), "HeroDashPressed")] private static void ScuttleDirection(HeroController __instance, out InputControlState[]? __state) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) __state = null; HeroActions owner = Tools.Owner; if (owner != null && Tools.ScuttleHeld(InputManager.ActiveDevice)) { __state = (InputControlState[]?)(object)new InputControlState[3] { ControlState.Invoke((OneAxisInputControl)(object)owner.Down), ControlState.Invoke((OneAxisInputControl)(object)owner.Left), ControlState.Invoke((OneAxisInputControl)(object)owner.Right) }; ControlState.Invoke((OneAxisInputControl)(object)owner.Down) = new InputControlState { State = true, Value = 1f, RawValue = 1f }; ControlState.Invoke((OneAxisInputControl)(object)owner.Left) = default(InputControlState); ControlState.Invoke((OneAxisInputControl)(object)owner.Right) = default(InputControlState); } } [HarmonyFinalizer] [HarmonyPatch(typeof(HeroController), "HeroDashPressed")] private static void RestoreDirection(InputControlState[]? __state) { //IL_001f: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) HeroActions owner = Tools.Owner; if (__state != null && owner != null) { ControlState.Invoke((OneAxisInputControl)(object)owner.Down) = __state[0]; ControlState.Invoke((OneAxisInputControl)(object)owner.Left) = __state[1]; ControlState.Invoke((OneAxisInputControl)(object)owner.Right) = __state[2]; } } [HarmonyPrefix] [HarmonyPatch(typeof(HeroController), "LookForQueueInput")] private static void ToolBindCancelsSprint(HeroController __instance) { bool hasValue = Tools.Held(InputManager.ActiveDevice).HasValue; bool num = hasValue && !_wasHeld; _wasHeld = hasValue; if (!num || __instance.IsInputBlocked() || __instance.IsPaused() || !IsGameplayScene.Invoke(__instance) || (Object)(object)InteractManager.BlockingInteractable != (Object)null) { return; } HeroActions? owner = Tools.Owner; if (owner != null && ((PlayerActionSet)owner).IsListeningForBinding) { return; } PlayMakerFSM sprintFSM = __instance.sprintFSM; if (SprintFsm.Accepts(sprintFSM, "TOOLTHROW") && __instance.GetWillThrowTool(true)) { string activeStateName = sprintFSM.ActiveStateName; sprintFSM.SendEvent("TOOLTHROW"); ManualLogSource? log = ExtraButtonSupportPlugin.Log; if (log != null) { log.LogInfo((object)("[extra] tool bind interrupted sprint: " + activeStateName + " -> " + sprintFSM.ActiveStateName)); } } } [HarmonyPrefix] [HarmonyPatch(typeof(HeroController), "GetWillThrowTool")] private static bool UseHeldSlot(HeroController __instance, bool reportFailure, ref bool __result) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0047: Unknown result type (might be due to invalid IL or missing references) AttackToolBinding? val = Tools.Held(InputManager.ActiveDevice); if (val.HasValue) { AttackToolBinding valueOrDefault = val.GetValueOrDefault(); AttackToolBinding binding = default(AttackToolBinding); ToolItem boundAttackTool = ToolItemManager.GetBoundAttackTool(valueOrDefault, (ToolEquippedReadSource)0, ref binding); WillThrowTool.Invoke(__instance) = boundAttackTool; __result = Object.op_Implicit((Object)(object)boundAttackTool) && CanThrowTool(__instance, boundAttackTool, binding, reportFailure); return false; } return true; } } internal static class SprintFsm { internal static bool Accepts(PlayMakerFSM fsm, string eventName) { FsmState activeState = fsm.Fsm.ActiveState; FsmTransition[] array = ((activeState != null) ? activeState.Transitions : null) ?? Array.Empty<FsmTransition>(); for (int i = 0; i < array.Length; i++) { if (array[i].EventName == eventName) { return true; } } return false; } } }