Decompiled source of AdminMod LobbyExpansion v1.1.2

BepInEx/plugins/AdminMod/AdminMod.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Cysharp.Threading.Tasks;
using Features.AIModuleStateMachine.Scripts.Core.Damageable;
using Features.CurrencyModule.Scripts;
using Features.DamageableTrackModule.Scripts;
using Features.ItemsModule.Scripts;
using Features.LevelModule.Scripts;
using Features.Movement.Scripts;
using Features.MultiplayerSessionServices.Scripts;
using Features.PlayerStatesModule.Scripts;
using Features.StatsUsageModule.Scripts.Entities;
using Features.StatsUsageModule.Scripts.Entities.EntityStatTypeEntities;
using Features.SynchronizedModelsModule.Scripts.JsonModelSynchronizer;
using Fusion;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using RSG.Muffin.StatsSubmodule.EntityStatsModule.Scripts.Modifier;
using RSG.Muffin.StatsSubmodule.EntityStatsModule.Scripts.StatsEntity;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.AddressableAssets;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using Zenject;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("AdminMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2")]
[assembly: AssemblyProduct("AdminMod")]
[assembly: AssemblyTitle("AdminMod")]
[assembly: AssemblyVersion("1.1.2.0")]
namespace LastPirates.AdminMod;

public class AdminESP : MonoBehaviour
{
	public bool EnableESP;

	public bool ShowPlayers = true;

	public bool ShowMonsters = true;

	public bool ShowChests = true;

	public float MaxDistance = 300f;

	private GUIStyle playerStyle;

	private GUIStyle monsterStyle;

	private GUIStyle chestStyle;

	private Texture2D boxTexture;

	private GUIStyle boxStyle;

	public static AdminESP Instance { get; private set; }

	public AdminESP(IntPtr pointer)
		: base(pointer)
	{
	}

