using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("BetterControls")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterControls")]
[assembly: AssemblyTitle("BetterControls")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 DysonSphereProgram.Modding.BetterControls
{
[BepInPlugin("com.zach.BetterControls", "BetterControls", "0.1.7.0")]
[BepInProcess("DSPGAME.exe")]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "com.zach.BetterControls";
public const string NAME = "BetterControls";
public const string VERSION = "0.1.7.0";
private Harmony _harmony;
internal static ManualLogSource Log;
private void Awake()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
try
{
_harmony = new Harmony("com.zach.BetterControls");
_harmony.PatchAll(typeof(BetterControls));
((BaseUnityPlugin)this).Logger.LogInfo((object)"BetterControls reflection fix loaded.");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)"BetterControls failed to patch. DSP may have changed too much.");
((BaseUnityPlugin)this).Logger.LogError((object)ex);
}
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Log = null;
}
}
public static class KeyIds
{
public const int Jump = 8;
public const int Takeoff = 9;
public const int ClosePanel0 = 32;
public const int Inventory = 34;
public const int ClosePanel1 = 33;
public const int GameMenu = 47;
}
internal static class BetterControls
{
private static bool[] conflicts;
private static readonly Dictionary<int, int> indexes = new Dictionary<int, int>();
private static readonly Dictionary<int, int> groups = new Dictionary<int, int>();
private static readonly Dictionary<int, int> linked = new Dictionary<int, int>();
private static FieldInfo Field(Type type, string name)
{
return AccessTools.Field(type, name);
}
private static T GetField<T>(object obj, string name)
{
if (obj == null)
{
return default(T);
}
FieldInfo fieldInfo = Field(obj.GetType(), name);
if (fieldInfo == null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Missing field " + obj.GetType().Name + "." + name));
}
return default(T);
}
return (T)fieldInfo.GetValue(obj);
}
private static bool SetField(object obj, string name, object value)
{
if (obj == null)
{
return false;
}
FieldInfo fieldInfo = Field(obj.GetType(), name);
if (fieldInfo == null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Missing field " + obj.GetType().Name + "." + name));
}
return false;
}
fieldInfo.SetValue(obj, value);
return true;
}
private static object Call(object obj, string methodName, params object[] args)
{
if (obj == null)
{
return null;
}
MethodInfo methodInfo = AccessTools.Method(obj.GetType(), methodName, (Type[])null, (Type[])null);
if (methodInfo == null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Missing method " + obj.GetType().Name + "." + methodName));
}
return null;
}
return methodInfo.Invoke(obj, args);
}
private static CombineKey GetKey(CombineKey builtin, CombineKey overrider)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
if (!((CombineKey)(ref overrider)).IsNull())
{
return overrider;
}
return builtin;
}
public static bool InventoryKeyDown()
{
try
{
if (VFInput.override_keys != null && VFInput.override_keys.Length > 34 && !((CombineKey)(ref VFInput.override_keys[34])).IsNull())
{
return ((CombineKey)(ref VFInput.override_keys[34])).GetKeyDown();
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Inventory override check failed; falling back to E. " + ex.Message));
}
}
if (VFInput.noModifier)
{
return Input.GetKeyDown((KeyCode)101);
}
return false;
}
public static bool MenuKeyDown()
{
try
{
if (VFInput.override_keys != null && VFInput.override_keys.Length > 47 && !((CombineKey)(ref VFInput.override_keys[47])).IsNull())
{
return ((CombineKey)(ref VFInput.override_keys[47])).GetKeyDown();
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Menu override check failed; falling back to Escape. " + ex.Message));
}
}
if (VFInput.noModifier)
{
return Input.GetKeyDown((KeyCode)27);
}
return false;
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(UIGame), "_OnUpdate")]
private static IEnumerable<CodeInstruction> PatchInventoryKey(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
//IL_0042: 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_0076: Expected O, but got Unknown
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(Input), "GetKeyDown", new Type[1] { typeof(KeyCode) }, (Type[])null);
MethodInfo operandAndAdvance = AccessTools.Method(typeof(BetterControls), "InventoryKeyDown", (Type[])null, (Type[])null);
CodeMatcher val = new CodeMatcher(instructions, generator).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => CodeInstructionExtensions.LoadsConstant(ci, (Enum)(object)(KeyCode)101)), (string)null),
new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null)
});
if (!val.IsValid)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)"Could not find the hardcoded E inventory check in UIGame._OnUpdate. Skipping inventory patch.");
}
return instructions;
}
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)"Patched UIGame._OnUpdate inventory key check.");
}
return val.RemoveInstruction().SetOperandAndAdvance((object)operandAndAdvance).InstructionEnumeration();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(VFInput), "OnUpdate")]
private static void OnVFInputUpdate()
{
try
{
VFInput.escape = MenuKeyDown() && !VFInput.inputing;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Menu key patch failed this frame. " + ex.Message));
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIOptionWindow), "_OnOpen")]
private static void OptionWindowOnOpen(UIOptionWindow __instance)
{
//IL_0011: 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_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: 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_00a2: 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_00d6: 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_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_0326: Unknown result type (might be due to invalid IL or missing references)
//IL_032b: Unknown result type (might be due to invalid IL or missing references)
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
//IL_033d: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_0210: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Unknown result type (might be due to invalid IL or missing references)
//IL_021e: Unknown result type (might be due to invalid IL or missing references)
//IL_037b: Unknown result type (might be due to invalid IL or missing references)
//IL_0384: Unknown result type (might be due to invalid IL or missing references)
//IL_0393: Unknown result type (might be due to invalid IL or missing references)
//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
try
{
BuiltinKey[] builtinKeys = DSPGame.key.builtinKeys;
GameOption field = GetField<GameOption>(__instance, "tempOption");
UIKeyEntry[] field2 = GetField<UIKeyEntry[]>(__instance, "keyEntries");
if (builtinKeys == null || field2 == null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)"BetterControls could not access option window key data. UI features skipped.");
}
return;
}
CombineKey[] overrideKeys = field.overrideKeys;
int num = builtinKeys.Length;
CombineKey[] array = (CombineKey[])(object)new CombineKey[num];
indexes.Clear();
groups.Clear();
linked.Clear();
for (int i = 0; i < num; i++)
{
BuiltinKey val = builtinKeys[i];
array[i] = GetKey(val.key, overrideKeys[val.id]);
indexes[val.id] = i;
}
for (int j = 0; j < num - 1; j++)
{
CombineKey key = builtinKeys[j].key;
if (groups.ContainsKey(j))
{
continue;
}
groups[j] = -1;
for (int k = j + 1; k < num; k++)
{
CombineKey key2 = builtinKeys[k].key;
if (((CombineKey)(ref key)).IsEquals(key2.keyCode, key2.modifier, key2.noneKey))
{
groups[j] = j;
groups[k] = j;
}
}
}
if (!groups.ContainsKey(num - 1))
{
groups[num - 1] = -1;
}
conflicts = new bool[num];
for (int l = 0; l < num - 1; l++)
{
CombineKey val2 = array[l];
if (conflicts[l])
{
continue;
}
for (int m = l + 1; m < num; m++)
{
CombineKey val3 = array[m];
if ((((BuiltinKey)(ref builtinKeys[l])).conflictKeyGroup & ((BuiltinKey)(ref builtinKeys[m])).conflictKeyGroup) > 0 && (groups[l] != groups[m] || groups[l] < 0) && ((CombineKey)(ref val2)).IsEquals(val3.keyCode, val3.modifier, val3.noneKey))
{
conflicts[l] = true;
conflicts[m] = true;
}
}
}
int[] array2 = new int[6] { 9, 8, 32, 34, 33, 47 };
for (int n = 0; n < array2.Length; n += 2)
{
if (!indexes.ContainsKey(array2[n]) || !indexes.ContainsKey(array2[n + 1]))
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)("BetterControls could not find linked key ids " + array2[n] + " and " + array2[n + 1]));
}
continue;
}
int num2 = indexes[array2[n]];
int num3 = indexes[array2[n + 1]];
linked[num2] = num3;
linked[num3] = num2;
CombineKey val4 = array[num3];
if (!((CombineKey)(ref array[num2])).IsEquals(val4.keyCode, val4.modifier, val4.noneKey) && num2 >= 0 && num2 < field2.Length && (Object)(object)field2[num2] != (Object)null)
{
Call(field2[num2], "OverrideKey", field, val4.keyCode, val4.modifier, val4.noneKey);
}
}
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)"BetterControls option-window reflection patch ran.");
}
}
catch (Exception ex)
{
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogWarning((object)("BetterControls option-window patch failed: " + ex));
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(BuiltinKey), "IsKeyVaild")]
private static bool IsKeyValid(ref bool __result)
{
__result = true;
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIKeyEntry), "SetEntry")]
private static void SetEntry(UIKeyEntry __instance, int _index, BuiltinKey _builtinKey, UIOptionWindow _optionWin)
{
//IL_0000: 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)
try
{
if (_builtinKey.id < 71 || 78 < _builtinKey.id)
{
((Component)__instance.setTheKeyInput).gameObject.SetActive(true);
((Component)__instance.setTheKeyToggle).gameObject.SetActive(true);
((Component)__instance.setDefaultUIButton).gameObject.SetActive(true);
((Component)__instance.setNoneKeyUIButton).gameObject.SetActive(true);
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("SetEntry patch failed: " + ex.Message));
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIKeyEntry), "Update")]
private static void Update(UIKeyEntry __instance)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//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_0053: Unknown result type (might be due to invalid IL or missing references)
try
{
if (conflicts != null && !((Object)(object)__instance == (Object)null))
{
BuiltinKey field = GetField<BuiltinKey>(__instance, "builtinKey");
if (indexes.TryGetValue(field.id, out var value) && value >= 0 && value < conflicts.Length && conflicts[value])
{
((Graphic)__instance.keyText).color = Color.red;
}
}
}
catch
{
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIKeyEntry), "OnSetNoneKeyClick")]
private static bool OnSetNoneKeyClick(UIKeyEntry __instance)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
try
{
UIOptionWindow field = GetField<UIOptionWindow>(__instance, "optionWin");
if ((Object)(object)field == (Object)null)
{
return true;
}
GameOption val = (GameOption)Call(field, "GetTempOption");
Call(__instance, "OverrideKey", val, 0, (byte)0, true);
return false;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("OnSetNoneKeyClick patch failed: " + ex.Message));
}
return true;
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIKeyEntry), "OverrideKey")]
private static bool OverrideKey(UIKeyEntry __instance, GameOption tempOption, int keyCode, byte modifier, bool noneKey)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_040e: Unknown result type (might be due to invalid IL or missing references)
//IL_042d: Unknown result type (might be due to invalid IL or missing references)
try
{
UIOptionWindow field = GetField<UIOptionWindow>(__instance, "optionWin");
BuiltinKey field2 = GetField<BuiltinKey>(__instance, "builtinKey");
if ((Object)(object)field == (Object)null)
{
return true;
}
if (__instance.inputUIButton._isPointerEnter && Input.GetKeyDown((KeyCode)323))
{
SetField(__instance, "nextNotOn", true);
}
int id = field2.id;
if (!indexes.TryGetValue(id, out var value))
{
return true;
}
CombineKey key = field2.key;
BuiltinKey[] builtinKeys = DSPGame.key.builtinKeys;
CombineKey[] overrideKeys = tempOption.overrideKeys;
int num = builtinKeys.Length;
CombineKey[] array = (CombineKey[])(object)new CombineKey[num];
for (int i = 0; i < num; i++)
{
array[i] = GetKey(builtinKeys[i].key, overrideKeys[builtinKeys[i].id]);
}
int keyCode2 = array[value].keyCode;
byte modifier2 = array[value].modifier;
bool noneKey2 = array[value].noneKey;
int num2 = keyCode;
byte b = modifier;
bool flag = noneKey;
if (keyCode == 0 && modifier == 0 && !noneKey)
{
num2 = key.keyCode;
b = key.modifier;
flag = key.noneKey;
}
if (keyCode2 == num2 && modifier2 == b && noneKey2 == flag)
{
__instance.inputUIButton.highlighted = false;
return false;
}
if (((CombineKey)(ref key)).IsEquals(num2, b, flag))
{
((CombineKey)(ref overrideKeys[id])).Reset();
}
else
{
overrideKeys[id].keyCode = num2;
overrideKeys[id].modifier = b;
overrideKeys[id].noneKey = flag;
}
field.SetTempOption(tempOption);
__instance.inputUIButton.highlighted = false;
int num3 = -1;
for (int j = 0; j < num; j++)
{
if (j != value && conflicts != null && conflicts[j] && (((BuiltinKey)(ref builtinKeys[j])).conflictKeyGroup & ((BuiltinKey)(ref builtinKeys[value])).conflictKeyGroup) > 0 && (groups[j] != groups[value] || groups[j] < 0) && ((CombineKey)(ref array[j])).IsEquals(keyCode2, modifier2, noneKey2))
{
if (num3 > -1 && (!linked.ContainsKey(num3) || linked[num3] != j))
{
num3 = -1;
break;
}
num3 = j;
}
}
if (num3 > -1 && conflicts != null)
{
conflicts[num3] = false;
if (linked.ContainsKey(num3))
{
conflicts[linked[num3]] = false;
}
}
if (conflicts != null)
{
conflicts[value] = false;
}
for (int k = 0; k < num; k++)
{
if (k == value || (((BuiltinKey)(ref builtinKeys[k])).conflictKeyGroup & ((BuiltinKey)(ref builtinKeys[value])).conflictKeyGroup) <= 0 || (groups[k] == groups[value] && groups[k] >= 0) || !((CombineKey)(ref array[k])).IsEquals(num2, b, flag))
{
continue;
}
if (conflicts != null)
{
conflicts[k] = true;
conflicts[value] = true;
if (linked.ContainsKey(k))
{
conflicts[linked[k]] = true;
}
}
Call(__instance, "StartConflictText", k);
__instance.setTheKeyToggle.isOn = false;
((Component)__instance.waitingText).gameObject.SetActive(false);
break;
}
if (linked.ContainsKey(value))
{
UIKeyEntry[] field3 = GetField<UIKeyEntry[]>(field, "keyEntries");
int num4 = linked[value];
if (field3 != null && num4 >= 0 && num4 < field3.Length && (Object)(object)field3[num4] != (Object)null && GetField<BuiltinKey>(field3[num4], "builtinKey").id != id)
{
Call(field3[num4], "OverrideKey", tempOption, num2, b, flag);
}
}
return false;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("OverrideKey reflection patch failed; letting original run. " + ex.Message));
}
return true;
}
}
}
}