Decompiled source of Quill v1.0.0

plugins/Quill.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using HarmonyLib;
using Il2Cpp;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using Quill;
using Quill.Commands;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Main), "Quill", "1.0", "Bee", null)]
[assembly: AssemblyTitle("Quill")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Quill")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5A0540FC-2C5A-4473-9351-B208EDEC535B")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Quill
{
	public class BeetleRegistry
	{
		private readonly Dictionary<string, BeetleData> _beetleCooldownCache = new Dictionary<string, BeetleData>();

		private readonly Dictionary<string, int> _nameToId = new Dictionary<string, int>();

		public void RegisterNameToIdCache()
		{
			RegisterClass(0, "dung", "d", "scarab", "0");
			RegisterClass(1, "goliath", "g", "1");
			RegisterClass(2, "ladybug", "lb", "2");
			RegisterClass(3, "rhino", "r", "3");
			RegisterClass(4, "earthboring", "earth", "ebb", "e", "4");
			RegisterClass(5, "bombardier", "bomba", "b", "5");
			RegisterClass(6, "tiger", "t", "6");
			RegisterClass(7, "click", "c", "7");
			RegisterClass(8, "fungus", "f", "fung", "8");
			RegisterClass(9, "firefly", "ff", "9");
			RegisterClass(10, "cyborg", "cy", "borg", "10");
			RegisterClass(11, "weevil", "longnosed", "w", "11");
			RegisterClass(12, "potato", "p", "12");
		}

		private void RegisterClass(int id, string canonicalName, params string[] aliases)
		{
			_nameToId[canonicalName.ToLowerInvariant()] = id;
			foreach (string text in aliases)
			{
				_nameToId[text.ToLowerInvariant()] = id;
			}
		}

		public bool TryGetId(string name, out int id)
		{
			if (_nameToId.TryGetValue(name.ToLowerInvariant(), out id))
			{
				return true;
			}
			id = -1;
			return false;
		}

		public Dictionary<string, BeetleData> GetBeetleCooldownCache()
		{
			return _beetleCooldownCache;
		}
	}
	public static class BeetleUtils
	{
		public static void Teleport(Main.PlayerData beetle)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0052: 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_0083: 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_00a1: Expected I4, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected I4, but got Unknown
			//IL_00cf: 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)
			BeetleActor actorByID = GetActorByID(beetle.NetworkID);
			MapInitializer val = Object.FindObjectsOfType<MapInitializer>()[0];
			NetworkPrefabSpawner val2 = Object.FindObjectsOfType<NetworkPrefabSpawner>()[0];
			Vector3 position = val.SpawnPositions[(TeamType)0].spawnTransform.position;
			Quaternion rotation = val.SpawnPositions[(TeamType)0].spawnTransform.rotation;
			val.SpawnPositions[(TeamType)0].spawnTransform.position = beetle.Position;
			val.SpawnPositions[(TeamType)0].spawnTransform.rotation = beetle.Rotation;
			val2.SpawnClassAndSetTeam(beetle.NetworkID, (TeamType)1, (int)beetle.BeetleID);
			GetActorByID(beetle.NetworkID)._team.Value = (int)beetle.team;
			val.SpawnPositions[(TeamType)0].spawnTransform.position = position;
			val.SpawnPositions[(TeamType)0].spawnTransform.rotation = rotation;
		}

		public static BeetleActor GetActorByID(ulong id)
		{
			BeetleActor[] allBeetles = GetAllBeetles();
			foreach (BeetleActor val in allBeetles)
			{
				if (((NetworkBehaviour)val).OwnerClientId == id)
				{
					return val;
				}
			}
			return GetLocalBeetle();
		}

		public static BeetleActor GetActorByName(string name)
		{
			BeetleActor[] allBeetles = GetAllBeetles();
			foreach (BeetleActor val in allBeetles)
			{
				if (GetPlayerName(val) == name)
				{
					return val;
				}
			}
			return GetLocalBeetle();
		}

		public static string GetMapName()
		{
			try
			{
				MapInitializer val = Object.FindObjectsOfType<MapInitializer>()[0];
				return ((Object)val.mapData).ToString().Replace("MapData_", "").Replace(" (MapDataSO)", "");
			}
			catch
			{
				return null;
			}
		}

		public static bool Pressed(Key key)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((ButtonControl)Keyboard.current[key]).wasPressedThisFrame;
		}

		public static string ModFolder()
		{
			string dataPath = Application.dataPath;
			string text = Directory.GetParent(dataPath)?.FullName;
			if (text == null)
			{
				return null;
			}
			return Path.Combine(text, "Mods");
		}

		public static BeetleActor[] GetAllBeetles()
		{
			return Il2CppArrayBase<BeetleActor>.op_Implicit(Object.FindObjectsOfType<BeetleActor>());
		}

		public static BeetleActor GetLocalBeetle()
		{
			BeetleActor[] allBeetles = GetAllBeetles();
			if (allBeetles.Length == 0)
			{
				return null;
			}
			BeetleActor[] array = allBeetles;
			foreach (BeetleActor val in array)
			{
				if (((NetworkBehaviour)val).IsLocalPlayer)
				{
					return val;
				}
			}
			return null;
		}

		public static bool IsHost()
		{
			if ((Object)(object)GetLocalBeetle() == (Object)null)
			{
				return false;
			}
			return ((NetworkBehaviour)GetLocalBeetle()).IsHost;
		}

		public static void ApplyModifer(ModifierType modifier, DungBall dungBall, float duration)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			dungBall.ModifiersController.AddModifierRpcDispatcher(modifier, duration);
		}

		public static List<(string player, string message)> GetChatHistory()
		{
			ChatLog val = Object.FindObjectOfType<ChatLog>();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			string text = ((TMP_Text)val.text).text;
			List<(string, string)> list = new List<(string, string)>();
			MatchCollection matchCollection = Regex.Matches(text, "<b><color=#.*?>(.*?)<\\/color><\\/b>:\\s*(.*)");
			foreach (Match item in matchCollection)
			{
				string value = item.Groups[1].Value;
				string value2 = item.Groups[2].Value;
				list.Add((value, value2));
			}
			return list;
		}

		public static void Score(TeamType team)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			BeetleActor[] allBeetles = GetAllBeetles();
			Goal[] array = Il2CppArrayBase<Goal>.op_Implicit(Object.FindObjectsOfType<Goal>());
			Goal[] array2 = array;
			foreach (Goal val in array2)
			{
				if (!((Object)(object)val == (Object)null) && val.OwnerTeam != team)
				{
					val.BallEnteredGoal_ServerRpc(0uL);
				}
			}
		}

		public static string GetPlayerName(BeetleActor beetle)
		{
			if ((Object)(object)beetle == (Object)null)
			{
				return "Unknown";
			}
			PlayerNametagsController instance = PlayerNametagsController.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				Enumerator<BeetleActor, NametagUI> enumerator = instance._activeNametags.GetEnumerator();
				while (enumerator.MoveNext())
				{
					KeyValuePair<BeetleActor, NametagUI> current = enumerator.Current;
					if ((Object)(object)current.key == (Object)(object)beetle)
					{
						return current.value.nameText.text;
					}
				}
			}
			return "Local Player";
		}

		public static string GetBeetletype(BeetleActor beetle)
		{
			return ((Object)beetle).name.Replace("(Clone)", "").Replace("BeetleActor_", "").Trim()
				.ToLower();
		}

		public static void SendChatMessage(string message)
		{
			ChatPanel val = Object.FindObjectOfType<ChatPanel>();
			if ((Object)(object)val != (Object)null)
			{
				message = message.Replace(">", "\\u003E");
				message = message.Replace("<", "\\u003C");
				val.SendChatMessage(message);
			}
		}
	}
	public class CommandManager
	{
		private string _newestMsg;

		private const char CommandPrefix = '!';

		private readonly Dictionary<string, ChatCommand> _commands = new Dictionary<string, ChatCommand>();

		public void RegisterCommand(string command, ChatCommand chatCommand)
		{
			_commands.Add(command.ToLower(), chatCommand);
			MelonLogger.Msg("Command " + chatCommand.Name + " registered!");
		}

		public void CommandHandler()
		{
			(string, string[], string)? newestCommand = GetNewestCommand();
			if (!newestCommand.HasValue)
			{
				return;
			}
			(string, string[], string) value = newestCommand.Value;
			string item = value.Item1;
			string[] item2 = value.Item2;
			string item3 = value.Item3;
			string text = item;
			string text2 = text;
			if (text2 == null)
			{
				return;
			}
			ChatCommand value2;
			if (text2 == "help")
			{
				BeetleUtils.SendChatMessage("----------HELP----------<size=15>");
				foreach (ChatCommand item4 in _commands.Select((KeyValuePair<string, ChatCommand> kvp) => kvp.Value))
				{
					BeetleUtils.SendChatMessage(item4.Name + " - " + item4.Description);
				}
				BeetleUtils.SendChatMessage("</size>----------HELP----------");
			}
			else if (_commands.TryGetValue(item, out value2))
			{
				value2.Execute(item2, item3);
			}
			else
			{
				BeetleUtils.SendChatMessage("Unknown command: " + item);
			}
		}

		private (string command, string[] args, string player)? GetNewestCommand()
		{
			List<(string, string)> chatHistory = BeetleUtils.GetChatHistory();
			if (chatHistory == null || chatHistory.Count == 0)
			{
				return null;
			}
			int index = chatHistory.Count - 1;
			string newestMsg = _newestMsg;
			_newestMsg = chatHistory[index].Item2?.ToLower();
			Debug.Assert(_newestMsg != null, "_newestMsg != null");
			if (_newestMsg == newestMsg)
			{
				return null;
			}
			if (_newestMsg.ToCharArray()[0] != '!')
			{
				return null;
			}
			string text = _newestMsg.Substring(1);
			string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			string item = array[0];
			string[] item2 = ((array.Length > 1) ? array.Skip(1).ToArray() : Array.Empty<string>());
			string item3 = chatHistory[index].Item1;
			MelonLogger.Msg("Command identified:" + _newestMsg);
			return (item, item2, item3);
		}
	}
	public class ChangeBeetle : ChatCommand
	{
		public ChangeBeetle()
			: base("beetle", "changes your beetle to the decided beetle", ChangeBeetleExecute, 1)
		{
		}

		public static void ChangeBeetleExecute(string[] args, string playername)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0088: Invalid comparison between Unknown and I4
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected I4, but got Unknown
			if (args.Length != 1)
			{
				BeetleUtils.SendChatMessage("usage: beetle [beetle name] (common aliases/ID works)");
				return;
			}
			string name = args[0].ToLower();
			Main.BeetleRegistry.TryGetId(name, out var id);
			if (id == -1)
			{
				BeetleUtils.SendChatMessage("unknown beetle " + id);
				return;
			}
			BeetleActor actorByName = BeetleUtils.GetActorByName(playername);
			ulong ownerClientId = ((NetworkBehaviour)actorByName).OwnerClientId;
			TeamType team = ((NetworkActor)actorByName).Team;
			NetworkPrefabSpawner val = Object.FindObjectsOfType<NetworkPrefabSpawner>()[0];
			if ((int)GameState.CurrentState != 2)
			{
				MapInitializer val2 = Object.FindObjectsOfType<MapInitializer>()[0];
				Vector3 position = val2.SpawnPositions[(TeamType)0].spawnTransform.position;
				Quaternion rotation = val2.SpawnPositions[(TeamType)0].spawnTransform.rotation;
				val2.SpawnPositions[(TeamType)0].spawnTransform.position = ((Component)actorByName).transform.position;
				val2.SpawnPositions[(TeamType)0].spawnTransform.rotation = ((Component)actorByName).transform.rotation;
				val.SpawnClassAndSetTeam(ownerClientId, (TeamType)1, id);
				BeetleActor[] allBeetles = BeetleUtils.GetAllBeetles();
				foreach (BeetleActor val3 in allBeetles)
				{
					if (((NetworkBehaviour)val3).OwnerClientId == ownerClientId)
					{
						val3._team.Value = (int)team;
					}
				}
				val2.SpawnPositions[(TeamType)0].spawnTransform.position = position;
				val2.SpawnPositions[(TeamType)0].spawnTransform.rotation = rotation;
			}
			else
			{
				BeetleUtils.SendChatMessage("You cannot change your beetle in the lobby!");
			}
		}
	}
	public class BeetleData
	{
		public float BallCooldown;

		public float NormalCooldown;

		public BeetleData(float ballCooldown, float normalCooldown)
		{
			BallCooldown = ballCooldown;
			NormalCooldown = normalCooldown;
		}

		public void ResetCooldowns(BeetleActor beetle)
		{
			beetle.Stats.AbilityStatsBall.ChargeDuration = BallCooldown;
			beetle.Stats.AbilityStatsNormal.ChargeDuration = NormalCooldown;
			beetle._abilityChargingBall.CurrentChargeTime = BallCooldown;
			beetle._abilityChargingNormal.CurrentChargeTime = NormalCooldown;
		}
	}
	public class ChatCommand
	{
		public string Name;

		public string Description;

		private readonly Action<string[], string> _execute;

		public ChatCommand(string name, string description, Action<string[], string> execute, int args)
		{
			Name = name;
			Description = description;
			_execute = execute;
		}

		public void Execute(string[] args, string player)
		{
			_execute(args, player);
		}
	}
	public class ClearDung : ChatCommand
	{
		public ClearDung()
			: base("clear", "destroys all dung", ClearDungExecute, 0)
		{
		}

		public static void ClearDungExecute(string[] args, string player)
		{
			Il2CppArrayBase<DungBall> val = Object.FindObjectsOfType<DungBall>();
			Il2CppArrayBase<BunnyPathJumper> val2 = Object.FindObjectsOfType<BunnyPathJumper>();
			BeetleUtils.SendChatMessage("Clearing dung...");
			foreach (DungBall item in val)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			foreach (BunnyPathJumper item2 in val2)
			{
				Object.Destroy((Object)(object)((Component)item2).gameObject);
			}
		}
	}
	public class SaveStates : ChatCommand
	{
		public class SaveState
		{
			public List<Main.PlayerData> players = new List<Main.PlayerData>();

			public List<Main.DungData> dungs = new List<Main.DungData>();
		}

		[HarmonyPatch(typeof(Goal), "BallEnteredGoal_ServerRpc")]
		private class Goal_BallEnteredGoal_ServerRpc_Patch
		{
			private static bool Prefix(ulong ballId)
			{
				if (!Main._quillEnabled || !Main.inCustom)
				{
					return true;
				}
				if (auto)
				{
					SaveStatesExecute(new string[1] { "load" }, "");
				}
				return !auto;
			}
		}

		private static SaveState currentState = new SaveState();

		private static bool auto = false;

		public static void Init()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			Harmony val = new Harmony("com.quill.SaveStates");
			val.PatchAll(Assembly.GetExecutingAssembly());
		}

		public SaveStates()
			: base("ss", "saves / loads savestates", SaveStatesExecute, 1)
		{
		}

		private static void SaveStatesExecute(string[] args, string playername)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00b8: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			if (args.Length == 0)
			{
				BeetleUtils.SendChatMessage("Usage: !ss [save, load]");
				return;
			}
			switch (args[0])
			{
			case "save":
			{
				currentState.players.Clear();
				currentState.dungs.Clear();
				BeetleActor[] allBeetles = BeetleUtils.GetAllBeetles();
				foreach (BeetleActor val3 in allBeetles)
				{
					Main.PlayerData item = new Main.PlayerData
					{
						NetworkID = ((NetworkBehaviour)val3).OwnerClientId,
						BeetleID = val3.ClassData.BeetleType,
						Position = ((Component)val3).transform.position,
						Rotation = ((Component)val3).transform.rotation,
						team = ((NetworkActor)val3).Team
					};
					currentState.players.Add(item);
				}
				{
					foreach (DungBall item3 in Object.FindObjectsOfType<DungBall>())
					{
						Main.DungData item2 = new Main.DungData
						{
							Size = item3.Size,
							Position = ((Component)item3).transform.position
						};
						currentState.dungs.Add(item2);
					}
					break;
				}
			}
			case "load":
				ClearDung.ClearDungExecute(new string[0], playername);
				foreach (Main.PlayerData player in currentState.players)
				{
					BeetleUtils.Teleport(player);
				}
				{
					foreach (Main.DungData dung in currentState.dungs)
					{
						NetworkPrefabSpawner val = Object.FindObjectsOfType<NetworkPrefabSpawner>()[0];
						RpcParams val2 = new RpcParams();
						val.SpawnDungBall_ServerRpc(dung.Position, Vector3.zero, dung.Size, 0f, val2);
					}
					break;
				}
			case "auto":
				BeetleUtils.SendChatMessage("Savestates " + (auto ? "wont " : "will") + "automatically load when you score");
				auto = !auto;
				break;
			default:
				BeetleUtils.SendChatMessage("Usage: SS [Save/Load]");
				break;
			}
		}
	}
	public class DisableScoring : ChatCommand
	{
		[HarmonyPatch(typeof(Goal), "BallEnteredGoal_ServerRpc")]
		private class Goal_BallEnteredGoal_ServerRpc_Patch
		{
			private static bool Prefix(ulong ballId)
			{
				if (Main._quillEnabled && Main.inCustom)
				{
					return AllowScoring;
				}
				return true;
			}
		}

		private static bool AllowScoring = true;

		public static void Init()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			Harmony val = new Harmony("com.quill.DisableGoals");
			val.PatchAll(Assembly.GetExecutingAssembly());
		}

		public DisableScoring()
			: base("goal", "Disables / Enables goals", ChangeGoalAvaliability, 0)
		{
		}

		private static void ChangeGoalAvaliability(string[] args, string playername)
		{
			if (args.Length == 0)
			{
				AllowScoring = !AllowScoring;
				if (AllowScoring)
				{
					BeetleUtils.SendChatMessage("Scoring is now Enabled");
				}
				else
				{
					BeetleUtils.SendChatMessage("Scoring is now Disabled");
				}
				return;
			}
			string text = args[0];
			string text2 = text;
			if (text2 != null)
			{
				if (text2 == "on" || text2 == "1")
				{
					AllowScoring = true;
					BeetleUtils.SendChatMessage("Scoring is now Enabled");
					return;
				}
				string text3 = text2;
				if (text3 == "off" || text3 == "0")
				{
					AllowScoring = false;
					BeetleUtils.SendChatMessage("Scoring is now Disabled");
					return;
				}
			}
			BeetleUtils.SendChatMessage("Usage: Score [on/off]");
		}
	}
	public class SpawnDung : ChatCommand
	{
		public SpawnDung()
			: base("dung", "Creates a dung sized [1 - 5]", ExecuteSpawnDung, 1)
		{
		}

		public static void ExecuteSpawnDung(string[] args, string player)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (args.Length < 1)
			{
				BeetleUtils.SendChatMessage("Usage: dung [1-5]");
				return;
			}
			if (!int.TryParse(args[0], out var result))
			{
				BeetleUtils.SendChatMessage("Argument must be a number between 1 and 5.");
				return;
			}
			if (result < 1 || result > 5)
			{
				BeetleUtils.SendChatMessage("Number must be between 1 and 5.");
				return;
			}
			BeetleActor actorByName = BeetleUtils.GetActorByName(player);
			BeetleUtils.SendChatMessage("Spawning dung sized  " + args[0] + " for " + BeetleUtils.GetPlayerName(actorByName));
			NetworkPrefabSpawner val = Object.FindObjectsOfType<NetworkPrefabSpawner>()[0];
			RpcParams val2 = new RpcParams();
			val.SpawnDungBall_ServerRpc(((Component)actorByName).transform.position, actorByName.Velocity, result, 0f, val2);
		}
	}
	public class Main : MelonMod
	{
		public class PlayerData
		{
			public ulong NetworkID;

			public BeetleType BeetleID;

			public TeamType team;

			public Vector3 Position;

			public Quaternion Rotation;
		}

		public class DungData
		{
			public int Size;

			public Vector3 Position;
		}

		public static bool _quillEnabled = false;

		public static bool inCustom = false;

		private static CommandManager CommandManager { get; } = new CommandManager();


		public static BeetleRegistry BeetleRegistry { get; } = new BeetleRegistry();


		public override void OnInitializeMelon()
		{
			CommandManager.RegisterCommand("dung", new SpawnDung());
			CommandManager.RegisterCommand("bunny", new BunnyModify());
			CommandManager.RegisterCommand("cooldowns", new FastCooldowns());
			CommandManager.RegisterCommand("clear", new ClearDung());
			CommandManager.RegisterCommand("beetle", new ChangeBeetle());
			CommandManager.RegisterCommand("goal", new DisableScoring());
			CommandManager.RegisterCommand("ss", new SaveStates());
			BeetleRegistry.RegisterNameToIdCache();
		}

		public override void OnUpdate()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected I4, but got Unknown
			if (!BeetleUtils.IsHost())
			{
				_quillEnabled = false;
				return;
			}
			State currentState = GameState.CurrentState;
			State val = currentState;
			switch ((int)val)
			{
			case 2:
				inCustom = true;
				break;
			case 0:
				inCustom = false;
				break;
			case 3:
				inCustom = true;
				break;
			}
			if (inCustom)
			{
				if (!_quillEnabled)
				{
					BeetleUtils.SendChatMessage("This server is running " + ((MelonBase)this).Info.Name + " " + ((MelonBase)this).Info.Version + " by " + ((MelonBase)this).Info.Author);
				}
				_quillEnabled = true;
				CommandManager.CommandHandler();
			}
		}
	}
}
namespace Quill.Commands
{
	public class BunnyModify : ChatCommand
	{
		public BunnyModify()
			: base("bunny", "starts, stops, or changes the speed | of the bunny", ExecuteBunnyModify, 1)
		{
		}

