Decompiled source of BigActions v1.0.0

BigActions.dll

Decompiled 7 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BigActions.Features.Discovery;
using BigActions.Features.SelfStow;
using BigActions.Game;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BigActions")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BigActions")]
[assembly: AssemblyTitle("BigActions")]
[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 BigActions
{
	[BepInPlugin("com.ruan.bigactions", "Big Actions", "1.0.0")]
	public sealed class Plugin : BasePlugin
	{
		public const string Guid = "com.ruan.bigactions";

		public const string Name = "Big Actions";

		public const string Version = "1.0.0";

		internal static ManualLogSource Logger;

		public override void Load()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BasePlugin)this).Log;
			PluginConfig.Init(((BasePlugin)this).Config);
			if (PluginConfig.EnableInteropDumper.Value)
			{
				InteropDumper.Dump();
			}
			if (PluginConfig.EnableGuardPatches.Value)
			{
				new Harmony("com.ruan.bigactions").PatchAll(typeof(SelfGuardPatches));
				Logger.LogInfo((object)"SelfGuardPatches aplicados.");
			}
			ClassInjector.RegisterTypeInIl2Cpp<SelfStowInput>();
			((BasePlugin)this).AddComponent<SelfStowInput>();
			ManualLogSource logger = Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(12, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Big Actions");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" carregado.");
			}
			logger.LogInfo(val);
		}
	}
	internal static class PluginConfig
	{
		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<KeyCode> BackpackKey;

		public static ConfigEntry<KeyCode> BeltKey;

		public static ConfigEntry<BothFullBehavior> BothFull;

		public static ConfigEntry<bool> EnableGuardPatches;

		public static ConfigEntry<bool> EnableInteropDumper;

		public static ConfigEntry<bool> Verbose;

		public static void Init(ConfigFile config)
		{
			Enabled = config.Bind<bool>("General", "Enabled", true, "Liga/desliga o mod.");
			BackpackKey = config.Bind<KeyCode>("Keys", "Backpack", (KeyCode)49, "Tecla pra mochila (toggle contextual: guarda/retira/troca conforme o estado).");
			BeltKey = config.Bind<KeyCode>("Keys", "Belt", (KeyCode)50, "Tecla pro cinto (toggle contextual).");
			BothFull = config.Bind<BothFullBehavior>("General", "BothOccupied", BothFullBehavior.DoNothing, "O que fazer quando mao E container estao cheios. O jogo nao tem swap nativo e voce so tem uma mao, entao troca atomica nao existe. DoNothing = seguro, nao faz nada. TryPlaceOverFull = experimental, so funciona se colocar num container cheio devolver o item antigo pra mao (a confirmar in-game).");
			EnableGuardPatches = config.Bind<bool>("Advanced", "EnableGuardPatches", false, "Aplica Harmony prefixes pra neutralizar o bloqueio de auto-interacao nos proprios pockets. So ligue se a predicao do cliente brigar com o mod; o caminho principal chama os Commands direto, pulando a mira.");
			EnableInteropDumper = config.Bind<bool>("Dev", "EnableInteropDumper", false, "Ferramenta de dev: despeja tipos/membros da interop que batem em keywords, num txt, no boot. Desligado por padrao.");
			Verbose = config.Bind<bool>("General", "Verbose", false, "Logs verbosos de cada acao.");
		}
	}
}
namespace BigActions.Game
{
	internal static class GameBindings
	{
		public static PlayerCharacter? LocalPlayer
		{
			get
			{
				if (!((Object)(object)WorldManager.localPlayerCharacter == (Object)null))
				{
					return WorldManager.localPlayerCharacter;
				}
				return null;
			}
		}

		public static PropHome? BackpackSlot(PlayerCharacter player)
		{
			PlayerRegistry registry = player.registry;
			if (registry != null)
			{
				return registry.backpackPocket;
			}
			return null;
		}

		public static PropHome? BeltSlot(PlayerCharacter player)
		{
			PlayerRegistry registry = player.registry;
			if (registry != null)
			{
				return registry.holsterPocket;
			}
			return null;
		}

