Decompiled source of GoblinLab v1.0.3

GoblinLab.dll

Decompiled 2 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Actors.Enemies;
using Assets.Scripts.Actors.Enemies;
using Assets.Scripts.Game.Combat;
using Assets.Scripts.Inventory__Items__Pickups.Stats;
using Assets.Scripts.Inventory__Items__Pickups.Weapons;
using Assets.Scripts.Managers;
using Assets.Scripts.Utility;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GoblinLab")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GoblinLab")]
[assembly: AssemblyTitle("GoblinLab")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GoblinLab
{
	public class Class1
	{
	}
	[HarmonyPatch]
	public static class DamageUtilityPatcher
	{
		[HarmonyPatch]
		private static class EnemyOnlyOverload
		{
			private static MethodBase TargetMethod()
			{
				if (_asm == null)
				{
					_asm = typeof(CombatScaling).Assembly;
				}
				Type type = _asm.GetType("Assets.Scripts.Game.Combat.DamageUtility", throwOnError: false);
				Type type2 = _asm.GetType("Assets.Scripts.Actors.Enemies.Enemy", throwOnError: false);
				Type type3 = _asm.GetType("Assets.Scripts.Actors.DcFlags", throwOnError: false);
				if (type == null || type2 == null)
				{
					return null;
				}
				if (_mEnemyOnly == null)
				{
					Type[] types = new Type[3]
					{
						type2,
						typeof(Vector3),
						type3 ?? typeof(int)
					};
					_mEnemyOnly = type.GetMethod("GetPlayerDamage", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null);
					if (_mEnemyOnly != null)
					{
						ManualLogSource log = _log;
						if (log != null)
						{
							log.LogInfo((object)"[GoblinLab] Patching DamageUtility.GetPlayerDamage(Enemy, Vector3, DcFlags) [postfix scrub]");
						}
					}
				}
				return _mEnemyOnly;
			}

			private static void Postfix(object __result)
			{
				if (Enabled && ScrubResult)
				{
					ForceZeroOnContainer(__result);
				}
			}
		}

		public static bool Enabled = true;

		public static bool ZeroArgDamage = true;

		public static bool ZeroArgKnockback = true;

		public static bool ScrubResult = true;

		public static bool LogCalls = false;

		public static bool LogStack = false;

		public static int LogCap = 0;

		private static long _calls;

		private static ManualLogSource _log;

		private static Assembly _asm;

		private static Type _tDamageUtility;

		private static Type _tEnemy;

		private static Type _tDcFlags;

		private static MethodBase _mWithFloat;

		private static MethodBase _mEnemyOnly;

		private static Type _tDamageContainer;

		private static PropertyInfo _piDamage;

		private static PropertyInfo _piKnockback;

		private static PropertyInfo _piDirection;

		private static PropertyInfo _piCrit;

		public static bool IsNoDamageEnabled
		{
			get
			{
				if (Enabled && ZeroArgDamage && ZeroArgKnockback)
				{
					return ScrubResult;
				}
				return false;
			}
		}

		public static void Init(ManualLogSource logger)
		{
			_log = logger;
		}

		public static void EnableNoDamagePreset()
		{
			Enabled = true;
			ZeroArgDamage = true;
			ZeroArgKnockback = true;
			ScrubResult = true;
			if (LogCalls)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)"[GoblinLab] Enemy NO-DAMAGE preset ENABLED (0 dmg, 0 kb, scrub).");
				}
			}
		}

		public static void DisableNoDamagePreset()
		{
			ZeroArgDamage = false;
			ZeroArgKnockback = false;
			ScrubResult = false;
			Enabled = false;
			if (LogCalls)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)"[GoblinLab] Enemy NO-DAMAGE preset DISABLED (restored).");
				}
			}
		}

		private static bool EnsureGameTypes()
		{
			if (_asm == null)
			{
				_asm = typeof(CombatScaling).Assembly;
			}
			if ((object)_tDamageUtility == null)
			{
				_tDamageUtility = _asm.GetType("Assets.Scripts.Game.Combat.DamageUtility", throwOnError: false);
			}
			if ((object)_tEnemy == null)
			{
				_tEnemy = _asm.GetType("Assets.Scripts.Actors.Enemies.Enemy", throwOnError: false);
			}
			if ((object)_tDcFlags == null)
			{
				_tDcFlags = _asm.GetType("Assets.Scripts.Actors.DcFlags", throwOnError: false);
			}
			if (_tDamageUtility == null || _tEnemy == null)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogWarning((object)"[GoblinLab] DamageUtility or Enemy type not found; patch skipped.");
				}
				return false;
			}
			return true;
		}

		private static void EnsureDamageContainer(object dc)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			if (dc == null || _tDamageContainer != null)
			{
				return;
			}
			_tDamageContainer = dc.GetType();
			_piDamage = _tDamageContainer.GetProperty("damage", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_piKnockback = _tDamageContainer.GetProperty("knockback", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_piDirection = _tDamageContainer.GetProperty("direction", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_piCrit = _tDamageContainer.GetProperty("crit", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!LogCalls)
			{
				return;
			}
			ManualLogSource log = _log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DU] Bound DC props: dmg=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_piDamage != null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" kb=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_piKnockback != null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" dir=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_piDirection != null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" crit=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_piCrit != null);
				}
				log.LogInfo(val);
			}
		}

		private static MethodBase TargetMethod()
		{
			if (!EnsureGameTypes())
			{
				return null;
			}
			if (_mWithFloat == null)
			{
				Type[] types = new Type[6]
				{
					typeof(float),
					typeof(float),
					typeof(Vector3),
					_tEnemy,
					typeof(string),
					_tDcFlags ?? typeof(int)
				};
				_mWithFloat = _tDamageUtility.GetMethod("GetPlayerDamage", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null);
				if (_mWithFloat != null)
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						log.LogInfo((object)"[GoblinLab] Patching DamageUtility.GetPlayerDamage(float, float, Vector3, Enemy, string, DcFlags)");
					}
				}
			}
			return _mWithFloat;
		}

		private static void Prefix(ref float damage, ref float knockback)
		{
			if (!Enabled)
			{
				return;
			}
			_calls++;
			if (LogCalls && (LogCap == 0 || _calls <= LogCap))
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)($"[DU] FLOAT overload #{_calls}: in damage={damage}, kb={knockback}" + (ZeroArgDamage ? " → dmg=0" : "") + (ZeroArgKnockback ? " → kb=0" : "")));
				}
			}
			if (ZeroArgDamage)
			{
				damage = 0f;
			}
			if (ZeroArgKnockback)
			{
				knockback = 0f;
			}
			if (LogStack && (LogCap == 0 || _calls <= LogCap))
			{
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					log2.LogInfo((object)Environment.StackTrace);
				}
			}
		}

		private static void Postfix(object __result)
		{
			if (Enabled && ScrubResult)
			{
				ForceZeroOnContainer(__result);
			}
		}

		private static void ForceZeroOnContainer(object dc)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (dc == null)
			{
				return;
			}
			EnsureDamageContainer(dc);
			try
			{
				if (_piDamage != null && _piDamage.CanWrite)
				{
					_piDamage.SetValue(dc, 0f, null);
				}
				if (_piKnockback != null && _piKnockback.CanWrite)
				{
					_piKnockback.SetValue(dc, 0f, null);
				}
				if (_piDirection != null && _piDirection.CanWrite)
				{
					_piDirection.SetValue(dc, Vector3.zero, null);
				}
				if (_piCrit != null && _piCrit.CanWrite)
				{
					_piCrit.SetValue(dc, false, null);
				}
				if (LogCalls && (LogCap == 0 || _calls <= LogCap))
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						log.LogInfo((object)"[DU] dc.damage := 0, dc.knockback := 0, dc.direction := Vector3.zero, dc.crit := false");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DU] Failed to scrub DamageContainer: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log2.LogWarning(val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Enemy), "CanMove")]
	public static class EnemyCanMovePatcher
	{
		public static bool Enabled = true;

		public static ManualLogSource Log;

		private static bool _loggedOnce;

		public static bool IsEnabled => Enabled;

		public static void Enable()
		{
			Enabled = true;
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"[GoblinLab] Enemy movement DISABLED (CanMove => false).");
			}
		}

		public static void Disable()
		{
			Enabled = false;
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"[GoblinLab] Enemy movement restored (CanMove original).");
			}
		}

		private static bool Prefix(ref bool __result)
		{
			if (!Enabled)
			{
				return true;
			}
			__result = false;
			if (!_loggedOnce && Log != null)
			{
				_loggedOnce = true;
				Log.LogInfo((object)"[GoblinLab] Enemy.CanMove() patched → false (first hit).");
			}
			return false;
		}
	}
	[BepInPlugin("com.bud.GoblinLab", "GoblinLab", "1.3.3")]
	public class Plugin : BasePlugin
	{
		internal static ManualLogSource LogSrc;

		public override void Load()
		{
			//IL_001e: 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_0029: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			LogSrc = Logger.CreateLogSource("GoblinLab");
			ClassInjector.RegisterTypeInIl2Cpp<TimeSkipper>();
			ClassInjector.RegisterTypeInIl2Cpp<TimeSkipperWindow>();
			GameObject val = new GameObject("GoblinLab_Controller");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<TimeSkipper>();
			val.AddComponent<TimeSkipperWindow>();
			EnemyCanMovePatcher.Log = LogSrc;
			DamageUtilityPatcher.Init(LogSrc);
			new Harmony("com.bud.GoblinLab").PatchAll();
			SpawnPatcher.Enable();
			EnemyCanMovePatcher.Disable();
			DamageUtilityPatcher.DisableNoDamagePreset();
			LogSrc.LogInfo((object)"GoblinLab loaded — controller spawned, patches applied.");
		}
	}
	public static class Spawner
	{
		public static void SpawnTest2NormalNearPlayer()
		{
			SpawnBossNearPlayer((EEnemy)11, 0, (EEnemyFlag)0);
		}

		public static void SpawnTest2BossNearPlayer()
		{
			SpawnBossNearPlayer((EEnemy)11, 0, (EEnemyFlag)2);
		}

		public static void SpawnEnt1BossNearPlayer()
		{
			SpawnBossNearPlayer((EEnemy)19, 0, (EEnemyFlag)2);
		}

		public static void SpawnBossNearPlayer(EEnemy enemy, int summonerId, EEnemyFlag flag)
		{
			//IL_00c6: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: 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_0129: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Expected O, but got Unknown
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = ResolvePlayerGameObject();
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource logSrc = Plugin.LogSrc;
					if (logSrc != null)
					{
						logSrc.LogInfo((object)"[Spawn] Player not found.");
					}
					return;
				}
				object obj = ResolveEnemyManager();
				if (obj == null)
				{
					ManualLogSource logSrc2 = Plugin.LogSrc;
					if (logSrc2 != null)
					{
						logSrc2.LogInfo((object)"[Spawn] EnemyManager not found.");
					}
					return;
				}
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				MethodInfo method = obj.GetType().GetMethod("SpawnBoss", bindingAttr, null, new Type[4]
				{
					typeof(EEnemy),
					typeof(int),
					typeof(EEnemyFlag),
					typeof(Vector3)
				}, null);
				if (method == null)
				{
					ManualLogSource logSrc3 = Plugin.LogSrc;
					if (logSrc3 != null)
					{
						logSrc3.LogInfo((object)"[Spawn] EnemyManager.SpawnBoss(EEnemy,int,EEnemyFlag,Vector3) not found.");
					}
					return;
				}
				Vector3 position = val.transform.position;
				Vector2 insideUnitCircle = Random.insideUnitCircle;
				Vector2 normalized = ((Vector2)(ref insideUnitCircle)).normalized;
				float num = Random.Range(5f, 12f);
				Vector3 val2 = position + new Vector3(normalized.x, 0f, normalized.y) * num;
				ManualLogSource logSrc4 = Plugin.LogSrc;
				bool flag2 = default(bool);
				if (logSrc4 != null)
				{
					BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(25, 4, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Spawn] SpawnBoss(");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<EEnemy>(enemy);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(summonerId);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<EEnemyFlag>(flag);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Vector3>(val2);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")");
					}
					logSrc4.LogInfo(val3);
				}
				object obj2 = method.Invoke(obj, new object[4] { enemy, summonerId, flag, val2 });
				if (obj2 == null)
				{
					ManualLogSource logSrc5 = Plugin.LogSrc;
					if (logSrc5 != null)
					{
						logSrc5.LogInfo((object)"[Spawn] Spawn returned null.");
					}
					return;
				}
				object obj3 = ((obj2 is Component) ? obj2 : null);
				GameObject val4 = (GameObject)(((object)((obj3 != null) ? ((Component)obj3).gameObject : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/));
				if ((Object)(object)val4 != (Object)null)
				{
					logSrc4 = Plugin.LogSrc;
					if (logSrc4 != null)
					{
						BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Spawn] Spawned '");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)val4).name);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' at ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Vector3>(val4.transform.position);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
						}
						logSrc4.LogInfo(val3);
					}
				}
				else
				{
					ManualLogSource logSrc6 = Plugin.LogSrc;
					if (logSrc6 != null)
					{
						logSrc6.LogInfo((object)"[Spawn] Spawned (object resolved, no GameObject property).");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logSrc7 = Plugin.LogSrc;
				if (logSrc7 != null)
				{
					logSrc7.LogWarning((object)("[Spawn] Exception: " + ex.Message));
				}
			}
		}

		private static object ResolvePlayer()
		{
			Type type = Type.GetType("Assets.Scripts.Actors.Player.MyPlayer, Assembly-CSharp", throwOnError: false) ?? FindTypeBySuffix("MyPlayer");
			if (type == null)
			{
				return null;
			}
			try
			{
				BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
				MethodInfo methodInfo = type.GetMethod("get_Instance", bindingAttr) ?? type.GetMethod("GetInstance", bindingAttr) ?? type.GetMethod("Instance", bindingAttr);
				if (methodInfo != null)
				{
					object obj = methodInfo.Invoke(null, null);
					if (obj != null)
					{
						return obj;
					}
				}
			}
			catch
			{
			}
			return FindFirstLiveComponentByType(type);
		}

		private static GameObject ResolvePlayerGameObject()
		{
			object obj = ResolvePlayer();
			if (obj == null)
			{
				return null;
			}
			object obj2 = ((obj is Component) ? obj : null);
			return (GameObject)(((object)((obj2 != null) ? ((Component)obj2).gameObject : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/));
		}

		private static object ResolveEnemyManager()
		{
			Type type = Type.GetType("Assets.Scripts.Managers.EnemyManager, Assembly-CSharp", throwOnError: false) ?? FindTypeBySuffix("EnemyManager");
			if (type == null)
			{
				return null;
			}
			try
			{
				BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
				MethodInfo methodInfo = type.GetMethod("get_Instance", bindingAttr) ?? type.GetMethod("GetInstance", bindingAttr) ?? type.GetMethod("Instance", bindingAttr);
				if (methodInfo != null)
				{
					object obj = methodInfo.Invoke(null, null);
					if (obj != null)
					{
						return obj;
					}
				}
			}
			catch
			{
			}
			return FindFirstLiveComponentByType(type);
		}

		private static object FindFirstLiveComponentByType(Type t)
		{
			//IL_0016: 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)
			if (t == null)
			{
				return null;
			}
			int sceneCount = SceneManager.sceneCount;
			for (int i = 0; i < sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				if (!((Scene)(ref sceneAt)).IsValid() || !((Scene)(ref sceneAt)).isLoaded)
				{
					continue;
				}
				GameObject[] rootGameObjects = ((Scene)(ref sceneAt)).GetRootGameObjects();
				for (int j = 0; j < rootGameObjects.Length; j++)
				{
					Component componentInChildren = rootGameObjects[j].GetComponentInChildren(t, true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						return componentInChildren;
					}
				}
			}
			return null;
		}

		private static Type FindTypeBySuffix(string suffix)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch
				{
					continue;
				}
				Type[] array = types;
				foreach (Type type in array)
				{
					if (type.Name == suffix)
					{
						return type;
					}
					string fullName = type.FullName;
					if (!string.IsNullOrEmpty(fullName) && fullName.EndsWith("." + suffix, StringComparison.Ordinal))
					{
						return type;
					}
				}
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(EnemyManager))]
	internal static class SpawnPatcher
	{
		public static bool IsEnabled { get; private set; } = true;


		[HarmonyPatch("GetNumMaxEnemies")]
		[HarmonyPrefix]
		private static bool Prefix(ref int __result)
		{
			if (!IsEnabled)
			{
				return true;
			}
			__result = 0;
			return false;
		}

		public static void Toggle()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			IsEnabled = !IsEnabled;
			ManualLogSource logSrc = Plugin.LogSrc;
			if (logSrc != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SpawnPatcher] No-Spawn toggled ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(IsEnabled ? "ENABLED" : "DISABLED");
				}
				logSrc.LogInfo(val);
			}
		}

		public static void Enable()
		{
			IsEnabled = true;
		}

		public static void Disable()
		{
			IsEnabled = false;
		}
	}
	public class TimeSkipper : MonoBehaviour
	{
		private static IntPtr _nfStage = IntPtr.Zero;

		private static IntPtr _nfSwarm = IntPtr.Zero;

		private static void EnsurePtrs()
		{
			if (!(_nfStage != IntPtr.Zero))
			{
				Type typeFromHandle = typeof(MyTime);
				BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
				_nfStage = (IntPtr)(typeFromHandle.GetField("NativeFieldInfoPtr_stageTimer", bindingAttr)?.GetValue(null) ?? ((object)IntPtr.Zero));
				_nfSwarm = (IntPtr)(typeFromHandle.GetField("NativeFieldInfoPtr_finalSwarmTimer", bindingAttr)?.GetValue(null) ?? ((object)IntPtr.Zero));
				if (_nfStage == IntPtr.Zero)
				{
					Plugin.LogSrc.LogInfo((object)"[TimeSkipper] stageTimer ptr not found.");
				}
				if (_nfSwarm == IntPtr.Zero)
				{
					Plugin.LogSrc.LogInfo((object)"[TimeSkipper] finalSwarmTimer ptr not found.");
				}
			}
		}

		private unsafe static float ReadStaticFloat(IntPtr nf)
		{
			if (nf == IntPtr.Zero)
			{
				return float.NaN;
			}
			float result = 0f;
			IL2CPP.il2cpp_field_static_get_value(nf, (void*)(&result));
			return result;
		}

		private unsafe static void WriteStaticFloat(IntPtr nf, float v)
		{
			if (!(nf == IntPtr.Zero))
			{
				IL2CPP.il2cpp_field_static_set_value(nf, (void*)(&v));
			}
		}

		private static void AddSeconds(IntPtr nf, float deltaSeconds, string label)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val;
			if (nf == IntPtr.Zero)
			{
				ManualLogSource logSrc = Plugin.LogSrc;
				val = new BepInExInfoLogInterpolatedStringHandler(27, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TimeSkipper] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ptr missing");
				}
				logSrc.LogInfo(val);
				return;
			}
			float num = ReadStaticFloat(nf);
			float num2 = num + deltaSeconds;
			WriteStaticFloat(nf, num2);
			string text = ((deltaSeconds >= 0f) ? "+" : "-");
			ManualLogSource logSrc2 = Plugin.LogSrc;
			val = new BepInExInfoLogInterpolatedStringHandler(24, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TimeSkipper] ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num2, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Mathf.Abs(deltaSeconds), "F0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s)");
			}
			logSrc2.LogInfo(val);
		}

		public static void AddStageSeconds(float deltaSeconds)
		{
			EnsurePtrs();
			AddSeconds(_nfStage, deltaSeconds, "stageTimer");
		}

		public static void AddSwarmSeconds(float deltaSeconds)
		{
			EnsurePtrs();
			AddSeconds(_nfSwarm, deltaSeconds, "finalSwarmTimer");
		}

		public static float ReadStage()
		{
			EnsurePtrs();
			return ReadStaticFloat(_nfStage);
		}

		public static float ReadSwarm()
		{
			EnsurePtrs();
			return ReadStaticFloat(_nfSwarm);
		}
	}
	public class TimeSkipperWindow : MonoBehaviour
	{
		private bool _visible;

		private float _panelX = 50f;

		private float _panelY = 50f;

		private const float BaseW = 260f;

		private const float BaseH = 28f;

		private const float ScaleH = 4f;

		private const float ScaleW = 1.6f;

		private const float WpnBtnW = 180f;

		private const float WpnBtnH = 36f;

		private const int WpnCols = 2;

		private const float WpnGapX = 12f;

		private const float WpnGapY = 10f;

		private const float PadOuter = 28f;

		private const float HeaderH = 26f;

		private const float GapHeaderBelow = 22f;

		private const float GapLine = 28f;

		private const float GapBtn = 34f;

		private const float GapAfterGroup = 56f;

		private const float ColGutter = 40f;

		private GUIStyle _btnStyle;

		private GUIStyle _miniBtnStyle;

		private GUIStyle _lblStyle;

		private GUIStyle _headerStyle;

		private GUIStyle _titleStyle;

		private GUIStyle _authorStyle;

		private float _panelW;

		private float _panelH;

		private static readonly string[] WeaponNames = new string[30]
		{
			"FireStaff", "Bone", "Sword", "Revolver", "Aura", "Axe", "Bow", "Aegis", "Test", "LightningStaff",
			"Flamewalker", "Rockets", "Bananarang", "Tornado", "Dexecutioner", "Sniper", "Frostwalker", "SpaceNoodle", "DragonsBreath", "Chunkers",
			"Mine", "PoisonFlask", "BlackHole", "Katana", "BloodMagic", "BluetoothDagger", "Dice", "HeroSword", "CorruptSword", "Shotgun"
		};

		private float BtnW => 416f;

		private float BtnH => 112f;

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)116))
			{
				_visible = !_visible;
			}
		}

		private void EnsureStyles()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			if (_btnStyle == null || _miniBtnStyle == null || _lblStyle == null || _headerStyle == null || _titleStyle == null || _authorStyle == null)
			{
				GUIStyle val = (GUIStyle)(((Object)(object)GUI.skin != (Object)null) ? ((object)GUI.skin.button) : ((object)new GUIStyle()));
				GUIStyle val2 = (GUIStyle)(((Object)(object)GUI.skin != (Object)null) ? ((object)GUI.skin.label) : ((object)new GUIStyle()));
				_btnStyle = new GUIStyle(val)
				{
					fontSize = 24,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					wordWrap = true
				};
				RectOffset padding = _btnStyle.padding;
				padding.left = 10;
				padding.right = 10;
				padding.top = 10;
				padding.bottom = 10;
				_btnStyle.padding = padding;
				GUIStyleState normal = _btnStyle.normal;
				normal.textColor = Color.white;
				_btnStyle.normal = normal;
				GUIStyleState hover = _btnStyle.hover;
				hover.textColor = new Color(1f, 0.95f, 0.4f, 1f);
				_btnStyle.hover = hover;
				GUIStyleState active = _btnStyle.active;
				active.textColor = Color.white;
				_btnStyle.active = active;
				_miniBtnStyle = new GUIStyle(_btnStyle)
				{
					fontSize = 18
				};
				_lblStyle = new GUIStyle(val2)
				{
					fontSize = 18,
					alignment = (TextAnchor)0
				};
				GUIStyleState normal2 = _lblStyle.normal;
				normal2.textColor = Color.white;
				_lblStyle.normal = normal2;
				_headerStyle = new GUIStyle(_lblStyle)
				{
					fontSize = 20,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_titleStyle = new GUIStyle(_lblStyle)
				{
					fontSize = 26,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_authorStyle = new GUIStyle(_lblStyle)
				{
					fontSize = 14,
					fontStyle = (FontStyle)2,
					alignment = (TextAnchor)4
				};
			}
		}

		private void OnGUI()
		{
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0778: Unknown result type (might be due to invalid IL or missing references)
			//IL_0791: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_080b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0662: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0702: Unknown result type (might be due to invalid IL or missing references)
			if (!_visible)
			{
				return;
			}
			EnsureStyles();
			float num = _panelX + 28f;
			float num2 = _panelY + 28f;
			float num3 = num;
			float num4 = num3 + BtnW + 40f;
			float num5 = num4 + BtnW + 40f;
			float num6 = num5 + BtnW + 40f;
			float num7 = num2;
			float num8;
			float num9 = (num8 = 112f);
			num8 += 48f;
			num8 += BtnH + 56f;
			num8 += 48f;
			num8 += BtnH + 34f;
			num8 += BtnH + 56f;
			float num10 = num9;
			num10 += 48f;
			num10 += 50f;
			num10 += BtnH + 34f;
			num10 += BtnH + 34f;
			num10 += BtnH + 56f;
			float num11 = num9;
			num11 += 48f;
			num11 += BtnH + 34f;
			num11 += BtnH + 34f;
			num11 += BtnH + 56f;
			float num12 = num9;
			int num13 = (WeaponNames.Length + 2 - 1) / 2;
			if (num13 > 0)
			{
				num12 += 48f;
				num12 += (float)num13 * 36f + (float)(num13 - 1) * 10f;
				num12 += 56f;
			}
			float num14 = Mathf.Max(Mathf.Max(num8, num10), Mathf.Max(num11, num12));
			float num15 = 372f;
			float num16 = num6 - num + num15;
			_panelW = num16 + 28f;
			_panelH = num14 + 28f;
			DrawFillRect(new Rect(_panelX + 6f, _panelY + 6f, _panelW, _panelH), new Color(0f, 0f, 0f, 0.45f));
			DrawFillRect(new Rect(_panelX - 6f, _panelY - 6f, _panelW + 12f, _panelH + 12f), new Color(0.65f, 0.75f, 0.65f, 0.95f));
			Rect r = new Rect(_panelX - 2f, _panelY - 2f, _panelW + 4f, _panelH + 4f);
			DrawFillRect(r, new Color(0.03f, 0.18f, 0.03f, 0.94f));
			DrawBorderRect(r, 2f, Color.white);
			GUI.Label(new Rect(_panelX + 28f, num7, _panelW - 56f, 26f), "Goblin Lab", _titleStyle);
			num7 += 30f;
			GUI.Label(new Rect(_panelX + 28f, num7, _panelW - 56f, 26f), "Author: Compton", _authorStyle);
			num7 += 82f;
			float num17 = num7;
			DrawHeaderBar(num3, num17, BtnW, "Player Utility");
			num17 += 48f;
			DrawButtonPlate(num3, num17, BtnW, BtnH);
			bool isNoDamageEnabled = DamageUtilityPatcher.IsNoDamageEnabled;
			string text = "God Mode: " + (isNoDamageEnabled ? "ENABLED" : "DISABLED");
			if (GUI.Button(new Rect(num3, num17, BtnW, BtnH), text, _btnStyle))
			{
				if (isNoDamageEnabled)
				{
					DamageUtilityPatcher.DisableNoDamagePreset();
				}
				else
				{
					DamageUtilityPatcher.EnableNoDamagePreset();
				}
			}
			num17 += BtnH + 56f;
			DrawHeaderBar(num3, num17, BtnW, "Enemy Controls");
			num17 += 48f;
			DrawButtonPlate(num3, num17, BtnW, BtnH);
			string text2 = (SpawnPatcher.IsEnabled ? "No-Spawn: ENABLED" : "No-Spawn: DISABLED");
			if (GUI.Button(new Rect(num3, num17, BtnW, BtnH), text2, _btnStyle))
			{
				SpawnPatcher.Toggle();
			}
			num17 += BtnH + 34f;
			DrawButtonPlate(num3, num17, BtnW, BtnH);
			bool flag = !EnemyCanMovePatcher.IsEnabled;
			string text3 = "Enemy Movement: " + (flag ? "ENABLED" : "DISABLED");
			if (GUI.Button(new Rect(num3, num17, BtnW, BtnH), text3, _btnStyle))
			{
				if (flag)
				{
					EnemyCanMovePatcher.Enable();
				}
				else
				{
					EnemyCanMovePatcher.Disable();
				}
			}
			float num18 = num7;
			DrawHeaderBar(num4, num18, BtnW, "Time Controls");
			num18 += 48f;
			float num19 = TimeSkipper.ReadStage();
			float num20 = TimeSkipper.ReadSwarm();
			GUI.Label(new Rect(num4, num18, BtnW, 22f), $"Stage: {num19:F1}s  |  Swarm: {num20:F1}s", _lblStyle);
			num18 += 50f;
			DrawButtonPlate(num4, num18, BtnW, BtnH);
			if (GUI.Button(new Rect(num4, num18, BtnW, BtnH), "Rewind -60s (Stage)", _btnStyle))
			{
				TimeSkipper.AddStageSeconds(-60f);
			}
			num18 += BtnH + 34f;
			DrawButtonPlate(num4, num18, BtnW, BtnH);
			if (GUI.Button(new Rect(num4, num18, BtnW, BtnH), "Skip +60s (Stage)", _btnStyle))
			{
				TimeSkipper.AddStageSeconds(60f);
			}
			num18 += BtnH + 34f;
			DrawButtonPlate(num4, num18, BtnW, BtnH);
			if (GUI.Button(new Rect(num4, num18, BtnW, BtnH), "Swarm +60s", _btnStyle))
			{
				TimeSkipper.AddSwarmSeconds(60f);
			}
			float num21 = num7;
			DrawHeaderBar(num5, num21, BtnW, "Spawns");
			num21 += 48f;
			DrawButtonPlate(num5, num21, BtnW, BtnH);
			if (GUI.Button(new Rect(num5, num21, BtnW, BtnH), "Dummy (Normal)", _btnStyle))
			{
				Spawner.SpawnTest2NormalNearPlayer();
			}
			num21 += BtnH + 34f;
			DrawButtonPlate(num5, num21, BtnW, BtnH);
			if (GUI.Button(new Rect(num5, num21, BtnW, BtnH), "Dummy (Boss)", _btnStyle))
			{
				Spawner.SpawnTest2BossNearPlayer();
			}
			num21 += BtnH + 34f;
			DrawButtonPlate(num5, num21, BtnW, BtnH);
			if (GUI.Button(new Rect(num5, num21, BtnW, BtnH), "Ent1 (Boss)", _btnStyle))
			{
				Spawner.SpawnEnt1BossNearPlayer();
			}
			float num22 = num7;
			DrawHeaderBar(num6, num22, num15, "Weapons");
			num22 += 48f;
			for (int i = 0; i < WeaponNames.Length; i++)
			{
				int num23 = i % 2;
				int num24 = i / 2;
				float num25 = num6 + (float)num23 * 192f;
				float num26 = num22 + (float)num24 * 46f;
				DrawFillRect(new Rect(num25, num26, 180f, 36f), new Color(1f, 1f, 1f, 0.08f));
				DrawBorderRect(new Rect(num25, num26, 180f, 36f), 1.2f, new Color(1f, 1f, 1f, 0.1f));
				string text4 = WeaponNames[i];
				if (!GUI.Button(new Rect(num25, num26, 180f, 36f), text4, _miniBtnStyle))
				{
					continue;
				}
				try
				{
					WeaponAdder.AddWeaponToPlayer((EWeapon)Enum.Parse(typeof(EWeapon), text4));
				}
				catch (Exception ex)
				{
					ManualLogSource logSrc = Plugin.LogSrc;
					if (logSrc != null)
					{
						logSrc.LogWarning((object)("[Weapons] Parse/add failed for " + text4 + ": " + ex.Message));
					}
				}
			}
		}

		private static void DrawFillRect(Rect r, Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			Color color = GUI.color;
			GUI.color = c;
			GUI.DrawTexture(r, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
		}

		private static void DrawBorderRect(Rect r, float t, Color c)
		{
			//IL_0016: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			DrawFillRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, t), c);
			DrawFillRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + ((Rect)(ref r)).height - t, ((Rect)(ref r)).width, t), c);
			DrawFillRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c);
			DrawFillRect(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width - t, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c);
		}

		private static void DrawButtonPlate(float x, float y, float w, float h)
		{
			//IL_0004: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			DrawFillRect(new Rect(x, y, w, h), new Color(1f, 1f, 1f, 0.08f));
			DrawBorderRect(new Rect(x, y, w, h), 1.5f, new Color(1f, 1f, 1f, 0.1f));
		}

		private void DrawHeaderBar(float x, float y, float width, string text)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			DrawFillRect(new Rect(x - 6f, y - 3f, width + 12f, 32f), new Color(0.1f, 0.35f, 0.1f, 0.95f));
			GUI.Label(new Rect(x + 6f, y, width, 26f), text, _headerStyle);
		}
	}
	public static class WeaponAdder
	{
		public static void AddWeaponToPlayer(EWeapon weapon, float _ignoredDamage = 0f, int _ignoredProjectiles = 0, float _ignoredProjectileSpeed = 0f)
		{
			//IL_0048: 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)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object obj = ResolvePlayer();
				if (obj == null)
				{
					ManualLogSource logSrc = Plugin.LogSrc;
					if (logSrc != null)
					{
						logSrc.LogInfo((object)"[WeaponAdder] Player not found.");
					}
					return;
				}
				object obj2 = ResolveWeaponInventory(obj);
				if (obj2 == null)
				{
					ManualLogSource logSrc2 = Plugin.LogSrc;
					if (logSrc2 != null)
					{
						logSrc2.LogInfo((object)"[WeaponAdder] WeaponInventory not found.");
					}
					return;
				}
				bool flag = default(bool);
				ManualLogSource logSrc3;
				if (WeaponPresent(obj2, weapon))
				{
					ToggleWeapon(obj2, weapon, enable: true);
					logSrc3 = Plugin.LogSrc;
					if (logSrc3 != null)
					{
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[WeaponAdder] ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<EWeapon>(weapon);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" already present → toggled ON.");
						}
						logSrc3.LogInfo(val);
					}
					return;
				}
				WeaponData val2 = CreateWeaponData(weapon);
				if ((Object)(object)val2 == (Object)null)
				{
					logSrc3 = Plugin.LogSrc;
					if (logSrc3 != null)
					{
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[WeaponAdder] Could not create WeaponData for ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<EWeapon>(weapon);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
						}
						logSrc3.LogInfo(val);
					}
					return;
				}
				TryCallMethod(val2, "Init");
				MethodInfo methodInfo = obj2.GetType().GetMethod("AddWeapon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
				{
					typeof(WeaponData),
					typeof(List<StatModifier>)
				}, null) ?? obj2.GetType().GetMethod("AddWeapon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (methodInfo == null)
				{
					ManualLogSource logSrc4 = Plugin.LogSrc;
					if (logSrc4 != null)
					{
						logSrc4.LogInfo((object)"[WeaponAdder] AddWeapon method not found on WeaponInventory.");
					}
					return;
				}
				methodInfo.Invoke(obj2, new object[2] { val2, null });
				logSrc3 = Plugin.LogSrc;
				if (logSrc3 != null)
				{
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[WeaponAdder] Added ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<EWeapon>(weapon);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
					}
					logSrc3.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logSrc5 = Plugin.LogSrc;
				if (logSrc5 != null)
				{
					logSrc5.LogWarning((object)("[WeaponAdder] EX: " + ex.Message));
				}
			}
		}

		private static object ResolvePlayer()
		{
			Type type = Type.GetType("Assets.Scripts.Actors.Player.MyPlayer, Assembly-CSharp", throwOnError: false);
			if (type == null)
			{
				return null;
			}
			BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			try
			{
				MethodInfo methodInfo = type.GetMethod("get_Instance", bindingAttr) ?? type.GetMethod("GetInstance", bindingAttr) ?? type.GetMethod("Instance", bindingAttr);
				if (methodInfo != null)
				{
					object obj = methodInfo.Invoke(null, null);
					if (obj != null)
					{
						return obj;
					}
				}
			}
			catch
			{
			}
			string[] array = new string[4] { "Instance", "s_instance", "_instance", "m_instance" };
			foreach (string name in array)
			{
				try
				{
					FieldInfo field = type.GetField(name, bindingAttr);
					if (field != null)
					{
						object value = field.GetValue(null);
						if (value != null)
						{
							return value;
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static object ResolveWeaponInventory(object player)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			object obj = player.GetType().GetProperty("inventory", bindingAttr)?.GetValue(player) ?? player.GetType().GetField("inventory", bindingAttr)?.GetValue(player) ?? player.GetType().GetProperty("Inventory", bindingAttr)?.GetValue(player) ?? player.GetType().GetField("Inventory", bindingAttr)?.GetValue(player);
			if (obj == null)
			{
				return null;
			}
			Type typeFromHandle = typeof(WeaponInventory);
			FieldInfo[] fields = obj.GetType().GetFields(bindingAttr);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (typeFromHandle.IsAssignableFrom(fieldInfo.FieldType))
				{
					return fieldInfo.GetValue(obj);
				}
			}
			PropertyInfo[] properties = obj.GetType().GetProperties(bindingAttr);
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (typeFromHandle.IsAssignableFrom(propertyInfo.PropertyType))
				{
					return propertyInfo.GetValue(obj, null);
				}
			}
			object obj2 = obj.GetType().GetField("weaponInventory", bindingAttr)?.GetValue(obj);
			if (obj2 == null)
			{
				obj2 = obj.GetType().GetProperty("weaponInventory", bindingAttr)?.GetValue(obj, null);
				if (obj2 == null)
				{
					PropertyInfo? property = obj.GetType().GetProperty("WeaponInventory", bindingAttr);
					if ((object)property == null)
					{
						return null;
					}
					obj2 = property.GetValue(obj, null);
				}
			}
			return obj2;
		}

		private static bool WeaponPresent(object wInv, EWeapon w)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			object obj = wInv.GetType().GetField("weapons", bindingAttr)?.GetValue(wInv);
			if (obj == null)
			{
				return false;
			}
			try
			{
				MethodInfo method = obj.GetType().GetMethod("ContainsKey", bindingAttr, null, new Type[1] { typeof(EWeapon) }, null);
				if (method != null)
				{
					return (bool)method.Invoke(obj, new object[1] { w });
				}
			}
			catch
			{
			}
			return false;
		}

		private static void ToggleWeapon(object wInv, EWeapon w, bool enable)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			wInv.GetType().GetMethod("ToggleWeapon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
			{
				typeof(EWeapon),
				typeof(bool)
			}, null)?.Invoke(wInv, new object[2] { w, enable });
		}

		private static WeaponData CreateWeaponData(EWeapon weapon)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				WeaponData val = ScriptableObject.CreateInstance<WeaponData>();
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				if (!SetMember(val, "eWeapon", weapon, flags))
				{
					ManualLogSource logSrc = Plugin.LogSrc;
					if (logSrc != null)
					{
						logSrc.LogInfo((object)"[WeaponAdder] eWeapon field/property not found — cannot proceed.");
					}
					return null;
				}
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource logSrc2 = Plugin.LogSrc;
				if (logSrc2 != null)
				{
					logSrc2.LogWarning((object)("[WeaponAdder] CreateWeaponData EX: " + ex.Message));
				}
				return null;
			}
		}

		private static bool SetMember(object obj, string name, object value, BindingFlags flags)
		{
			try
			{
				Type type = obj.GetType();
				FieldInfo field = type.GetField(name, flags);
				if (field != null && field.FieldType.IsAssignableFrom(value.GetType()))
				{
					field.SetValue(obj, value);
					return true;
				}
				PropertyInfo property = type.GetProperty(name, flags);
				if (property != null && property.CanWrite && property.PropertyType.IsAssignableFrom(value.GetType()))
				{
					property.SetValue(obj, value, null);
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void TryCallMethod(object obj, string name)
		{
			try
			{
				obj.GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)?.Invoke(obj, null);
			}
			catch
			{
			}
		}
	}
}