Decompiled source of Blobz v0.1.2

Blobz.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(BlobzMod), "Blobz", "0.1.1", "Blobz Team", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Blobz")]
[assembly: AssemblyConfiguration("release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Blobz")]
[assembly: AssemblyTitle("Blobz")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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;
		}
	}
}
public class BlobzMod : MelonMod
{
	private enum PlayerDetected
	{
		Unknown,
		InOnline,
		InLocal
	}

	private struct DetectRule
	{
		public string Class;

		public string Prop;

		public string Value;

		public PlayerDetected Result;

		public DetectRule(string cls, string prop, string value, PlayerDetected result)
		{
			Class = cls;
			Prop = prop;
			Value = value;
			Result = result;
		}
	}

	private const int Radius = 14;

	private static readonly Color BgBlue = new Color(0f, 0.31f, 1f, 1f);

	private static readonly Color BtnBlue = new Color(0.2f, 0.46f, 1f, 1f);

	private static readonly Color BtnHover = new Color(0.35f, 0.58f, 1f, 1f);

	private static readonly Color DangerBg = new Color(0.75f, 0.12f, 0.12f, 1f);

	private static readonly Color DangerHover = new Color(0.92f, 0.22f, 0.22f, 1f);

	private static readonly Color YellowBtn = new Color(0.95f, 0.78f, 0.1f, 1f);

	private static readonly Color YellowBtnHover = new Color(1f, 0.88f, 0.32f, 1f);

	private static readonly Color WarnYellow = new Color(1f, 0.8f, 0.15f, 1f);

	private static readonly Color TabIdle = new Color(0.78f, 0.72f, 0.62f);

	private static readonly Color TabDangerIdle = new Color(0.95f, 0.45f, 0.42f);

	private static readonly Color TabDangerOn = new Color(1f, 0.3f, 0.3f);

	private readonly string[] credits = new string[3] { "most stuff by Claude.", "idea by @itzalligator.", "thats all you need to know" };

	private const float FlySpeed = 9f;

	private const float FlyBoost = 2f;

	private const float GrabStrength = 12f;

	private const float GrabMaxSpeed = 40f;

	private const float FlingRadius = 2.2f;

	private const float FlingSpeed = 30f;

	private const float FlingCooldown = 0.5f;

	private bool open;

	private bool acknowledged;

	private int tab;

	private float winX = 60f;

	private float winY = 60f;

	private const float WinW = 380f;

	private const float WinH = 340f;

	private bool dragging;

	private Vector2 dragOffset;

	private readonly string[] tabNames = new string[5] { "Credits", "Game", "Danger", "Items (BETA)", "Local-only" };

	private readonly string[] itemLabels = new string[4] { "Ball Large", "Ball Small", "Traffic Cone", "Dumpster" };

	private readonly string[] itemObjects = new string[4] { "Ball Large", "Ball Small", "TrafficConeFlag", "dumpster" };

	private GUIStyle sWindow;

	private GUIStyle sButton;

	private GUIStyle sDangerButton;

	private GUIStyle sYellowButton;

	private GUIStyle sTab;

	private GUIStyle sTabOn;

	private GUIStyle sTabDanger;

	private GUIStyle sTabDangerOn;

	private GUIStyle sCenter;

	private GUIStyle sSmall;

	private GUIStyle sTitle;

	private GUIStyle sClose;

	private GUIStyle sWarn;

	private bool stylesReady;

	private bool guiFailed;

	private float timeScale = 1f;

	private bool showFps;

	private float fps;

	private bool inputErrorLogged;

	private bool dangerErrorLogged;

	private string lastFailMsg;

	private bool firstDrawLogged;

	private bool gravGun;

	private bool flyOn;

	private bool godOn;

	private bool picking;

	private bool lowGrav;

	private bool gravitySaved;

	private bool flingPunch;

	private bool punchSaved;

	private float savedPunchForce;

	private float nextPunchCheck;

	private const float FlingPunchMul = 10f;

	private PropertyInfo punchProp;

	private MethodInfo applyUpdates;

	private Vector3 savedGravity;

	private static readonly Vector3 LowGravity = new Vector3(0f, -3f, 0f);

	private Rigidbody grabRb;

	private float grabDist;

	private readonly List<Rigidbody> flyBodies = new List<Rigidbody>();

	private readonly HashSet<int> flyIds = new HashSet<int>();

	private readonly Dictionary<int, bool> origGravity = new Dictionary<int, bool>();

	private readonly Dictionary<int, float> flingCooldown = new Dictionary<int, float>();

	private PlayerDetected playerDetected;

	private float nextAutoCheck;

	private bool autoErrLogged;

	private readonly DetectRule[] rules = new DetectRule[2]
	{
		new DetectRule("CoreNet.Utils.NetUtils", "IsLocalGame()", "False", PlayerDetected.InOnline),
		new DetectRule("CoreNet.Utils.NetUtils", "IsLocalGame()", "True", PlayerDetected.InLocal)
	};

	private string signalText = "";

	private readonly Dictionary<string, Type> wrapCache = new Dictionary<string, Type>();

	private readonly Dictionary<string, object> instCache = new Dictionary<string, object>();

	private readonly Dictionary<string, float> nextScan = new Dictionary<string, float>();

	private bool cursorSaved;

	private bool savedVisible;

	private CursorLockMode savedLock;

	private bool cursorErrLogged;

	private bool clipErrLogged;

	private bool speedSet;

	private float ax;

	private float ay;

	private float aw;

	private const string LocalHint = "Local games only.\n\nBlobz couldn't confirm this is a local game, so these tools are locked to keep online lobbies fair.";

	private readonly float[] tabWidths = new float[5] { 62f, 48f, 58f, 92f, 76f };

	public override void OnInitializeMelon()
	{
		((MelonBase)this).LoggerInstance.Msg("Blobz 0.1.1 loaded. Press F2 (or Insert).");
	}

	private bool ManualLocal()
	{
		return false;
	}

	private bool FeaturesUnlocked()
	{
		if (playerDetected != PlayerDetected.InLocal)
		{
			return ManualLocal();
		}
		return true;
	}

	private bool IsLocalGame()
	{
		return FeaturesUnlocked();
	}

	private string LocalSource()
	{
		if (playerDetected == PlayerDetected.InLocal)
		{
			return "Local (auto-detected) - unlocked";
		}
		if (ManualLocal())
		{
			return "Local (dev override) - unlocked";
		}
		if (playerDetected == PlayerDetected.InOnline)
		{
			return "Online - locked";
		}
		return "Not detected - locked";
	}

