Decompiled source of LimitlessPerks v1.1.0

plugins/LimitlessPerks/LimitlessPerks.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using LimitlessPerks.Core;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("LimitlessPerks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("LimitlessPerks")]
[assembly: AssemblyTitle("LimitlessPerks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[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.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;
		}
	}
	[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 LimitlessPerks
{
	public static class ConfigManager
	{
		public static bool EnabledLimitlessPerk;
	}
	[BepInPlugin("com.prideunique.limitlessperks", "LimitlessPerks", "1.1.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.prideunique.limitlessperks";

		public const string PLUGIN_NAME = "LimitlessPerks";

		public const string PLUGIN_VERSION = "1.1.0";

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)4;
			Harmony val = new Harmony("com.prideunique.limitlessperks");
			Type[] types = typeof(Plugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.GetCustomAttribute<PatchOnEntryAttribute>() != null)
				{
					val.PatchAll(type);
				}
			}
		}
	}
}
namespace LimitlessPerks.Patches
{
	[PatchOnEntry]
	[HarmonyPatch]
	public class ENT_PlayerPatch
	{
		[HarmonyPatch(typeof(ENT_Player), "CreateCommands")]
		[HarmonyPostfix]
		private static void ENT_PlayerCreateCommands(ENT_Player __instance)
		{
			ENT_Player __instance2 = __instance;
			CommandConsole.AddCommand("addperks", (Action<string[]>)delegate(string[] args)
			{
				//IL_0100: 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)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)__instance2 == (Object)null) && args != null && args.Length > 1 && int.TryParse(args[1], out var result) && result > 0)
				{
					Perk perkAsset = CL_AssetManager.GetPerkAsset(args[0], "");
					if (!((Object)(object)perkAsset == (Object)null))
					{
						Perk val = Object.Instantiate<Perk>(perkAsset);
						bool flag = false;
						PerkModule_ItemAdder val2 = null;
						for (int num = val.modules.Count - 1; num >= 0; num--)
						{
							PerkModule val3 = val.modules[num];
							if (val3 != null && ((object)val3).GetType() == typeof(PerkModule_ItemAdder))
							{
								flag = true;
								val2 = (PerkModule_ItemAdder)(object)((val3 is PerkModule_ItemAdder) ? val3 : null);
								break;
							}
						}
						if (flag && result > 1)
						{
							for (int i = 1; i < result; i++)
							{
								List<Item> list = new List<Item>();
								foreach (Item_Object item in val2.itemsToAdd)
								{
									if (!((Object)(object)item == (Object)null))
									{
										Item clone = item.itemData.GetClone();
										clone.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f;
										clone.bagRotation = Quaternion.LookRotation(clone.upDirection);
										list.Add(clone);
									}
								}
								Inventory.instance.LoadItemsIntoBag(list);
							}
						}
						__instance2.AddPerk(val, result);
					}
				}
			}, true);
			CommandConsole.AddCommand("enablelimitlessperks", (Action<string[]>)delegate
			{
				ConfigManager.EnabledLimitlessPerk = true;
			}, true);
			CommandConsole.AddCommand("disablelimitlessperks", (Action<string[]>)delegate
			{
				ConfigManager.EnabledLimitlessPerk = false;
			}, true);
			CommandConsole.AddCommand("togglelimitlessperks", (Action<string[]>)delegate
			{
				ConfigManager.EnabledLimitlessPerk = !ConfigManager.EnabledLimitlessPerk;
			}, true);
		}

		public static float MaxGravityReplacement(float a, float b)
		{
			if (!ConfigManager.EnabledLimitlessPerk)
			{
				return Mathf.Max(a, b);
			}
			return a;
		}