	private void Awake()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		if (AdminModPlugin.Instance != null)
		{
			EnableESP = AdminModPlugin.Instance.EnableESP.Value;
		}
		boxTexture = new Texture2D(1, 1);
		boxTexture.SetPixel(0, 0, Color.white);
		boxTexture.Apply();
	}

	private void InitStyles()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		//IL_002b: 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_006f: Expected O, but got Unknown
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		if (playerStyle == null)
		{
			playerStyle = new GUIStyle(GUI.skin.label);
			playerStyle.normal.textColor = Color.green;
			playerStyle.fontSize = 12;
			playerStyle.fontStyle = (FontStyle)1;
			playerStyle.alignment = (TextAnchor)4;
			monsterStyle = new GUIStyle(GUI.skin.label);
			monsterStyle.normal.textColor = Color.red;
			monsterStyle.fontSize = 12;
			monsterStyle.fontStyle = (FontStyle)1;
			monsterStyle.alignment = (TextAnchor)4;
			chestStyle = new GUIStyle(GUI.skin.label);
			chestStyle.normal.textColor = Color.yellow;
			chestStyle.fontSize = 12;
			chestStyle.fontStyle = (FontStyle)1;
			chestStyle.alignment = (TextAnchor)4;
		}
	}

	private void OnGUI()
	{
		if (!EnableESP)
		{
			return;
		}
		try
		{
			DrawESP();
		}
		catch (Exception ex)
		{
			EnableESP = false;
			AdminModPlugin.Log.LogError((object)("[AdminESP] ESP desativado após falha de desenho: " + ex));
		}
	}

	private void DrawESP()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Invalid comparison between Unknown and I4
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_036e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0373: Unknown result type (might be due to invalid IL or missing references)
		//IL_0378: Unknown result type (might be due to invalid IL or missing references)
		//IL_037a: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: 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_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_038e: 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_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
		if (!EnableESP || (int)Event.current.type != 7)
		{
			return;
		}
		MaxDistance = Mathf.Clamp(MaxDistance, 50f, 1000f);
		Camera main = Camera.main;
		if ((Object)(object)main == (Object)null)
		{
			return;
		}
		InitStyles();
		if (ShowPlayers && (Object)(object)PlayerAdmin.Instance != (Object)null)
		{
			List<GameObject> allPlayers = PlayerAdmin.Instance.GetAllPlayers();
			GameObject localPlayer = PlayerAdmin.Instance.GetLocalPlayer();
			foreach (GameObject item in allPlayers)
			{
				if ((Object)(object)item == (Object)null || !item.activeInHierarchy || (Object)(object)item == (Object)(object)localPlayer)
				{
					continue;
				}
				float num = Vector3.Distance(((Component)main).transform.position, item.transform.position);
				if (!(num > MaxDistance))
				{
					Vector3 val = main.WorldToScreenPoint(item.transform.position + Vector3.up * 1f);
					if (val.z > 0f)
					{
						float num2 = (float)Screen.height - val.y;
						string text = $"[PIRATA] {((Object)item).name}\n{num:F1}m";
						GUI.Label(new Rect(val.x - 100f, num2 - 30f, 200f, 40f), text, playerStyle);
						DrawESPBox(val.x, num2, 30f, 60f, Color.green);
					}
				}
			}
		}
		if (ShowMonsters && (Object)(object)WorldAdmin.Instance != (Object)null)
		{
			foreach (GameObject monster in WorldAdmin.Instance.GetMonsters())
			{
				if ((Object)(object)monster == (Object)null || !monster.activeInHierarchy)
				{
					continue;
				}
				float num3 = Vector3.Distance(((Component)main).transform.position, monster.transform.position);
				if (!(num3 > MaxDistance))
				{
					Vector3 val2 = main.WorldToScreenPoint(monster.transform.position + Vector3.up * 0.8f);
					if (val2.z > 0f)
					{
						float num4 = (float)Screen.height - val2.y;
						string text2 = $"[MONSTRO] {((Object)monster).name}\n{num3:F1}m";
						GUI.Label(new Rect(val2.x - 100f, num4 - 30f, 200f, 40f), text2, monsterStyle);
						DrawESPBox(val2.x, num4, 25f, 45f, Color.red);
					}
				}
			}
		}
		if (!ShowChests || !((Object)(object)WorldAdmin.Instance != (Object)null))
		{
			return;
		}
		foreach (GameObject chest in WorldAdmin.Instance.GetChests())
		{
			if ((Object)(object)chest == (Object)null || !chest.activeInHierarchy)
			{
				continue;
			}
			float num5 = Vector3.Distance(((Component)main).transform.position, chest.transform.position);
			if (!(num5 > MaxDistance))
			{
				Vector3 val3 = main.WorldToScreenPoint(chest.transform.position);
				if (val3.z > 0f)
				{
					float num6 = (float)Screen.height - val3.y;
					string text3 = $"[BAÚ/OURO] {((Object)chest).name}\n{num5:F1}m";
					GUI.Label(new Rect(val3.x - 100f, num6 - 25f, 200f, 40f), text3, chestStyle);
					DrawESPBox(val3.x, num6, 20f, 20f, Color.yellow);
				}
			}
		}
	}

	private void DrawESPBox(float centerX, float centerY, float width, float height, Color color)
	{
		//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_0051: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		Color color2 = GUI.color;
		GUI.color = color;
		float num = centerX - width / 2f;
		float num2 = centerY - height / 2f;
		if (boxStyle == null)
		{
			boxStyle = new GUIStyle();
			boxStyle.normal.background = boxTexture;
		}
		GUI.Box(new Rect(num, num2, width, 2f), "", boxStyle);
		GUI.Box(new Rect(num, num2 + height - 2f, width, 2f), "", boxStyle);
		GUI.Box(new Rect(num, num2, 2f, height), "", boxStyle);
		GUI.Box(new Rect(num + width - 2f, num2, 2f, height), "", boxStyle);
		GUI.color = color2;
	}

	private void OnDestroy()
	{
		if ((Object)(object)boxTexture != (Object)null)
		{
			Object.Destroy((Object)(object)boxTexture);
		}
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
[BepInPlugin("com.admin.lastpirates", "Last Pirates Admin & Lobby Expansion", "1.1.2")]
public class AdminModPlugin : BasePlugin
{
	public const string PLUGIN_GUID = "com.admin.lastpirates";

	public const string PLUGIN_NAME = "Last Pirates Admin & Lobby Expansion";

	public const string PLUGIN_VERSION = "1.1.2";

	private Harmony harmony;

	public static AdminModPlugin Instance { get; private set; }

	public static ManualLogSource Log
	{
		get
		{
			if (Instance == null)
			{
				return null;
			}
			return Instance.PluginLog;
		}
	}

	public ConfigEntry<KeyCode> MenuToggleKey { get; private set; }

	public ConfigEntry<int> MaxLobbyPlayers { get; private set; }

	public ConfigEntry<bool> EnableLateJoin { get; private set; }

	public ConfigEntry<bool> EnableESP { get; private set; }

	public ConfigEntry<bool> GodModeDefault { get; private set; }

	public ConfigEntry<float> FlySpeedMultiplier { get; private set; }

	public ConfigEntry<float> SpeedMultiplier { get; private set; }

	public ConfigEntry<float> ElasticReachMultiplier { get; private set; }

	private ManualLogSource PluginLog => ((BasePlugin)this).Log;

	public override void Load()
	{
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Expected O, but got Unknown
		Instance = this;
		MenuToggleKey = ((BasePlugin)this).Config.Bind<KeyCode>("Atalhos", "MenuToggleKey", (KeyCode)282, "Tecla para abrir/fechar o Menu de Admin (ex: F1, Insert, F4)");
		MaxLobbyPlayers = ((BasePlugin)this).Config.Bind<int>("Lobby", "MaxLobbyPlayers", 4, "Capacidade máxima de jogadores na sala criada pelo Host (4 a 32)");
		EnableLateJoin = ((BasePlugin)this).Config.Bind<bool>("Lobby", "EnableLateJoin", false, "Experimental: mantém o lobby Steam aberto; não implementa a sincronização de quem entra durante a partida.");
		EnableESP = ((BasePlugin)this).Config.Bind<bool>("Visual", "EnableESP", false, "Ativa/Desativa o ESP de jogadores, monstros e baús");
		GodModeDefault = ((BasePlugin)this).Config.Bind<bool>("Admin", "GodModeDefault", false, "Inicia com God Mode ativado");
		FlySpeedMultiplier = ((BasePlugin)this).Config.Bind<float>("Admin", "FlySpeedMultiplier", 15f, "Velocidade do modo de voo (Noclip)");
		SpeedMultiplier = ((BasePlugin)this).Config.Bind<float>("Admin", "SpeedMultiplier", 2f, "Multiplicador de velocidade de corrida");
		ElasticReachMultiplier = ((BasePlugin)this).Config.Bind<float>("Admin", "ElasticReachMultiplier", 3f, "Multiplicador de alcance dos braços elásticos");
		PluginLog.LogInfo((object)string.Format("[AdminMod] Inicializando {0} v{1}...", "Last Pirates Admin & Lobby Expansion", "1.1.2"));
		try
		{
			harmony = new Harmony("com.admin.lastpirates");
			AssetDiagnostics.Install(harmony);
			if (Environment.GetEnvironmentVariable("ADMINMOD_DIAGNOSTICS_ONLY") == "1")
			{
				PluginLog.LogInfo((object)"[AdminMod] Diagnostic-only startup: gameplay patches and components disabled.");
				return;
			}
			if (Environment.GetEnvironmentVariable("ADMINMOD_SKIP_GAMEPLAY_PATCHES") != "1")
			{
				LobbyExpansion.ApplyPatches(harmony);
			}
			PluginLog.LogInfo((object)("[AdminMod] Verificação dos patches concluída. Quantidade aplicada: " + LobbyExpansion.AppliedPatches));
		}
		catch (Exception arg)
		{
			PluginLog.LogError((object)$"[AdminMod] Erro ao aplicar patches Harmony: {arg}");
		}
		((BasePlugin)this).AddComponent<AdminUI>();
		((BasePlugin)this).AddComponent<PlayerAdmin>();
		((BasePlugin)this).AddComponent<WorldAdmin>();
		((BasePlugin)this).AddComponent<ItemSpawner>();
		((BasePlugin)this).AddComponent<AdminESP>();
		PluginLog.LogInfo((object)"[AdminMod] Mod carregado com sucesso! Pressione F1, Insert, F4 ou clique no botão [☠\ufe0f ADMIN] no topo da tela!");
	}

	public override bool Unload()
	{
		try
		{
			if ((Object)(object)PlayerAdmin.Instance != (Object)null)
			{
				Object.Destroy((Object)(object)PlayerAdmin.Instance);
			}
			if ((Object)(object)WorldAdmin.Instance != (Object)null)
			{
				Object.Destroy((Object)(object)WorldAdmin.Instance);
			}
			if ((Object)(object)AdminUI.Instance != (Object)null)
			{
				Object.Destroy((Object)(object)AdminUI.Instance);
			}
			if ((Object)(object)ItemSpawner.Instance != (Object)null)
			{
				Object.Destroy((Object)(object)ItemSpawner.Instance);
			}
			if ((Object)(object)AdminESP.Instance != (Object)null)
			{
				Object.Destroy((Object)(object)AdminESP.Instance);
			}
			LobbyExpansion.Restore();
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
		catch (Exception ex)
		{
			PluginLog.LogWarning((object)("Falha ao remover patches: " + ex.Message));
		}
		if (Instance == this)
		{
			Instance = null;
		}
		return true;
	}
}
public class AdminUI : MonoBehaviour
{
	public bool IsMenuOpen;

	public bool IsMinimized;

	private Rect window = new Rect(30f, 40f, 570f, 560f);

	private readonly string[] tabs = new string[6] { "LOBBY", "JOGADORES", "PODERES", "ITENS", "MUNDO", "ESP" };

	private int tab;

	private int playerPage;

	private int itemPage;

	private int category;

	private CursorLockMode savedLock;

	private bool savedVisible;

	private bool faulted;

	private GUIStyle wrapped;

	private GUIStyle title;

	private WindowFunction drawWindow;

	private bool smoke;

	private int smokeTab = -1;

	private readonly bool[] smokeRendered = new bool[6];

	private float smokeNext;

	public static AdminUI Instance { get; private set; }

	public AdminUI(IntPtr pointer)
		: base(pointer)
	{
	}//IL_0015: Unknown result type (might be due to invalid IL or missing references)
	//IL_001a: Unknown result type (might be due to invalid IL or missing references)


	private void Awake()
	{
		Instance = this;
		drawWindow = WindowFunction.op_Implicit((Action<int>)DrawWindow);
		smoke = Environment.GetEnvironmentVariable("ADMINMOD_UI_SMOKE_TEST") == "1";
		if (smoke)
		{
			ToggleMenu();
			smokeNext = Time.unscaledTime + 3f;
		}
	}

	private void Update()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		if (ModSupport.Key(AdminModPlugin.Instance.MenuToggleKey.Value, down: true) || ModSupport.Key((KeyCode)282, down: true) || ModSupport.Key((KeyCode)277, down: true) || ModSupport.Key((KeyCode)285, down: true))
		{
			ToggleMenu();
		}
		if (!smoke || !(Time.unscaledTime >= smokeNext))
		{
			return;
		}
		if (faulted)
		{
			smoke = false;
			return;
		}
		smokeNext = Time.unscaledTime + 1f;
		smokeTab++;
		if (smokeTab >= tabs.Length)
		{
			smoke = false;
			ToggleMenu();
			bool flag = Array.TrueForAll(smokeRendered, (bool rendered) => rendered);
			AdminModPlugin.Log.LogInfo((object)(flag ? "[UI-SMOKE] PASS: all six tabs rendered without exceptions; gameplay actions not tested." : "[UI-SMOKE] INCOMPLETE: some tabs did not receive a repaint."));
		}
		else
		{
			tab = smokeTab;
		}
	}

	public void ToggleMenu()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		if (!IsMenuOpen)
		{
			savedLock = Cursor.lockState;
			savedVisible = Cursor.visible;
			IsMenuOpen = true;
			faulted = false;
		}
		else
		{
			IsMenuOpen = false;
			RestoreCursor();
		}
	}

	private void RestoreCursor()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		Cursor.lockState = savedLock;
		Cursor.visible = savedVisible;
	}

	private void LateUpdate()
	{
		if (IsMenuOpen)
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}
	}

	private void OnDisable()
	{
		if (IsMenuOpen)
		{
			IsMenuOpen = false;
			RestoreCursor();
		}
	}

	private void OnDestroy()
	{
		OnDisable();
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	[HideFromIl2Cpp]
	private void Fail(Exception ex)
	{
		if (!faulted)
		{
			faulted = true;
			AdminModPlugin.Log.LogError((object)("[AdminUI] Desenho suspenso após uma falha; F1 fecha o menu. " + ex));
		}
	}

	private void OnGUI()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		if (faulted)
		{
			return;
		}
		try
		{
			if (wrapped == null)
			{
				wrapped = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true,
					fontSize = 13
				};
				title = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1
				};
			}
			if (!IsMenuOpen)
			{
				if (GUI.Button(new Rect((float)Mathf.Max(0, Screen.width - 150), 10f, 140f, 30f), "ADMIN [F1]"))
				{
					ToggleMenu();
				}
			}
			else
			{
				((Rect)(ref window)).width = Mathf.Min(570, Screen.width);
				((Rect)(ref window)).height = (IsMinimized ? 85 : Mathf.Min(560, Screen.height));
				((Rect)(ref window)).x = Mathf.Clamp(((Rect)(ref window)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref window)).width));
				((Rect)(ref window)).y = Mathf.Clamp(((Rect)(ref window)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref window)).height));
				window = GUI.Window(19770305, window, drawWindow, "Last Pirates AdminMod 1.1.2");
			}
		}
		catch (Exception ex)
		{
			Fail(ex);
		}
	}

	private void DrawWindow(int id)
	{
		//IL_003c: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Invalid comparison between Unknown and I4
		if (faulted)
		{
			return;
		}
		try
		{
			float num = ((Rect)(ref window)).width - 24f;
			if (GUI.Button(new Rect(((Rect)(ref window)).width - 90f, 22f, 35f, 24f), IsMinimized ? "+" : "-"))
			{
				IsMinimized = !IsMinimized;
			}
			if (GUI.Button(new Rect(((Rect)(ref window)).width - 50f, 22f, 35f, 24f), "X"))
			{
				ToggleMenu();
			}
			GUI.Label(new Rect(12f, 24f, num - 95f, 26f), "ADMIN | " + (ModSupport.IsHost ? "HOST" : "SEM HOST"), title);
			if (!IsMinimized)
			{
				for (int i = 0; i < tabs.Length; i++)
				{
					if (GUI.Button(new Rect(12f + (float)i * num / 6f, 56f, num / 6f - 3f, 30f), ((tab == i) ? "• " : "") + tabs[i]))
					{
						tab = i;
					}
				}
				switch (tab)
				{
				case 0:
					Lobby();
					break;
				case 1:
					Players();
					break;
				case 2:
					Powers();
					break;
				case 3:
					Items();
					break;
				case 4:
					World();
					break;
				case 5:
					Esp();
					break;
				}
				GUI.Label(new Rect(12f, ((Rect)(ref window)).height - 66f, num, 58f), ModSupport.LastMessage, wrapped);
				if (smoke && smokeTab == tab && !smokeRendered[tab] && (int)Event.current.type == 7)
				{
					AdminModPlugin.Log.LogInfo((object)("[UI-SMOKE] Rendered tab " + tabs[tab]));
					smokeRendered[tab] = true;
				}
			}
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref window)).width - 100f, 48f));
		}
		catch (Exception ex)
		{
			Fail(ex);
		}
	}

	private void Label(float y, string text, float height = 28f)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		GUI.Label(new Rect(14f, y, ((Rect)(ref window)).width - 28f, height), text, wrapped);
	}

	private bool Button(float y, string text)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		return GUI.Button(new Rect(14f, y, ((Rect)(ref window)).width - 28f, 28f), text);
	}

	private bool Toggle(float y, bool value, string text)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		return GUI.Toggle(new Rect(14f, y, ((Rect)(ref window)).width - 28f, 28f), value, text);
	}

	private float Step(float y, string text, float value, float min, float max, float step)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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)
		GUI.Label(new Rect(14f, y, ((Rect)(ref window)).width - 120f, 28f), text + ": " + value.ToString("0.0"), wrapped);
		if (GUI.Button(new Rect(((Rect)(ref window)).width - 100f, y, 38f, 26f), "-"))
		{
			value -= step;
		}
		if (GUI.Button(new Rect(((Rect)(ref window)).width - 56f, y, 38f, 26f), "+"))
		{
			value += step;
		}
		return Mathf.Clamp(value, min, max);
	}

	private void Lobby()
	{
		Label(100f, "Capacidade experimental. Ajuste antes de criar a sala.");
		LobbyExpansion.TargetMaxPlayers = (int)Step(136f, "Jogadores", LobbyExpansion.TargetMaxPlayers, 4f, 32f, 1f);
		AdminModPlugin.Instance.MaxLobbyPlayers.Value = LobbyExpansion.TargetMaxPlayers;
		Label(176f, "Mais de 4 jogadores exige teste multiplayer. Late-join adicional ainda indisponível.", 56f);
		Label(242f, "Jogadores detectados: " + (PlayerAdmin.Instance?.GetPlayersData().Count ?? 0));
		if (Button(280f, "Atualizar jogadores e objetos"))
		{
			PlayerAdmin.Instance?.RefreshPlayerList();
			WorldAdmin.Instance?.RefreshWorldObjects();
		}
	}

	private void Players()
	{
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
		PlayerAdmin instance = PlayerAdmin.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		List<PlayerAdmin.PlayerData> playersData = instance.GetPlayersData();
		playerPage = Mathf.Clamp(playerPage, 0, Mathf.Max(0, playersData.Count - 1));
		if (playersData.Count == 0)
		{
			Label(105f, "Nenhum avatar detectado. Entre em uma partida.");
			return;
		}
		playerPage = (int)Step(98f, "Jogador (índice)", playerPage, 0f, playersData.Count - 1, 1f);
		PlayerAdmin.PlayerData playerData = playersData[playerPage];
		if (!((Object)(object)playerData.GameObject == (Object)null))
		{
			Label(133f, playerData.Name + " | " + (playerData.IsDead ? "MORTO" : (playerData.Health.ToString("0") + "/" + playerData.MaxHealth.ToString("0") + " HP")));
			if (Button(170f, "Curar / Reviver"))
			{
				instance.RevivePlayer(playerData.GameObject);
			}
			if (Button(203f, "Matar selecionado"))
			{
				instance.KillPlayer(playerData.GameObject);
			}
			if (Button(236f, "Ir até o jogador"))
			{
				instance.TeleportTo(playerData.GameObject);
			}
			if (Button(269f, "Puxar selecionado (requer autoridade)"))
			{
				instance.BringToMe(playerData.GameObject);
			}
			if (GUI.Button(new Rect(14f, 302f, 170f, 28f), "Expulsar"))
			{
				instance.KickPlayer(playerData.GameObject);
			}
			if (GUI.Button(new Rect(192f, 302f, 170f, 28f), "Ban nesta sessão"))
			{
				instance.BanPlayer(playerData.GameObject);
			}
			if (GUI.Button(new Rect(370f, 302f, 175f, 28f), "Observar / parar"))
			{
				instance.ToggleSpectate(playerData.GameObject);
			}
			if (Button(337f, playerData.IsFrozen ? "Descongelar selecionado" : "Congelar (requer autoridade)"))
			{
				instance.ToggleFreezePlayer(playerData);
			}
			playerData.HasGodMode = Toggle(372f, playerData.HasGodMode, "Regenerar vida do selecionado");
			if (GUI.Button(new Rect(14f, 409f, 128f, 28f), "Reviver todos"))
			{
				instance.ReviveAll();
			}
			if (GUI.Button(new Rect(148f, 409f, 128f, 28f), "Matar outros"))
			{
				instance.KillAllPlayers(includeHost: false);
			}
			if (GUI.Button(new Rect(282f, 409f, 128f, 28f), "Puxar outros"))
			{
				instance.BringAllToMe();
			}
			if (GUI.Button(new Rect(416f, 409f, 128f, 28f), "Impulso"))
			{
				instance.SlapPlayer(playerData.GameObject, 25f);
			}
		}
	}

	private void Powers()
	{
		PlayerAdmin instance = PlayerAdmin.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			instance.GodMode = Toggle(100f, instance.GodMode, "Bloquear dano local + regenerar vida");
			instance.InfiniteStamina = Toggle(132f, instance.InfiniteStamina, "Estamina infinita");
			instance.InfiniteElasticReach = Toggle(164f, instance.InfiniteElasticReach, "Aumentar alcance");
			instance.ElasticMultiplier = Step(198f, "Multiplicador de alcance", instance.ElasticMultiplier, 1f, 8f, 0.5f);
			instance.SuperSpeed = Toggle(232f, instance.SuperSpeed, "Super velocidade");
			instance.SpeedMultiplier = Step(266f, "Multiplicador de velocidade", instance.SpeedMultiplier, 1f, 5f, 0.5f);
			instance.NoclipMode = Toggle(300f, instance.NoclipMode, "Voo / noclip");
			instance.FlySpeed = Step(334f, "Velocidade de voo", instance.FlySpeed, 1f, 40f, 1f);
			Label(371f, "Voo: WASD, espaço e Ctrl. Feche o menu para mover.");
			if (Button(412f, "+1000 moedas compartilhadas"))
			{
				instance.GiveGold(null, 1000);
			}
		}
	}

	private void Items()
	{
		//IL_0031: 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)
		ItemSpawner instance = ItemSpawner.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		instance.SetSearch(GUI.TextField(new Rect(14f, 98f, ((Rect)(ref window)).width - 132f, 28f), instance.GetSearch()));
		if (GUI.Button(new Rect(((Rect)(ref window)).width - 110f, 98f, 96f, 28f), "Atualizar"))
		{
			instance.ScanAllItemsInGame();
		}
		category = (int)Step(133f, "Categoria", category, 0f, instance.Categories.Length - 1, 1f);
		instance.SetCategory(instance.Categories[category]);
		Label(163f, instance.Categories[category]);
		instance.SetQuantity((int)Step(195f, "Quantidade", instance.GetQuantity(), 1f, 25f, 1f));
		List<ItemSpawner.SpawnableItem> filteredItems = instance.GetFilteredItems();
		int num = Mathf.Max(1, (filteredItems.Count + 4) / 5);
		itemPage = (int)Step(230f, "Página (índice)", itemPage, 0f, num - 1, 1f);
		for (int i = 0; i < 5; i++)
		{
			int num2 = itemPage * 5 + i;
			if (num2 >= filteredItems.Count)
			{
				break;
			}
			if (Button(265 + i * 34, "Gerar: " + filteredItems[num2].Name))
			{
				instance.SpawnItem(filteredItems[num2], instance.GetQuantity());
			}
		}
		if (filteredItems.Count == 0)
		{
			Label(280f, "Sem itens carregados nesta categoria. Atualize dentro da partida.", 60f);
		}
	}

	private void World()
	{
		WorldAdmin instance = WorldAdmin.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			instance.FreezeMonsters = Toggle(105f, instance.FreezeMonsters, "Congelar navegação/física dos inimigos");
			Label(143f, "Só afeta inimigos sob autoridade do host; ataques podem continuar.", 56f);
			if (Button(213f, "Eliminar inimigos controlados pelo host"))
			{
				instance.KillAllMonsters();
			}
			if (Button(257f, "Gerar um baú carregado"))
			{
				instance.SpawnGoldChestAtPlayer();
			}
			if (Button(301f, "Avançar nível (experimental)"))
			{
				instance.ForceCompleteIsland();
			}
			Label(343f, "A transição segue as condições do serviço de níveis do jogo.", 50f);
		}
	}

	private void Esp()
	{
		AdminESP instance = AdminESP.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			instance.EnableESP = Toggle(105f, instance.EnableESP, "Ativar ESP");
			instance.ShowPlayers = Toggle(141f, instance.ShowPlayers, "Jogadores");
			instance.ShowMonsters = Toggle(177f, instance.ShowMonsters, "Inimigos");
			instance.ShowChests = Toggle(213f, instance.ShowChests, "Itens / tesouros");
			instance.MaxDistance = Step(260f, "Distância máxima (m)", instance.MaxDistance, 50f, 1000f, 50f);
		}
	}
}
internal static class AssetDiagnostics
{
	private static int reports;