	private PlayerDetected DetectPlayerState()
	{
		bool flag = false;
		bool flag2 = true;
		DetectRule[] array = rules;
		for (int i = 0; i < array.Length; i++)
		{
			DetectRule detectRule = array[i];
			string text = ReadSignal(detectRule.Class, detectRule.Prop);
			bool flag3 = text != null && string.Equals(text, detectRule.Value, StringComparison.OrdinalIgnoreCase);
			if (detectRule.Result == PlayerDetected.InOnline)
			{
				if (flag3)
				{
					return PlayerDetected.InOnline;
				}
			}
			else if (detectRule.Result == PlayerDetected.InLocal)
			{
				flag = true;
				if (!flag3)
				{
					flag2 = false;
				}
			}
		}
		if (!(flag && flag2))
		{
			return PlayerDetected.Unknown;
		}
		return PlayerDetected.InLocal;
	}

	private Type GetWrapper(string fullClass)
	{
		if (wrapCache.TryGetValue(fullClass, out var value))
		{
			return value;
		}
		int num = fullClass.LastIndexOf('.');
		string ns = ((num >= 0) ? fullClass.Substring(0, num) : "");
		string name = ((num >= 0) ? fullClass.Substring(num + 1) : fullClass);
		value = FindWrapperType(ns, name);
		wrapCache[fullClass] = value;
		return value;
	}

	private string CallStatic(string fullClass, string method)
	{
		Type wrapper = GetWrapper(fullClass);
		if (wrapper == null)
		{
			return null;
		}
		BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		MethodInfo method2 = wrapper.GetMethod(method, bindingAttr, null, Type.EmptyTypes, null);
		if (method2 == null)
		{
			return null;
		}
		object obj = method2.Invoke(null, null);
		if (obj != null)
		{
			return obj.ToString();
		}
		return "null";
	}

	private string ReadSignal(string fullClass, string prop)
	{
		if (prop.EndsWith("()"))
		{
			return CallStatic(fullClass, prop.Substring(0, prop.Length - 2));
		}
		if (!instCache.TryGetValue(fullClass, out var value) || !IsAlive(value))
		{
			value = null;
			instCache.Remove(fullClass);
			if (!nextScan.TryGetValue(fullClass, out var value2) || Time.unscaledTime >= value2)
			{
				nextScan[fullClass] = Time.unscaledTime + 2f;
				value = FindFirstInstance(fullClass);
				if (value != null)
				{
					instCache[fullClass] = value;
				}
			}
		}
		if (value == null)
		{
			return null;
		}
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		PropertyInfo property = value.GetType().GetProperty(prop, bindingAttr);
		if (property == null || !property.CanRead)
		{
			return null;
		}
		MethodInfo getMethod = property.GetGetMethod(nonPublic: true);
		object value3 = property.GetValue((getMethod != null && getMethod.IsStatic) ? null : value);
		if (value3 != null)
		{
			return value3.ToString();
		}
		return "null";
	}

	private static bool IsAlive(object o)
	{
		Object val = (Object)((o is Object) ? o : null);
		if (val != (Object)null)
		{
			return ((Il2CppObjectBase)val).Pointer != IntPtr.Zero;
		}
		return false;
	}

	private object FindFirstInstance(string fullClass)
	{
		int num = fullClass.LastIndexOf('.');
		string ns = ((num >= 0) ? fullClass.Substring(0, num) : "");
		string name = ((num >= 0) ? fullClass.Substring(num + 1) : fullClass);
		if (!wrapCache.TryGetValue(fullClass, out var value))
		{
			value = FindWrapperType(ns, name);
			wrapCache[fullClass] = value;
		}
		if (value == null)
		{
			return null;
		}
		Il2CppReferenceArray<Object> val = Resources.FindObjectsOfTypeAll(Il2CppType.From(value));
		if (val == null || ((Il2CppArrayBase<Object>)(object)val).Length == 0)
		{
			return null;
		}
		return Activator.CreateInstance(value, ((Il2CppObjectBase)((Il2CppArrayBase<Object>)(object)val)[0]).Pointer);
	}

	private void RefreshAutoDetect()
	{
		if (Time.unscaledTime < nextAutoCheck)
		{
			return;
		}
		nextAutoCheck = Time.unscaledTime + 0.5f;
		try
		{
			signalText = "IsLocalGame()=" + (ReadSignal("CoreNet.Utils.NetUtils", "IsLocalGame()") ?? "n/a") + "  IsLocalServerGame()=" + (ReadSignal("CoreNet.Utils.NetUtils", "IsLocalServerGame()") ?? "n/a");
		}
		catch
		{
			signalText = "signals unavailable";
		}
		PlayerDetected playerDetected;
		try
		{
			playerDetected = DetectPlayerState();
		}
		catch (Exception ex)
		{
			playerDetected = PlayerDetected.Unknown;
			if (!autoErrLogged)
			{
				autoErrLogged = true;
				((MelonBase)this).LoggerInstance.Warning("Player detection failed (features stay locked): " + ex.Message);
			}
		}
		if (playerDetected != this.playerDetected)
		{
			this.playerDetected = playerDetected;
			((MelonBase)this).LoggerInstance.Msg("PlayerDetected = " + playerDetected.ToString() + (FeaturesUnlocked() ? " -> features UNLOCKED" : " -> features LOCKED"));
			if (!FeaturesUnlocked())
			{
				DisableAllDanger();
			}
		}
	}

	public override void OnUpdate()
	{
		try
		{
			Keyboard current = Keyboard.current;
			if (current != null && (((ButtonControl)current.f2Key).wasPressedThisFrame || ((ButtonControl)current.insertKey).wasPressedThisFrame))
			{
				open = !open;
				guiFailed = false;
				((MelonBase)this).LoggerInstance.Msg("Menu " + (open ? "opened" : "closed") + " (F2 / Insert)");
			}
		}
		catch (Exception ex)
		{
			if (!inputErrorLogged)
			{
				inputErrorLogged = true;
				((MelonBase)this).LoggerInstance.Error("Input read failed: " + ex.Message);
			}
		}
		fps = Mathf.Lerp(fps, 1f / Mathf.Max(Time.unscaledDeltaTime, 0.0001f), 0.1f);
		UpdateCursor();
		ApplySpeed();
		RefreshAutoDetect();
		SafeDanger(HandleMouse);
	}

	[DllImport("user32.dll")]
	private static extern bool ClipCursor(IntPtr lpRect);