		public static bool HandOccupied(PlayerCharacter player)
		{
			PlayerHands hands = player.hands;
			if (hands != null)
			{
				return hands.isHoldingSomething;
			}
			return false;
		}

		public static Prop? HeldProp(PlayerCharacter player)
		{
			PlayerHands hands = player.hands;
			if (hands != null)
			{
				return hands.heldProp;
			}
			return null;
		}

		public static bool IsHomeEmpty(PropHome home)
		{
			return (Object)(object)home.pinnedProp == (Object)null;
		}

		public static Prop? PinnedProp(PropHome home)
		{
			return home.pinnedProp;
		}

		public static bool HomeAccepts(PropHome home, Prop prop)
		{
			return home.IsSafeToPlace(prop);
		}

		public static List<PropHome>? ContentPockets(Prop wearable)
		{
			return wearable.childPropHomes;
		}

		public static void PlaceInHome(PlayerCharacter player, Prop prop, PropHome home)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			player.playerNetworking.CmdPlaceInHome(prop, home.shellReference);
		}

		public static void TakeFromHome(PlayerCharacter player, Prop prop)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			player.playerNetworking.CmdPickUp(new PlayerHeldInformation(prop));
		}

		public static string HomeName(PropHome home)
		{
			//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)
			return ((object)home.saveableHomeName/*cast due to .constrained prefix*/).ToString();
		}
	}
	internal sealed class ItemContainer
	{
		private readonly PlayerCharacter _player;

		private readonly PropHome _equipSlot;

		private Prop? _held;

		private Prop? _wearable;

		private PropHome? _emptyFitPocket;

		private PropHome? _occupiedPocket;

		public ContainerKind Kind { get; }

		public ItemContainer(PlayerCharacter player, ContainerKind kind, PropHome equipSlot)
		{
			_player = player;
			Kind = kind;
			_equipSlot = equipSlot;
		}

		public void Toggle()
		{
			_held = GameBindings.HeldProp(_player);
			_wearable = GameBindings.PinnedProp(_equipSlot);
			_emptyFitPocket = null;
			_occupiedPocket = null;
			bool heldFitsEquipSlot = (Object)(object)_held != (Object)null && GameBindings.IsHomeEmpty(_equipSlot) && GameBindings.HomeAccepts(_equipSlot, _held);
			int value = 0;
			if ((Object)(object)_wearable != (Object)null)
			{
				List<PropHome> val = GameBindings.ContentPockets(_wearable);
				if (val != null)
				{
					value = val.Count;
					if ((Object)(object)_held != (Object)null)
					{
						_emptyFitPocket = FirstEmptyAccepting(val, _held);
					}
					_occupiedPocket = FirstOccupied(val);
				}
			}
			StowAction stowAction = StowDecider.Decide(new StowState((Object)(object)_held != (Object)null, heldFitsEquipSlot, (Object)(object)_wearable != (Object)null, (Object)(object)_emptyFitPocket != (Object)null, (Object)(object)_occupiedPocket != (Object)null));
			Log($"held={(Object)(object)_held != (Object)null} equipado={(Object)(object)_wearable != (Object)null} bolsos={value} vaga={(Object)(object)_emptyFitPocket != (Object)null} item={(Object)(object)_occupiedPocket != (Object)null} -> {stowAction}");
			StowExecutor.Execute(stowAction, this);
		}

		public void Equip()
		{
			if (!((Object)(object)_held == (Object)null))
			{
				GameBindings.PlaceInHome(_player, _held, _equipSlot);
			}
		}

		public void Unequip()
		{
			if (!((Object)(object)_wearable == (Object)null))
			{
				GameBindings.TakeFromHome(_player, _wearable);
			}
		}

		public void Stow()
		{
			if (!((Object)(object)_held == (Object)null) && !((Object)(object)_emptyFitPocket == (Object)null))
			{
				GameBindings.PlaceInHome(_player, _held, _emptyFitPocket);
			}
		}

		public void Take()
		{
			if (!((Object)(object)_occupiedPocket == (Object)null))
			{
				Prop val = GameBindings.PinnedProp(_occupiedPocket);
				if (!((Object)(object)val == (Object)null))
				{
					GameBindings.TakeFromHome(_player, val);
				}
			}
		}

		public void Swap()
		{
			if (!((Object)(object)_held == (Object)null) && !((Object)(object)_occupiedPocket == (Object)null))
			{
				GameBindings.PlaceInHome(_player, _held, _occupiedPocket);
			}
		}

		private static PropHome? FirstEmptyAccepting(List<PropHome> pockets, Prop held)
		{
			for (int i = 0; i < pockets.Count; i++)
			{
				PropHome val = pockets[i];
				if ((Object)(object)val != (Object)null && GameBindings.IsHomeEmpty(val) && GameBindings.HomeAccepts(val, held))
				{
					return val;
				}
			}
			return null;
		}

		private static PropHome? FirstOccupied(List<PropHome> pockets)
		{
			for (int i = 0; i < pockets.Count; i++)
			{
				PropHome val = pockets[i];
				if ((Object)(object)val != (Object)null && !GameBindings.IsHomeEmpty(val))
				{
					return val;
				}
			}
			return null;
		}

		private void Log(string msg)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if (PluginConfig.Verbose.Value)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(3, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ContainerKind>(Kind);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(msg);
				}
				logger.LogInfo(val);
			}
		}
	}
	internal static class LocalPlayer
	{
		public static bool TryGetContainer(ContainerKind kind, out ItemContainer container)
		{
			container = null;
			PlayerCharacter localPlayer = GameBindings.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			PropHome val = ((kind == ContainerKind.Backpack) ? GameBindings.BackpackSlot(localPlayer) : GameBindings.BeltSlot(localPlayer));
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			container = new ItemContainer(localPlayer, kind, val);
			return true;
		}

		public static bool InGameplay()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if ((Object)(object)GameBindings.LocalPlayer == (Object)null)
			{
				return false;
			}
			if ((int)Cursor.lockState != 1)
			{
				return false;
			}
			return true;
		}
	}
}
namespace BigActions.Features.SelfStow
{
	public enum BothFullBehavior
	{
		DoNothing,
		TryPlaceOverFull
	}
	public enum ContainerKind
	{
		Backpack,
		Belt
	}
	internal static class SelfGuardPatches
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static bool ForceAllowGrab(PropHome __instance, ref bool __result)
		{
			if (!IsLocalOwnPocket(__instance))
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static bool ForceAllowPlace(PropHome __instance, ref bool __result)
		{
			if (!IsLocalOwnPocket(__instance))
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool IsLocalOwnPocket(PropHome home)
		{
			PlayerCharacter localPlayer = GameBindings.LocalPlayer;
			if ((Object)(object)localPlayer != (Object)null && (Object)(object)home != (Object)null)
			{
				return (Object)(object)home.parentCharacter == (Object)(object)localPlayer;
			}
			return false;
		}
	}
	internal sealed class SelfStowInput : MonoBehaviour
	{
		public SelfStowInput(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Update()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (PluginConfig.Enabled.Value && LocalPlayer.InGameplay())
			{
				if (Input.GetKeyDown(PluginConfig.BackpackKey.Value))
				{
					Trigger(ContainerKind.Backpack);
				}
				else if (Input.GetKeyDown(PluginConfig.BeltKey.Value))
				{
					Trigger(ContainerKind.Belt);
				}
			}
		}

		private static void Trigger(ContainerKind kind)
		{
			if (LocalPlayer.TryGetContainer(kind, out ItemContainer container))
			{
				container.Toggle();
			}
		}
	}
	public enum StowAction
	{
		None,
		Equip,
		Unequip,
		Stow,
		Take,
		Swap
	}
	public static class StowDecider
	{
		public static StowAction Decide(StowState s)
		{
			if (s.HeldFitsEquipSlot)
			{
				return StowAction.Equip;
			}
			if (!s.WearableEquipped)
			{
				return StowAction.None;
			}
			if (s.HandOccupied)
			{
				if (s.PocketHasRoomForHeld)
				{
					return StowAction.Stow;
				}
				if (s.PocketHasItem)
				{
					return StowAction.Swap;
				}
				return StowAction.None;
			}
			if (s.PocketHasItem)
			{
				return StowAction.Take;
			}
			return StowAction.Unequip;
		}
	}
	internal static class StowExecutor
	{
		public static void Execute(StowAction action, ItemContainer container)
		{
			switch (action)
			{
			case StowAction.Equip:
				container.Equip();
				break;
			case StowAction.Unequip:
				container.Unequip();
				break;
			case StowAction.Stow:
				container.Stow();
				break;
			case StowAction.Take:
				container.Take();
				break;
			case StowAction.Swap:
				if (PluginConfig.BothFull.Value == BothFullBehavior.TryPlaceOverFull)
				{
					container.Swap();
				}
				break;
			case StowAction.None:
				break;
			}
		}
	}
	public readonly struct StowState
	{
		public readonly bool HandOccupied;

		public readonly bool HeldFitsEquipSlot;

		public readonly bool WearableEquipped;

		public readonly bool PocketHasRoomForHeld;

		public readonly bool PocketHasItem;

		public StowState(bool handOccupied, bool heldFitsEquipSlot, bool wearableEquipped, bool pocketHasRoomForHeld, bool pocketHasItem)
		{
			HandOccupied = handOccupied;
			HeldFitsEquipSlot = heldFitsEquipSlot;
			WearableEquipped = wearableEquipped;
			PocketHasRoomForHeld = pocketHasRoomForHeld;
			PocketHasItem = pocketHasItem;
		}
	}
}
namespace BigActions.Features.Discovery
{
	internal static class InteropDumper
	{
		private static readonly string[] Keywords = new string[18]
		{
			"Pocket", "Holster", "Backpack", "Belt", "Home", "Pin", "Prop", "Stow", "Hand", "Held",
			"Cmd", "Rpc", "Server", "Snatch", "Grab", "Place", "Inventory", "Container"
		};