	internal static void Install(Harmony harmony)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		MethodInfo methodInfo = AccessTools.Method(typeof(AddressablesImpl), "LogException", new Type[2]
		{
			typeof(AsyncOperationHandle),
			typeof(Exception)
		}, (Type[])null);
		harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AssetDiagnostics), "Report", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static void Report(AsyncOperationHandle __0, Exception __1)
	{
		if (reports++ >= 6)
		{
			return;
		}
		try
		{
			StringBuilder stringBuilder = new StringBuilder("[AssetDiagnostics] Scene/resource dependency failure:\n");
			int budget = 40;
			Dump(__0, stringBuilder, 0, ref budget);
			if (__1 != null)
			{
				stringBuilder.AppendLine(((Object)__1).ToString());
			}
			AdminModPlugin.Log.LogError((object)stringBuilder.ToString());
		}
		catch (Exception ex)
		{
			AdminModPlugin.Log.LogWarning((object)("[AssetDiagnostics] Cannot inspect dependency: " + ex.Message));
		}
	}

	private static void Dump(AsyncOperationHandle handle, StringBuilder text, int depth, ref int budget)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (budget-- > 0 && depth <= 5 && handle.IsValid())
		{
			text.Append(' ', depth * 2).Append(handle.Status).Append(" ")
				.AppendLine(handle.DebugName);
			if (handle.OperationException != null)
			{
				text.AppendLine(((Object)handle.OperationException).ToString());
			}
			List<AsyncOperationHandle> val = new List<AsyncOperationHandle>();
			handle.GetDependencies(val);
			for (int i = 0; i < val.Count; i++)
			{
				Dump(val[i], text, depth + 1, ref budget);
			}
		}
	}
}
internal static class GameApi
{
	internal static NetworkRunner Runner
	{
		get
		{
			List<NetworkRunner> instances = NetworkRunner._instances;
			for (int i = 0; i < instances.Count; i++)
			{
				if ((Object)(object)instances[i] != (Object)null && instances[i].IsRunning)
				{
					return instances[i];
				}
			}
			return null;
		}
	}

