Decompiled source of EasyMode v1.0.8

EasyMode.dll

Decompiled 3 weeks ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("EasyMode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+df08f0405cb9c0007f0f7dde273bd2bed33ffe5d")]
[assembly: AssemblyProduct("EasyMode")]
[assembly: AssemblyTitle("EasyMode")]
[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 EasyMode
{
	internal static class EasyModeCombatPatches
	{
		internal static float DamageTakenMultiplier = 0.5f;

		internal static float DamageDealtMultiplier = 2f;

		private static Entity ResolveHitAttacker(HitEvent e)
		{
			if (e == null)
			{
				return null;
			}
			try
			{
				Entity value = Traverse.Create((object)e).Field<Entity>("_source").Value;
				if ((Object)(object)value != (Object)null)
				{
					return value;
				}
			}
			catch
			{
			}
			try
			{
				StaticHitbox value2 = Traverse.Create((object)e).Field<StaticHitbox>("<hitbox>k__BackingField").Value;
				if ((Object)(object)value2 != (Object)null)
				{
					return Traverse.Create((object)value2).Field<Entity>("_e").Value;
				}
			}
			catch
			{
			}
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(HitEvent), "<hitbox>k__BackingField") ?? AccessTools.Field(typeof(HitEvent), "hitbox");
				if (fieldInfo != null)
				{
					object? value3 = fieldInfo.GetValue(e);
					StaticHitbox val = (StaticHitbox)((value3 is StaticHitbox) ? value3 : null);
					if ((Object)(object)val != (Object)null)
					{
						return Traverse.Create((object)val).Field<Entity>("_e").Value;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static void ApplyOutgoingPlayerHit(Entity victim, HitEvent e)
		{
			float num = 0f;
			FieldInfo fieldInfo = AccessTools.Field(typeof(HitEvent), "<baseDamage>k__BackingField");
			if (fieldInfo != null)
			{
				try
				{
					num = (float)fieldInfo.GetValue(e);
				}
				catch
				{
					num = 0f;
				}
			}
			if (!Mathf.Approximately(num, 0f))
			{
				float num2 = num * DamageDealtMultiplier;
				try
				{
					fieldInfo.SetValue(e, num2);
				}
				catch
				{
				}
				EasyModeDiagnostics.DamageIncreased("out/baseDamage", num, num2, "target=" + ((object)victim).GetType().Name);
			}
			else
			{
				float damageMultiplier = e.damageMultiplier;
				e.damageMultiplier *= DamageDealtMultiplier;
				EasyModeDiagnostics.DamageIncreased("out/damageMultiplier", damageMultiplier, e.damageMultiplier, "target=" + ((object)victim).GetType().Name);
			}
		}

		private static void ApplyProcessHitEventMultipliers(Entity __instance, HitEvent e)
		{
			if (e == null)
			{
				EasyModeDiagnostics.Fail("ProcessHitEvent", "HitEvent=null");
				return;
			}
			Entity val;
			try
			{
				val = ResolveHitAttacker(e);
			}
			catch (Exception ex)
			{
				EasyModeDiagnostics.Fail("ProcessHitEvent", "ResolveHitAttacker: " + ex.Message);
				return;
			}
			if (val is Player)
			{
				ApplyOutgoingPlayerHit(__instance, e);
			}
		}

		[HarmonyPatch(typeof(Player), "ReduceDamage", new Type[] { typeof(HitEvent) })]
		[HarmonyPrefix]
		internal static void PlayerReduceDamagePrefix(HitEvent e)
		{
			if (e != null)
			{
				float damageMultiplier = e.damageMultiplier;
				e.damageMultiplier *= DamageTakenMultiplier;
				EasyModeDiagnostics.DamageReduced("ReduceDamage(pre)", damageMultiplier, e.damageMultiplier, "target=Player");
			}
		}

		internal static void ProcessHitEventUniversalPrefix(Entity __instance, HitEvent e)
		{
			ApplyProcessHitEventMultipliers(__instance, e);
		}

		[HarmonyPatch(typeof(Entity), "TakeDamage", new Type[] { typeof(float) })]
		[HarmonyPrefix]
		internal static void TakeDamageFloatPrefix(Entity __instance, ref float damage)
		{
			if (__instance is Player && damage > 0f)
			{
				float before = damage;
				damage *= DamageTakenMultiplier;
				EasyModeDiagnostics.DamageReduced("TakeDamage(float)", before, damage, "target=Player");
			}
		}

		[HarmonyPatch(typeof(Entity), "TakeAffliction", new Type[] { typeof(HitEvent) })]
		[HarmonyPrefix]
		internal static void TakeAfflictionHitPrefix(Entity __instance, HitEvent e)
		{
			if (__instance is Player && e != null)
			{
				float damageMultiplier = e.damageMultiplier;
				e.damageMultiplier *= DamageTakenMultiplier;
				EasyModeDiagnostics.DamageReduced("TakeAffliction(HitEvent)", damageMultiplier, e.damageMultiplier, "target=Player");
			}
			else if (__instance is Player && e == null)
			{
				EasyModeDiagnostics.Fail("TakeAffliction(HitEvent)", "HitEvent=null on Player");
			}
		}

		[HarmonyPatch(typeof(Entity), "TakeAffliction", new Type[]
		{
			typeof(AFFLICTIONTYPE),
			typeof(float)
		})]
		[HarmonyPrefix]
		internal static void TakeAfflictionAmountPrefix(Entity __instance, ref float amount)
		{
			if (__instance is Player && amount > 0f)
			{
				float before = amount;
				amount *= DamageTakenMultiplier;
				EasyModeDiagnostics.DamageReduced("TakeAffliction(amount)", before, amount, "target=Player");
			}
		}

		[HarmonyPatch(typeof(Player), "TakeShellDamage")]
		[HarmonyPrefix]
		internal static void TakeShellDamagePrefix(Player __instance, ref float damage)
		{
			if ((Object)(object)__instance != (Object)null && damage > 0f)
			{
				float before = damage;
				damage *= DamageTakenMultiplier;
				EasyModeDiagnostics.DamageReduced("TakeShellDamage", before, damage, "target=Player");
			}
		}
	}
	internal static class EasyModeDiagnostics
	{
		private static float _nextDamageReducedLog;

		private static float _nextDamageIncreasedLog;

		private static float _nextIncomeLog;

		internal const float DamageReducedCooldown = 1.25f;

		internal const float DamageIncreasedCooldown = 1.25f;

		internal const float IncomeCooldown = 0.75f;

		internal static void Fail(string context, string detail)
		{
			ManualLogSource modLog = EasyModePlugin.ModLog;
			if (modLog != null)
			{
				modLog.LogError((object)("FAIL [" + context + "] " + detail));
			}
		}

		internal static void DamageReduced(string context, float before, float after, string extra = "")
		{
			if (!VerifyScale(before, after, EasyModeCombatPatches.DamageTakenMultiplier, out var reason))
			{
				Fail(context, $"expected mult {EasyModeCombatPatches.DamageTakenMultiplier}; before={Format(before)} after={Format(after)} ({reason}) {extra}");
			}
			else if (!Mathf.Approximately(before, 0f) && !(Time.realtimeSinceStartup < _nextDamageReducedLog))
			{
				_nextDamageReducedLog = Time.realtimeSinceStartup + 1.25f;
				string text = (string.IsNullOrEmpty(extra) ? "" : (" " + extra));
				ManualLogSource modLog = EasyModePlugin.ModLog;
				if (modLog != null)
				{
					modLog.LogInfo((object)$"DAMAGE REDUCED [{context}] before={Format(before)} after={Format(after)} mult={EasyModeCombatPatches.DamageTakenMultiplier}{text}");
				}
			}
		}

		internal static void DamageIncreased(string context, float before, float after, string extra = "")
		{
			if (!VerifyScale(before, after, EasyModeCombatPatches.DamageDealtMultiplier, out var reason))
			{
				Fail(context, $"expected mult {EasyModeCombatPatches.DamageDealtMultiplier}; before={Format(before)} after={Format(after)} ({reason}) {extra}");
			}
			else if (!Mathf.Approximately(before, 0f) && !(Time.realtimeSinceStartup < _nextDamageIncreasedLog))
			{
				_nextDamageIncreasedLog = Time.realtimeSinceStartup + 1.25f;
				string text = (string.IsNullOrEmpty(extra) ? "" : (" " + extra));
				ManualLogSource modLog = EasyModePlugin.ModLog;
				if (modLog != null)
				{
					modLog.LogInfo((object)$"DAMAGE INCREASED [{context}] before={Format(before)} after={Format(after)} mult={EasyModeCombatPatches.DamageDealtMultiplier}{text}");
				}
			}
		}

		internal static void IncomeFromCollectable(CURRENCY c, int beforeAmount, int afterAmount)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.realtimeSinceStartup < _nextIncomeLog))
			{
				_nextIncomeLog = Time.realtimeSinceStartup + 0.75f;
				ManualLogSource modLog = EasyModePlugin.ModLog;
				if (modLog != null)
				{
					modLog.LogInfo((object)$"INCOME INCREASED [CurrencyCollectable] currency={c} amount={beforeAmount}->{afterAmount} mult={EasyModeEconomyPatches.CurrencyIncomeMultiplier}");
				}
			}
		}

		internal static void IncomeFromSetCurrency(CURRENCY c, int oldTotal, int requested, int adjusted)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.realtimeSinceStartup < _nextIncomeLog))
			{
				_nextIncomeLog = Time.realtimeSinceStartup + 0.75f;
				ManualLogSource modLog = EasyModePlugin.ModLog;
				if (modLog != null)
				{
					modLog.LogInfo((object)$"INCOME INCREASED [SetCurrency] currency={c} oldTotal={oldTotal} requested={requested} adjusted={adjusted} mult={EasyModeEconomyPatches.CurrencyIncomeMultiplier}");
				}
			}
		}

		private static bool VerifyScale(float before, float after, float mult, out string reason)
		{
			reason = "";
			float num = before * mult;
			if (!Mathf.Approximately(num, after))
			{
				float v = Mathf.Abs(after - num);
				reason = "delta=" + Format(v);
				return false;
			}
			return true;
		}

		private static string Format(float v)
		{
			return v.ToString(CultureInfo.InvariantCulture);
		}
	}
	internal static class EasyModeEconomyPatches
	{
		internal static int CurrencyIncomeMultiplier = 3;

		internal static void AddCurrencyPrefix(CURRENCY c, ref int amt, bool updateCurrencyText)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (amt > 0)
			{
				int num = amt;
				amt *= CurrencyIncomeMultiplier;
				ManualLogSource modLog = EasyModePlugin.ModLog;
				if (modLog != null)
				{
					modLog.LogInfo((object)$"INCOME INCREASED [Wallet.AddCurrency] currency={c} amt={num}->{amt} mult={CurrencyIncomeMultiplier}");
				}
			}
		}
	}
	[BepInPlugin("com.leona.act_easymode", "EasyMode", "1.0.8")]
	public class EasyModePlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.leona.act_easymode";

		public const string PluginName = "EasyMode";

		public const string PluginVersion = "1.0.8";

		private Harmony _harmony;

		internal static EasyModePlugin Instance { get; private set; }

		internal static ManualLogSource ModLog { get; private set; }

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			Instance = this;
			ModLog = ((BaseUnityPlugin)this).Logger;
			LoadConfig();
			_harmony = new Harmony("com.leona.act_easymode");
			try
			{
				_harmony.PatchAll(typeof(EasyModePlugin).Assembly);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
				throw;
			}
			VerifyAndManualFallback();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"EasyMode 1.0.8 loaded.");
		}

		private void LoadConfig()
		{
			ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "DamageTakenMultiplier", EasyModeCombatPatches.DamageTakenMultiplier, "Incoming damage multiplier applied to Player.ReduceDamage(HitEvent).");
			ConfigEntry<float> val2 = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "DamageDealtMultiplier", EasyModeCombatPatches.DamageDealtMultiplier, "Outgoing damage multiplier applied to Entity.ProcessHitEvent(HitEvent).");
			ConfigEntry<int> obj = ((BaseUnityPlugin)this).Config.Bind<int>("Multipliers", "CurrencyIncomeMultiplier", EasyModeEconomyPatches.CurrencyIncomeMultiplier, "Multiplier applied to positive amounts passed into InventoryData.Wallet.AddCurrency(...).");
			EasyModeCombatPatches.DamageTakenMultiplier = val.Value;
			EasyModeCombatPatches.DamageDealtMultiplier = val2.Value;
			EasyModeEconomyPatches.CurrencyIncomeMultiplier = obj.Value;
			((BaseUnityPlugin)this).Logger.LogInfo((object)($"[EasyMode] Config: DamageTakenMultiplier={EasyModeCombatPatches.DamageTakenMultiplier}, " + $"DamageDealtMultiplier={EasyModeCombatPatches.DamageDealtMultiplier}, " + $"CurrencyIncomeMultiplier={EasyModeEconomyPatches.CurrencyIncomeMultiplier}"));
		}

		private void VerifyAndManualFallback()
		{
			MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Player), "ReduceDamage", new Type[1] { typeof(HitEvent) }, (Type[])null);
			if (methodInfo == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"[EasyMode] Player.ReduceDamage(HitEvent) not found — game version mismatch?");
				return;
			}
			int num = CountPatchSteps(methodInfo);
			if (num == 0)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[EasyMode] ReduceDamage had no Harmony steps; applying manual prefix.");
				TryPatchReduceDamageManual();
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[EasyMode] Patched Player.ReduceDamage ({num} step(s)).");
			}
			TryPatchManualProcessHitEvents();
			TryPatchManualEconomy();
			LogVerify(typeof(Player), "ProcessHitEvent", typeof(HitEvent));
			LogVerify(typeof(Enemy), "ProcessHitEvent", typeof(HitEvent));
			LogVerify(typeof(Entity), "ProcessHitEvent", typeof(HitEvent));
			LogVerify(typeof(Wallet), "AddCurrency", typeof(CURRENCY), typeof(int), typeof(bool));
		}

		private void TryPatchManualProcessHitEvents()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			HarmonyMethod val = new HarmonyMethod(typeof(EasyModeCombatPatches), "ProcessHitEventUniversalPrefix", (Type[])null);
			Type[] array = new Type[3]
			{
				typeof(Player),
				typeof(Enemy),
				typeof(Entity)
			};
			foreach (Type type in array)
			{
				MethodInfo methodInfo = AccessTools.DeclaredMethod(type, "ProcessHitEvent", new Type[1] { typeof(HitEvent) }, (Type[])null);
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[EasyMode] " + type.Name + ".ProcessHitEvent(HitEvent) not found."));
				}
				else if (CountPatchSteps(methodInfo) <= 0)
				{
					try
					{
						_harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)("[EasyMode] Manual prefix applied to " + type.Name + ".ProcessHitEvent."));
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)ex);
					}
				}
			}
		}

		private void TryPatchManualEconomy()
		{
			TryManualEconomyPrefix(typeof(Wallet), "AddCurrency", new Type[3]
			{
				typeof(CURRENCY),
				typeof(int),
				typeof(bool)
			}, "AddCurrencyPrefix");
		}

		private void TryManualEconomyPrefix(Type declaringType, string methodName, Type[] argTypes, string patchMethodName)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			MethodInfo methodInfo = ((argTypes.Length == 0) ? AccessTools.DeclaredMethod(declaringType, methodName, (Type[])null, (Type[])null) : AccessTools.DeclaredMethod(declaringType, methodName, argTypes, (Type[])null));
			if (methodInfo == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[EasyMode] Method not found: " + declaringType.Name + "." + methodName));
			}
			else if (CountPatchSteps(methodInfo) <= 0)
			{
				try
				{
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(EasyModeEconomyPatches), patchMethodName, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("[EasyMode] Manual prefix applied to " + declaringType.Name + "." + methodName + "."));
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)ex);
				}
			}
		}

		private void TryPatchReduceDamageManual()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Player), "ReduceDamage", new Type[1] { typeof(HitEvent) }, (Type[])null);
				if (!(methodInfo == null) && CountPatchSteps(methodInfo) <= 0)
				{
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(EasyModeCombatPatches), "PlayerReduceDamagePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[EasyMode] Manual prefix applied to Player.ReduceDamage.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
		}

		private static void LogVerify(Type declaringType, string name, params Type[] args)
		{
			MethodInfo methodInfo = ((args.Length == 0) ? AccessTools.DeclaredMethod(declaringType, name, (Type[])null, (Type[])null) : AccessTools.DeclaredMethod(declaringType, name, args, (Type[])null));
			if (methodInfo == null)
			{
				ManualLogSource modLog = ModLog;
				if (modLog != null)
				{
					modLog.LogWarning((object)("[EasyMode] Method not found: " + declaringType.Name + "." + name));
				}
				return;
			}
			int num = CountPatchSteps(methodInfo);
			if (num == 0)
			{
				ManualLogSource modLog2 = ModLog;
				if (modLog2 != null)
				{
					modLog2.LogError((object)("[EasyMode] No Harmony patches on " + declaringType.Name + "." + name));
				}
			}
			else
			{
				ManualLogSource modLog3 = ModLog;
				if (modLog3 != null)
				{
					modLog3.LogInfo((object)$"[EasyMode] Patched {declaringType.Name}.{name} ({num} step(s)).");
				}
			}
		}

		private static int CountPatchSteps(MethodBase method)
		{
			Patches patchInfo = Harmony.GetPatchInfo(method);
			if (patchInfo == null)
			{
				return 0;
			}
			return (patchInfo.Prefixes?.Count ?? 0) + (patchInfo.Postfixes?.Count ?? 0) + (patchInfo.Transpilers?.Count ?? 0) + (patchInfo.Finalizers?.Count ?? 0);
		}
	}
}