	private void UpdateCursor()
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		if (open)
		{
			try
			{
				if (!cursorSaved)
				{
					savedLock = Cursor.lockState;
					savedVisible = Cursor.visible;
					cursorSaved = true;
				}
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
			catch (Exception ex)
			{
				if (!cursorErrLogged)
				{
					cursorErrLogged = true;
					((MelonBase)this).LoggerInstance.Warning("Cursor.lockState failed: " + ex.Message);
				}
			}
			try
			{
				ClipCursor(IntPtr.Zero);
				return;
			}
			catch (Exception ex2)
			{
				if (!clipErrLogged)
				{
					clipErrLogged = true;
					((MelonBase)this).LoggerInstance.Warning("ClipCursor failed: " + ex2.Message);
				}
				return;
			}
		}
		if (cursorSaved)
		{
			try
			{
				Cursor.lockState = savedLock;
				Cursor.visible = savedVisible;
			}
			catch
			{
			}
			cursorSaved = false;
		}
	}

	public override void OnLateUpdate()
	{
		UpdateCursor();
		ApplySpeed();
	}

	private void SetSpeed(float v)
	{
		try
		{
			timeScale = v;
			Time.timeScale = v;
			speedSet = !Mathf.Approximately(v, 1f);
			((MelonBase)this).LoggerInstance.Msg("Speed -> " + v + "x (Time.timeScale now reads " + Time.timeScale + ")");
		}
		catch (Exception ex)
		{
			((MelonBase)this).LoggerInstance.Warning("Setting speed failed: " + ex.Message);
		}
	}

	private void ApplySpeed()
	{
		if (!speedSet)
		{
			return;
		}
		try
		{
			if (Mathf.Approximately(Time.timeScale, 1f) && !Mathf.Approximately(timeScale, 1f))
			{
				Time.timeScale = timeScale;
			}
		}
		catch
		{
		}
	}

	private static string IlClassName(MonoBehaviour o, out string ns)
	{
		IntPtr intPtr = IL2CPP.il2cpp_object_get_class(((Il2CppObjectBase)o).Pointer);
		ns = Marshal.PtrToStringAnsi(IL2CPP.il2cpp_class_get_namespace(intPtr)) ?? "";
		return Marshal.PtrToStringAnsi(IL2CPP.il2cpp_class_get_name(intPtr)) ?? "";
	}