	internal static bool IsHost
	{
		get
		{
			if ((Object)(object)Runner != (Object)null)
			{
				if (!Runner.IsServer)
				{
					return Runner.IsSharedModeMasterClient;
				}
				return true;
			}
			return false;
		}
	}

	internal static T Service<T>() where T : Il2CppObjectBase
	{
		foreach (SceneContext item in Object.FindObjectsOfType<SceneContext>())
		{
			if (!((Object)(object)item == (Object)null) && ((Context)item).Container != null)
			{
				Object val = ((Context)item).Container.TryResolve(Il2CppType.Of<T>());
				if (val != null)
				{
					return ((Il2CppObjectBase)val).TryCast<T>();
				}
			}
		}
		return default(T);
	}

	internal static PlayerCharacterMovableBase Movement(GameObject obj)
	{
		if (!((Object)(object)obj == (Object)null))
		{
			return obj.GetComponentInChildren<PlayerCharacterMovableBase>();
		}
		return null;
	}

	internal static EntityStatEntityNetworkedBase Stats(GameObject obj)
	{
		if (!((Object)(object)obj == (Object)null))
		{
			return obj.GetComponentInChildren<EntityStatEntityNetworkedBase>();
		}
		return null;
	}

	internal static PlayerRef Owner(GameObject obj)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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)
		PlayerCharacterMovableBase val = Movement(obj);
		NetworkObject val2 = (((Object)(object)val != (Object)null) ? ((SimulationBehaviour)val).Object : obj.GetComponent<NetworkObject>());
		PlayerRef result;
		if ((Object)(object)val2 == (Object)null)
		{
			result = default(PlayerRef);
			return result;
		}
		result = val2.InputAuthority;
		if (!((PlayerRef)(ref result)).IsRealPlayer)
		{
			return val2.StateAuthority;
		}
		return val2.InputAuthority;
	}

	internal static bool IsLocal(GameObject obj)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Runner != (Object)null)
		{
			return Owner(obj) == Runner.LocalPlayer;
		}
		return false;
	}

	internal static void Kick(GameObject obj)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		if (ModSupport.RequireHost() && !((Object)(object)obj == (Object)null) && !IsLocal(obj))
		{
			IMultiplayerService val = GameApi.Service<IMultiplayerService>();
			if (val == null)
			{
				ModSupport.Warn("Serviço de expulsão ainda não disponível nesta cena.");
				return;
			}
			NetworkRunner runner = Runner;
			PlayerRef val2 = Owner(obj);
			val.KickFromRoom(runner, ((PlayerRef)(ref val2)).PlayerId);
			ModSupport.Warn("Solicitação de expulsão enviada pelo serviço do jogo.");
		}
	}

	internal static void Teleport(GameObject obj, Vector3 position)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		if (ModSupport.RequireHost())
		{
			PlayerCharacterMovableBase val = Movement(obj);
			if ((Object)(object)val == (Object)null)
			{
				ModSupport.Warn("Controlador de movimento não disponível.");
			}
			else if (!((NetworkBehaviour)val).HasStateAuthority)
			{
				ModSupport.Warn("Teleporte remoto indisponível: o cliente controla este avatar no modo Shared.");
			}
			else
			{
				((CharacterMovableBase)val).ChangePosition(position, (Nullable<Quaternion>)null, true);
			}
		}
	}
}
public class ItemSpawner : MonoBehaviour
{
	public class SpawnableItem
	{
		public string Name;

		public string Category;

		public GameObject Prefab;

		public Object OriginalObject;
	}

	private List<SpawnableItem> allItems = new List<SpawnableItem>();

	private string searchFilter = "";

	private string selectedCategory = "TODOS";

	private int spawnQuantity = 1;

	private float lastScanTime;

	private int lastReportedCount = -1;

	public readonly string[] Categories = new string[6] { "TODOS", "\ud83d\udcb0 TESOUROS", "⚔\ufe0f ARMAS/EQUIP", "\ud83e\uddea CONSUMÍVEIS", "\ud83d\udddd\ufe0f UTILITÁRIOS", "\ud83d\udce6 BAÚS" };

	private readonly List<UniTask<NetworkBehaviour>> pending = new List<UniTask<NetworkBehaviour>>();

	public static ItemSpawner Instance { get; private set; }

	public ItemSpawner(IntPtr pointer)
		: base(pointer)
	{
	}

	private void Awake()
	{
		Instance = this;
	}

	private void Start()
	{
		ScanAllItemsInGame();
	}

	private void Update()
	{
		PollSpawns();
		if (Time.time - lastScanTime > 10f)
		{
			lastScanTime = Time.time;
			ScanAllItemsInGame();
		}
	}

	[HideFromIl2Cpp]
	public List<SpawnableItem> GetFilteredItems()
	{
		List<SpawnableItem> list = new List<SpawnableItem>();
		for (int i = 0; i < allItems.Count; i++)
		{
			SpawnableItem spawnableItem = allItems[i];
			if (spawnableItem != null && !((Object)(object)spawnableItem.Prefab == (Object)null) && (selectedCategory == "TODOS" || (selectedCategory == "\ud83d\udcb0 TESOUROS" && (spawnableItem.Category == "TESOUROS" || spawnableItem.Name.ToLowerInvariant().Contains("gold") || spawnableItem.Name.ToLowerInvariant().Contains("treasure") || spawnableItem.Name.ToLowerInvariant().Contains("relic") || spawnableItem.Name.ToLowerInvariant().Contains("coin"))) || (selectedCategory == "⚔\ufe0f ARMAS/EQUIP" && (spawnableItem.Category == "ARMAS" || spawnableItem.Name.ToLowerInvariant().Contains("sword") || spawnableItem.Name.ToLowerInvariant().Contains("gun") || spawnableItem.Name.ToLowerInvariant().Contains("weapon") || spawnableItem.Name.ToLowerInvariant().Contains("shield") || spawnableItem.Name.ToLowerInvariant().Contains("cutlass"))) || (selectedCategory == "\ud83e\uddea CONSUMÍVEIS" && (spawnableItem.Category == "CONSUMÍVEIS" || spawnableItem.Name.ToLowerInvariant().Contains("potion") || spawnableItem.Name.ToLowerInvariant().Contains("heal") || spawnableItem.Name.ToLowerInvariant().Contains("food") || spawnableItem.Name.ToLowerInvariant().Contains("rum") || spawnableItem.Name.ToLowerInvariant().Contains("drink"))) || (selectedCategory == "\ud83d\udddd\ufe0f UTILITÁRIOS" && (spawnableItem.Category == "UTILITÁRIOS" || spawnableItem.Name.ToLowerInvariant().Contains("key") || spawnableItem.Name.ToLowerInvariant().Contains("torch") || spawnableItem.Name.ToLowerInvariant().Contains("light") || spawnableItem.Name.ToLowerInvariant().Contains("map") || spawnableItem.Name.ToLowerInvariant().Contains("compass"))) || (selectedCategory == "\ud83d\udce6 BAÚS" && (spawnableItem.Category == "BAÚS" || spawnableItem.Name.ToLowerInvariant().Contains("chest") || spawnableItem.Name.ToLowerInvariant().Contains("crate") || spawnableItem.Name.ToLowerInvariant().Contains("box")))) && (string.IsNullOrEmpty(searchFilter) || spawnableItem.Name.ToLowerInvariant().Contains(searchFilter.ToLowerInvariant())))
			{
				list.Add(spawnableItem);
			}
		}
		return list;
	}

	public void SetSearch(string filter)
	{
		searchFilter = filter ?? "";
	}

	public string GetSearch()
	{
		return searchFilter;
	}

	public void SetCategory(string cat)
	{
		selectedCategory = cat;
	}

	public string GetCategory()
	{
		return selectedCategory;
	}

	public void SetQuantity(int qty)
	{
		spawnQuantity = Mathf.Clamp(qty, 1, 50);
	}

	public int GetQuantity()
	{
		return spawnQuantity;
	}

