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.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MouseTweaks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("MouseTweaks")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
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;
}
}
}
namespace MouseTweaks
{
[HarmonyPatch(typeof(InventoryGrid), "GetHoveredElement")]
internal static class InventoryGridGetHoveredElementPatch
{
private static void Postfix(InventoryGrid __instance, ref Element __result)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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)
//IL_003f: 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_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
KeyboardShortcut value = MouseTweaksPlugin.MoveNDrop.Value;
if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
{
value = MouseTweaksPlugin.MoveNDrop2.Value;
if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
{
return;
}
}
if ((MouseTweaksPlugin.MoveNDrop.Value.IsKeyHeld() || MouseTweaksPlugin.MoveNDrop2.Value.IsKeyHeld()) && __result != null && Input.GetKey((KeyCode)323) && __instance.m_onSelected != null)
{
ItemData itemAt = __instance.GetInventory().GetItemAt(__instance.GetButtonPos(__result.m_go).x, __instance.GetButtonPos(__result.m_go).y);
if (itemAt != null)
{
__instance.m_onSelected(__instance, itemAt, __result.m_pos, (Modifier)2);
}
}
}
}
[BepInPlugin("Azumatt.MouseTweaks", "MouseTweaks", "1.0.2")]
public class MouseTweaksPlugin : BaseUnityPlugin
{
internal const string ModName = "MouseTweaks";
internal const string ModVersion = "1.0.2";
internal const string Author = "Azumatt";
private const string ModGUID = "Azumatt.MouseTweaks";
private static string ConfigFileName = "Azumatt.MouseTweaks.cfg";
private static string ConfigFileFullPath;
private readonly Harmony _harmony = new Harmony("Azumatt.MouseTweaks");
public static readonly ManualLogSource MouseTweaksLogger;
internal static ConfigEntry<KeyboardShortcut> InventoryUseItemKeyCodeConfig;
internal static ConfigEntry<KeyboardShortcut> MoveNDrop;
internal static ConfigEntry<KeyboardShortcut> MoveNDrop2;
public void Awake()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: 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)
InventoryUseItemKeyCodeConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Input", "InventoryUseItem", new KeyboardShortcut((KeyCode)324, Array.Empty<KeyCode>()), "Keybinding for using/consuming/equipping an item in the inventory (Mouse1 = right mouse button).\nIf this is set to anything other than Mouse1, you no longer have to hold shift to split a stack when right clicking.\nAvailable KeyCodes can be found here: https://docs.unity3d.com/ScriptReference/KeyCode.html");
MoveNDrop = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Input", "Move & Drop Key1", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), "Keybinding that is held down to quick move or drop items from the player inventory.\nIf this is blank (None), the behaviour will not run and moving/dropping items quickly won't happen.\nAvailable KeyCodes can be found here: https://docs.unity3d.com/ScriptReference/KeyCode.html");
MoveNDrop2 = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Input", "Move & Drop Key2", new KeyboardShortcut((KeyCode)305, Array.Empty<KeyCode>()), "Alternative Keybinding that is held down to quick move or drop items from the player inventory. This is just defining a secondary key that you can also hold down.\nIf this is blank (None), the behaviour will not run and moving/dropping items quickly won't happen.\nAvailable KeyCodes can be found here: https://docs.unity3d.com/ScriptReference/KeyCode.html");
Assembly executingAssembly = Assembly.GetExecutingAssembly();
_harmony.PatchAll(executingAssembly);
SetupWatcher();
}
private void OnDestroy()
{
((BaseUnityPlugin)this).Config.Save();
}
private void SetupWatcher()
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
fileSystemWatcher.Changed += ReadConfigValues;
fileSystemWatcher.Created += ReadConfigValues;
fileSystemWatcher.Renamed += ReadConfigValues;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
}
private void ReadConfigValues(object sender, FileSystemEventArgs e)
{
if (!File.Exists(ConfigFileFullPath))
{
return;
}
try
{
MouseTweaksLogger.LogDebug((object)"ReadConfigValues called");
((BaseUnityPlugin)this).Config.Reload();
}
catch
{
MouseTweaksLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
MouseTweaksLogger.LogError((object)"Please check your config entries for spelling and format!");
}
}
static MouseTweaksPlugin()
{
string configPath = Paths.ConfigPath;
char directorySeparatorChar = Path.DirectorySeparatorChar;
ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
MouseTweaksLogger = Logger.CreateLogSource("MouseTweaks");
InventoryUseItemKeyCodeConfig = null;
MoveNDrop = null;
MoveNDrop2 = null;
}
}
public static class KeyboardExtensions
{
public static bool IsKeyDown(this KeyboardShortcut shortcut)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey))
{
return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
}
return false;
}
public static bool IsKeyHeld(this KeyboardShortcut shortcut)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey))
{
return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
}
return false;
}
}
}
namespace MouseTweaks.DropSingleItem
{
[HarmonyPatch(typeof(InventoryGui), "UpdateItemDrag")]
internal class InventoryGui_UpdateItemDrag
{
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
MethodInfo method = typeof(ZInput).GetMethod("GetMouseButton", new Type[1] { typeof(int) });
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int i = 1; i < list.Count; i++)
{
if (list[i - 1].opcode == OpCodes.Ldc_I4_1 && CodeInstructionExtensions.Calls(list[i], method))
{
list[i - 1] = new CodeInstruction(OpCodes.Nop, (object)null);
list[i] = new CodeInstruction(OpCodes.Ldc_I4_S, (object)0);
}
}
return list.AsEnumerable();
}
}
[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
internal class InventoryGui_OnRightClickItem
{
public static bool Prefix(InventoryGui __instance, ref int ___m_dragAmount, InventoryGrid grid, ItemData item, Vector2i pos)
{
//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_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
bool flag = (Object)(object)__instance.m_dragGo != (Object)null;
KeyboardShortcut value = MouseTweaksPlugin.InventoryUseItemKeyCodeConfig.Value;
bool flag2 = (int)((KeyboardShortcut)(ref value)).MainKey == 324;
bool flag3 = flag2 && Input.GetKey((KeyCode)304);
if (!flag2 || flag3)
{
if (!flag && item != null && item.m_stack > 1)
{
__instance.SetupDragItem(item, grid.GetInventory(), item.m_stack / 2);
return false;
}
if (flag3)
{
return false;
}
}
if (!flag)
{
return flag2;
}
ItemData dragItem = __instance.m_dragItem;
if (!Utils.CanStackItem(dragItem, item))
{
return false;
}
Inventory dragInventory = __instance.m_dragInventory;
int dragAmount = __instance.m_dragAmount;
int stack = dragItem.m_stack;
___m_dragAmount = 1;
__instance.OnSelectedItem(grid, item, pos, (Modifier)0);
int num = dragAmount - (stack - dragItem.m_stack);
if (num > 0)
{
__instance.SetupDragItem(dragItem, dragInventory, num);
}
return false;
}
}
[HarmonyPatch(typeof(InventoryGui), "Awake")]
internal class InventoryGui_Awake
{
public static void Postfix(InventoryGui __instance, Button ___m_dropButton)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
InventoryGui __instance2 = __instance;
((UnityEvent)((Component)___m_dropButton).gameObject.AddComponent<RightClickButtonComponent>().OnRightClick).AddListener((UnityAction)delegate
{
OnDropSingleOutside(__instance2);
});
}
private static void OnDropSingleOutside(InventoryGui __instance)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)__instance.m_dragGo))
{
return;
}
ItemData dragItem = __instance.m_dragItem;
Inventory dragInventory = __instance.m_dragInventory;
int dragAmount = __instance.m_dragAmount;
int stack = dragItem.m_stack;
MouseTweaksPlugin.MouseTweaksLogger.LogDebug((object)("Drop single item " + dragItem.m_shared.m_name));
if (!dragInventory.ContainsItem(dragItem))
{
__instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
}
else if (((Humanoid)Player.m_localPlayer).DropItem(dragInventory, dragItem, 1))
{
__instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
int num = dragAmount - (stack - dragItem.m_stack);
if (dragInventory.ContainsItem(dragItem) && num > 0)
{
__instance.SetupDragItem(dragItem, dragInventory, num);
}
else
{
__instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
}
__instance.UpdateCraftingPanel(false);
}
}
}
[HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")]
internal class InventoryGrid_UpdateInventory
{
public static void Postfix(InventoryGrid __instance, Inventory inventory, ItemData dragItem)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Invalid comparison between Unknown and I4
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
KeyboardShortcut value = MouseTweaksPlugin.InventoryUseItemKeyCodeConfig.Value;
if ((int)((KeyboardShortcut)(ref value)).MainKey != 324 && dragItem == null && MouseTweaksPlugin.InventoryUseItemKeyCodeConfig.Value.IsKeyDown())
{
ItemData item = __instance.GetItem(new Vector2i(Input.mousePosition));
if (item != null && Object.op_Implicit((Object)(object)Player.m_localPlayer))
{
((Humanoid)Player.m_localPlayer).UseItem(inventory, item, true);
}
}
}
}
[HarmonyPatch(typeof(InventoryGrid), "OnLeftClick")]
internal class InventoryGrid_OnLeftClick
{
public struct State
{
public bool DoubleClicked;
}
private const float DoubleClickThreshold = 0.2f;
private static float LastItemClickedTime;
public static bool Prefix(ref State __state)
{
__state.DoubleClicked = (double)Time.unscaledTime - (double)LastItemClickedTime < 0.200000002980232;
LastItemClickedTime = Time.unscaledTime;
InventoryGui instance = InventoryGui.instance;
if (!__state.DoubleClicked || !Object.op_Implicit((Object)(object)instance.m_dragGo))
{
return true;
}
__state.DoubleClicked = false;
GrabFullStackItemDrag(instance);
return false;
}
public static void Postfix(State __state)
{
InventoryGui instance = InventoryGui.instance;
if (__state.DoubleClicked && Object.op_Implicit((Object)(object)instance.m_dragGo))
{
GrabFullStackItemDrag(instance);
}
}
private static void GrabFullStackItemDrag(InventoryGui __instance)
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
int dragAmount = __instance.m_dragAmount;
Container currentContainer = __instance.m_currentContainer;
if ((Object)(object)currentContainer != (Object)null)
{
GrabFullStackItemDrag(__instance, currentContainer.GetInventory());
}
GrabFullStackItemDrag(__instance, ((Humanoid)Player.m_localPlayer).GetInventory());
ItemData dragItem = __instance.m_dragItem;
int stack = dragItem.m_stack;
if (dragAmount != stack)
{
__instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
__instance.SetupDragItem(dragItem, __instance.m_dragInventory, dragItem.m_stack);
__instance.UpdateCraftingPanel(false);
}
}
private static void GrabFullStackItemDrag(InventoryGui __instance, Inventory inventory)
{
ItemData dragItem = __instance.m_dragItem;
Inventory dragInventory = __instance.m_dragInventory;
List<ItemData> list = new List<ItemData>();
inventory.GetAllItems(dragItem.m_shared.m_name, list);
while (list.Any() && dragItem.m_stack < dragItem.m_shared.m_maxStackSize)
{
ItemData val = list.Last();
list.RemoveAt(list.Count - 1);
if (Utils.CanStackItem(dragItem, val))
{
dragInventory.MoveItemToThis(inventory, val, val.m_stack, dragItem.m_gridPos.x, dragItem.m_gridPos.y);
}
}
}
}
[HarmonyPatch(typeof(Button), "OnPointerClick")]
internal class Button_OnPointerClick
{
public static void Postfix(Button __instance, PointerEventData eventData)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)eventData.button == 1 && ((UIBehaviour)__instance).IsActive() && ((Selectable)__instance).IsInteractable())
{
RightClickButtonComponent component = ((Component)__instance).GetComponent<RightClickButtonComponent>();
if (Object.op_Implicit((Object)(object)component))
{
((UnityEvent)component.OnRightClick).Invoke();
}
}
}
}
internal static class InventoryGui_Extensions
{
public static void SetupDragItem(this InventoryGui instance, ItemData item, Inventory inventory, int amount)
{
Traverse.Create((object)instance).Method("SetupDragItem", new Type[3]
{
typeof(ItemData),
typeof(Inventory),
typeof(int)
}, (object[])null).GetValue(new object[3] { item, inventory, amount });
}
public static void UpdateCraftingPanel(this InventoryGui instance, bool focusView = false)
{
Traverse.Create((object)instance).Method("UpdateCraftingPanel", new Type[1] { typeof(bool) }, (object[])null).GetValue(new object[1] { focusView });
}
public static void OnSelectedItem(this InventoryGui instance, InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod)
{
//IL_005b: 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)
Traverse.Create((object)instance).Method("OnSelectedItem", new Type[4]
{
typeof(InventoryGrid),
typeof(ItemData),
typeof(Vector2i),
typeof(Modifier)
}, (object[])null).GetValue(new object[4] { grid, item, pos, mod });
}
}
internal class RightClickButtonComponent : MonoBehaviour
{
public ButtonClickedEvent OnRightClick = new ButtonClickedEvent();
}
internal class Utils
{
public static bool CanStackItem(ItemData a, ItemData b)
{
if (a != null && b != null)
{
if (a != b && !(a.m_shared.m_name != b.m_shared.m_name) && a.m_shared.m_maxStackSize != 1 && b.m_shared.m_maxStackSize != 1)
{
if (a.m_shared.m_maxQuality > 1 || b.m_shared.m_maxQuality > 1)
{
return a.m_quality == b.m_quality;
}
return true;
}
return false;
}
return true;
}
}
}