	private static Type FindWrapperType(string ns, string name)
	{
		string text = ((ns.Length > 0) ? (ns + "." + name) : name);
		string name2 = "Il2Cpp" + text;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			try
			{
				Type type = assembly.GetType(text, throwOnError: false);
				if (type == null)
				{
					type = assembly.GetType(name2, throwOnError: false);
				}
				if (type != null)
				{
					return type;
				}
			}
			catch
			{
			}
		}
		return null;
	}

	private void DumpBools(string ns, string name, MonoBehaviour sample)
	{
		try
		{
			Type type = FindWrapperType(ns, name);
			if (type == null)
			{
				((MelonBase)this).LoggerInstance.Msg("  (" + name + ": wrapper type not found)");
				return;
			}
			object obj = null;
			try
			{
				obj = Activator.CreateInstance(type, ((Il2CppObjectBase)sample).Pointer);
			}
			catch
			{
			}
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			int num = 0;
			PropertyInfo[] properties = type.GetProperties(bindingAttr);
			foreach (PropertyInfo propertyInfo in properties)
			{
				Type propertyType = propertyInfo.PropertyType;
				if ((!(propertyType == typeof(bool)) && !(propertyType == typeof(int)) && !(propertyType == typeof(float)) && !(propertyType == typeof(string)) && !propertyType.IsEnum) || !propertyInfo.CanRead || propertyInfo.GetIndexParameters().Length != 0 || propertyInfo.Name.IndexOf("drawInspector", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					continue;
				}
				MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
				bool flag = getMethod != null && getMethod.IsStatic;
				if (flag || obj != null)
				{
					object obj3;
					try
					{
						obj3 = (flag ? propertyInfo.GetValue(null) : propertyInfo.GetValue(obj));
					}
					catch
					{
						continue;
					}
					((MelonBase)this).LoggerInstance.Msg("  " + ((ns.Length > 0) ? (ns + ".") : "") + name + "." + propertyInfo.Name + (flag ? " (static)" : "") + " = " + obj3);
					if (++num >= 24)
					{
						break;
					}
				}
			}
		}
		catch
		{
		}
	}

	private void DumpMethods(string ns, string name)
	{
		try
		{
			Type type = FindWrapperType(ns, name);
			if (type == null)
			{
				return;
			}
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			string text = ((ns.Length > 0) ? (ns + ".") : "") + name;
			int num = 0;
			MethodInfo[] methods = type.GetMethods(bindingAttr);
			foreach (MethodInfo methodInfo in methods)
			{
				if (!methodInfo.IsSpecialName)
				{
					((MelonBase)this).LoggerInstance.Msg("  method " + text + "." + methodInfo.Name + "(" + methodInfo.GetParameters().Length + ")" + (methodInfo.IsStatic ? " (static)" : ""));
					if (++num >= 40)
					{
						break;
					}
				}
			}
		}
		catch
		{
		}
	}

	private void DumpInfo()
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		((MelonBase)this).LoggerInstance.Msg("=== Blobz dump start ===");
		Scene val;
		try
		{
			Instance loggerInstance = ((MelonBase)this).LoggerInstance;
			string[] obj = new string[5]
			{
				"Scenes loaded: ",
				SceneManager.sceneCount.ToString(),
				", active: '",
				null,
				null
			};
			val = SceneManager.GetActiveScene();
			obj[3] = ((Scene)(ref val)).name;
			obj[4] = "'";
			loggerInstance.Msg(string.Concat(obj));
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				((MelonBase)this).LoggerInstance.Msg("Scene " + i + ": '" + ((Scene)(ref sceneAt)).name + "' loaded=" + ((Scene)(ref sceneAt)).isLoaded);
			}
			((MelonBase)this).LoggerInstance.Msg("timeScale=" + Time.timeScale + " fixedDeltaTime=" + Time.fixedDeltaTime);
		}
		catch (Exception ex)
		{
			((MelonBase)this).LoggerInstance.Warning("Dump (scenes) failed: " + ex.Message);
		}
		try
		{
			int num = 0;
			foreach (GameObject item in Resources.FindObjectsOfTypeAll<GameObject>())
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				val = item.scene;
				if (((Scene)(ref val)).IsValid() && !((Object)(object)item.transform.parent != (Object)null))
				{
					((MelonBase)this).LoggerInstance.Msg("Root: " + ((Object)item).name);
					if (++num >= 80)
					{
						break;
					}
				}
			}
		}
		catch (Exception ex2)
		{
			((MelonBase)this).LoggerInstance.Warning("Dump (roots) failed: " + ex2.Message);
		}
		try
		{
			string[] array = new string[17]
			{
				"network", "corenet", "online", "lobby", "steam", "session", "connect", "multi", "match", "mode",
				"local", "player", "member", "platform", "playing", "client", "server"
			};
			SortedDictionary<string, int> sortedDictionary = new SortedDictionary<string, int>();
			Dictionary<string, MonoBehaviour> dictionary = new Dictionary<string, MonoBehaviour>();
			int num2 = 0;
			foreach (MonoBehaviour item2 in Resources.FindObjectsOfTypeAll<MonoBehaviour>())
			{
				if ((Object)(object)item2 == (Object)null)
				{
					continue;
				}
				num2++;
				string text;
				string ns;
				try
				{
					text = IlClassName(item2, out ns);
				}
				catch
				{
					continue;
				}
				if (!ns.StartsWith("UnityEngine") && !ns.StartsWith("Unity") && !ns.StartsWith("TMPro") && !ns.StartsWith("MelonLoader") && !ns.StartsWith("Il2Cpp") && !ns.StartsWith("System"))
				{
					string key = ((ns.Length > 0) ? (ns + "." + text) : text);
					sortedDictionary.TryGetValue(key, out var value);
					sortedDictionary[key] = value + 1;
					if (!dictionary.ContainsKey(key))
					{
						dictionary[key] = item2;
					}
				}
			}
			((MelonBase)this).LoggerInstance.Msg("MonoBehaviours total=" + num2 + ", distinct game classes=" + sortedDictionary.Count);
			int num3 = 0;
			foreach (KeyValuePair<string, int> item3 in sortedDictionary)
			{
				((MelonBase)this).LoggerInstance.Msg("Class: " + item3.Key + " x" + item3.Value);
				if (++num3 >= 600)
				{
					((MelonBase)this).LoggerInstance.Msg("(class list truncated)");
					break;
				}
			}
			string[] array2 = new string[6] { "scenemanager", "levelmanager", "restart", "matchmanager", "gamemanager", "gamemode" };
			foreach (KeyValuePair<string, MonoBehaviour> item4 in dictionary)
			{
				string text2 = item4.Key.ToLowerInvariant();
				int num4 = item4.Key.LastIndexOf('.');
				string ns2 = ((num4 >= 0) ? item4.Key.Substring(0, num4) : "");
				string name = ((num4 >= 0) ? item4.Key.Substring(num4 + 1) : item4.Key);
				string[] array3 = array2;
				foreach (string value2 in array3)
				{
					if (text2.Contains(value2))
					{
						DumpMethods(ns2, name);
						break;
					}
				}
				bool flag = false;
				array3 = array;
				foreach (string value3 in array3)
				{
					if (text2.Contains(value3))
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					DumpBools(ns2, name, item4.Value);
				}
			}
		}
		catch (Exception ex3)
		{
			((MelonBase)this).LoggerInstance.Warning("Dump (classes) failed: " + ex3.Message);
		}
		((MelonBase)this).LoggerInstance.Msg("=== Blobz dump end ===");
	}

	public override void OnFixedUpdate()
	{
		SafeDanger(DangerPhysics);
	}

	private void SafeDanger(Action a)
	{
		try
		{
			a();
		}
		catch (Exception ex)
		{
			if (!dangerErrorLogged)
			{
				dangerErrorLogged = true;
				((MelonBase)this).LoggerInstance.Error("Danger tools failed and were turned off: " + ex);
			}
			DisableAllDanger();
		}
	}

	private bool MouseOverMenu(Vector2 mouse)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		if (!open)
		{
			return false;
		}
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(winX, winY, 380f, 340f);
		return ((Rect)(ref val)).Contains(new Vector2(mouse.x, (float)Screen.height - mouse.y));
	}

	private void HandleMouse()
	{
		//IL_0046: 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)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		if (!IsLocalGame())
		{
			if (gravGun || flyOn || godOn)
			{
				DisableAllDanger();
			}
			return;
		}
		Mouse current = Mouse.current;
		Camera main = Camera.main;
		if (current == null || (Object)(object)main == (Object)null)
		{
			return;
		}
		Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
		bool flag = MouseOverMenu(val);
		Ray val2 = main.ScreenPointToRay(new Vector3(val.x, val.y, 0f));
		if (picking && current.leftButton.wasPressedThisFrame && !flag)
		{
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(val2, ref val3, 500f) && (Object)(object)((RaycastHit)(ref val3)).rigidbody != (Object)null)
			{
				SelectFlyTarget(((RaycastHit)(ref val3)).rigidbody);
				picking = false;
			}
		}
		else
		{
			if (!gravGun)
			{
				return;
			}
			RaycastHit val4 = default(RaycastHit);
			if (current.leftButton.wasPressedThisFrame && !flag && (Object)(object)grabRb == (Object)null && Physics.Raycast(val2, ref val4, 500f) && (Object)(object)((RaycastHit)(ref val4)).rigidbody != (Object)null)
			{
				grabRb = ((RaycastHit)(ref val4)).rigidbody;
				grabDist = ((RaycastHit)(ref val4)).distance;
			}
			if ((Object)(object)grabRb != (Object)null)
			{
				grabDist = Mathf.Clamp(grabDist + ((InputControl<Vector2>)(object)current.scroll).ReadValue().y * 0.01f, 1f, 60f);
				if (!current.leftButton.isPressed)
				{
					grabRb = null;
				}
			}
		}
	}

	private void DangerPhysics()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: 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_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_031b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0329: Unknown result type (might be due to invalid IL or missing references)
		//IL_032e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: 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_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: 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_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: 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_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		if (!IsLocalGame())
		{
			return;
		}
		if (lowGrav)
		{
			Physics.gravity = LowGravity;
		}
		if (flingPunch)
		{
			EnforceFlingPunch();
		}
		Camera main = Camera.main;
		Mouse current = Mouse.current;
		if (gravGun && (Object)(object)grabRb != (Object)null && (Object)(object)main != (Object)null && current != null)
		{
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
			Ray val2 = main.ScreenPointToRay(new Vector3(val.x, val.y, 0f));
			Vector3 point = ((Ray)(ref val2)).GetPoint(grabDist);
			grabRb.velocity = Vector3.ClampMagnitude((point - grabRb.position) * 12f, 40f);
		}
		if ((flyOn || godOn) && flyBodies.Count > 0)
		{
			flyBodies.RemoveAll((Rigidbody b) => (Object)(object)b == (Object)null);
			if (flyBodies.Count == 0)
			{
				flyIds.Clear();
				origGravity.Clear();
				picking = true;
				return;
			}
			Keyboard current2 = Keyboard.current;
			if (current2 != null && (Object)(object)main != (Object)null)
			{
				Vector3 forward = ((Component)main).transform.forward;
				forward.y = 0f;
				((Vector3)(ref forward)).Normalize();
				Vector3 right = ((Component)main).transform.right;
				right.y = 0f;
				((Vector3)(ref right)).Normalize();
				Vector3 val3 = Vector3.zero;
				if (((ButtonControl)current2.wKey).isPressed)
				{
					val3 += forward;
				}
				if (((ButtonControl)current2.sKey).isPressed)
				{
					val3 -= forward;
				}
				if (((ButtonControl)current2.dKey).isPressed)
				{
					val3 += right;
				}
				if (((ButtonControl)current2.aKey).isPressed)
				{
					val3 -= right;
				}
				if (((ButtonControl)current2.spaceKey).isPressed)
				{
					val3 += Vector3.up;
				}
				if (((ButtonControl)current2.leftCtrlKey).isPressed)
				{
					val3 -= Vector3.up;
				}
				float num = 9f * (((ButtonControl)current2.leftShiftKey).isPressed ? 2f : 1f);
				Vector3 velocity = ((((Vector3)(ref val3)).sqrMagnitude > 0f) ? (((Vector3)(ref val3)).normalized * num) : Vector3.zero);
				foreach (Rigidbody flyBody in flyBodies)
				{
					flyBody.velocity = velocity;
				}
			}
		}
		if (!godOn || flyBodies.Count <= 0)
		{
			return;
		}
		Vector3 val4 = Vector3.zero;
		foreach (Rigidbody flyBody2 in flyBodies)
		{
			val4 += flyBody2.position;
		}
		val4 /= (float)flyBodies.Count;
		float time = Time.time;
		foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(val4, 2.2f))
		{
			Rigidbody attachedRigidbody = item.attachedRigidbody;
			if (!((Object)(object)attachedRigidbody == (Object)null))
			{
				int instanceID = ((Object)attachedRigidbody).GetInstanceID();
				if (!flyIds.Contains(instanceID) && (!flingCooldown.TryGetValue(instanceID, out var value) || !(time < value)))
				{
					flingCooldown[instanceID] = time + 0.5f;
					Vector3 val5 = attachedRigidbody.position - val4;
					val5.y += 0.3f;
					attachedRigidbody.velocity = ((Vector3)(ref val5)).normalized * 30f;
				}
			}
		}
	}

	private List<Rigidbody> BuildRagdoll(Rigidbody start)
	{
		Dictionary<int, Rigidbody> dictionary = new Dictionary<int, Rigidbody>();
		Dictionary<int, List<int>> dictionary2 = new Dictionary<int, List<int>>();
		foreach (Joint item in Object.FindObjectsOfType<Joint>())
		{
			Rigidbody component = ((Component)item).GetComponent<Rigidbody>();
			Rigidbody connectedBody = item.connectedBody;
			if (!((Object)(object)component == (Object)null) && !((Object)(object)connectedBody == (Object)null))
			{
				int instanceID = ((Object)component).GetInstanceID();
				int instanceID2 = ((Object)connectedBody).GetInstanceID();
				dictionary[instanceID] = component;
				dictionary[instanceID2] = connectedBody;
				if (!dictionary2.ContainsKey(instanceID))
				{
					dictionary2[instanceID] = new List<int>();
				}
				if (!dictionary2.ContainsKey(instanceID2))
				{
					dictionary2[instanceID2] = new List<int>();
				}
				dictionary2[instanceID].Add(instanceID2);
				dictionary2[instanceID2].Add(instanceID);
			}
		}
		List<Rigidbody> list = new List<Rigidbody>();
		HashSet<int> hashSet = new HashSet<int>();
		Queue<int> queue = new Queue<int>();
		int instanceID3 = ((Object)start).GetInstanceID();
		dictionary[instanceID3] = start;
		queue.Enqueue(instanceID3);
		hashSet.Add(instanceID3);
		while (queue.Count > 0 && list.Count < 64)
		{
			int key = queue.Dequeue();
			list.Add(dictionary[key]);
			if (!dictionary2.TryGetValue(key, out var value))
			{
				continue;
			}
			foreach (int item2 in value)
			{
				if (hashSet.Add(item2))
				{
					queue.Enqueue(item2);
				}
			}
		}
		return list;
	}

	private void SelectFlyTarget(Rigidbody hit)
	{
		ReleaseFlyTarget();
		flyBodies.AddRange(BuildRagdoll(hit));
		foreach (Rigidbody flyBody in flyBodies)
		{
			int instanceID = ((Object)flyBody).GetInstanceID();
			flyIds.Add(instanceID);
			origGravity[instanceID] = flyBody.useGravity;
			flyBody.useGravity = false;
		}
		((MelonBase)this).LoggerInstance.Msg("Selected character with " + flyBodies.Count + " bodies.");
	}

	private void ReleaseFlyTarget()
	{
		foreach (Rigidbody flyBody in flyBodies)
		{
			if (!((Object)(object)flyBody == (Object)null))
			{
				flyBody.useGravity = !origGravity.TryGetValue(((Object)flyBody).GetInstanceID(), out var value) || value;
			}
		}
		flyBodies.Clear();
		flyIds.Clear();
		origGravity.Clear();
		flingCooldown.Clear();
	}

	private bool BindPunchModifier()
	{
		if (punchProp != null)
		{
			return true;
		}
		Type wrapper = GetWrapper("GB.Game.Gameplay.GameplayModifiers");
		if (wrapper == null)
		{
			((MelonBase)this).LoggerInstance.Warning("Fling Punches: GameplayModifiers not found.");
			return false;
		}
		BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		punchProp = wrapper.GetProperty("punchForceMul", bindingAttr);
		applyUpdates = wrapper.GetMethod("ApplyUpdates", bindingAttr, null, Type.EmptyTypes, null);
		if (punchProp == null)
		{
			((MelonBase)this).LoggerInstance.Warning("Fling Punches: punchForceMul not found.");
			return false;
		}
		return true;
	}

	private void SetFlingPunches(bool on)
	{
		try
		{
			if (!on && !flingPunch && !punchSaved)
			{
				return;
			}
			if (!BindPunchModifier())
			{
				flingPunch = false;
				return;
			}
			if (on)
			{
				if (!punchSaved)
				{
					savedPunchForce = (float)punchProp.GetValue(null);
					punchSaved = true;
				}
				punchProp.SetValue(null, 10f);
				flingPunch = true;
			}
			else
			{
				flingPunch = false;
				if (punchSaved)
				{
					punchProp.SetValue(null, savedPunchForce);
					punchSaved = false;
				}
			}
			if (applyUpdates != null)
			{
				applyUpdates.Invoke(null, null);
			}
			((MelonBase)this).LoggerInstance.Msg("Fling Punches " + (on ? "ON" : "OFF") + " (punchForceMul " + (on ? 10f : savedPunchForce) + ")");
		}
		catch (Exception ex)
		{
			flingPunch = false;
			((MelonBase)this).LoggerInstance.Warning("Fling Punches failed: " + ((ex.InnerException != null) ? ex.InnerException.Message : ex.Message));
		}
	}

	private void EnforceFlingPunch()
	{
		if (Time.unscaledTime < nextPunchCheck)
		{
			return;
		}
		nextPunchCheck = Time.unscaledTime + 0.5f;
		if (!(punchProp == null) && !Mathf.Approximately((float)punchProp.GetValue(null), 10f))
		{
			punchProp.SetValue(null, 10f);
			if (applyUpdates != null)
			{
				applyUpdates.Invoke(null, null);
			}
		}
	}

	private void SetLowGravity(bool on)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (on)
			{
				if (!gravitySaved)
				{
					savedGravity = Physics.gravity;
					gravitySaved = true;
				}
				lowGrav = true;
				Physics.gravity = LowGravity;
			}
			else
			{
				lowGrav = false;
				if (gravitySaved)
				{
					Physics.gravity = savedGravity;
					gravitySaved = false;
				}
			}
		}
		catch (Exception ex)
		{
			lowGrav = false;
			((MelonBase)this).LoggerInstance.Warning("Low Gravity failed: " + ex.Message);
		}
	}

	private void SetGravGun(bool on)
	{
		gravGun = on;
		if (!on)
		{
			grabRb = null;
		}
	}

	private void SetFly(bool on)
	{
		flyOn = on;
		AfterFlyToggle();
	}

	private void SetGod(bool on)
	{
		godOn = on;
		AfterFlyToggle();
	}

	private void AfterFlyToggle()
	{
		if (flyOn || godOn)
		{
			if (flyBodies.Count == 0)
			{
				picking = true;
			}
		}
		else
		{
			picking = false;
			ReleaseFlyTarget();
		}
	}

	private void DisableAllDanger()
	{
		SetLowGravity(on: false);
		SetFlingPunches(on: false);
		gravGun = false;
		flyOn = false;
		godOn = false;
		picking = false;
		grabRb = null;
		ReleaseFlyTarget();
	}

	public override void OnGUI()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Invalid comparison between Unknown and I4
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Event current = Event.current;
			if (open && current != null && (int)current.type == 8)
			{
				UpdateCursor();
			}
		}
		catch
		{
		}
		if (guiFailed)
		{
			return;
		}
		try
		{
			if (showFps || picking)
			{
				BuildStyles();
			}
			if (showFps)
			{
				GUI.Label(new Rect(10f, 10f, 140f, 24f), "FPS: " + Mathf.RoundToInt(fps), sTitle);
			}
			if (picking)
			{
				GUI.Label(new Rect((float)Screen.width / 2f - 200f, 40f, 400f, 30f), "Click your character to select it", sCenter);
			}
			if (open)
			{
				BuildStyles();
				DrawMenu();
				if (!firstDrawLogged)
				{
					firstDrawLogged = true;
					((MelonBase)this).LoggerInstance.Msg("Menu drew successfully.");
				}
			}
		}
		catch (Exception ex)
		{
			guiFailed = true;
			open = false;
			string message = ex.Message;
			if (message != lastFailMsg)
			{
				lastFailMsg = message;
				((MelonBase)this).LoggerInstance.Error("Blobz GUI failed (press F2 to retry): " + ex);
			}
		}
	}

	private void DrawMenu()
	{
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Invalid comparison between Unknown and I4
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Invalid comparison between Unknown and I4
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: 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_0133: Unknown result type (might be due to invalid IL or missing references)
		winX = Mathf.Clamp(winX, 0f, Mathf.Max(0f, (float)Screen.width - 380f));
		winY = Mathf.Clamp(winY, 0f, Mathf.Max(0f, (float)Screen.height - 340f));
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(winX, winY, 344f, 30f);
		Rect val2 = new Rect(winX + 380f - 32f, winY + 5f, 24f, 22f);
		Event current = Event.current;
		if (current != null)
		{
			if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition))
			{
				dragging = true;
				dragOffset = new Vector2(current.mousePosition.x - winX, current.mousePosition.y - winY);
				current.Use();
			}
			else if (dragging && (int)current.type == 3)
			{
				winX = current.mousePosition.x - dragOffset.x;
				winY = current.mousePosition.y - dragOffset.y;
				current.Use();
			}
			else if ((int)current.type == 1)
			{
				dragging = false;
			}
		}
		GUI.Box(new Rect(winX, winY, 380f, 340f), GUIContent.none, sWindow);
		GUI.Label(new Rect(winX + 12f, winY + 6f, 200f, 20f), "Blobz", sTitle);
		if (GUI.Button(val2, "X", sClose))
		{
			open = false;
		}
		ax = winX + 16f;
		ay = winY + 36f;
		aw = 348f;
		if (!acknowledged)
		{
			DrawWarning();
		}
		else
		{
			DrawMain();
		}
	}

	private void DrawWarning()
	{
		//IL_001d: 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)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		GUI.Label(new Rect(ax, ay + 40f, aw, 26f), "<color=#FFD54A>WARNING</color>", sCenter);
		GUI.Label(new Rect(ax, ay + 72f, aw, 70f), "This version of the mod menu is currently a stub. Please note that most functionality is not yet completed.", sCenter);
		if (GUI.Button(new Rect(ax + (aw - 140f) / 2f, ay + 160f, 140f, 34f), "Continue", sButton))
		{
			acknowledged = true;
			tab = 0;
		}
	}

	private void DrawMain()
	{
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		float num = 0f;
		float[] array = tabWidths;
		foreach (float num2 in array)
		{
			num += num2;
		}
		float num3 = ax + (aw - num) / 2f;
		for (int j = 0; j < tabNames.Length; j++)
		{
			bool num4 = j == 2;
			bool flag = tab == j;
			GUIStyle val = ((!num4) ? (flag ? sTabOn : sTab) : (flag ? sTabDangerOn : sTabDanger));
			if (GUI.Button(new Rect(num3, ay, tabWidths[j], 26f), tabNames[j], val))
			{
				tab = j;
			}
			num3 += tabWidths[j];
		}
		switch (tab)
		{
		case 0:
			DrawCredits();
			break;
		case 1:
			DrawGame();
			break;
		case 2:
			DrawDanger();
			break;
		case 3:
			DrawItems();
			break;
		case 4:
			DrawLocal();
			break;
		}
	}

	private void DrawCredits()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		float num = ay + 50f;
		string[] array = credits;
		foreach (string text in array)
		{
			GUI.Label(new Rect(ax, num, aw, 26f), text, sCenter);
			num += 30f;
		}
	}

	private void DrawGame()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: 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_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: 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)
		float num = ay + 36f;
		GUI.Label(new Rect(ax, num, aw, 24f), "Game speed: " + timeScale.ToString("0.0#") + "x", sCenter);
		num += 28f;
		float[] array = new float[4] { 0.5f, 1f, 1.5f, 2f };
		float num2 = (aw - 18f) / 4f;
		for (int i = 0; i < array.Length; i++)
		{
			if (GUI.Button(new Rect(ax + (float)i * (num2 + 6f), num, num2, 28f), array[i] + "x", sButton))
			{
				SetSpeed(array[i]);
			}
		}
		num += 36f;
		if (GUI.Button(new Rect(ax, num, aw, 28f), "FPS counter: " + (showFps ? "ON" : "OFF"), sButton))
		{
			showFps = !showFps;
		}
		num += 36f;
		if (GUI.Button(new Rect(ax, num, aw, 28f), "Dump scene info to log", sButton))
		{
			DumpInfo();
		}
		num += 36f;
		GUI.Label(new Rect(ax, num, aw, 24f), "Mode: " + LocalSource(), sSmall);
		GUI.Label(new Rect(ax, num + 22f, aw, 34f), signalText, sSmall);
	}

	private void DrawDanger()
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		if (!IsLocalGame())
		{
			GUI.Label(new Rect(ax, ay + 50f, aw, 100f), "Local games only.\n\nBlobz couldn't confirm this is a local game, so these tools are locked to keep online lobbies fair.", sSmall);
			return;
		}
		float num = ay + 40f;
		if (GUI.Button(new Rect(ax, num, aw, 32f), "Gravity Gun: " + (gravGun ? "ON" : "OFF"), sDangerButton))
		{
			SetGravGun(!gravGun);
		}
		num += 40f;
		if (GUI.Button(new Rect(ax, num, aw, 32f), "Grant Fly: " + (flyOn ? "ON" : "OFF"), sDangerButton))
		{
			SetFly(!flyOn);
		}
		num += 40f;
		if (GUI.Button(new Rect(ax, num, aw, 32f), "Fling Punches: " + (flingPunch ? "ON" : "OFF"), sDangerButton))
		{
			SetFlingPunches(!flingPunch);
		}
		num += 40f;
		if (GUI.Button(new Rect(ax, num, aw - 36f, 32f), "God Mode: " + (godOn ? "ON" : "OFF"), sDangerButton))
		{
			SetGod(!godOn);
		}
		GUI.Label(new Rect(ax + aw - 32f, num + 1f, 30f, 30f), "!", sWarn);
		num += 40f;
		if (GUI.Button(new Rect(ax, num, aw, 32f), "Low Gravity: " + (lowGrav ? "ON" : "OFF"), sYellowButton))
		{
			SetLowGravity(!lowGrav);
		}
		num += 44f;
		string text = "";
		if (picking)
		{
			text = "Click your character to select it.";
		}
		else if (gravGun && (flyOn || godOn))
		{
			text = "Hold left mouse to drag. WASD fly, Space up, Ctrl down, Shift boost.";
		}
		else if (gravGun)
		{
			text = "Hold left mouse on anything to drag it. Scroll = distance.";
		}
		else if (flyOn || godOn)
		{
			text = "WASD fly, Space up, Ctrl down, Shift boost.";
		}
		else if (flingPunch)
		{
			text = "Fling Punches is on: punches launch people.";
		}
		if (text.Length > 0)
		{
			GUI.Label(new Rect(ax, num, aw, 40f), text, sSmall);
		}
	}

	private void DrawItems()
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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)
		if (!IsLocalGame())
		{
			GUI.Label(new Rect(ax, ay + 50f, aw, 100f), "Local games only.\n\nBlobz couldn't confirm this is a local game, so these tools are locked to keep online lobbies fair.", sSmall);
			return;
		}
		float num = ay + 36f;
		GUI.Label(new Rect(ax, num, aw, 22f), "Spawns in front of the camera", sCenter);
		num += 28f;
		for (int i = 0; i < itemLabels.Length; i++)
		{
			if (GUI.Button(new Rect(ax, num, aw, 28f), itemLabels[i], sButton))
			{
				Spawn(itemObjects[i]);
			}
			num += 33f;
		}
	}

	private void DrawLocal()
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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)
		if (!IsLocalGame())
		{
			GUI.Label(new Rect(ax, ay + 50f, aw, 100f), "Local games only.\n\nBlobz couldn't confirm this is a local game, so these tools are locked to keep online lobbies fair.", sSmall);
			return;
		}
		if (GUI.Button(new Rect(ax, ay + 50f, aw, 32f), "Restart round", sButton))
		{
			TryRestartRound();
		}
		GUI.Label(new Rect(ax, ay + 90f, aw, 50f), "Uses the game's own round restart.", sSmall);
	}

	private void TryRestartRound()
	{
		try
		{
			if (!IsLocalGame())
			{
				return;
			}
			Type type = FindWrapperType("CoreNet.Components", "NetRoundOrganiser");
			if (type == null)
			{
				((MelonBase)this).LoggerInstance.Warning("Restart: NetRoundOrganiser type not found.");
				return;
			}
			BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic;
			PropertyInfo property = type.GetProperty("Instance", bindingFlags | BindingFlags.Static);
			object obj = ((property != null) ? property.GetValue(null) : null);
			if (obj == null)
			{
				((MelonBase)this).LoggerInstance.Warning("Restart: no active round organiser (start a match first).");
				return;
			}
			MethodInfo method = type.GetMethod("RestartRound", bindingFlags | BindingFlags.Instance, null, Type.EmptyTypes, null);
			if (method == null)
			{
				((MelonBase)this).LoggerInstance.Warning("Restart: RestartRound() not found.");
				return;
			}
			method.Invoke(obj, null);
			((MelonBase)this).LoggerInstance.Msg("RestartRound() called.");
		}
		catch (Exception ex)
		{
			string text = ((ex.InnerException != null) ? ex.InnerException.Message : ex.Message);
			((MelonBase)this).LoggerInstance.Warning("Restart failed: " + text);
		}
	}

	private void Spawn(string name)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = null;
		foreach (GameObject item in Resources.FindObjectsOfTypeAll<GameObject>())
		{
			if (!((Object)(object)item == (Object)null) && string.Equals(((Object)item).name, name, StringComparison.OrdinalIgnoreCase))
			{
				val = item;
				Scene scene = item.scene;
				if (!((Scene)(ref scene)).IsValid())
				{
					break;
				}
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			((MelonBase)this).LoggerInstance.Warning("No object named '" + name + "'");
			return;
		}
		Camera main = Camera.main;
		Vector3 val2 = (((Object)(object)main != (Object)null) ? (((Component)main).transform.position + ((Component)main).transform.forward * 5f) : (Vector3.up * 3f));
		GameObject val3 = ((Il2CppObjectBase)Object.Instantiate<GameObject>(val, val2, Quaternion.identity)).TryCast<GameObject>();
		if ((Object)(object)val3 != (Object)null)
		{
			val3.SetActive(true);
		}
	}

	private void BuildStyles()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Expected O, but got Unknown
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Expected O, but got Unknown
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Expected O, but got Unknown
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Expected O, but got Unknown
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Expected O, but got Unknown
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Expected O, but got Unknown
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Expected O, but got Unknown
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Expected O, but got Unknown
		if (!stylesReady)
		{
			sWindow = new GUIStyle();
			sWindow.normal.background = Rounded(BgBlue);
			sWindow.border = new RectOffset(14, 14, 14, 14);
			sButton = MakeBtn(BtnBlue, BtnHover);
			sDangerButton = MakeBtn(DangerBg, DangerHover);
			sYellowButton = MakeBtn(YellowBtn, YellowBtnHover);
			GUIStyleState normal = sYellowButton.normal;
			GUIStyleState hover = sYellowButton.hover;
			Color val = (sYellowButton.active.textColor = Color.white);
			Color textColor = (hover.textColor = val);
			normal.textColor = textColor;
			sTab = MakeTab(TabIdle, Color.white);
			sTabOn = MakeTab(Color.white, Color.white);
			sTabDanger = MakeTab(TabDangerIdle, TabDangerOn);
			sTabDangerOn = MakeTab(TabDangerOn, TabDangerOn);
			sCenter = new GUIStyle();
			sCenter.richText = true;
			sCenter.wordWrap = true;
			sCenter.fontSize = 14;
			sCenter.fontStyle = (FontStyle)1;
			sCenter.alignment = (TextAnchor)4;
			sCenter.normal.textColor = Color.white;
			sSmall = new GUIStyle();
			sSmall.wordWrap = true;
			sSmall.fontSize = 12;
			sSmall.alignment = (TextAnchor)4;
			sSmall.normal.textColor = new Color(0.85f, 0.9f, 1f);
			sTitle = new GUIStyle();
			sTitle.fontSize = 13;
			sTitle.fontStyle = (FontStyle)1;
			sTitle.alignment = (TextAnchor)3;
			sTitle.normal.textColor = Color.white;
			sClose = new GUIStyle();
			sClose.fontSize = 14;
			sClose.fontStyle = (FontStyle)1;
			sClose.alignment = (TextAnchor)4;
			sClose.normal.textColor = Color.white;
			sClose.hover.textColor = new Color(1f, 0.6f, 0.6f);
			sWarn = new GUIStyle();
			sWarn.normal.background = Rounded(WarnYellow);
			sWarn.border = new RectOffset(14, 14, 14, 14);
			sWarn.fontSize = 18;
			sWarn.fontStyle = (FontStyle)1;
			sWarn.alignment = (TextAnchor)4;
			sWarn.normal.textColor = new Color(0.2f, 0.12f, 0f);
			sWarn.margin = new RectOffset(3, 3, 3, 3);
			stylesReady = true;
		}
	}

	private GUIStyle MakeTab(Color idle, Color hover)
	{
		//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_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: 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_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		GUIStyle val = new GUIStyle
		{
			fontSize = 13,
			fontStyle = (FontStyle)1,
			alignment = (TextAnchor)4,
			padding = new RectOffset(0, 0, 2, 2),
			margin = new RectOffset(2, 2, 0, 0)
		};
		val.normal.textColor = idle;
		val.hover.textColor = hover;
		val.active.textColor = hover;
		return val;
	}

	private GUIStyle MakeBtn(Color normal, Color hover)
	{
		//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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		//IL_004a: 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)
		//IL_0059: Expected O, but got Unknown
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Expected O, but got Unknown
		GUIStyle val = new GUIStyle();
		Texture2D background = Rounded(normal);
		Texture2D background2 = Rounded(hover);
		val.normal.background = background;
		val.hover.background = background2;
		val.active.background = background2;
		val.border = new RectOffset(14, 14, 14, 14);
		val.padding = new RectOffset(8, 8, 4, 4);
		val.margin = new RectOffset(3, 3, 3, 3);
		val.fontSize = 14;
		val.fontStyle = (FontStyle)1;
		val.alignment = (TextAnchor)4;
		val.normal.textColor = Color.white;
		val.hover.textColor = Color.white;
		val.active.textColor = Color.white;
		return val;
	}

	private static Texture2D Rounded(Color fill)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
		int num = 32;
		Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
		((Object)val).hideFlags = (HideFlags)61;
		((Texture)val).filterMode = (FilterMode)1;
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num2 = ((j < 14) ? ((float)(14 - j) - 0.5f) : ((j >= num - 14) ? ((float)(j - (num - 14)) + 0.5f) : 0f));
				float num3 = ((i < 14) ? ((float)(14 - i) - 0.5f) : ((i >= num - 14) ? ((float)(i - (num - 14)) + 0.5f) : 0f));
				float num4 = 1f;
				if (num2 > 0f && num3 > 0f)
				{
					num4 = Mathf.Clamp01(14f - Mathf.Sqrt(num2 * num2 + num3 * num3) + 0.5f);
				}
				val.SetPixel(j, i, new Color(fill.r, fill.g, fill.b, fill.a * num4));
			}
		}
		val.Apply();
		return val;
	}
}