	public void ScanAllItemsInGame()
	{
		allItems.Clear();
		try
		{
			foreach (MonoItem item in Resources.FindObjectsOfTypeAll<MonoItem>())
			{
				if (!((Object)(object)item == (Object)null) && ModSupport.IsPrefab(((Component)item).gameObject) && !((Object)(object)((Component)item).GetComponent<NetworkObject>() == (Object)null))
				{
					allItems.Add(new SpawnableItem
					{
						Name = CleanItemName(((Object)item).name),
						Category = CategorizeItem(((Object)item).name),
						Prefab = ((Component)item).gameObject,
						OriginalObject = (Object)(object)item
					});
				}
			}
		}
		catch (Exception ex)
		{
			ModSupport.Warn("Falha ao catalogar itens reais: " + ex.Message);
		}
		allItems.Sort((SpawnableItem a, SpawnableItem b) => StringComparer.OrdinalIgnoreCase.Compare(a.Name, b.Name));
		lastScanTime = Time.time;
		if (AdminModPlugin.Log != null && lastReportedCount != allItems.Count)
		{
			lastReportedCount = allItems.Count;
			AdminModPlugin.Log.LogInfo((object)("[ItemSpawner] Prefabs reais catalogados: " + allItems.Count));
		}
	}

	private string CategorizeItem(string name)
	{
		string text = name.ToLowerInvariant();
		if (text.Contains("chest") || text.Contains("crate") || text.Contains("baú") || text.Contains("box"))
		{
			return "BAÚS";
		}
		if (text.Contains("sword") || text.Contains("gun") || text.Contains("sabre") || text.Contains("pistol") || text.Contains("weapon") || text.Contains("trident"))
		{
			return "ARMAS";
		}
		if (text.Contains("potion") || text.Contains("rum") || text.Contains("heal") || text.Contains("food") || text.Contains("elixir") || text.Contains("drink"))
		{
			return "CONSUMÍVEIS";
		}
		if (text.Contains("key") || text.Contains("torch") || text.Contains("light") || text.Contains("lanterna") || text.Contains("compass") || text.Contains("chave"))
		{
			return "UTILITÁRIOS";
		}
		return "TESOUROS";
	}

	private string CleanItemName(string raw)
	{
		return raw.Replace("(Clone)", "").Replace("Prefab", "").Replace("_", " ")
			.Trim();
	}

	[HideFromIl2Cpp]
	public void SpawnItem(SpawnableItem item, int quantity)
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: 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)
		//IL_00d8: 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)
		if (!ModSupport.RequireHost())
		{
			return;
		}
		GameObject val = PlayerAdmin.Instance?.GetLocalPlayer();
		MonoItem val2 = (((Object)(object)item?.Prefab != (Object)null) ? item.Prefab.GetComponent<MonoItem>() : null);
		IItemSpawnService val3 = GameApi.Service<IItemSpawnService>();
		if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || val3 == null || !ModSupport.IsPrefab(((Component)val2).gameObject))
		{
			ModSupport.Warn("Entre na partida e atualize o catálogo; prefab/serviço de itens indisponível.");
			return;
		}
		if (pending.Count != 0)
		{
			ModSupport.Warn("Aguarde concluir o spawn anterior.");
			return;
		}
		for (int i = 0; i < Mathf.Clamp(quantity, 1, 25); i++)
		{
			Vector3 val4 = val.transform.position + val.transform.forward * 2f + Vector3.up * (0.5f + 0.3f * (float)i);
			pending.Add(val3.SpawnItem((NetworkBehaviour)(object)val2, val4, val.transform.rotation, (ItemData)null, false, 0f));
		}
		ModSupport.Warn("Solicitações de spawn enviadas ao serviço do jogo: " + pending.Count);
	}

	private void PollSpawns()
	{
		for (int num = pending.Count - 1; num >= 0; num--)
		{
			Awaiter<NetworkBehaviour> awaiter = pending[num].GetAwaiter();
			if (awaiter.IsCompleted)
			{
				pending.RemoveAt(num);
				try
				{
					NetworkBehaviour result = awaiter.GetResult();
					if ((Object)(object)result == (Object)null || (Object)(object)((SimulationBehaviour)result).Object == (Object)null || !((SimulationBehaviour)result).Object.IsValid)
					{
						throw new InvalidOperationException("O jogo não confirmou um objeto de rede válido.");
					}
					ModSupport.Warn("Item criado pelo serviço de rede: " + ((Object)result).name);
				}
				catch (Exception ex)
				{
					ModSupport.Warn("Falha ao gerar item: " + ex.GetBaseException().Message);
				}
			}
		}
	}

	private void OnDestroy()
	{
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
public static class LobbyExpansion
{
	public static int TargetMaxPlayers = 4;

	public static bool AllowMidGameJoin;

	private static readonly Dictionary<MultiplayerSessionConfig, int> originalCapacity = new Dictionary<MultiplayerSessionConfig, int>();

	public static int AppliedPatches { get; private set; }

	public static void ApplyPatches(Harmony harmony)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		TargetMaxPlayers = Mathf.Clamp(AdminModPlugin.Instance.MaxLobbyPlayers.Value, 4, 32);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(MultiplayerService), "CreateRoom", new Type[2]
		{
			typeof(NetworkRunner),
			typeof(SessionCreateData)
		}, (Type[])null), new HarmonyMethod(typeof(LobbyExpansion), "Capacity", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		AppliedPatches = 1;
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerDamageable), "Damage", new Type[1] { typeof(DamageData) }, (Type[])null), new HarmonyMethod(typeof(LobbyExpansion), "Damage", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		AppliedPatches++;
		AllowMidGameJoin = false;
		ModSupport.Warn("Capacidade experimental aplicada ao serviço Photon. Late-join adicional ainda indisponível.");
	}

	private static void Capacity(MultiplayerService __instance)
	{
		MultiplayerSessionConfig multiplayerSessionConfig = __instance._multiplayerSessionConfig;
		if (!((Object)(object)multiplayerSessionConfig == (Object)null))
		{
			if (!originalCapacity.ContainsKey(multiplayerSessionConfig))
			{
				originalCapacity.Add(multiplayerSessionConfig, multiplayerSessionConfig._MaxPlayersInRoom_k__BackingField);
			}
			multiplayerSessionConfig._MaxPlayersInRoom_k__BackingField = Mathf.Clamp(TargetMaxPlayers, 4, 32);
		}
	}

	public static void Restore()
	{
		foreach (KeyValuePair<MultiplayerSessionConfig, int> item in originalCapacity)
		{
			if ((Object)(object)item.Key != (Object)null)
			{
				item.Key._MaxPlayersInRoom_k__BackingField = item.Value;
			}
		}
		originalCapacity.Clear();
	}

	private static bool Damage(PlayerDamageable __instance)
	{
		PlayerAdmin instance = PlayerAdmin.Instance;
		if ((Object)(object)instance == (Object)null || !GameApi.IsHost || (Object)(object)__instance == (Object)null)
		{
			return true;
		}
		if (instance.GodMode && ((NetworkBehaviour)__instance).HasStateAuthority)
		{
			return !GameApi.IsLocal(((Component)__instance).gameObject);
		}
		return true;
	}
}
internal static class ModSupport
{
	internal sealed class PhysicsState
	{
		private readonly CharacterController controller;

		private readonly Rigidbody body;

		private readonly bool enabled;

		private readonly bool kinematic;

		private readonly bool gravity;

		private readonly Dictionary<Collider, bool> colliders = new Dictionary<Collider, bool>();

		internal PhysicsState(GameObject obj)
		{
			controller = obj.GetComponent<CharacterController>();
			body = obj.GetComponent<Rigidbody>();
			if ((Object)(object)controller != (Object)null)
			{
				enabled = ((Collider)controller).enabled;
			}
			if ((Object)(object)body != (Object)null)
			{
				kinematic = body.isKinematic;
				gravity = body.useGravity;
			}
			foreach (Collider componentsInChild in obj.GetComponentsInChildren<Collider>())
			{
				colliders[componentsInChild] = componentsInChild.enabled;
			}
		}

		internal void Freeze(bool noclip = false)
		{
			if ((Object)(object)controller != (Object)null)
			{
				((Collider)controller).enabled = false;
			}
			if ((Object)(object)body != (Object)null)
			{
				StopBody(body);
				body.isKinematic = true;
				body.useGravity = false;
			}
			if (!noclip)
			{
				return;
			}
			foreach (Collider key in colliders.Keys)
			{
				if ((Object)(object)key != (Object)null)
				{
					key.enabled = false;
				}
			}
		}

		internal void Restore()
		{
			if ((Object)(object)controller != (Object)null)
			{
				((Collider)controller).enabled = enabled;
			}
			if ((Object)(object)body != (Object)null)
			{
				body.isKinematic = kinematic;
				body.useGravity = gravity;
			}
			foreach (KeyValuePair<Collider, bool> collider in colliders)
			{
				if ((Object)(object)collider.Key != (Object)null)
				{
					collider.Key.enabled = collider.Value;
				}
			}
		}
	}

	internal static string LastMessage = "Aguardando uma sessão host compatível.";

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

	internal static bool IsHost => GameApi.IsHost;

	internal static void Warn(string message)
	{
		LastMessage = message;
		if (!warnings.TryGetValue(message, out var value) || !(Time.realtimeSinceStartup - value < 10f))
		{
			warnings[message] = Time.realtimeSinceStartup;
			if (AdminModPlugin.Log != null)
			{
				AdminModPlugin.Log.LogWarning((object)message);
			}
		}
	}

	internal static object Read(object instance, string name)
	{
		if (instance == null)
		{
			return null;
		}
		Type type = (instance as Type) ?? instance.GetType();
		object obj = ((instance is Type) ? null : instance);
		BindingFlags bindingAttr = (BindingFlags)(0x30 | ((obj == null) ? 8 : 4));
		try
		{
			PropertyInfo property = type.GetProperty(name, bindingAttr);
			if (property != null && property.CanRead && property.GetIndexParameters().Length == 0)
			{
				return property.GetValue(obj, null);
			}
			FieldInfo field = type.GetField(name, bindingAttr);
			return (field == null) ? null : field.GetValue(obj);
		}
		catch (Exception ex)
		{
			Warn("Falha ao ler " + type.Name + "." + name + ": " + ex.GetBaseException().Message);
			return null;
		}
	}

