Decompiled source of Moderator v1.0.4

IronLabs.Moderator.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using IronLabs.SharedLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("IronLabs.Moderator")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IronLabs.Moderator")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("CA2ABD79-CB95-41E2-999B-52AE9310670C")]
[assembly: AssemblyFileVersion("1.0.4")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.4.22438")]
namespace IronLabs.Moderator
{
	internal static class AdminAccess
	{
		private const string RequestRpc = "IronLabs_Moderator_AdminRequest";

		private const string ResponseRpc = "IronLabs_Moderator_AdminResponse";

		private static ZRoutedRpc _registeredRpc;

		private static bool _serverConfirmedAdmin;

		internal static bool LocalPlayerIsAdminOrHost()
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				if (!ZNet.instance.IsServer())
				{
					return _serverConfirmedAdmin;
				}
				return true;
			}
			return false;
		}

		internal static void RegisterRpcs()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null && instance != _registeredRpc)
			{
				instance.Register("IronLabs_Moderator_AdminRequest", (Action<long>)ReceiveRequest);
				instance.Register<bool>("IronLabs_Moderator_AdminResponse", (Action<long, bool>)ReceiveResponse);
				_registeredRpc = instance;
				ModeratorPlugin.ModLogger.LogDebug("Administrator validation RPCs registered.");
			}
		}

		internal static void RequestStatus()
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && ZRoutedRpc.instance != null)
			{
				_serverConfirmedAdmin = false;
				ZRoutedRpc.instance.InvokeRoutedRPC("IronLabs_Moderator_AdminRequest", Array.Empty<object>());
				ModeratorPlugin.ModLogger.LogDebug("Requested administrator validation from the server.");
			}
		}

		internal static void ResetSession()
		{
			_registeredRpc = null;
			_serverConfirmedAdmin = false;
		}

		private static void ReceiveRequest(long sender)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZRoutedRpc.instance != null)
			{
				ZNetPeer peer = ZNet.instance.GetPeer(sender);
				bool flag = peer != null && ZNet.instance.IsAdmin(peer.m_socket.GetHostName());
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "IronLabs_Moderator_AdminResponse", new object[1] { flag });
				ModeratorPlugin.ModLogger.LogDebug($"Administrator validation completed for peer {sender}: {flag}.");
			}
		}

		private static void ReceiveResponse(long sender, bool isAdmin)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && ZNet.instance.GetPeer(sender) != null)
			{
				_serverConfirmedAdmin = isAdmin;
				if (!isAdmin)
				{
					ModeratorState.SetEnabled(active: false);
				}
				ModeratorPlugin.ModLogger.LogDebug($"Server administrator validation received: {isAdmin}.");
			}
		}
	}
	internal static class AdminPlayerModes
	{
		internal static void Apply(bool enabled)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				localPlayer.SetGodMode(enabled);
				localPlayer.SetGhostMode(enabled);
				ModeratorPlugin.ModLogger.LogDebug($"Administrator god and ghost modes set to {enabled}.");
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	internal static class CommandRegistrationPatch
	{
		private static void Postfix()
		{
			ModeratorPlugin.RegisterCommands();
			ModeratorPlugin.ModLogger.LogDebug("Custom commands were registered after vanilla terminal initialization.");
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class ConsoleEventCommandConstructorPatch
	{
		private static bool Prefix(string command)
		{
			return !string.Equals(command, "devcommands", StringComparison.OrdinalIgnoreCase);
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class FailableCommandConstructorPatch
	{
		private static bool Prefix(string command)
		{
			return !string.Equals(command, "devcommands", StringComparison.OrdinalIgnoreCase);
		}
	}
	[HarmonyPatch(typeof(ConsoleCommand), "ShowCommand")]
	internal static class HideDevCommandsPatch
	{
		private static void Postfix(ConsoleCommand __instance, ref bool __result)
		{
			if (__instance.IsCheat)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(ConsoleCommand), "RunAction")]
	internal static class BlockDevCommandsPatch
	{
		private static bool Prefix(ConsoleCommand __instance)
		{
			return !__instance.IsCheat;
		}
	}
	internal static class ExploreMapCommand
	{
		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("exploremap", "Explores the entire map.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				ModeratorPlugin.ModLogger.LogError("Exploremap command failed because the map is not available.");
				args.Context.AddString("The map is not available yet.");
				return;
			}
			Minimap.instance.ExploreAll();
			ModeratorMapSharing.Enable();
			args.Context.AddString("The entire map has been explored and connected players are visible.");
			ModeratorPlugin.ModLogger.LogDebug("Exploremap command revealed the local map and enabled player tracking.");
		}
	}
	internal static class GotoCommand
	{
		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("goto", "[player] - Teleports you to a player.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null || args.Length != 2)
			{
				Fail(args, "Usage: goto <player>");
			}
			else if (!PlayerPositionRpc.Request(args[1], delegate(Vector3 position)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				Teleport(position, args.Context);
			}))
			{
				Fail(args, "No matching player was found.");
			}
		}

		private static void Teleport(Vector3 destination, Terminal context)
		{
			//IL_0013: 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_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)
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				((Character)Player.m_localPlayer).TeleportTo(destination, ((Component)Player.m_localPlayer).transform.rotation, true);
				context.AddString($"Teleported to: {destination}");
				ModeratorPlugin.ModLogger.LogDebug($"Goto command teleported the local player to {destination}.");
			}
		}

		private static void Fail(ConsoleEventArgs args, string message)
		{
			ModeratorPlugin.ModLogger.LogError("Goto command failed: " + message);
			args.Context.AddString(message);
		}
	}
	internal static class ItemSetCommand
	{
		private const string Usage = "Usage: itemset <meadows|blackforest|swamp|mountain|plains>";

		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("itemset", "[biome] - Replaces current items with a biome item set.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			string text = ((args.Length == 2) ? GetItemSet(args[1]) : null);
			if (text == null)
			{
				args.Context.AddString("Usage: itemset <meadows|blackforest|swamp|mountain|plains>");
				return;
			}
			if ((Object)(object)ItemSets.instance == (Object)null || !ItemSets.instance.TryGetSet(text, true, -1, -1))
			{
				Fail(args, text);
				return;
			}
			args.Context.AddString("Applied the " + text + " item set.");
			ModeratorPlugin.ModLogger.LogDebug("The " + text + " item set was applied.");
		}

		private static string GetItemSet(string biome)
		{
			return biome.ToLowerInvariant() switch
			{
				"meadows" => "Meadows", 
				"blackforest" => "BlackForest", 
				"swamp" => "Swamps", 
				"mountain" => "Mountains", 
				"plains" => "Plains", 
				_ => null, 
			};
		}

		private static void Fail(ConsoleEventArgs args, string itemSet)
		{
			string text = "The " + itemSet + " item set could not be applied.";
			args.Context.AddString(text);
			ModeratorPlugin.ModLogger.LogError(text);
		}
	}
	internal static class ModeratorCommandAudit
	{
		internal static ConsoleEvent Wrap(ConsoleEvent execute)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				Player localPlayer = Player.m_localPlayer;
				string text = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "unknown";
				ModeratorPlugin.ModLogger.LogInfo("Moderator command invoked by '" + text + "': " + args.FullLine);
				execute.Invoke(args);
			};
		}
	}
	internal static class ModeratorModeCommand
	{
		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("moderator", "Toggles moderator mode.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			bool num = !ModeratorState.IsActive;
			ModeratorState.SetEnabled(num);
			string text = (num ? "enabled" : "disabled");
			Terminal context = args.Context;
			if (context != null)
			{
				context.AddString("Moderator mode " + text + ".");
			}
			ModeratorPlugin.ModLogger.LogInfo("Moderator mode " + text + ".");
		}
	}
	internal static class PlayerCommandUtility
	{
		internal static bool TryFindPlayer(string name, out Vector3 position, out ZDOID characterId)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			characterId = ZDOID.None;
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
			{
				if (player.m_name.Equals(name, StringComparison.OrdinalIgnoreCase))
				{
					position = player.m_position;
					characterId = player.m_characterID;
					return true;
				}
			}
			return false;
		}

		internal static void Teleport(ZDOID characterId, Vector3 position, Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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)
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, characterId, "RPC_TeleportTo", new object[3] { position, rotation, true });
		}
	}
	internal static class PlayerListCommand
	{
		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("playerlist", "Prints online players.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				ModeratorPlugin.ModLogger.LogError("Playerlist command failed because ZNet is unavailable.");
				args.Context.AddString("The player list is not available.");
				return;
			}
			List<string> list = new List<string>();
			foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
			{
				string text = (IsAdmin(player) ? "  <color=#00A000>[Moderator]</color>" : string.Empty);
				list.Add(player.m_name + text);
			}
			args.Context.AddString(string.Join("\n", list));
			ModeratorPlugin.ModLogger.LogDebug($"Playerlist command returned {list.Count} online player entries.");
		}

		private static bool IsAdmin(PlayerInfo player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			if (ZNet.instance.PlayerIsAdmin(player.m_userInfo.m_id))
			{
				return true;
			}
			if (ZNet.instance.IsServer())
			{
				return player.m_userInfo.m_id == UserInfo.GetLocalUser().UserId;
			}
			return false;
		}
	}
	internal static class SummonCommand
	{
		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("summon", "[player] - Teleports a player to you.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || args.Length < 2 || !PlayerCommandUtility.TryFindPlayer(args[1], out var _, out var characterId))
			{
				ModeratorPlugin.ModLogger.LogError("Summon command failed because the player was not found.");
				args.Context.AddString("Usage: summon <player>");
			}
			else
			{
				PlayerCommandUtility.Teleport(characterId, ((Component)Player.m_localPlayer).transform.position, ((Component)Player.m_localPlayer).transform.rotation);
				args.Context.AddString("Summoned player: " + args[1]);
				ModeratorPlugin.ModLogger.LogDebug("Summon command teleported '" + args[1] + "' to the local player.");
			}
		}
	}
	internal static class ResetMapCommand
	{
		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("resetmap", "Hides the entire explored map.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				ModeratorPlugin.ModLogger.LogError("Resetmap command failed because the map is unavailable.");
				args.Context.AddString("The map is not available yet.");
				return;
			}
			Minimap.instance.Reset();
			ModeratorMapSharing.Disable();
			args.Context.AddString("The entire map exploration has been reset.");
			ModeratorPlugin.ModLogger.LogDebug("Resetmap command cleared the local map exploration.");
		}
	}
	internal static class SpawnCommand
	{
		internal static void Register()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("spawn", "[prefab] [amount=1] [level=1] [radius=0.5]", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, new ConsoleOptionsFetcher(GetPrefabNames), false, false, true);
		}

		private static void Execute(ConsoleEventArgs args)
		{
			if (args.Length < 2 || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				Fail(args, "Usage: spawn <prefab> [amount] [level] [radius]");
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(args[1]);
			if ((Object)(object)prefab == (Object)null)
			{
				Fail(args, "Prefab not found: " + args[1]);
				return;
			}
			Spawn(prefab, args.TryParameterInt(2, 1), args.TryParameterInt(3, 1), args.TryParameterFloat(4, 0.5f));
			args.Context.AddString("Spawned prefab: " + args[1]);
			ModeratorPlugin.ModLogger.LogDebug("Spawn command created prefab '" + args[1] + "'.");
		}

		private static void Spawn(GameObject prefab, int amount, int level, float radius)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			amount = Mathf.Max(1, amount);
			for (int i = 0; i < amount; i++)
			{
				Vector3 val = Random.insideUnitSphere * radius;
				Vector3 val2 = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f + Vector3.up + val;
				GameObject obj = Object.Instantiate<GameObject>(prefab, val2, Quaternion.identity);
				ItemDrop.OnCreateNew(obj);
				Character component = obj.GetComponent<Character>();
				if (component != null)
				{
					component.SetLevel(Mathf.Clamp(level, 1, 9));
				}
				ItemDrop component2 = obj.GetComponent<ItemDrop>();
				if (component2 != null)
				{
					component2.SetQuality(Mathf.Clamp(level, 1, 4));
				}
			}
		}

		private static List<string> GetPrefabNames()
		{
			if (!((Object)(object)ZNetScene.instance == (Object)null))
			{
				return ZNetScene.instance.GetPrefabNames();
			}
			return new List<string>();
		}

		private static void Fail(ConsoleEventArgs args, string message)
		{
			ModeratorPlugin.ModLogger.LogError("Spawn command failed: " + message);
			args.Context.AddString(message);
		}
	}
	[BepInPlugin("IronLabs.Moderator", "IronLabs.Moderator", "1.0.4")]
	public sealed class ModeratorPlugin : IronLabsPlugin
	{
		private static readonly HashSet<string> CommandsRequiringModerator = new HashSet<string> { "exploremap", "goto", "itemset", "playerlist", "summon", "resetmap", "spawn" };

		private const string PluginGuid = "IronLabs.Moderator";

		private const string PluginName = "IronLabs.Moderator";

		private const string PluginVersion = "1.0.4";

		internal static ModLog ModLogger { get; private set; }

		private void Awake()
		{
			ModLogger = InitializePlugin("IronLabs.Moderator");
			RegisterCommands();
			ModLogger.LogInfo("IronLabs.Moderator 1.0.4 is loaded.");
		}

		private void OnDestroy()
		{
			ModeratorMapSharing.Disable();
			ShutdownPlugin();
			ModLogger = null;
		}

		private void Update()
		{
			PlayerPositionRpc.Update();
			ModeratorMapSharing.Update();
		}

		internal static void RegisterCommands()
		{
			ModeratorModeCommand.Register();
			ExploreMapCommand.Register();
			GotoCommand.Register();
			ItemSetCommand.Register();
			PlayerListCommand.Register();
			SummonCommand.Register();
			ResetMapCommand.Register();
			SpawnCommand.Register();
		}

		internal static bool RequiresEnabledModerator(string command)
		{
			return CommandsRequiringModerator.Contains(command);
		}
	}
	internal static class ModeratorMapSharing
	{
		private const float RefreshInterval = 30f;

		private static readonly Dictionary<ZDOID, PlayerInfo> Players = new Dictionary<ZDOID, PlayerInfo>();

		private static float _nextRefresh;

		private static bool _enabled;

		internal static void Enable()
		{
			_enabled = true;
			_nextRefresh = 0f;
			ModeratorPlugin.ModLogger.LogDebug("Moderator map player tracking enabled.");
		}

		internal static void Disable()
		{
			if (_enabled || Players.Count > 0)
			{
				ModeratorPlugin.ModLogger.LogDebug("Moderator map player tracking disabled.");
			}
			_enabled = false;
			Players.Clear();
		}

		internal static void Update()
		{
			if (_enabled && ModeratorState.IsActive && !((Object)(object)ZNet.instance == (Object)null) && !(Time.unscaledTime < _nextRefresh))
			{
				_nextRefresh = Time.unscaledTime + 30f;
				RefreshPlayers();
			}
		}

		internal static void AddPlayers(List<PlayerInfo> players)
		{
			//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_002a: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!_enabled || !ModeratorState.IsActive)
			{
				return;
			}
			foreach (PlayerInfo value in Players.Values)
			{
				if (!Contains(players, value.m_characterID))
				{
					players.Add(value);
				}
			}
		}

		private static void RefreshPlayers()
		{
			//IL_001a: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
			foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
			{
				if (!IsLocalPlayer(player.m_characterID))
				{
					ZDOID characterID = player.m_characterID;
					if (!((ZDOID)(ref characterID)).IsNone())
					{
						hashSet.Add(player.m_characterID);
						RequestPosition(player);
					}
				}
			}
			RemoveDisconnected(hashSet);
		}

		private static void RequestPosition(PlayerInfo player)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ZDOID characterId = player.m_characterID;
			string playerName = player.m_name;
			PlayerPositionRpc.Request(characterId, playerName, delegate(Vector3 position)
			{
				//IL_0014: 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_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				if (_enabled && ModeratorState.IsActive)
				{
					Players[characterId] = CreatePlayerInfo(playerName, characterId, position);
				}
			});
		}

		private static PlayerInfo CreatePlayerInfo(string name, ZDOID characterId, Vector3 position)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			return new PlayerInfo
			{
				m_name = name,
				m_characterID = characterId,
				m_publicPosition = true,
				m_position = position
			};
		}

		private static void RemoveDisconnected(HashSet<ZDOID> connected)
		{
			//IL_001a: 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_0021: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			List<ZDOID> list = new List<ZDOID>();
			foreach (ZDOID key in Players.Keys)
			{
				if (!connected.Contains(key))
				{
					list.Add(key);
				}
			}
			foreach (ZDOID item in list)
			{
				Players.Remove(item);
			}
		}

		private static bool Contains(List<PlayerInfo> players, ZDOID characterId)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			foreach (PlayerInfo player in players)
			{
				if (player.m_characterID == characterId)
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsLocalPlayer(ZDOID characterId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return ZNet.instance.LocalPlayerCharacterID == characterId;
		}
	}
	internal static class ModeratorState
	{
		internal const string ModeratorZdoKey = "IronLabs.Moderator.Active";

		internal const string ModeratorLabel = "<color=#00A000>[Moderator]</color>";

		internal static bool IsActive { get; private set; }

		internal static void SetEnabled(bool active)
		{
			IsActive = active;
			if (!active)
			{
				ModeratorMapSharing.Disable();
			}
			AdminPlayerModes.Apply(active);
			Player localPlayer = Player.m_localPlayer;
			ZNetView obj = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).GetComponent<ZNetView>() : null);
			ZDO val = ((obj != null) ? obj.GetZDO() : null);
			if (val != null && val.IsOwner())
			{
				val.Set("IronLabs.Moderator.Active", active);
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "GetOtherPublicPlayers")]
	internal static class ShowPlayersToModeratorOnMapPatch
	{
		private static void Postfix(List<PlayerInfo> playerList)
		{
			ModeratorMapSharing.AddPlayers(playerList);
		}
	}
	[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
	internal static class LocalModeratorStatePatch
	{
		private static void Postfix()
		{
			ModeratorState.SetEnabled(active: false);
			AdminAccess.RequestStatus();
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	internal static class AdminRpcRegistrationPatch
	{
		private static void Postfix()
		{
			AdminAccess.RegisterRpcs();
			PlayerPositionRpc.RegisterResponseRpc();
		}
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class PlayerPositionRpcRegistrationPatch
	{
		private static void Postfix(Player __instance, ZNetView ___m_nview)
		{
			PlayerPositionRpc.RegisterPlayerRpc(__instance, ___m_nview);
		}
	}
	[HarmonyPatch(typeof(Player), "GetHoverName")]
	internal static class ModeratorHoverNamePatch
	{
		private static void Postfix(Player __instance, ref string __result)
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (component != null)
			{
				ZDO zDO = component.GetZDO();
				if (((zDO != null) ? new bool?(zDO.GetBool("IronLabs.Moderator.Active", false)) : ((bool?)null)) == true)
				{
					__result += "  <color=#00A000>[Moderator]</color>";
				}
			}
		}
	}
	[HarmonyPatch(typeof(ConsoleCommand), "IsValid")]
	internal static class ModeratorCommandValidationPatch
	{
		private static void Postfix(ConsoleCommand __instance, ref bool __result)
		{
			if (__instance.OnlyAdmin)
			{
				bool num = AdminAccess.LocalPlayerIsAdminOrHost();
				bool flag = ModeratorPlugin.RequiresEnabledModerator(__instance.Command) && !ModeratorState.IsActive;
				if (!num || flag)
				{
					__result = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnDestroy")]
	internal static class ModeratorDisconnectPatch
	{
		private static void Postfix()
		{
			ModeratorState.SetEnabled(active: false);
			AdminAccess.ResetSession();
			PlayerPositionRpc.ResetSession();
		}
	}
	[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
	internal static class MapTeleportPatch
	{
		private static bool Prefix(Minimap __instance)
		{
			//IL_001a: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!CanTeleport() || !TryGetMapPosition(__instance, out var position))
			{
				return true;
			}
			position.y = WorldGenerator.instance.GetHeight(position.x, position.z);
			Player localPlayer = Player.m_localPlayer;
			((Character)localPlayer).TeleportTo(position, ((Component)localPlayer).transform.rotation, true);
			__instance.SetMapMode((MapMode)1);
			ModeratorPlugin.ModLogger.LogDebug($"Map teleport moved the local player to {position}.");
			return false;
		}

		private static bool CanTeleport()
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null && WorldGenerator.instance != null && ModeratorState.IsActive)
			{
				return ZInput.GetKey((KeyCode)304, true);
			}
			return false;
		}

		private static bool TryGetMapPosition(Minimap map, out Vector3 position)
		{
			//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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)map.m_mapImageLarge).transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			Vector2 val2 = default(Vector2);
			if ((Object)(object)val == (Object)null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(val, Vector2.op_Implicit(ZInput.mousePosition), (Camera)null, ref val2))
			{
				position = Vector3.zero;
				return false;
			}
			Vector2 val3 = Rect.PointToNormalized(val.rect, val2);
			Rect uvRect = map.m_mapImageLarge.uvRect;
			float num = ((Rect)(ref uvRect)).xMin + val3.x * ((Rect)(ref uvRect)).width;
			float num2 = ((Rect)(ref uvRect)).yMin + val3.y * ((Rect)(ref uvRect)).height;
			float num3 = (float)map.m_textureSize / 2f;
			position = new Vector3((num * (float)map.m_textureSize - num3) * map.m_pixelSize, 0f, (num2 * (float)map.m_textureSize - num3) * map.m_pixelSize);
			return true;
		}
	}
	internal static class PlayerPositionRpc
	{
		private sealed class PendingRequest
		{
			internal Action<Vector3> Callback;

			internal float ExpiresAt;

			internal bool LogResponse;
		}

		private const string RequestRpc = "IronLabs_Moderator_PositionRequest";

		private const string ResponseRpc = "IronLabs_Moderator_PositionResponse";

		private const float RequestTimeout = 5f;

		private static readonly Dictionary<int, PendingRequest> PendingRequests = new Dictionary<int, PendingRequest>();

		private static ZRoutedRpc _registeredRpc;

		private static int _nextRequestId;

		internal static void RegisterResponseRpc()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null && instance != _registeredRpc)
			{
				instance.Register<int, Vector3>("IronLabs_Moderator_PositionResponse", (Action<long, int, Vector3>)ReceiveResponse);
				_registeredRpc = instance;
				ModeratorPlugin.ModLogger.LogDebug("Player position response RPC registered.");
			}
		}

		internal static void RegisterPlayerRpc(Player player, ZNetView netView)
		{
			if (((netView != null) ? netView.GetZDO() : null) != null)
			{
				netView.Register<int>("IronLabs_Moderator_PositionRequest", (Action<long, int>)delegate(long sender, int requestId)
				{
					SendResponse(player, sender, requestId);
				});
			}
		}

		internal static bool Request(string playerName, Action<Vector3> callback)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!PlayerCommandUtility.TryFindPlayer(playerName, out var _, out var characterId) || ZRoutedRpc.instance == null)
			{
				return false;
			}
			return Request(characterId, playerName, callback, logRequest: true);
		}

		internal static bool Request(ZDOID characterId, string playerName, Action<Vector3> callback, bool logRequest = false)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (((ZDOID)(ref characterId)).IsNone() || ZRoutedRpc.instance == null)
			{
				return false;
			}
			int num = ++_nextRequestId;
			PendingRequests[num] = new PendingRequest
			{
				Callback = callback,
				ExpiresAt = Time.unscaledTime + 5f,
				LogResponse = logRequest
			};
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, characterId, "IronLabs_Moderator_PositionRequest", new object[1] { num });
			if (logRequest)
			{
				ModeratorPlugin.ModLogger.LogDebug($"Requested the private position of '{playerName}' with request {num}.");
			}
			return true;
		}

		internal static void Update()
		{
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, PendingRequest> pendingRequest in PendingRequests)
			{
				if (Time.unscaledTime >= pendingRequest.Value.ExpiresAt)
				{
					list.Add(pendingRequest.Key);
				}
			}
			foreach (int item in list)
			{
				PendingRequests.Remove(item);
			}
		}

		internal static void ResetSession()
		{
			_registeredRpc = null;
			_nextRequestId = 0;
			PendingRequests.Clear();
		}

		private static void SendResponse(Player player, long sender, int requestId)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null) && ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "IronLabs_Moderator_PositionResponse", new object[2]
				{
					requestId,
					((Component)player).transform.position
				});
			}
		}

		private static void ReceiveResponse(long sender, int requestId, Vector3 position)
		{
			//IL_0022: 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)
			if (PendingRequests.TryGetValue(requestId, out var value))
			{
				PendingRequests.Remove(requestId);
				value.Callback(position);
				if (value.LogResponse)
				{
					ModeratorPlugin.ModLogger.LogDebug($"Received private player position {position} for request {requestId} from peer {sender}.");
				}
			}
		}
	}
}
namespace IronLabs.SharedLib
{
	public abstract class IronLabsPlugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private bool _patchesApplied;