		[HarmonyPatch(typeof(ENT_Player), "Movement")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> ENT_PlayerMovement(IEnumerable<CodeInstruction> instructions)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(Mathf), "Max", new Type[2]
			{
				typeof(float),
				typeof(float)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ENT_PlayerPatch), "MaxGravityReplacement", new Type[2]
			{
				typeof(float),
				typeof(float)
			}, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				return list.AsEnumerable();
			}
			return new CodeMatcher((IEnumerable<CodeInstruction>)list, (ILGenerator)null).Start().MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)0.2f, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null)
			}).ThrowIfInvalid("Failed to match first `Mathf.Max` in ENT_Player.Movement")
				.SetOperandAndAdvance((object)methodInfo2)
				.InstructionEnumeration();
		}

		public static float DamageResistClampReplacement(float value, float min, float max)
		{
			if (!ConfigManager.EnabledLimitlessPerk)
			{
				return Mathf.Clamp(value, min, max);
			}
			if (value < min)
			{
				return min;
			}
			return value;
		}

		[HarmonyPatch(typeof(ENT_Player), "Damage")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> ENT_PlayerDamage(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(Mathf), "Clamp", new Type[3]
			{
				typeof(float),
				typeof(float),
				typeof(float)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ENT_PlayerPatch), "DamageResistClampReplacement", new Type[3]
			{
				typeof(float),
				typeof(float),
				typeof(float)
			}, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				return list.AsEnumerable();
			}
			return new CodeMatcher((IEnumerable<CodeInstruction>)list, (ILGenerator)null).Start().MatchForward(true, (CodeMatch[])(object)new CodeMatch[5]
			{
				new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"damageResist", (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null)
			}).ThrowIfInvalid("Failed to match first `Mathf.Clamp` in ENT_Player.Damage")
				.SetOperandAndAdvance((object)methodInfo2)
				.InstructionEnumeration();
		}
	}
	[PatchOnEntry]
	[HarmonyPatch]
	public static class PerkPatch
	{
		public class PerkOriginalData
		{
			public int stackMax;

			public bool canStack;

			public List<string> buffIds;

			public List<string> baseBuffIds;
		}

		private static Dictionary<Perk, PerkOriginalData> _originalPerkData = new Dictionary<Perk, PerkOriginalData>();

		[HarmonyPatch(typeof(Perk), "Update")]
		[HarmonyPrefix]
		private static void PerkUpdate(ref Perk __instance)
		{
			PerkOriginalData value;
			bool flag = _originalPerkData.TryGetValue(__instance, out value);
			if (!flag)
			{
				PerkOriginalData perkOriginalData = new PerkOriginalData();
				perkOriginalData.stackMax = __instance.stackMax;
				perkOriginalData.canStack = __instance.canStack;
				List<string> list = new List<string>();
				for (int i = 0; i < __instance.buff.buffs.Count; i++)
				{
					Buff val = __instance.buff.buffs[i];
					if (val != null)
					{
						list.Add(val.id);
					}
				}
				perkOriginalData.buffIds = list;
				List<string> list2 = new List<string>();
				for (int j = 0; j < __instance.baseBuff.buffs.Count; j++)
				{
					Buff val2 = __instance.buff.buffs[j];
					if (val2 != null)
					{
						list2.Add(val2.id);
					}
				}
				perkOriginalData.baseBuffIds = list2;
				_originalPerkData.Add(__instance, perkOriginalData);
			}
			if (!ConfigManager.EnabledLimitlessPerk)
			{
				if (!flag)
				{
					return;
				}
				__instance.stackMax = value.stackMax;
				__instance.canStack = value.canStack;
				if (value.baseBuffIds == null || value.baseBuffIds.Count <= 0)
				{
					return;
				}
				for (int num = __instance.buff.buffs.Count - 1; num >= 0; num--)
				{
					Buff val3 = __instance.buff.buffs[num];
					if (val3 != null)
					{
						bool num2 = value.baseBuffIds.Contains(val3.id);
						bool flag2 = value.buffIds != null && value.buffIds.Contains(val3.id);
						if (num2 && !flag2)
						{
							__instance.baseBuff.buffs.Add(val3);
							__instance.buff.buffs.RemoveAt(num);
						}
					}
				}
				return;
			}
			for (int num3 = __instance.baseBuff.buffs.Count - 1; num3 >= 0; num3--)
			{
				Buff val4 = __instance.baseBuff.buffs[num3];
				if (val4 != null)
				{
					__instance.buff.buffs.Add(val4);
					__instance.baseBuff.buffs.Remove(val4);
				}
			}
			__instance.stackMax = int.MaxValue;
			__instance.canStack = true;
		}
	}
}
namespace LimitlessPerks.Core
{
	[PublicAPI]
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	internal sealed class PatchOnEntryAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}