	internal static bool RequireHost()
	{
		if (IsHost)
		{
			return true;
		}
		Warn("Comando indisponível: autoridade de host não confirmada. Entre como host; se persistir, a integração de rede desta versão precisa ser identificada.");
		return false;
	}

	internal static bool IsLocal(GameObject obj)
	{
		if ((Object)(object)obj != (Object)null)
		{
			return GameApi.IsLocal(obj);
		}
		return false;
	}

	internal static MethodInfo FindMethod(Type type, string name, params Type[] parameters)
	{
		return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null);
	}

	internal static bool InvokeFirst(GameObject target, string[] names, object argument)
	{
		foreach (Component componentsInChild in target.GetComponentsInChildren<Component>())
		{
			if ((Object)(object)componentsInChild == (Object)null)
			{
				continue;
			}
			foreach (string name in names)
			{
				Type[] parameters = ((argument == null) ? Type.EmptyTypes : new Type[1] { argument.GetType() });
				MethodInfo methodInfo = FindMethod(((object)componentsInChild).GetType(), name, parameters);
				if (!(methodInfo == null) && !methodInfo.IsStatic && !methodInfo.ContainsGenericParameters)
				{
					try
					{
						methodInfo.Invoke(componentsInChild, (argument == null) ? null : new object[1] { argument });
						return true;
					}
					catch (Exception ex)
					{
						Warn("Falha em " + methodInfo.Name + ": " + ex.GetBaseException().Message);
						return false;
					}
				}
			}
		}
		return false;
	}

	internal static void StopBody(Rigidbody body)
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)body == (Object)null) && !body.isKinematic)
		{
			PropertyInfo propertyInfo = ((object)body).GetType().GetProperty("linearVelocity") ?? ((object)body).GetType().GetProperty("velocity");
			if (propertyInfo != null && propertyInfo.CanWrite)
			{
				propertyInfo.SetValue(body, Vector3.zero, null);
			}
			body.angularVelocity = Vector3.zero;
		}
	}

	internal static bool IsPrefab(GameObject obj)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)obj != (Object)null)
		{
			Scene scene = obj.scene;
			if (!((Scene)(ref scene)).IsValid())
			{
				return (Object)(object)obj.transform.parent == (Object)null;
			}
		}
		return false;
	}

	internal unsafe static bool Key(KeyCode key, bool down)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Invalid comparison between Unknown and I4
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Invalid comparison between Unknown and I4
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (down ? Input.GetKeyDown(key) : Input.GetKey(key))
			{
				return true;
			}
		}
		catch (InvalidOperationException)
		{
		}
		Keyboard current = Keyboard.current;
		if (current == null)
		{
			return false;
		}
		KeyControl val = null;
		if ((int)key != 304)
		{
			Key result;
			if ((int)key == 306)
			{
				val = current.leftCtrlKey;
			}
			else if (Enum.TryParse<Key>(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(), ignoreCase: true, out result))
			{
				val = current[result];
			}
		}
		else
		{
			val = current.leftShiftKey;
		}
		if (val != null)
		{
			if (!down)
			{
				return ((ButtonControl)val).isPressed;
			}
			return ((ButtonControl)val).wasPressedThisFrame;
		}
		return false;
	}
}
public class PlayerAdmin : MonoBehaviour
{
	public class PlayerData
	{
		public GameObject GameObject;

		public string Name;

		public string SteamID = "N/A";

		public float Health;

		public float MaxHealth;

		public bool IsDead;

		public bool IsLocal;

		public bool IsFrozen;

		public bool HasGodMode;