		private static void DespawnBunny()
		{
			Il2CppArrayBase<BunnyPathJumper> val = Object.FindObjectsOfType<BunnyPathJumper>();
			foreach (BunnyPathJumper item in val)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
		}

		private static void ExecuteBunnyModify(string[] args, string player)
		{
			if (args.Length < 1)
			{
				BeetleUtils.SendChatMessage("Usage: bunny [start, stop, speed (measured in seconds between bunnys)] [0-100]");
				return;
			}
			BunnySpawner val = Object.FindObjectsOfType<BunnySpawner>()[0];
			switch (args[0].ToLower())
			{
			case "start":
				val.spawnInterval = 15;
				val.spawnIntervalSuddenDeath = 10;
				BeetleUtils.SendChatMessage("Starting the Bunny Spawner...");
				break;
			case "stop":
				val.spawnInterval = 9999999;
				val.spawnIntervalSuddenDeath = 9999999;
				BeetleUtils.SendChatMessage("Stopping the Bunny Spawner...");
				DespawnBunny();
				break;
			case "speed":
			{
				if (args.Length != 2)
				{
					BeetleUtils.SendChatMessage("missing args: bunny speed [0-100]");
					break;
				}
				if (!int.TryParse(args[1], out var result))
				{
					BeetleUtils.SendChatMessage("Argument must be a number between 1 and 100.");
				}
				if (result <= 0 || result >= 100)
				{
					BeetleUtils.SendChatMessage("Argument must be a number between 1 and 100.");
					break;
				}
				val.spawnInterval = result;
				val.spawnIntervalSuddenDeath = result;
				val.SpawnBunnyAndUpdateTime();
				DespawnBunny();
				BeetleUtils.SendChatMessage("Setting spawn interval to " + result);
				break;
			}
			default:
				BeetleUtils.SendChatMessage("Usage: bunny [start, stop, speed] [1-100]");
				break;
			}
		}
	}
	public class FastCooldowns : ChatCommand
	{
		public FastCooldowns()
			: base("cooldowns", "Manage Cooldowns being on or off", FastCooldownsExecute, 1)
		{
		}