		private static readonly string[] TargetAssemblies = new string[2] { "Assembly-CSharp", "Mirror" };

		public static void Dump()
		{
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				foreach (Assembly item in AppDomain.CurrentDomain.GetAssemblies().Where(delegate(Assembly a)
				{
					string name = a.GetName().Name;
					return name != null && ((ReadOnlySpan<string>)TargetAssemblies).Contains(name);
				}))
				{
					StringBuilder stringBuilder2 = stringBuilder;
					StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(8, 1, stringBuilder2);
					handler.AppendLiteral("=== ");
					handler.AppendFormatted(item.GetName().Name);
					handler.AppendLiteral(" ===");
					stringBuilder2.AppendLine(ref handler);
					foreach (Type item2 in from t in SafeTypes(item)
						orderby t.FullName
						select t)
					{
						if (Matches(item2.Name))
						{
							stringBuilder.AppendLine(item2.FullName);
							MemberInfo[] members = item2.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
							foreach (MemberInfo memberInfo in members)
							{
								stringBuilder.Append("    ").AppendLine(memberInfo.ToString());
							}
						}
					}
				}
				string text = Path.Combine(Paths.PluginPath, "BigActions");
				Directory.CreateDirectory(text);
				string text2 = Path.Combine(text, "interop-dump.txt");
				File.WriteAllText(text2, stringBuilder.ToString());
				ManualLogSource logger = Plugin.Logger;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(26, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("InteropDumper: escrito em ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
				}
				logger.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("InteropDumper falhou: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				logger2.LogError(val2);
			}
		}

		private static bool Matches(string name)
		{
			return Keywords.Any((string k) => name.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0);
		}

		private static Type[] SafeTypes(Assembly asm)
		{
			try
			{
				return asm.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type t) => t != null).ToArray();
			}
		}
	}
}