		protected ModLog InitializePlugin(string pluginGuid)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			ModLog modLog = new ModLog(((BaseUnityPlugin)this).Logger);
			Version version = ((object)this).GetType().Assembly.GetName().Version;
			modLog.LogInfo($"AssemblyVersion: {version}.");
			_harmony = new Harmony(pluginGuid);
			PatchOwnNamespace(modLog);
			return modLog;
		}

		protected void PatchOwnNamespace(ModLog log)
		{
			if (_patchesApplied)
			{
				log.LogDebug("Harmony patches are already active; skipping registration.");
				return;
			}
			string text = ((object)this).GetType().Namespace;
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (type.Namespace == text)
				{
					_harmony.CreateClassProcessor(type).Patch();
				}
			}
			_patchesApplied = true;
			log.LogDebug("Harmony patches were applied for the plugin namespace.");
		}

		protected void ShutdownPlugin()
		{
			if (_patchesApplied)
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
				_patchesApplied = false;
			}
		}
	}
	public sealed class ModLog
	{
		private readonly ManualLogSource _logger;

		public ModLog(ManualLogSource logger)
		{
			_logger = logger;
		}

		public void LogFatal(object message)
		{
			Write((LogLevel)1, message);
		}

		public void LogError(object message)
		{
			Write((LogLevel)2, message);
		}

		public void LogWarning(object message)
		{
			Write((LogLevel)4, message);
		}

		public void LogMessage(object message)
		{
			Write((LogLevel)8, message);
		}

		public void LogInfo(object message)
		{
			Write((LogLevel)16, message);
		}

		public void LogDebug(object message)
		{
			Write((LogLevel)32, message);
		}

		public void Log(LogLevel level, object message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Write(level, message);
		}

		private void Write(LogLevel level, object message)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			string arg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
			_logger.Log(level, (object)$"[{arg}] {message}");
		}
	}
}