		private static void FastCooldownsExecute(string[] args, string playername)
		{
			//IL_0030: 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)
			BeetleActor actorByName = BeetleUtils.GetActorByName(playername);
			if (((NetworkBehaviour)actorByName).OwnerClientId != 0)
			{
				BeetleUtils.SendChatMessage("Giving Back abilities");
				string[] array = new string[1];
				BeetleType beetleType = actorByName.ClassData.BeetleType;
				array[0] = ((object)(BeetleType)(ref beetleType)).ToString();
				string[] args2 = array;
				ChangeBeetle.ChangeBeetleExecute(args2, playername);
				return;
			}
			string beetletype = BeetleUtils.GetBeetletype(actorByName);
			Dictionary<string, BeetleData> beetleCooldownCache = Main.BeetleRegistry.GetBeetleCooldownCache();
			if (!beetleCooldownCache.ContainsKey(beetletype))
			{
				float chargeDuration = actorByName.Stats.AbilityStatsBall.ChargeDuration;
				float chargeDuration2 = actorByName.Stats.AbilityStatsNormal.ChargeDuration;
				beetleCooldownCache.Add(beetletype, new BeetleData(chargeDuration, chargeDuration2));
			}
			if (args.Length != 1)
			{
				BeetleUtils.SendChatMessage("Usage: Cooldowns [on/off]");
			}
			string text = args[0];
			string text2 = text;
			if (!(text2 == "on"))
			{
				if (text2 == "off")
				{
					actorByName.Stats.AbilityStatsBall.ChargeDuration = 0.1f;
					actorByName.Stats.AbilityStatsNormal.ChargeDuration = 0.1f;
					BeetleUtils.SendChatMessage("Cooldowns turning off");
				}
				else
				{
					BeetleUtils.SendChatMessage("Usage: Cooldowns [on/off]");
				}
			}
			else
			{
				beetleCooldownCache[beetletype].ResetCooldowns(actorByName);
				BeetleUtils.SendChatMessage("cooldowns turning on");
			}
		}
	}
}