		public Vector3 Position
		{
			get
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)GameObject != (Object)null))
				{
					return Vector3.zero;
				}
				return GameObject.transform.position;
			}
		}
	}

	public bool GodMode;

	public bool InfiniteStamina;

	public bool InfiniteElasticReach;

	public bool NoclipMode;

	public bool SuperSpeed;

	public bool SuperJump;

	public bool InvisibleToMonsters;

	public float SpeedMultiplier = 2.5f;

	public float ElasticMultiplier = 4f;

	public float FlySpeed = 15f;

	private readonly List<PlayerData> players = new List<PlayerData>();

	private readonly Dictionary<GameObject, ModSupport.PhysicsState> frozen = new Dictionary<GameObject, ModSupport.PhysicsState>();

	private readonly Dictionary<EntityStatType, StatModifier> modifiers = new Dictionary<EntityStatType, StatModifier>();

	private EntityStatEntityNetworkedBase modifiedStats;

	private readonly HashSet<string> sessionBans = new HashSet<string>(StringComparer.Ordinal);

	private NetworkRunner session;

	private float nextScan;

	private float nextPower;

	private Camera spectateCamera;

	private Vector3 cameraPosition;

	private Quaternion cameraRotation;

	private GameObject spectating;

	private GameObject flightPlayer;

	private ModSupport.PhysicsState flightState;

	private bool flightInputEnabled;

	public static PlayerAdmin Instance { get; private set; }

	public PlayerAdmin(IntPtr pointer)
		: base(pointer)
	{
	}

	private void Awake()
	{
		Instance = this;
		AdminModPlugin instance = AdminModPlugin.Instance;
		GodMode = instance.GodModeDefault.Value;
		FlySpeed = instance.FlySpeedMultiplier.Value;
		SpeedMultiplier = instance.SpeedMultiplier.Value;
		ElasticMultiplier = instance.ElasticReachMultiplier.Value;
	}

	private void Update()
	{
		try
		{
			NetworkRunner runner = GameApi.Runner;
			if ((Object)(object)runner != (Object)(object)session)
			{
				RestoreModifiedState();
				players.Clear();
				sessionBans.Clear();
				session = runner;
				GodMode = (InfiniteStamina = (InfiniteElasticReach = (NoclipMode = (SuperSpeed = false))));
			}
			if (Time.unscaledTime >= nextScan)
			{
				nextScan = Time.unscaledTime + 1f;
				RefreshPlayerList();
			}
			if (!GameApi.IsHost)
			{
				RestoreModifiedState();
				return;
			}
			UpdateFlight();
			if (Time.unscaledTime >= nextPower)
			{
				nextPower = Time.unscaledTime + 0.25f;
				ApplyPowers();
			}
		}
		catch (Exception ex)
		{
			ModSupport.Warn("Admin: " + ex.GetBaseException().Message);
		}
	}

	[HideFromIl2Cpp]
	public List<PlayerData> GetPlayersData()
	{
		return new List<PlayerData>(players);
	}

	[HideFromIl2Cpp]
	public List<GameObject> GetAllPlayers()
	{
		return (from p in players
			where (Object)(object)p.GameObject != (Object)null
			select p.GameObject).ToList();
	}

	public GameObject GetLocalPlayer()
	{
		return players.FirstOrDefault((PlayerData p) => p.IsLocal && (Object)(object)p.GameObject != (Object)null)?.GameObject;
	}

	public void RefreshPlayerList()
	{
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<int, PlayerData> dictionary = players.Where((PlayerData p) => (Object)(object)p.GameObject != (Object)null).ToDictionary((PlayerData p) => ((Object)p.GameObject).GetInstanceID());
		players.Clear();
		NetworkRunner runner = GameApi.Runner;
		if ((Object)(object)runner == (Object)null)
		{
			return;
		}
		IPlayerStateService val = GameApi.Service<IPlayerStateService>();
		foreach (PlayerCharacterMovableBase item in Object.FindObjectsOfType<PlayerCharacterMovableBase>())
		{
			if ((Object)(object)item == (Object)null || (Object)(object)((SimulationBehaviour)item).Object == (Object)null || !((SimulationBehaviour)item).Object.IsValid)
			{
				continue;
			}
			GameObject gameObject = ((Component)item).gameObject;
			PlayerRef val2 = GameApi.Owner(gameObject);
			if (((PlayerRef)(ref val2)).IsRealPlayer)
			{
				if (!dictionary.TryGetValue(((Object)gameObject).GetInstanceID(), out var value))
				{
					value = new PlayerData();
				}
				value.GameObject = gameObject;
				value.IsLocal = val2 == runner.LocalPlayer;
				value.Name = "Pirata " + ((PlayerRef)(ref val2)).PlayerId + (value.IsLocal ? " (você)" : "");
				value.SteamID = runner.GetPlayerUserId(val2) ?? "N/A";
				EntityStatEntityNetworkedBase val3 = GameApi.Stats(gameObject);
				IStat val4 = (((Object)(object)val3 != (Object)null) ? ((StatEntityNetworkedBase<EntityStatType>)(object)val3).GetStat((EntityStatType)1) : null);
				value.Health = ((val4 != null) ? val4.FullValue : 0f);
				value.MaxHealth = ((val4 != null) ? val4.MaxValue : 0f);
				value.IsDead = ((val != null) ? val.IsPlayerDead(((PlayerRef)(ref val2)).PlayerId) : (value.Health <= 0f));
				players.Add(value);
				if (GameApi.IsHost && !value.IsLocal && sessionBans.Contains(value.SteamID))
				{
					GameApi.Kick(gameObject);
				}
			}
		}
		foreach (GameObject item2 in frozen.Keys.Where((GameObject obj) => (Object)(object)obj == (Object)null || !players.Any((PlayerData p) => (Object)(object)p.GameObject == (Object)(object)obj)).ToList())
		{
			frozen[item2].Restore();
			frozen.Remove(item2);
		}
	}

	public void KillPlayer(GameObject target)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null) && ModSupport.RequireHost())
		{
			IPlayerStateService val = GameApi.Service<IPlayerStateService>();
			if (val == null)
			{
				ModSupport.Warn("Serviço de estados indisponível.");
				return;
			}
			PlayerRef val2 = GameApi.Owner(target);
			val.ChangePlayerState(((PlayerRef)(ref val2)).PlayerId, (PlayerState)2, true);
		}
	}

	public void KillAllPlayers(bool includeHost)
	{
		foreach (PlayerData playersDatum in GetPlayersData())
		{
			if (includeHost || !playersDatum.IsLocal)
			{
				KillPlayer(playersDatum.GameObject);
			}
		}
	}

	public void RevivePlayer(GameObject target)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null) && ModSupport.RequireHost())
		{
			IPlayerStateService val = GameApi.Service<IPlayerStateService>();
			if (val == null)
			{
				ModSupport.Warn("Serviço de estados indisponível.");
				return;
			}
			Refill(target, (EntityStatType)1);
			PlayerRef val2 = GameApi.Owner(target);
			val.ChangePlayerState(((PlayerRef)(ref val2)).PlayerId, (PlayerState)1, true);
		}
	}

	public void ReviveAll()
	{
		foreach (PlayerData playersDatum in GetPlayersData())
		{
			RevivePlayer(playersDatum.GameObject);
		}
	}

	public void KickPlayer(GameObject target)
	{
		GameApi.Kick(target);
	}

	public void BanPlayer(GameObject target)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null) && ModSupport.RequireHost() && !GameApi.IsLocal(target))
		{
			string playerUserId = GameApi.Runner.GetPlayerUserId(GameApi.Owner(target));
			if (string.IsNullOrWhiteSpace(playerUserId))
			{
				ModSupport.Warn("ID de conta não disponível; ban cancelado.");
				return;
			}
			sessionBans.Add(playerUserId);
			GameApi.Kick(target);
			ModSupport.Warn("Bloqueado nesta sessão por ID Photon; tentativas de retorno serão expulsas após detectar o avatar.");
		}
	}

	[HideFromIl2Cpp]
	public void ToggleFreezePlayer(PlayerData player)
	{
		if ((Object)(object)player?.GameObject == (Object)null || !ModSupport.RequireHost())
		{
			return;
		}
		PlayerCharacterMovableBase val = GameApi.Movement(player.GameObject);
		if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).HasStateAuthority)
		{
			ModSupport.Warn("Freeze remoto exige autoridade do avatar; indisponível neste cliente Shared.");
			return;
		}
		if ((Object)(object)player.GameObject == (Object)(object)flightPlayer)
		{
			NoclipMode = false;
			RestoreFlight();
		}
		if (frozen.TryGetValue(player.GameObject, out var value))
		{
			value.Restore();
			frozen.Remove(player.GameObject);
			player.IsFrozen = false;
		}
		else
		{
			value = new ModSupport.PhysicsState(player.GameObject);
			frozen.Add(player.GameObject, value);
			value.Freeze();
			player.IsFrozen = true;
		}
	}

	public void SlapPlayer(GameObject target, float force)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null) && ModSupport.RequireHost())
		{
			PlayerCharacterMovableBase val = GameApi.Movement(target);
			if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).HasStateAuthority || (Object)(object)val.Rigidbody == (Object)null || val.Rigidbody.isKinematic)
			{
				ModSupport.Warn("Impulso exige autoridade e física ativa do avatar.");
			}
			else
			{
				val.Rigidbody.AddForce(Vector3.up * Mathf.Clamp(force, 0f, 50f), (ForceMode)2);
			}
		}
	}

	public void TeleportToOcean(GameObject target)
	{
		//IL_0010: 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_002f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)target != (Object)null)
		{
			GameApi.Teleport(target, new Vector3(target.transform.position.x, -20f, target.transform.position.z));
		}
	}

	public void TeleportTo(GameObject target)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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)
		if ((Object)(object)target != (Object)null && (Object)(object)GetLocalPlayer() != (Object)null)
		{
			GameApi.Teleport(GetLocalPlayer(), target.transform.position + Vector3.right * 2f);
		}
	}

	public void BringToMe(GameObject target)
	{
		//IL_0020: 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_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		GameObject localPlayer = GetLocalPlayer();
		if ((Object)(object)localPlayer != (Object)null && (Object)(object)target != (Object)null)
		{
			GameApi.Teleport(target, localPlayer.transform.position + localPlayer.transform.forward * 2f);
		}
	}

	public void BringAllToMe()
	{
		foreach (PlayerData playersDatum in GetPlayersData())
		{
			if (!playersDatum.IsLocal)
			{
				BringToMe(playersDatum.GameObject);
			}
		}
	}

	public void GiveGold(GameObject target, int amount)
	{
		if (!ModSupport.RequireHost())
		{
			return;
		}
		CurrencyModel val = GameApi.Service<CurrencyModel>();
		AddCurrencyNetworkEvent val2 = GameApi.Service<AddCurrencyNetworkEvent>();
		if (val == null || val2 == null)
		{
			ModSupport.Warn("Moeda da sessão indisponível nesta cena.");
			return;
		}
		int num = (int)Math.Min(Math.Max(0L, amount), 2147483647L - (long)val.CurrentCurrency);
		if (num > 0)
		{
			val2.SendEvent(num);
		}
		ModSupport.Warn("Solicitado +" + num + " para a moeda compartilhada da tripulação.");
	}

	private void Refill(GameObject obj, EntityStatType type)
	{
		//IL_0012: 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)
		EntityStatEntityNetworkedBase val = GameApi.Stats(obj);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		IStat stat = ((StatEntityNetworkedBase<EntityStatType>)(object)val).GetStat(type);
		if (stat != null)
		{
			float num = stat.MaxValue - stat.FullValue;
			if (num > 0.01f && !float.IsInfinity(num))
			{
				((StatEntityNetworkedBase<EntityStatType>)(object)val).AddStatValueSynchronized(type, num, (RPCType)3);
			}
		}
	}

	private void ApplyPowers()
	{
		GameObject localPlayer = GetLocalPlayer();
		EntityStatEntityNetworkedBase val = GameApi.Stats(localPlayer);
		if ((Object)(object)val != (Object)(object)modifiedStats)
		{
			RestoreModifiers();
			modifiedStats = val;
		}
		foreach (PlayerData player in players)
		{
			if (!player.IsDead && (player.HasGodMode || (player.IsLocal && GodMode)))
			{
				Refill(player.GameObject, (EntityStatType)1);
			}
		}
		if (!((Object)(object)localPlayer == (Object)null))
		{
			if (InfiniteStamina)
			{
				Refill(localPlayer, (EntityStatType)5);
				Refill(localPlayer, (EntityStatType)9);
			}
			SetModifier((EntityStatType)3, SuperSpeed ? (SpeedMultiplier - 1f) : 0f);
			SetModifier((EntityStatType)4, SuperSpeed ? (SpeedMultiplier - 1f) : 0f);
			SetModifier((EntityStatType)12, InfiniteElasticReach ? (ElasticMultiplier - 1f) : 0f);
			SetModifier((EntityStatType)18, InfiniteElasticReach ? (ElasticMultiplier - 1f) : 0f);
		}
	}

	private void SetModifier(EntityStatType type, float value)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		//IL_0086: 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_0041: 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)
		if ((Object)(object)modifiedStats == (Object)null || !((NetworkBehaviour)modifiedStats).HasStateAuthority)
		{
			return;
		}
		if (modifiers.TryGetValue(type, out var value2))
		{
			if (Mathf.Approximately(value2.Value, value))
			{
				return;
			}
			((StatEntityNetworkedBase<EntityStatType>)(object)modifiedStats).RemoveModifierSynchronized(type, value2, (RPCType)3);
			modifiers.Remove(type);
		}
		if (!Mathf.Approximately(value, 0f))
		{
			StatModifier val = new StatModifier(Mathf.Clamp(value, 0f, 9f), (ModifierType)2, 19770305);
			((StatEntityNetworkedBase<EntityStatType>)(object)modifiedStats).AddModifierSynchronized(type, val, (RPCType)3);
			modifiers[type] = val;
		}
	}

	private void RestoreModifiers()
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)modifiedStats != (Object)null && (Object)(object)((SimulationBehaviour)modifiedStats).Object != (Object)null && ((SimulationBehaviour)modifiedStats).Object.IsValid)
		{
			foreach (KeyValuePair<EntityStatType, StatModifier> modifier in modifiers)
			{
				((StatEntityNetworkedBase<EntityStatType>)(object)modifiedStats).RemoveModifierSynchronized(modifier.Key, modifier.Value, (RPCType)3);
			}
		}
		modifiers.Clear();
		modifiedStats = null;
	}

	private void UpdateFlight()
	{
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: 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_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: 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_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: 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)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0167: Unknown result type (might be due to invalid IL or missing references)
		GameObject localPlayer = GetLocalPlayer();
		if (!NoclipMode || (Object)(object)localPlayer == (Object)null || frozen.ContainsKey(localPlayer))
		{
			RestoreFlight();
			return;
		}
		PlayerCharacterMovableBase val = GameApi.Movement(localPlayer);
		if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).HasStateAuthority)
		{
			NoclipMode = false;
			RestoreFlight();
			return;
		}
		if ((Object)(object)flightPlayer != (Object)(object)localPlayer)
		{
			RestoreFlight();
			flightPlayer = localPlayer;
			flightState = new ModSupport.PhysicsState(localPlayer);
			flightInputEnabled = val._isMovementInputEnabled;
			val.SetMovementInputEnabled(false);
			flightState.Freeze(noclip: true);
		}
		if ((Object)(object)AdminUI.Instance != (Object)null && AdminUI.Instance.IsMenuOpen)
		{
			return;
		}
		Camera main = Camera.main;
		if (!((Object)(object)main == (Object)null))
		{
			Vector3 val2 = Vector3.zero;
			if (ModSupport.Key((KeyCode)119, down: false))
			{
				val2 += ((Component)main).transform.forward;
			}
			if (ModSupport.Key((KeyCode)115, down: false))
			{
				val2 -= ((Component)main).transform.forward;
			}
			if (ModSupport.Key((KeyCode)100, down: false))
			{
				val2 += ((Component)main).transform.right;
			}
			if (ModSupport.Key((KeyCode)97, down: false))
			{
				val2 -= ((Component)main).transform.right;
			}
			if (ModSupport.Key((KeyCode)32, down: false))
			{
				val2 += Vector3.up;
			}
			if (ModSupport.Key((KeyCode)306, down: false))
			{
				val2 -= Vector3.up;
			}
			((CharacterMovableBase)val).ChangePosition(((CharacterMovableBase)val).GetPosition() + ((Vector3)(ref val2)).normalized * Mathf.Clamp(FlySpeed, 1f, 50f) * Time.deltaTime, (Nullable<Quaternion>)null, true);
		}
	}

	private void RestoreFlight()
	{
		if (flightState != null)
		{
			flightState.Restore();
		}
		if ((Object)(object)flightPlayer != (Object)null)
		{
			PlayerCharacterMovableBase val = GameApi.Movement(flightPlayer);
			if ((Object)(object)val != (Object)null)
			{
				val.SetMovementInputEnabled(flightInputEnabled);
			}
		}
		flightState = null;
		flightPlayer = null;
	}

	public void ToggleSpectate(GameObject target)
	{
		//IL_0052: 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_0068: 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)
		if ((Object)(object)target == (Object)null || (Object)(object)target == (Object)(object)spectating)
		{
			RestoreCamera();
			return;
		}
		if ((Object)(object)spectateCamera == (Object)null)
		{
			spectateCamera = Camera.main;
			if ((Object)(object)spectateCamera == (Object)null)
			{
				return;
			}
			cameraPosition = ((Component)spectateCamera).transform.localPosition;
			cameraRotation = ((Component)spectateCamera).transform.localRotation;
		}
		spectating = target;
	}

	private void LateUpdate()
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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_006a: 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_0099: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)spectating == (Object)null || !spectating.activeInHierarchy)
		{
			RestoreCamera();
		}
		else if ((Object)(object)spectateCamera != (Object)null)
		{
			((Component)spectateCamera).transform.position = spectating.transform.position - spectating.transform.forward * 3f + Vector3.up * 2f;
			((Component)spectateCamera).transform.LookAt(spectating.transform.position + Vector3.up);
		}
	}

	private void RestoreCamera()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)spectateCamera != (Object)null)
		{
			((Component)spectateCamera).transform.localPosition = cameraPosition;
			((Component)spectateCamera).transform.localRotation = cameraRotation;
		}
		spectateCamera = null;
		spectating = null;
	}

	private void RestoreModifiedState()
	{
		RestoreFlight();
		RestoreModifiers();
		RestoreCamera();
		foreach (ModSupport.PhysicsState value in frozen.Values)
		{
			value.Restore();
		}
		frozen.Clear();
		foreach (PlayerData player in players)
		{
			player.IsFrozen = false;
		}
	}

	private void OnDisable()
	{
		RestoreModifiedState();
	}

	private void OnDestroy()
	{
		RestoreModifiedState();
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
public class WorldAdmin : MonoBehaviour
{
	public bool FreezeMonsters;

	private readonly List<GameObject> monsters = new List<GameObject>();

	private readonly List<GameObject> items = new List<GameObject>();

	private readonly Dictionary<NavMeshAgent, bool> stoppedAgents = new Dictionary<NavMeshAgent, bool>();

	private readonly Dictionary<Rigidbody, ModSupport.PhysicsState> stoppedBodies = new Dictionary<Rigidbody, ModSupport.PhysicsState>();

	private float nextScan;

	private UniTask<bool> transition;

	public static WorldAdmin Instance { get; private set; }

	public WorldAdmin(IntPtr pointer)
		: base(pointer)
	{
	}

	private void Awake()
	{
		Instance = this;
	}

	private void Update()
	{
		try
		{
			if (Time.unscaledTime >= nextScan)
			{
				nextScan = Time.unscaledTime + 2f;
				RefreshWorldObjects();
			}
			if (!ModSupport.IsHost || !FreezeMonsters)
			{
				RestoreMonsters();
			}
			else
			{
				foreach (GameObject monster in monsters)
				{
					if ((Object)(object)monster == (Object)null)
					{
						continue;
					}
					EnemyStatHealthController component = monster.GetComponent<EnemyStatHealthController>();
					if ((Object)(object)component == (Object)null || !((NetworkBehaviour)component).HasStateAuthority)
					{
						continue;
					}
					foreach (NavMeshAgent componentsInChild in monster.GetComponentsInChildren<NavMeshAgent>())
					{
						if (((Behaviour)componentsInChild).enabled && componentsInChild.isOnNavMesh)
						{
							if (!stoppedAgents.ContainsKey(componentsInChild))
							{
								stoppedAgents.Add(componentsInChild, componentsInChild.isStopped);
							}
							componentsInChild.isStopped = true;
						}
					}
					Rigidbody component2 = monster.GetComponent<Rigidbody>();
					if ((Object)(object)component2 != (Object)null)
					{
						if (!stoppedBodies.ContainsKey(component2))
						{
							stoppedBodies.Add(component2, new ModSupport.PhysicsState(monster));
						}
						stoppedBodies[component2].Freeze();
					}
				}
			}
			if (transition != null && transition.GetAwaiter().IsCompleted)
			{
				UniTask<bool> obj = transition;
				transition = null;
				ModSupport.Warn(obj.GetAwaiter().GetResult() ? "O serviço do jogo concluiu a transição." : "O jogo recusou a transição de nível.");
			}
		}
		catch (Exception ex)
		{
			ModSupport.Warn("Mundo: " + ex.GetBaseException().Message);
		}
	}

	[HideFromIl2Cpp]
	public List<GameObject> GetMonsters()
	{
		return new List<GameObject>(monsters);
	}

	[HideFromIl2Cpp]
	public List<GameObject> GetChests()
	{
		return new List<GameObject>(items);
	}

	public void RefreshWorldObjects()
	{
		monsters.Clear();
		items.Clear();
		foreach (EnemyStatHealthController item in Object.FindObjectsOfType<EnemyStatHealthController>())
		{
			if ((Object)(object)item != (Object)null && (Object)(object)((SimulationBehaviour)item).Object != (Object)null && ((SimulationBehaviour)item).Object.IsValid && !item._isDead)
			{
				monsters.Add(((Component)item).gameObject);
			}
		}
		foreach (MonoItem item2 in Object.FindObjectsOfType<MonoItem>())
		{
			if ((Object)(object)item2 != (Object)null && (Object)(object)((SimulationBehaviour)item2).Object != (Object)null && ((SimulationBehaviour)item2).Object.IsValid)
			{
				items.Add(((Component)item2).gameObject);
			}
		}
	}

	public void KillAllMonsters()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		if (!ModSupport.RequireHost())
		{
			return;
		}
		RefreshWorldObjects();
		int num = 0;
		foreach (GameObject monster in monsters)
		{
			EnemyStatHealthController component = monster.GetComponent<EnemyStatHealthController>();
			if ((Object)(object)component != (Object)null && ((NetworkBehaviour)component).HasStateAuthority)
			{
				PlayerRef localPlayer = GameApi.Runner.LocalPlayer;
				component.Dead(((PlayerRef)(ref localPlayer)).PlayerId);
				num++;
			}
		}
		ModSupport.Warn("Rotina de morte acionada em " + num + " inimigos sob autoridade do host.");
	}

	public void ForceCompleteIsland()
	{
		if (ModSupport.RequireHost() && transition == null)
		{
			ILevelService val = GameApi.Service<ILevelService>();
			if (val == null || !val.IsNextLevelLoadAvailable())
			{
				ModSupport.Warn("O serviço de níveis não permite avançar agora.");
				return;
			}
			transition = val.LoadNextLevel(false);
			ModSupport.Warn("Transição solicitada ao serviço do jogo; aguardando resultado.");
		}
	}

	public void SpawnGoldChestAtPlayer()
	{
		if (!ModSupport.RequireHost() || (Object)(object)ItemSpawner.Instance == (Object)null)
		{
			return;
		}
		ItemSpawner instance = ItemSpawner.Instance;
		instance.ScanAllItemsInGame();
		string category = instance.GetCategory();
		string search = instance.GetSearch();
		try
		{
			instance.SetCategory("TODOS");
			instance.SetSearch("");
			foreach (ItemSpawner.SpawnableItem filteredItem in instance.GetFilteredItems())
			{
				if (filteredItem.Category == "BAÚS")
				{
					instance.SpawnItem(filteredItem, 1);
					return;
				}
			}
			ModSupport.Warn("Nenhum prefab de baú carregado nesta cena.");
		}
		finally
		{
			instance.SetCategory(category);
			instance.SetSearch(search);
		}
	}

	private void RestoreMonsters()
	{
		foreach (KeyValuePair<NavMeshAgent, bool> stoppedAgent in stoppedAgents)
		{
			if ((Object)(object)stoppedAgent.Key != (Object)null && ((Behaviour)stoppedAgent.Key).enabled && stoppedAgent.Key.isOnNavMesh)
			{
				stoppedAgent.Key.isStopped = stoppedAgent.Value;
			}
		}
		stoppedAgents.Clear();
		foreach (ModSupport.PhysicsState value in stoppedBodies.Values)
		{
			value.Restore();
		}
		stoppedBodies.Clear();
	}

	private void OnDisable()
	{
		RestoreMonsters();
	}

	private void OnDestroy()
	{
		RestoreMonsters();
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}