Decompiled source of AdvancedAdminPanel v2.2.7

BepInEx/plugins/AdminPanel.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("AdminPanel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AdminPanel")]
[assembly: AssemblyTitle("AdminPanel")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AdminPanel
{
	[BepInPlugin("com.halitb.adminpanel", "AdminPanel", "2.2.6")]
	public class AdminPanelPlugin : BaseUnityPlugin
	{
		private class ItemEntry
		{
			public ItemDrop Drop;

			public string Prefab;

			public string Display;

			public string Info;

			public string Cat;

			public string Sub;

			public Sprite Icon;

			public bool IconTried;
		}

		private class SeEntry
		{
			public StatusEffect Se;

			public string Display;

			public string Tooltip;

			public int Hash;

			public int Bucket;
		}

		private class CreatureEntry
		{
			public GameObject Prefab;

			public string Name;

			public string Display;

			public string Faction;

			public bool Boss;

			public bool Tamable;
		}

		[HarmonyPatch]
		private static class CheatPatches
		{
			[HarmonyPatch(typeof(Player), "UseStamina")]
			[HarmonyPrefix]
			private static bool NoStaminaPrefix(Player __instance)
			{
				if (NoStaminaFlag)
				{
					return !((Object)(object)__instance == (Object)(object)Player.m_localPlayer);
				}
				return true;
			}

			[HarmonyPatch(typeof(Character), "Damage")]
			[HarmonyPrefix]
			private static void OneHitPrefix(Character __instance, HitData hit)
			{
				if (!OneHitKillFlag || hit == null || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				try
				{
					if (!((Object)(object)hit.GetAttacker() != (Object)(object)Player.m_localPlayer))
					{
						hit.m_damage.m_damage = 1E+09f;
					}
				}
				catch
				{
				}
			}
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
		private static class CursorPatch
		{
			[HarmonyPrefix]
			private static bool Prefix()
			{
				if ((Object)(object)Instance == (Object)null || !Instance._visible)
				{
					return true;
				}
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "TakeInput")]
		private static class InputBlockPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ref bool __result)
			{
				if ((Object)(object)Instance != (Object)null && Instance._visible)
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "StartAttack")]
		private static class BlockAttackPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(Humanoid __instance)
			{
				if ((Object)(object)Instance != (Object)null && Instance._visible)
				{
					return !((Object)(object)__instance == (Object)(object)Player.m_localPlayer);
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class CameraLockPatch
		{
			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("ZInput");
				if (!(type == null))
				{
					return AccessTools.Method(type, "GetMouseDelta", Type.EmptyTypes, (Type[])null);
				}
				return null;
			}

			[HarmonyPostfix]
			private static void Postfix(ref Vector2 __result)
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Instance != (Object)null && Instance._visible && (Instance._cameraLockCfg == null || Instance._cameraLockCfg.Value))
				{
					__result = Vector2.zero;
				}
			}
		}

		[HarmonyPatch]
		private static class RpcRegistration
		{
			[HarmonyPatch(typeof(ZNet), "Awake")]
			[HarmonyPostfix]
			private static void ZNetAwakePostfix()
			{
				if (ZRoutedRpc.instance != null)
				{
					ZRoutedRpc.instance.Register<ZPackage>("AP_InvData", (Action<long, ZPackage>)OnInventoryData);
				}
			}
		}

		public const string PluginGuid = "com.halitb.adminpanel";

		public const string PluginName = "AdminPanel";

		public const string PluginVersion = "2.2.6";

		internal static AdminPanelPlugin Instance;

		private ConfigEntry<KeyCode> _toggleKey;

		private ConfigEntry<KeyCode> _mapTpKey;

		private ConfigEntry<string> _fontChoiceCfg;

		private ConfigEntry<int> _fontSizeCfg;

		private ConfigEntry<int> _panelAlphaCfg;

		private ConfigEntry<bool> _cameraLockCfg;

		private int _fontSizeLive;

		private int _panelAlphaLive;

		private int _rebindTarget;

		private int _rebindTargetLayout;

		private Vector2 _settingsScroll;

		private static readonly string[] FontChoices = new string[5] { "Norse (auto)", "Norse Bold", "Norse", "Averia Serif", "Default" };

		private bool _visible;

		private Rect _windowRect = new Rect(60f, 60f, 740f, 680f);

		private Rect _lastSavedRect;

		private int _tab;

		private static readonly string[] TabNames = new string[8] { "Items", "Creatures", "Bosses", "Player", "World", "Players", "Server", "Settings" };

		private string _itemSearch = "";

		private Vector2 _itemScroll;

		private int _itemAmount = 1;

		private int _itemQuality = 1;

		private long _giveTargetId;

		private List<PlayerInfo> _othersSnapshot;

		private int _itemSort;

		private List<ItemEntry> _itemWindowList;

		private int _itemWindowFirst;

		private int _itemWindowVisible;

		private int _itemWindowTotal;

		private static readonly string[] ItemSortModes = new string[3] { "A → Z", "Z → A", "Category" };

		private static readonly string[] CreatureSortModes = new string[3] { "A → Z", "Z → A", "Faction" };

		private int _creatureSort;

		private string _openDropdown;

		private string _openDropdownLayout;

		private List<ItemEntry> _filteredItemsCache;

		private string _itemFilterKey = "";

		private int _favVersion;

		private int _recentVersion;

		private List<CreatureEntry> _filteredCreaturesCache;

		private string _creatureFilterKey = "";

		private List<string> _creatureCats;

		private List<string> _subCatsCache;

		private string _subCatsKey;

		private List<ItemEntry> _itemIndex;

		private List<SeEntry> _seIndex;

		private List<SeEntry> _seFilteredCache;

		private string _seFilterKey;

		private string _mainCat = "All";

		private string _subCat = "All";

		private ConfigEntry<string> _favoritesCfg;

		private ConfigEntry<string> _crafterNameCfg;

		private ConfigEntry<string> _bulkPackCfg;

		private HashSet<string> _favorites;

		private readonly List<ItemEntry> _recentItems = new List<ItemEntry>();

		private static readonly string[] MainCats = new string[14]
		{
			"All", "★ Fav", "Recent", "Kits", "Weapons", "Shields", "Armor", "Accessories", "Ammo", "Tools",
			"Food & Potions", "Materials", "Trophies", "Misc"
		};

		private static readonly Dictionary<string, string> MaterialBiome = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Wood", "Meadows" },
			{ "Stone", "Meadows" },
			{ "Resin", "Meadows" },
			{ "Feathers", "Meadows" },
			{ "LeatherScraps", "Meadows" },
			{ "DeerHide", "Meadows" },
			{ "Flint", "Meadows" },
			{ "RawMeat", "Meadows" },
			{ "NeckTail", "Meadows" },
			{ "BoarMeat", "Meadows" },
			{ "DeerMeat", "Meadows" },
			{ "Honey", "Meadows" },
			{ "Dandelion", "Meadows" },
			{ "BeechSeeds", "Meadows" },
			{ "QueenBee", "Meadows" },
			{ "FineWood", "Black Forest" },
			{ "RoundLog", "Black Forest" },
			{ "Coal", "Black Forest" },
			{ "Tin", "Black Forest" },
			{ "TinOre", "Black Forest" },
			{ "Copper", "Black Forest" },
			{ "CopperOre", "Black Forest" },
			{ "CopperScrap", "Black Forest" },
			{ "Bronze", "Black Forest" },
			{ "BronzeNails", "Black Forest" },
			{ "TrollHide", "Black Forest" },
			{ "BoneFragments", "Black Forest" },
			{ "SurtlingCore", "Black Forest" },
			{ "GreydwarfEye", "Black Forest" },
			{ "Thistle", "Black Forest" },
			{ "AncientSeed", "Black Forest" },
			{ "Amber", "Black Forest" },
			{ "AmberPearl", "Black Forest" },
			{ "Ruby", "Black Forest" },
			{ "Coins", "Black Forest" },
			{ "CarrotSeeds", "Black Forest" },
			{ "FirCone", "Black Forest" },
			{ "PineCone", "Black Forest" },
			{ "Iron", "Swamp" },
			{ "IronScrap", "Swamp" },
			{ "WitheredBone", "Swamp" },
			{ "Chain", "Swamp" },
			{ "ElderBark", "Swamp" },
			{ "Guck", "Swamp" },
			{ "Ooze", "Swamp" },
			{ "Entrails", "Swamp" },
			{ "Bloodbag", "Swamp" },
			{ "TurnipSeeds", "Swamp" },
			{ "IronNails", "Swamp" },
			{ "Root", "Swamp" },
			{ "SerpentScale", "Swamp" },
			{ "Chitin", "Swamp" },
			{ "Silver", "Mountain" },
			{ "SilverOre", "Mountain" },
			{ "Obsidian", "Mountain" },
			{ "WolfPelt", "Mountain" },
			{ "WolfFang", "Mountain" },
			{ "FreezeGland", "Mountain" },
			{ "Crystal", "Mountain" },
			{ "WolfClaw", "Mountain" },
			{ "WolfHairBundle", "Mountain" },
			{ "JuteRed", "Mountain" },
			{ "DragonEgg", "Mountain" },
			{ "OnionSeeds", "Mountain" },
			{ "BlackMetal", "Plains" },
			{ "BlackMetalScrap", "Plains" },
			{ "Barley", "Plains" },
			{ "Flax", "Plains" },
			{ "LoxPelt", "Plains" },
			{ "Needle", "Plains" },
			{ "LinenThread", "Plains" },
			{ "Tar", "Plains" },
			{ "BarleyFlour", "Plains" },
			{ "LoxMeat", "Plains" },
			{ "Cloudberry", "Plains" },
			{ "BlackMarble", "Mistlands" },
			{ "Sap", "Mistlands" },
			{ "Eitr", "Mistlands" },
			{ "RefinedEitr", "Mistlands" },
			{ "YggdrasilWood", "Mistlands" },
			{ "Carapace", "Mistlands" },
			{ "Softtissue", "Mistlands" },
			{ "ScaleHide", "Mistlands" },
			{ "BlackCore", "Mistlands" },
			{ "Wisp", "Mistlands" },
			{ "Mandible", "Mistlands" },
			{ "RoyalJelly", "Mistlands" },
			{ "SeekerBrain", "Mistlands" },
			{ "JuteBlue", "Mistlands" },
			{ "FlametalNew", "Ashlands" },
			{ "FlametalOreNew", "Ashlands" },
			{ "Grausten", "Ashlands" },
			{ "CharredBone", "Ashlands" },
			{ "ProustitePowder", "Ashlands" },
			{ "CelestialFeather", "Ashlands" },
			{ "AskHide", "Ashlands" },
			{ "Blackwood", "Ashlands" },
			{ "SulfurStone", "Ashlands" },
			{ "MoltenCore", "Ashlands" },
			{ "CharcoalResin", "Ashlands" },
			{ "GemstoneRed", "Ashlands" },
			{ "GemstoneGreen", "Ashlands" },
			{ "GemstoneBlue", "Ashlands" },
			{ "BonemawSerpentMeat", "Ashlands" }
		};

		private static readonly (string Name, (string Prefab, int Count)[] Items)[] GearKits = new(string, (string, int)[])[8]
		{
			("Bronze Kit", new(string, int)[6]
			{
				("ArmorBronzeChest", 1),
				("ArmorBronzeLegs", 1),
				("HelmetBronze", 1),
				("CapeDeerHide", 1),
				("SwordBronze", 1),
				("ShieldBronzeBuckler", 1)
			}),
			("Iron Kit", new(string, int)[6]
			{
				("ArmorIronChest", 1),
				("ArmorIronLegs", 1),
				("HelmetIron", 1),
				("CapeTrollHide", 1),
				("SwordIron", 1),
				("ShieldBanded", 1)
			}),
			("Wolf Kit", new(string, int)[6]
			{
				("ArmorWolfChest", 1),
				("ArmorWolfLegs", 1),
				("HelmetDrake", 1),
				("CapeWolf", 1),
				("SwordSilver", 1),
				("ShieldSilver", 1)
			}),
			("Padded Kit", new(string, int)[6]
			{
				("ArmorPaddedCuirass", 1),
				("ArmorPaddedGreaves", 1),
				("HelmetPadded", 1),
				("CapeLox", 1),
				("SwordBlackmetal", 1),
				("ShieldBlackmetal", 1)
			}),
			("Carapace Kit", new(string, int)[6]
			{
				("ArmorCarapaceChest", 1),
				("ArmorCarapaceLegs", 1),
				("HelmetCarapace", 1),
				("CapeFeather", 1),
				("SwordMistwalker", 1),
				("ShieldCarapace", 1)
			}),
			("Ashlands Kit", new(string, int)[6]
			{
				("ArmorAshlandsMediumChest", 1),
				("ArmorAshlandsMediumlegs", 1),
				("HelmetAshlandsMediumHood", 1),
				("CapeAsksvin", 1),
				("SwordNiedhogg", 1),
				("ShieldFlametal", 1)
			}),
			("Food Pack", new(string, int)[5]
			{
				("FishAndBread", 10),
				("MeatPlatter", 10),
				("YggdrasilPorridge", 10),
				("MeadHealthMajor", 5),
				("MeadStaminaLingering", 5)
			}),
			("Builder Pack", new(string, int)[7]
			{
				("Hammer", 1),
				("Hoe", 1),
				("Cultivator", 1),
				("Wood", 50),
				("Stone", 50),
				("IronNails", 100),
				("FineWood", 50)
			})
		};

		private string _creatureSearch = "";

		private Vector2 _creatureScroll;

		private List<CreatureEntry> _creWindowList;

		private int _creWindowFirst;

		private int _creWindowVisible;

		private int _creWindowTotal;

		private int _creatureCount = 1;

		private int _creatureLevel = 1;

		private List<CreatureEntry> _creatureIndex;

		private string _creatureCat = "All";

		private bool _spawnAtCrosshair;

		private string _petName = "";

		private string _arenaA;

		private string _arenaB;

		private int _arenaCountA = 5;

		private int _arenaCountB = 5;

		private ConfigEntry<string> _spawnPresetsCfg;

		private string _presetName = "";

		private string _weather = "";

		private float _timeSlider = 0.5f;

		private bool _timeLocked;

		private float _windAngle;

		private float _windIntensity = 0.5f;

		private bool _windLocked;

		private ConfigEntry<string> _bookmarksCfg;

		private string _bookmarkName = "";

		private string _tpX = "0";

		private string _tpY = "0";

		private string _tpZ = "0";

		private string _newGlobalKey = "";

		private bool _peaceful;

		private Vector2 _worldScroll;

		private static readonly (string Label, string Location)[] QuickJumps = new(string, string)[8]
		{
			("Spawn", "StartTemple"),
			("Eikthyr", "Eikthyrnir"),
			("The Elder", "GDKing"),
			("Bonemass", "Bonemass"),
			("Moder", "Dragonqueen"),
			("Yagluth", "GoblinKing"),
			("The Queen", "Mistlands_DvergrBossEntrance1"),
			("Fader", "FaderLocation")
		};

		private bool _god;

		private bool _ghost;

		private bool _fly;

		private bool _noCost;

		private float _speedMult = 1f;

		private float _jumpMult = 1f;

		private bool _infiniteWeight;

		private bool _noStamina;

		private bool _oneHitKill;

		private float _pickupRange = 2f;

		private float _baseWalk = -1f;

		private float _baseRun;

		private float _baseSwim;

		private float _baseJump;

		private float _baseWeight;

		private float _basePickup;

		private Player _appliedTo;

		private string _seSearch = "";

		private Vector2 _seScroll;

		private bool _showStatusEffects;

		private Vector2 _playerScroll;

		private Vector2 _playersScroll;

		private string _broadcastText = "";

		private ConfigEntry<string> _playerNotesCfg;

		private ConfigEntry<string> _windowRectCfg;

		private bool _resizing;

		private bool _notesDirty;

		private Dictionary<string, string> _playerNotes;

		private string _inspectPlayerName;

		private List<(string name, int stack, int quality)> _inspectInventory;

		private bool _inspectPending;

		private float _inspectRequestTime;

		private Vector2 _inspectScroll;

		private readonly List<string> _joinLog = new List<string>();

		private HashSet<string> _lastSeenPlayers = new HashSet<string>();

		private bool _seenPlayersInit;

		private float _nextPlayerPoll;

		private float _nextInvClean;

		private Vector2 _serverScroll;

		private static readonly string[] RaidEvents = new string[14]
		{
			"army_eikthyr", "army_theelder", "army_bonemass", "army_moder", "army_goblin", "army_seekers", "army_gjall", "foresttrolls", "skeletons", "blobs",
			"surtlings", "wolves", "bats", "army_charred"
		};

		private Vector2 _bossScroll;

		private static readonly (string Prefab, string Label, string OfferPrefab, int OfferCount)[] BossList = new(string, string, string, int)[7]
		{
			("Eikthyr", "Eikthyr", "TrophyDeer", 2),
			("gd_king", "The Elder", "AncientSeed", 3),
			("Bonemass", "Bonemass", "WitheredBone", 10),
			("Dragon", "Moder", "DragonEgg", 3),
			("GoblinKing", "Yagluth", "GoblinTotem", 5),
			("SeekerQueen", "The Queen", "DvergrKeyFragment", 9),
			("Fader", "Fader", "BellFragment", 3)
		};

		private GUIStyle _windowStyle;

		private GUIStyle _buttonStyle;

		private GUIStyle _labelStyle;

		private GUIStyle _headerStyle;

		private GUIStyle _textFieldStyle;

		private GUIStyle _toggleStyle;

		private GUIStyle _tabStyle;

		private GUIStyle _catStyle;

		private GUIStyle _rowEven;

		private GUIStyle _rowOdd;

		private GUIStyle _dimLabelStyle;

		private Texture2D _texWood;

		private bool _skinReady;

		private bool _fontApplied;

		private float _nextFontTry;

		private int _fontTries;

		internal static bool NoStaminaFlag;

		internal static bool OneHitKillFlag;

		private static MethodInfo _screenToWorld;

		private static readonly string[] SeBucketNames = new string[6] { "Boss Powers", "Armor Set Bonuses", "Potions & Mead", "Debuffs & Environment", "Comfort & Rest", "Other" };

		private static readonly string[] SeDebuffKeys = new string[19]
		{
			"Burning", "Cold", "Freezing", "Frost", "Wet", "Poison", "Smoked", "Tared", "Harpooned", "Stagger",
			"Encumbered", "Slime", "Lightning", "Immobilized", "Barnacle", "Puke", "Debuff", "Curse", "Bleeding"
		};

		private static readonly string[] SeComfortKeys = new string[11]
		{
			"Rested", "Resting", "Shelter", "Comfort", "Campfire", "Warm", "Fire", "Sated", "SoftDeath", "Sitting",
			"Bed"
		};

		private string _unbanId = "";

		private static Player LocalPlayer => Player.m_localPlayer;

		private void Awake()
		{
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Expected O, but got Unknown
			//IL_02be: 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_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)288, "Key that opens/closes the admin panel");
			_mapTpKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "MapTeleportKey", (KeyCode)116, "With the full map open, hover a spot and press this key to teleport there");
			_favoritesCfg = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "Favorites", "", "Comma-separated favorite item prefabs");
			_crafterNameCfg = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "CrafterName", "", "Crafter signature on given items (empty = none)");
			_bulkPackCfg = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "BulkPack", "Wood:50,Stone:50,FineWood:30,Iron:30,BronzeNails:100", "Items granted by the Bulk Pack button (prefab:count, comma-separated)");
			_spawnPresetsCfg = ((BaseUnityPlugin)this).Config.Bind<string>("Creatures", "SpawnPresets", "", "Saved creature spawn presets");
			_bookmarksCfg = ((BaseUnityPlugin)this).Config.Bind<string>("World", "Bookmarks", "", "Saved teleport bookmarks");
			_playerNotesCfg = ((BaseUnityPlugin)this).Config.Bind<string>("Players", "Notes", "", "Per-player admin notes");
			_windowRectCfg = ((BaseUnityPlugin)this).Config.Bind<string>("General", "WindowRect", "60,60,740,680", "Admin panel window position+size x,y,width,height (auto-saved)");
			_fontChoiceCfg = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "Font", FontChoices[0], new ConfigDescription("Panel font. 'Norse (auto)' picks the best available game font; 'Default' is Unity's built-in font.", (AcceptableValueBase)(object)new AcceptableValueList<string>(FontChoices), Array.Empty<object>()));
			_fontSizeCfg = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "FontSize", 13, new ConfigDescription("Base font size for panel text; headers, tabs and the title scale with it.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 20), Array.Empty<object>()));
			_panelAlphaCfg = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PanelOpacity", 96, new ConfigDescription("Panel background opacity in percent.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(55, 100), Array.Empty<object>()));
			_cameraLockCfg = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "CameraLockWhilePanelOpen", true, "Lock mouse-look while the panel is open (like the inventory). Turn off to keep the camera live.");
			_fontSizeLive = _fontSizeCfg.Value;
			_panelAlphaLive = _panelAlphaCfg.Value;
			try
			{
				string[] array = _windowRectCfg.Value.Split(new char[1] { ',' });
				if (array.Length == 4 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3) && float.TryParse(array[3], out var result4))
				{
					_windowRect = new Rect(result, result2, result3, result4);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Bad WindowRect config, using default: " + ex.Message));
			}
			_lastSavedRect = _windowRect;
			_favorites = new HashSet<string>(_favoritesCfg.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
			_playerNotes = ParseKv(_playerNotesCfg.Value);
			Harmony.CreateAndPatchAll(typeof(RpcRegistration), (string)null);
			Harmony.CreateAndPatchAll(typeof(CheatPatches), (string)null);
			try
			{
				Harmony.CreateAndPatchAll(typeof(CursorPatch), (string)null);
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Cursor patch failed (panel still works): " + ex2.Message));
			}
			try
			{
				Harmony.CreateAndPatchAll(typeof(InputBlockPatch), (string)null);
			}
			catch (Exception ex3)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Input-block patch failed (panel still works): " + ex3.Message));
			}
			try
			{
				Harmony.CreateAndPatchAll(typeof(BlockAttackPatch), (string)null);
			}
			catch (Exception ex4)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Attack-block patch failed (panel still works): " + ex4.Message));
			}
			try
			{
				Harmony.CreateAndPatchAll(typeof(CameraLockPatch), (string)null);
			}
			catch (Exception ex5)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Camera-lock patch failed (panel still works): " + ex5.Message));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press {2} in-game.", "AdminPanel", "2.2.6", _toggleKey.Value));
		}

		private static string EncKv(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				return s.Replace("%", "%25").Replace("|", "%7C").Replace("=", "%3D");
			}
			return s;
		}

		private static string DecKv(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				return s.Replace("%3D", "=").Replace("%7C", "|").Replace("%25", "%");
			}
			return s;
		}

		private static Dictionary<string, string> ParseKv(string raw)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			string[] array = raw.Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				int num = text.IndexOf('=');
				if (num > 0)
				{
					dictionary[DecKv(text.Substring(0, num))] = DecKv(text.Substring(num + 1));
				}
			}
			return dictionary;
		}

		private static string JoinKv(Dictionary<string, string> dict)
		{
			return string.Join("|", dict.Select((KeyValuePair<string, string> kv) => EncKv(kv.Key) + "=" + EncKv(kv.Value)));
		}

		private static void OnInventoryData(long sender, ZPackage pkg)
		{
			AdminPanelPlugin instance = Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			try
			{
				string inspectPlayerName = pkg.ReadString();
				int num = pkg.ReadInt();
				if (num >= 0 && num <= 512)
				{
					List<(string, int, int)> list = new List<(string, int, int)>();
					for (int i = 0; i < num; i++)
					{
						string item = pkg.ReadString();
						int item2 = pkg.ReadInt();
						int item3 = pkg.ReadInt();
						list.Add((item, item2, item3));
					}
					instance._inspectPlayerName = inspectPlayerName;
					instance._inspectInventory = list;
					instance._inspectPending = false;
				}
			}
			catch (Exception)
			{
			}
		}

		private static long PeerIdOf(PlayerInfo info)
		{
			return ((ZDOID)(ref info.m_characterID)).UserID;
		}

		private static long ServerUid()
		{
			return (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null)?.m_uid ?? 0;
		}

		private long SelfUid()
		{
			//IL_003c: 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_0042: 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)
			if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)LocalPlayer == (Object)null)
			{
				return 0L;
			}
			string playerName = LocalPlayer.GetPlayerName();
			foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
			{
				if (player.m_name == playerName)
				{
					return PeerIdOf(player);
				}
			}
			return 0L;
		}

		private void Update()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Invalid comparison between Unknown and I4
			if (_rebindTarget == 0 && Input.GetKeyDown(_toggleKey.Value))
			{
				_visible = !_visible;
				if (_visible)
				{
					RefreshCaches();
				}
				else
				{
					FlushNotes();
					CommitUiSettings();
					_openDropdown = null;
				}
			}
			if (_visible && (((_itemIndex == null || _seIndex == null) && (Object)(object)ObjectDB.instance != (Object)null) || (_creatureIndex == null && (Object)(object)ZNetScene.instance != (Object)null)))
			{
				RefreshCaches();
			}
			if (_rebindTarget == 0 && Input.GetKeyDown(_mapTpKey.Value) && (Object)(object)LocalPlayer != (Object)null && (Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2)
			{
				TeleportToMapCursor();
			}
			if (_visible && Input.GetMouseButtonUp(0))
			{
				CommitUiSettings();
			}
			EventSystem current = EventSystem.current;
			if ((Object)(object)current != (Object)null && !((Behaviour)current).enabled)
			{
				((Behaviour)current).enabled = true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer != (Object)(object)_appliedTo)
			{
				ReapplyPlayerState(localPlayer);
				_appliedTo = localPlayer;
			}
			if ((Object)(object)localPlayer != (Object)null && Time.time >= _nextInvClean)
			{
				_nextInvClean = Time.time + 2f;
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				if (inventory != null)
				{
					List<ItemData> list = (from i in inventory.GetAllItems()
						where i.m_shared == null || i.m_shared.m_icons == null || i.m_shared.m_icons.Length == 0
						select i).ToList();
					if (list.Count > 0)
					{
						foreach (ItemData item in list)
						{
							inventory.RemoveItem(item);
						}
						((BaseUnityPlugin)this).Logger.LogWarning((object)$"Auto-removed {list.Count} icon-less item(s) that would freeze the inventory.");
						((Character)localPlayer).Message((MessageType)1, $"[Admin] Removed {list.Count} broken item(s) from your bag", 0, (Sprite)null);
					}
				}
			}
			if (!((Object)(object)ZNet.instance != (Object)null) || !(Time.time >= _nextPlayerPoll))
			{
				return;
			}
			_nextPlayerPoll = Time.time + 3f;
			HashSet<string> hashSet = new HashSet<string>(from p in ZNet.instance.GetPlayerList()
				select p.m_name);
			if (_seenPlayersInit)
			{
				foreach (string item2 in hashSet.Except(_lastSeenPlayers))
				{
					_joinLog.Insert(0, $"{DateTime.Now:HH:mm} + {item2} joined");
				}
				foreach (string item3 in _lastSeenPlayers.Except(hashSet))
				{
					_joinLog.Insert(0, $"{DateTime.Now:HH:mm} - {item3} left");
				}
			}
			else
			{
				_seenPlayersInit = true;
			}
			if (_joinLog.Count > 100)
			{
				_joinLog.RemoveRange(100, _joinLog.Count - 100);
			}
			_lastSeenPlayers = hashSet;
		}

		private void OnDisable()
		{
			FlushNotes();
		}

		private void FlushNotes()
		{
			if (_notesDirty)
			{
				_playerNotesCfg.Value = JoinKv(_playerNotes);
				((BaseUnityPlugin)this).Config.Save();
				_notesDirty = false;
			}
		}

		private void ReapplyPlayerState(Player p)
		{
			_baseWalk = ((Character)p).m_walkSpeed;
			_baseRun = ((Character)p).m_runSpeed;
			_baseSwim = ((Character)p).m_swimSpeed;
			_baseJump = ((Character)p).m_jumpForce;
			_baseWeight = p.m_maxCarryWeight;
			_basePickup = p.m_autoPickupRange;
			if (_god)
			{
				p.SetGodMode(true);
			}
			if (_ghost)
			{
				p.SetGhostMode(true);
			}
			if (_noCost)
			{
				p.SetNoPlacementCost(true);
			}
			if (_infiniteWeight)
			{
				p.m_maxCarryWeight = 100000f;
			}
			if (_speedMult > 1.001f)
			{
				((Character)p).m_walkSpeed = _baseWalk * _speedMult;
				((Character)p).m_runSpeed = _baseRun * _speedMult;
				((Character)p).m_swimSpeed = _baseSwim * _speedMult;
			}
			if (_jumpMult > 1.001f)
			{
				((Character)p).m_jumpForce = _baseJump * _jumpMult;
			}
			if (_pickupRange > 2.001f)
			{
				p.m_autoPickupRange = _pickupRange;
			}
			_fly = false;
		}

		private void TeleportToMapCursor()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (_screenToWorld == null)
			{
				_screenToWorld = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (Type[])null);
			}
			if (_screenToWorld == null)
			{
				Message("Map teleport unavailable (game API changed)");
				return;
			}
			Vector3 val = (Vector3)_screenToWorld.Invoke(Minimap.instance, new object[1] { Input.mousePosition });
			TeleportToWorld(val, $"map point ({val.x:0}, {val.z:0})");
		}

		private void TeleportToWorld(Vector3 world, string label)
		{
			//IL_0000: 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_0037: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			float num = world.y;
			float num2 = default(float);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(world, ref num2))
			{
				num = num2;
			}
			((Character)LocalPlayer).TeleportTo(new Vector3(world.x, num + 1.5f, world.z), ((Component)LocalPlayer).transform.rotation, true);
			Message("Teleporting to " + label);
		}

		private static (string cat, string sub) Categorize(ItemDrop drop)
		{
			//IL_000d: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected I4, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			SharedData shared = drop.m_itemData.m_shared;
			ItemType itemType = shared.m_itemType;
			switch (itemType - 1)
			{
			case 2:
			case 3:
			case 13:
			case 21:
				if ((int)shared.m_skillType == 12)
				{
					return (cat: "Tools", sub: "Pickaxes");
				}
				return (cat: "Weapons", sub: ((object)Unsafe.As<SkillType, SkillType>(ref shared.m_skillType)/*cast due to .constrained prefix*/).ToString());
			case 4:
				return (cat: "Shields", sub: "All");
			case 5:
				return (cat: "Armor", sub: "Helmets");
			case 6:
				return (cat: "Armor", sub: "Chest");
			case 10:
				return (cat: "Armor", sub: "Legs");
			case 16:
				return (cat: "Armor", sub: "Capes");
			case 9:
			case 17:
				return (cat: "Accessories", sub: "All");
			case 8:
			case 22:
				return (cat: "Ammo", sub: "All");
			case 1:
				return (cat: "Food & Potions", sub: (shared.m_food > 0f) ? "Food" : "Potions & Other");
			case 14:
			case 18:
				return (cat: "Tools", sub: "All");
			case 12:
				return (cat: "Trophies", sub: "All");
			case 0:
			{
				string value;
				return (cat: "Materials", sub: MaterialBiome.TryGetValue(((Object)drop).name, out value) ? value : "Other");
			}
			default:
				return (cat: "Misc", sub: "All");
			}
		}

		private static string LocalizeSafe(string token, string fallback)
		{
			string text = ((Localization.instance != null) ? Localization.instance.Localize(token) : fallback);
			if (string.IsNullOrEmpty(text) || text.StartsWith("["))
			{
				text = fallback;
			}
			return text;
		}

		private static string ShortDesc(string token, int max)
		{
			string text = LocalizeSafe(token, "");
			if (string.IsNullOrEmpty(text))
			{
				return "";
			}
			text = text.Replace('\n', ' ').Replace('\r', ' ').Trim();
			if (text.Length > max)
			{
				text = text.Substring(0, max).TrimEnd(Array.Empty<char>()) + "…";
			}
			return text;
		}

		private static string BuildDamageLine(DamageTypes d)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_00a7: 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)
			//IL_00cf: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>(4);
			if (d.m_damage > 0f)
			{
				list.Add($"Dmg {d.m_damage:0}");
			}
			if (d.m_blunt > 0f)
			{
				list.Add($"Blunt {d.m_blunt:0}");
			}
			if (d.m_slash > 0f)
			{
				list.Add($"Slash {d.m_slash:0}");
			}
			if (d.m_pierce > 0f)
			{
				list.Add($"Pierce {d.m_pierce:0}");
			}
			if (d.m_chop > 0f)
			{
				list.Add($"Chop {d.m_chop:0}");
			}
			if (d.m_pickaxe > 0f)
			{
				list.Add($"Pickaxe {d.m_pickaxe:0}");
			}
			if (d.m_fire > 0f)
			{
				list.Add($"Fire {d.m_fire:0}");
			}
			if (d.m_frost > 0f)
			{
				list.Add($"Frost {d.m_frost:0}");
			}
			if (d.m_lightning > 0f)
			{
				list.Add($"Lightning {d.m_lightning:0}");
			}
			if (d.m_poison > 0f)
			{
				list.Add($"Poison {d.m_poison:0}");
			}
			if (d.m_spirit > 0f)
			{
				list.Add($"Spirit {d.m_spirit:0}");
			}
			return string.Join(" · ", list);
		}

		private static string BuildStatLine(SharedData s)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected I4, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			if (s == null)
			{
				return "";
			}
			if (s.m_food > 0f)
			{
				List<string> list = new List<string>(4);
				list.Add($"+{s.m_food:0} HP");
				if (s.m_foodStamina > 0f)
				{
					list.Add($"+{s.m_foodStamina:0} ST");
				}
				if (s.m_foodEitr > 0f)
				{
					list.Add($"+{s.m_foodEitr:0} Eitr");
				}
				list.Add($"{s.m_foodBurnTime:0}s");
				return string.Join(" · ", list);
			}
			ItemType itemType = s.m_itemType;
			switch (itemType - 3)
			{
			case 0:
			case 1:
			case 6:
			case 11:
			case 12:
			case 17:
			case 19:
			case 20:
			{
				string text2 = BuildDamageLine(s.m_damages);
				if (text2.Length <= 0)
				{
					return ShortDesc(s.m_description, 60);
				}
				return text2;
			}
			case 3:
			case 4:
			case 8:
			case 14:
			{
				string text = $"Armor {s.m_armor:0}";
				if (s.m_armorPerLevel > 0f)
				{
					text += $" (+{s.m_armorPerLevel:0}/lv)";
				}
				return text;
			}
			case 2:
				return $"Block {s.m_blockPower:0}";
			default:
				return ShortDesc(s.m_description, 60);
			}
		}

		private static int ClassifySe(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return 5;
			}
			if (name.StartsWith("GP_", StringComparison.OrdinalIgnoreCase))
			{
				return 0;
			}
			if (name.StartsWith("SetEffect_", StringComparison.OrdinalIgnoreCase))
			{
				return 1;
			}
			if (name.StartsWith("Potion_", StringComparison.OrdinalIgnoreCase))
			{
				return 2;
			}
			string[] seDebuffKeys = SeDebuffKeys;
			foreach (string value in seDebuffKeys)
			{
				if (name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return 3;
				}
			}
			seDebuffKeys = SeComfortKeys;
			foreach (string value2 in seDebuffKeys)
			{
				if (name.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return 4;
				}
			}
			return 5;
		}

		private List<SeEntry> FilteredStatusEffects()
		{
			if (_seFilteredCache != null && _seSearch == _seFilterKey)
			{
				return _seFilteredCache;
			}
			if (_seIndex == null)
			{
				_seFilteredCache = new List<SeEntry>();
				_seFilterKey = _seSearch;
				return _seFilteredCache;
			}
			IEnumerable<SeEntry> source = _seIndex;
			if (!string.IsNullOrEmpty(_seSearch))
			{
				source = _seIndex.Where((SeEntry e) => e.Display.IndexOf(_seSearch, StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)e.Se).name.IndexOf(_seSearch, StringComparison.OrdinalIgnoreCase) >= 0);
			}
			_seFilteredCache = source.ToList();
			_seFilterKey = _seSearch;
			return _seFilteredCache;
		}

		private void RefreshCaches()
		{
			_itemIndex = null;
			_seIndex = null;
			_seFilteredCache = null;
			_seFilterKey = null;
			_creatureIndex = null;
			_creatureCats = null;
			_subCatsCache = null;
			_subCatsKey = null;
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				_itemIndex = (from e in (from go in ObjectDB.instance.m_items
						select go.GetComponent<ItemDrop>() into id
						where (Object)(object)id != (Object)null
						select id).Select(delegate(ItemDrop id)
					{
						var (cat, sub) = Categorize(id);
						return new ItemEntry
						{
							Drop = id,
							Prefab = ((Object)id).name,
							Display = LocalizeSafe(id.m_itemData.m_shared.m_name, ((Object)id).name),
							Info = BuildStatLine(id.m_itemData.m_shared),
							Cat = cat,
							Sub = sub
						};
					})
					orderby e.Cat, e.Sub, e.Display
					select e).ToList();
				_seIndex = (from se in ObjectDB.instance.m_StatusEffects
					where (Object)(object)se != (Object)null
					select new SeEntry
					{
						Se = se,
						Display = LocalizeSafe(se.m_name, ((Object)se).name),
						Tooltip = ShortDesc(se.m_tooltip, 90),
						Hash = se.NameHash(),
						Bucket = ClassifySe(((Object)se).name)
					} into e
					orderby e.Bucket
					select e).ThenBy<SeEntry, string>((SeEntry e) => e.Display, StringComparer.OrdinalIgnoreCase).ToList();
			}
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				_creatureIndex = (from e in ZNetScene.instance.m_prefabs.Where((GameObject p) => (Object)(object)p != (Object)null && (Object)(object)p.GetComponent<Character>() != (Object)null && (Object)(object)p.GetComponent<Player>() == (Object)null).Select(delegate(GameObject p)
					{
						Character component = p.GetComponent<Character>();
						return new CreatureEntry
						{
							Prefab = p,
							Name = ((Object)p).name,
							Display = LocalizeSafe(component.m_name, ((Object)p).name),
							Faction = ((object)Unsafe.As<Faction, Faction>(ref component.m_faction)/*cast due to .constrained prefix*/).ToString(),
							Boss = component.IsBoss(),
							Tamable = ((Object)(object)p.GetComponent<Tameable>() != (Object)null)
						};
					})
					orderby e.Faction, e.Display
					select e).ToList();
				_creatureCats = new List<string> { "All", "Bosses", "Tamable" };
				_creatureCats.AddRange(from f in _creatureIndex.Select((CreatureEntry e) => e.Faction).Distinct()
					orderby f
					select f);
			}
		}

		private static Texture2D SolidTex(Color c)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, c);
			val.Apply();
			return val;
		}

		private void EnsureSkin()
		{
			//IL_0010: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Expected O, but got Unknown
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Expected O, but got Unknown
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Expected O, but got Unknown
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Expected O, but got Unknown
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Expected O, but got Unknown
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Expected O, but got Unknown
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Expected O, but got Unknown
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Expected O, but got Unknown
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Expected O, but got Unknown
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Expected O, but got Unknown
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Expected O, but got Unknown
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Expected O, but got Unknown
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Expected O, but got Unknown
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			if (!_skinReady)
			{
				_texWood = SolidTex(WoodColor(_panelAlphaLive));
				Texture2D background = SolidTex(new Color(0.22f, 0.16f, 0.1f, 1f));
				Texture2D background2 = SolidTex(new Color(0.31f, 0.23f, 0.13f, 1f));
				Texture2D background3 = SolidTex(new Color(0.16f, 0.115f, 0.07f, 1f));
				Texture2D background4 = SolidTex(new Color(0.07f, 0.05f, 0.035f, 1f));
				Color textColor = default(Color);
				((Color)(ref textColor))..ctor(0.87f, 0.79f, 0.62f);
				Color textColor2 = default(Color);
				((Color)(ref textColor2))..ctor(0.98f, 0.78f, 0.35f);
				_windowStyle = new GUIStyle(GUI.skin.window);
				_windowStyle.normal.background = _texWood;
				_windowStyle.onNormal.background = _texWood;
				_windowStyle.normal.textColor = textColor2;
				_windowStyle.onNormal.textColor = textColor2;
				_windowStyle.fontStyle = (FontStyle)1;
				_windowStyle.fontSize = 15;
				_buttonStyle = new GUIStyle(GUI.skin.button);
				_buttonStyle.normal.background = background;
				_buttonStyle.hover.background = background2;
				_buttonStyle.active.background = background3;
				_buttonStyle.onNormal.background = background2;
				_buttonStyle.normal.textColor = textColor;
				_buttonStyle.hover.textColor = textColor2;
				_buttonStyle.active.textColor = textColor2;
				_buttonStyle.onNormal.textColor = textColor2;
				_buttonStyle.fontStyle = (FontStyle)1;
				_labelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13
				};
				_labelStyle.normal.textColor = textColor;
				_headerStyle = new GUIStyle(_labelStyle)
				{
					fontStyle = (FontStyle)1,
					fontSize = 14
				};
				_headerStyle.normal.textColor = textColor2;
				_textFieldStyle = new GUIStyle(GUI.skin.textField);
				_textFieldStyle.normal.background = background4;
				_textFieldStyle.focused.background = background4;
				_textFieldStyle.hover.background = background4;
				_textFieldStyle.normal.textColor = textColor;
				_textFieldStyle.focused.textColor = textColor2;
				_textFieldStyle.hover.textColor = textColor;
				_toggleStyle = new GUIStyle(GUI.skin.toggle)
				{
					fontSize = 13
				};
				_toggleStyle.normal.textColor = textColor;
				_toggleStyle.onNormal.textColor = textColor2;
				_toggleStyle.hover.textColor = textColor;
				_toggleStyle.onHover.textColor = textColor2;
				_buttonStyle.padding = new RectOffset(10, 10, 5, 5);
				_buttonStyle.margin = new RectOffset(3, 3, 3, 3);
				_buttonStyle.fontSize = 13;
				_tabStyle = new GUIStyle(_buttonStyle)
				{
					fontSize = 14
				};
				_tabStyle.padding = new RectOffset(12, 12, 8, 8);
				_tabStyle.margin = new RectOffset(3, 3, 4, 4);
				Texture2D background5 = SolidTex(new Color(0.42f, 0.3f, 0.12f, 1f));
				_tabStyle.onNormal.background = background5;
				_tabStyle.onHover.background = background5;
				_catStyle = new GUIStyle(_buttonStyle)
				{
					fontSize = 12
				};
				_catStyle.padding = new RectOffset(10, 10, 6, 6);
				_catStyle.margin = new RectOffset(3, 3, 4, 4);
				_catStyle.onNormal.background = background5;
				_catStyle.onHover.background = background5;
				_rowEven = new GUIStyle();
				_rowEven.padding = new RectOffset(4, 4, 3, 3);
				_rowOdd = new GUIStyle(_rowEven);
				_rowOdd.normal.background = SolidTex(new Color(1f, 1f, 1f, 0.035f));
				_dimLabelStyle = new GUIStyle(_labelStyle)
				{
					fontSize = 12
				};
				_dimLabelStyle.normal.textColor = new Color(0.62f, 0.55f, 0.44f);
				ApplyFontSizes();
				_skinReady = true;
			}
		}

		private static Font FindValheimFont()
		{
			Font[] source = Resources.FindObjectsOfTypeAll<Font>();
			return ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.IndexOf("Norsebold", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.IndexOf("AveriaSerifLibre", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0));
		}

		private static Font FindFontFor(string choice)
		{
			Font[] source = Resources.FindObjectsOfTypeAll<Font>();
			return (Font)(choice switch
			{
				"Norse Bold" => ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.IndexOf("Norsebold", StringComparison.OrdinalIgnoreCase) >= 0)), 
				"Norse" => ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)f).name.IndexOf("bold", StringComparison.OrdinalIgnoreCase) < 0)), 
				"Averia Serif" => ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.IndexOf("AveriaSerifLibre", StringComparison.OrdinalIgnoreCase) >= 0)), 
				_ => FindValheimFont(), 
			});
		}

		private void ApplyFont()
		{
			if (_fontApplied)
			{
				return;
			}
			Font val = null;
			if (_fontChoiceCfg.Value != "Default")
			{
				if (Time.time < _nextFontTry)
				{
					return;
				}
				_nextFontTry = Time.time + 1f;
				val = FindFontFor(_fontChoiceCfg.Value);
				if ((Object)(object)val == (Object)null && ++_fontTries < 10)
				{
					return;
				}
			}
			GUIStyle[] array = (GUIStyle[])(object)new GUIStyle[11]
			{
				_windowStyle, _buttonStyle, _labelStyle, _headerStyle, _textFieldStyle, _toggleStyle, _tabStyle, _catStyle, _rowEven, _rowOdd,
				_dimLabelStyle
			};
			foreach (GUIStyle val2 in array)
			{
				if (val2 != null)
				{
					val2.font = val;
				}
			}
			_fontApplied = true;
		}

		private void OnGUI()
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Invalid comparison between Unknown and I4
			if (_visible)
			{
				EnsureSkin();
				ApplyFont();
				((Rect)(ref _windowRect)).width = Mathf.Clamp(((Rect)(ref _windowRect)).width, 660f, (float)Screen.width);
				((Rect)(ref _windowRect)).height = Mathf.Clamp(((Rect)(ref _windowRect)).height, 300f, (float)Screen.height);
				((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _windowRect)).width));
				((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _windowRect)).height));
				_windowRect = GUI.Window(918273, _windowRect, new WindowFunction(DrawWindow), $"⚔ Valheim Admin Panel ⚔   [{_toggleKey.Value} to close]", _windowStyle);
				if ((int)Event.current.type == 1)
				{
					SaveWindowRect();
				}
			}
		}

		private void SaveWindowRect()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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)
			if (!(_windowRect == _lastSavedRect))
			{
				_lastSavedRect = _windowRect;
				_windowRectCfg.Value = $"{((Rect)(ref _windowRect)).x:0},{((Rect)(ref _windowRect)).y:0},{((Rect)(ref _windowRect)).width:0},{((Rect)(ref _windowRect)).height:0}";
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private float ListView(float reserve)
		{
			return Mathf.Clamp(((Rect)(ref _windowRect)).height - reserve - (float)Mathf.Max(0, _fontSizeLive - 13) * 3f, 160f, 4000f);
		}

		private void DrawWindow(int id)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Invalid comparison between Unknown and I4
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Invalid comparison between Unknown and I4
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LocalPlayer == (Object)null)
			{
				GUILayout.Label("Not in game (no local player).", _labelStyle, Array.Empty<GUILayoutOption>());
				GUI.DragWindow();
				return;
			}
			if ((int)Event.current.type == 8)
			{
				_openDropdownLayout = _openDropdown;
				_rebindTargetLayout = _rebindTarget;
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			for (int i = 0; i < TabNames.Length; i++)
			{
				if (GUILayout.Toggle(_tab == i, TabNames[i], _tabStyle, Array.Empty<GUILayoutOption>()) && _tab != i)
				{
					_tab = i;
					_openDropdown = null;
					_rebindTarget = 0;
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(14f);
			try
			{
				switch (_tab)
				{
				case 0:
					DrawItemsTab();
					break;
				case 1:
					DrawCreaturesTab();
					break;
				case 2:
					DrawBossesTab();
					break;
				case 3:
					DrawPlayerTab();
					break;
				case 4:
					DrawWorldTab();
					break;
				case 5:
					DrawPlayersTab();
					break;
				case 6:
					DrawServerTab();
					break;
				case 7:
					DrawSettingsTab();
					break;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"AdminPanel tab {_tab} draw error: {ex.Message}");
			}
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).width - 22f, ((Rect)(ref _windowRect)).height - 22f, 22f, 22f);
			GUI.Label(val, "◢", _dimLabelStyle);
			Event current = Event.current;
			if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition))
			{
				_resizing = true;
				current.Use();
			}
			else if (_resizing && (int)current.type == 3)
			{
				((Rect)(ref _windowRect)).width = Mathf.Clamp(current.mousePosition.x + 11f, 660f, (float)Screen.width - ((Rect)(ref _windowRect)).x);
				((Rect)(ref _windowRect)).height = Mathf.Clamp(current.mousePosition.y + 11f, 300f, (float)Screen.height - ((Rect)(ref _windowRect)).y);
				current.Use();
			}
			else if ((int)current.type == 1 && _resizing)
			{
				_resizing = false;
				SaveWindowRect();
			}
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
		}

		private List<PlayerInfo> OtherPlayers()
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return new List<PlayerInfo>();
			}
			string myName = (((Object)(object)LocalPlayer != (Object)null) ? LocalPlayer.GetPlayerName() : "");
			return (from p in ZNet.instance.GetPlayerList()
				where p.m_name != myName
				select p).ToList();
		}

		private int GiveTargetIndex(List<PlayerInfo> others)
		{
			if (_giveTargetId == 0L)
			{
				return -1;
			}
			return others.FindIndex((PlayerInfo p) => PeerIdOf(p) == _giveTargetId);
		}

		private string GiveTargetName(List<PlayerInfo> others)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			int num = GiveTargetIndex(others);
			if (num >= 0)
			{
				return others[num].m_name;
			}
			return "(nobody)";
		}

		private void CycleGiveTarget(List<PlayerInfo> others)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (others.Count == 0)
			{
				_giveTargetId = 0L;
				return;
			}
			int index = (GiveTargetIndex(others) + 1) % others.Count;
			_giveTargetId = PeerIdOf(others[index]);
		}

		private Vector3 SpawnPos(float distance = 3f)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (_spawnAtCrosshair && (Object)(object)GameCamera.instance != (Object)null)
			{
				Transform transform = ((Component)GameCamera.instance).transform;
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(transform.position, transform.forward, ref val, 200f))
				{
					return ((RaycastHit)(ref val)).point + Vector3.up * 0.3f;
				}
			}
			return ((Component)LocalPlayer).transform.position + ((Component)LocalPlayer).transform.forward * distance + Vector3.up * 0.5f;
		}

		private void SrvRpc(string method, params object[] parameters)
		{
			long num = ServerUid();
			if (num == 0L && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()))
			{
				Message("Not connected to a server");
			}
			else if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(num, method, parameters);
			}
		}

		private void SendServerSpawn(int kind, string prefabName, Vector3 pos, int count, int levelOrQuality, bool tamed, string petName = "")
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(kind);
			val.Write(prefabName);
			val.Write(pos);
			val.Write(count);
			val.Write(levelOrQuality);
			val.Write(tamed);
			val.Write(petName ?? "");
			SrvRpc("AP_SrvSpawn", val);
		}

		private void SendServerGive(long targetUid, string prefabName, int amount, int quality)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(targetUid);
			val.Write(prefabName);
			val.Write(amount);
			val.Write(quality);
			val.Write(_crafterNameCfg.Value ?? "");
			SrvRpc("AP_SrvGive", val);
		}

		private void Message(string text)
		{
			Player localPlayer = LocalPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)1, "[Admin] " + text, 0, (Sprite)null);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)text);
		}

		private static bool HasIcon(ItemDrop drop)
		{
			Sprite[] icons = drop.m_itemData.m_shared.m_icons;
			if (icons != null)
			{
				return icons.Length != 0;
			}
			return false;
		}

		private void DrawIcon(ItemEntry e)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = GUILayoutUtility.GetRect(26f, 26f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(26f),
				GUILayout.Height(26f)
			});
			if (!e.IconTried)
			{
				e.IconTried = true;
				try
				{
					e.Icon = e.Drop.m_itemData.GetIcon();
				}
				catch
				{
				}
			}
			Sprite icon = e.Icon;
			if (!((Object)(object)icon == (Object)null) && !((Object)(object)icon.texture == (Object)null))
			{
				Rect textureRect = icon.textureRect;
				Texture2D texture = icon.texture;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height);
				GUI.DrawTextureWithTexCoords(rect, (Texture)(object)texture, val);
			}
		}

		private void ToggleFavorite(string prefab)
		{
			if (!_favorites.Remove(prefab))
			{
				_favorites.Add(prefab);
			}
			_favoritesCfg.Value = string.Join(",", _favorites);
			_favVersion++;
			((BaseUnityPlugin)this).Config.Save();
		}

		private void MarkRecent(ItemEntry e)
		{
			_recentItems.RemoveAll((ItemEntry r) => r.Prefab == e.Prefab);
			_recentItems.Insert(0, e);
			if (_recentItems.Count > 25)
			{
				_recentItems.RemoveAt(_recentItems.Count - 1);
			}
			_recentVersion++;
		}

		private List<ItemEntry> FilteredItems()
		{
			string text = $"{_mainCat}|{_subCat}|{_itemSearch}|{_favVersion}|{_recentItems.Count}|{_recentVersion}|{_itemSort}";
			if (_filteredItemsCache != null && text == _itemFilterKey)
			{
				return _filteredItemsCache;
			}
			IEnumerable<ItemEntry> source = _itemIndex;
			if (_mainCat == "★ Fav")
			{
				source = _itemIndex.Where((ItemEntry e) => _favorites.Contains(e.Prefab));
			}
			else if (_mainCat == "Recent")
			{
				source = _recentItems;
			}
			else if (_mainCat != "All")
			{
				source = _itemIndex.Where((ItemEntry e) => e.Cat == _mainCat);
				if (_subCat != "All")
				{
					source = source.Where((ItemEntry e) => e.Sub == _subCat);
				}
			}
			if (!string.IsNullOrEmpty(_itemSearch))
			{
				source = source.Where((ItemEntry e) => e.Display.IndexOf(_itemSearch, StringComparison.OrdinalIgnoreCase) >= 0 || e.Prefab.IndexOf(_itemSearch, StringComparison.OrdinalIgnoreCase) >= 0);
			}
			if (_mainCat != "Recent")
			{
				source = _itemSort switch
				{
					1 => source.OrderByDescending<ItemEntry, string>((ItemEntry e) => e.Display, StringComparer.OrdinalIgnoreCase), 
					2 => (from e in source
						orderby e.Cat, e.Sub
						select e).ThenBy<ItemEntry, string>((ItemEntry e) => e.Display, StringComparer.OrdinalIgnoreCase), 
					_ => source.OrderBy<ItemEntry, string>((ItemEntry e) => e.Display, StringComparer.OrdinalIgnoreCase), 
				};
			}
			_filteredItemsCache = source.ToList();
			_itemFilterKey = text;
			return _filteredItemsCache;
		}

		private void GiveKit((string Name, (string Prefab, int Count)[] Items) kit, long targetUid)
		{
			(string, int)[] item = kit.Items;
			for (int i = 0; i < item.Length; i++)
			{
				var (prefabName, amount) = item[i];
				SendServerGive(targetUid, prefabName, amount, 1);
			}
			Message("Kit '" + kit.Name + "' sent");
		}

		private void DropdownButton(string id, string label, string[] options, int selected, float width)
		{
			string text = options[Mathf.Clamp(selected, 0, options.Length - 1)];
			if (GUILayout.Button(label + ": " + text + "  " + ((_openDropdown == id) ? "▲" : "▼"), _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(width) }))
			{
				_openDropdown = ((_openDropdown == id) ? null : id);
			}
		}

		private bool DropdownOptions(string id, string[] options, ref int selected, float width)
		{
			if (_openDropdownLayout != id)
			{
				return false;
			}
			bool result = false;
			for (int i = 0; i < options.Length; i++)
			{
				if (GUILayout.Button(((i == selected) ? "• " : "    ") + options[i], _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(width) }))
				{
					selected = i;
					_openDropdown = null;
					result = true;
				}
			}
			return result;
		}

		private void DrawItemsTab()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a8: Invalid comparison between Unknown and I4
			//IL_084b: Unknown result type (might be due to invalid IL or missing references)
			//IL_085f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0864: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0adf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b18: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 2; i++)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				int num = (MainCats.Length + 1) / 2;
				for (int j = i * num; j < Mathf.Min(MainCats.Length, (i + 1) * num); j++)
				{
					if (GUILayout.Toggle(_mainCat == MainCats[j], MainCats[j], _catStyle, Array.Empty<GUILayoutOption>()) && _mainCat != MainCats[j])
					{
						_mainCat = MainCats[j];
						_subCat = "All";
						_itemScroll = Vector2.zero;
					}
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.Space(12f);
			if ((int)Event.current.type == 8 || _othersSnapshot == null)
			{
				_othersSnapshot = OtherPlayers();
			}
			List<PlayerInfo> othersSnapshot = _othersSnapshot;
			if (_mainCat == "Kits")
			{
				GUILayout.Label("Gear kits (delivered to inventory via server):", _headerStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Give target:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
				if (GUILayout.Button(GiveTargetName(othersSnapshot), _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }))
				{
					CycleGiveTarget(othersSnapshot);
				}
				GUILayout.EndHorizontal();
				_itemScroll = GUILayout.BeginScrollView(_itemScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(Mathf.Min(ListView(300f), (float)GearKits.Length * 28f + 96f)) });
				(string, (string, int)[])[] gearKits = GearKits;
				for (int k = 0; k < gearKits.Length; k++)
				{
					(string, (string, int)[]) kit = gearKits[k];
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(kit.Item1, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) });
					GUILayout.Label(string.Join(", ", kit.Item2.Select(((string Prefab, int Count) tuple) => (tuple.Count <= 1) ? tuple.Prefab : $"{tuple.Prefab} x{tuple.Count}")), _labelStyle, Array.Empty<GUILayoutOption>());
					GUILayout.FlexibleSpace();
					if (GUILayout.Button("To me", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
					{
						GiveKit(kit, SelfUid());
					}
					if (GUILayout.Button("Give", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }))
					{
						int num2 = GiveTargetIndex(othersSnapshot);
						if (num2 >= 0)
						{
							GiveKit(kit, PeerIdOf(othersSnapshot[num2]));
						}
					}
					GUILayout.EndHorizontal();
				}
				GUILayout.Space(10f);
				GUILayout.Label("Bulk pack (edit in config file):", _headerStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(_bulkPackCfg.Value, _labelStyle, Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Grab bulk pack", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
				{
					string[] array = _bulkPackCfg.Value.Split(new char[1] { ',' });
					for (int k = 0; k < array.Length; k++)
					{
						string[] array2 = array[k].Trim().Split(new char[1] { ':' });
						if (array2.Length == 2 && int.TryParse(array2[1], out var result))
						{
							SendServerGive(SelfUid(), array2[0].Trim(), result, 1);
						}
					}
					Message("Bulk pack requested");
				}
				GUILayout.EndHorizontal();
				GUILayout.EndScrollView();
				return;
			}
			if (_itemIndex != null && _mainCat != "All" && _mainCat != "★ Fav" && _mainCat != "Recent")
			{
				if (_subCatsCache == null || _subCatsKey != _mainCat)
				{
					_subCatsCache = (from s in (from e in _itemIndex
							where e.Cat == _mainCat
							select e.Sub).Distinct()
						orderby s
						select s).ToList();
					_subCatsKey = _mainCat;
				}
				List<string> subCatsCache = _subCatsCache;
				if (subCatsCache.Count > 1)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					if (GUILayout.Toggle(_subCat == "All", "All", _catStyle, Array.Empty<GUILayoutOption>()) && _subCat != "All")
					{
						_subCat = "All";
						_itemScroll = Vector2.zero;
					}
					foreach (string item in subCatsCache)
					{
						if (GUILayout.Toggle(_subCat == item, item, _catStyle, Array.Empty<GUILayoutOption>()) && _subCat != item)
						{
							_subCat = item;
							_itemScroll = Vector2.zero;
						}
					}
					GUILayout.EndHorizontal();
					GUILayout.Space(10f);
				}
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			_itemSearch = GUILayout.TextField(_itemSearch, _textFieldStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Amount:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
			int.TryParse(GUILayout.TextField(_itemAmount.ToString(), _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }), out _itemAmount);
			GUILayout.Label("Quality:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			int.TryParse(GUILayout.TextField(_itemQuality.ToString(), _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }), out _itemQuality);
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Give target:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
			if (GUILayout.Button(GiveTargetName(othersSnapshot), _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }))
			{
				CycleGiveTarget(othersSnapshot);
			}
			GUILayout.Label("Drop = ground | Bag = your bag | Give = target's bag", _labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			DropdownButton("itemSort", "Sort", ItemSortModes, _itemSort, 150f);
			GUILayout.EndHorizontal();
			DropdownOptions("itemSort", ItemSortModes, ref _itemSort, 150f);
			if (_itemIndex == null)
			{
				GUILayout.Label("Item DB not loaded.", _labelStyle, Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Space(10f);
			float num3 = ListView(330f);
			if ((int)Event.current.type == 8 || _itemWindowList == null)
			{
				_itemWindowList = FilteredItems();
				_itemWindowTotal = _itemWindowList.Count;
				_itemWindowFirst = Mathf.Clamp(Mathf.FloorToInt(_itemScroll.y / 32f) - 1, 0, Mathf.Max(0, _itemWindowTotal));
				_itemWindowVisible = Mathf.Max(0, Mathf.Min(_itemWindowTotal - _itemWindowFirst, Mathf.CeilToInt(num3 / 32f) + 3));
			}
			List<ItemEntry> itemWindowList = _itemWindowList;
			int itemWindowTotal = _itemWindowTotal;
			int itemWindowFirst = _itemWindowFirst;
			int itemWindowVisible = _itemWindowVisible;
			_itemScroll = GUILayout.BeginScrollView(_itemScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num3) });
			if (itemWindowFirst > 0)
			{
				GUILayout.Space((float)itemWindowFirst * 32f);
			}
			for (int num4 = itemWindowFirst; num4 < itemWindowFirst + itemWindowVisible; num4++)
			{
				ItemEntry itemEntry = itemWindowList[num4];
				GUILayout.BeginHorizontal((num4 % 2 == 0) ? _rowEven : _rowOdd, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
				if (GUILayout.Button(_favorites.Contains(itemEntry.Prefab) ? "★" : "☆", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }))
				{
					ToggleFavorite(itemEntry.Prefab);
				}
				DrawIcon(itemEntry);
				GUILayout.Space(6f);
				GUILayout.Label(itemEntry.Display, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) });
				GUILayout.Label(itemEntry.Info, _dimLabelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.FlexibleSpace();
				int num5 = Math.Max(1, _itemAmount);
				int num6 = Math.Max(1, _itemQuality);
				if (GUILayout.Button("Drop", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }))
				{
					SendServerSpawn(0, itemEntry.Prefab, SpawnPos(1.5f), num5, num6, tamed: false);
					MarkRecent(itemEntry);
					Message($"Requested {num5}x {itemEntry.Display}");
				}
				bool flag = HasIcon(itemEntry.Drop);
				if (GUILayout.Button(flag ? "Bag" : "✕", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) }))
				{
					if (flag)
					{
						SendServerGive(SelfUid(), itemEntry.Prefab, num5, num6);
						MarkRecent(itemEntry);
						Message($"Requested {num5}x {itemEntry.Display} to bag");
					}
					else
					{
						Message(itemEntry.Display + " has no icon — it would corrupt your inventory (drop only)");
					}
				}
				if (GUILayout.Button(flag ? "Give" : "✕", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }))
				{
					int num7 = GiveTargetIndex(othersSnapshot);
					if (!flag)
					{
						Message(itemEntry.Display + " has no icon — cannot be given");
					}
					else if (num7 >= 0)
					{
						SendServerGive(PeerIdOf(othersSnapshot[num7]), itemEntry.Prefab, num5, num6);
						MarkRecent(itemEntry);
						Message($"Sent {num5}x {itemEntry.Display} to {othersSnapshot[num7].m_name}");
					}
					else
					{
						Message("No give target selected");
					}
				}
				GUILayout.EndHorizontal();
			}
			int num8 = itemWindowTotal - (itemWindowFirst + itemWindowVisible);
			if (num8 > 0)
			{
				GUILayout.Space((float)num8 * 32f);
			}
			GUILayout.EndScrollView();
			GUILayout.Label($"{itemWindowTotal} items", _dimLabelStyle, Array.Empty<GUILayoutOption>());
		}

		private List<CreatureEntry> FilteredCreatures()
		{
			string text = $"{_creatureCat}|{_creatureSearch}|{_creatureSort}";
			if (_filteredCreaturesCache != null && text == _creatureFilterKey)
			{
				return _filteredCreaturesCache;
			}
			IEnumerable<CreatureEntry> source = _creatureIndex;
			if (_creatureCat == "Bosses")
			{
				source = source.Where((CreatureEntry e) => e.Boss);
			}
			else if (_creatureCat == "Tamable")
			{
				source = source.Where((CreatureEntry e) => e.Tamable);
			}
			else if (_creatureCat != "All")
			{
				source = source.Where((CreatureEntry e) => e.Faction == _creatureCat);
			}
			if (!string.IsNullOrEmpty(_creatureSearch))
			{
				source = source.Where((CreatureEntry e) => e.Display.IndexOf(_creatureSearch, StringComparison.OrdinalIgnoreCase) >= 0 || e.Name.IndexOf(_creatureSearch, StringComparison.OrdinalIgnoreCase) >= 0);
			}
			_filteredCreaturesCache = (_creatureSort switch
			{
				1 => source.OrderByDescending<CreatureEntry, string>((CreatureEntry e) => e.Display, StringComparer.OrdinalIgnoreCase), 
				2 => source.OrderBy((CreatureEntry e) => e.Faction).ThenBy<CreatureEntry, string>((CreatureEntry e) => e.Display, StringComparer.OrdinalIgnoreCase), 
				_ => source.OrderBy<CreatureEntry, string>((CreatureEntry e) => e.Display, StringComparer.OrdinalIgnoreCase), 
			}).ToList();
			_creatureFilterKey = text;
			return _filteredCreaturesCache;
		}

		private void DrawCreaturesTab()
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Invalid comparison between Unknown and I4
			//IL_06c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06db: Unknown result type (might be due to invalid IL or missing references)
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0948: Unknown result type (might be due to invalid IL or missing references)
			//IL_09be: Unknown result type (might be due to invalid IL or missing references)
			if (_creatureIndex == null)
			{
				GUILayout.Label("Scene DB not loaded.", _labelStyle, Array.Empty<GUILayoutOption>());
				return;
			}
			List<string> list = _creatureCats;
			if (list == null)
			{
				list = new List<string> { "All", "Bosses", "Tamable" };
				list.AddRange(from f in _creatureIndex.Select((CreatureEntry e) => e.Faction).Distinct()
					orderby f
					select f);
				_creatureCats = list;
			}
			for (int num = 0; num < 2; num++)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				int num2 = (list.Count + 1) / 2;
				for (int num3 = num * num2; num3 < Mathf.Min(list.Count, (num + 1) * num2); num3++)
				{
					if (GUILayout.Toggle(_creatureCat == list[num3], list[num3], _catStyle, Array.Empty<GUILayoutOption>()) && _creatureCat != list[num3])
					{
						_creatureCat = list[num3];
						_creatureScroll = Vector2.zero;
					}
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			_creatureSearch = GUILayout.TextField(_creatureSearch, _textFieldStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Count:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) });
			int.TryParse(GUILayout.TextField(_creatureCount.ToString(), _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }), out _creatureCount);
			GUILayout.Label("Stars:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
			if (int.TryParse(GUILayout.TextField((_creatureLevel - 1).ToString(), _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }), out var result))
			{
				_creatureLevel = Mathf.Clamp(result, 0, 10) + 1;
			}
			_spawnAtCrosshair = GUILayout.Toggle(_spawnAtCrosshair, " At crosshair", _toggleStyle, Array.Empty<GUILayoutOption>());
			DropdownButton("creatureSort", "Sort", CreatureSortModes, _creatureSort, 150f);
			GUILayout.EndHorizontal();
			DropdownOptions("creatureSort", CreatureSortModes, ref _creatureSort, 150f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Pet name:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
			_petName = GUILayout.TextField(_petName, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			if (GUILayout.Button("Undo last spawn", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
			{
				SrvRpc("AP_SrvUndo");
				Message("Undo requested");
			}
			GUILayout.Label("Arena: A=" + (_arenaA ?? "?") + " vs B=" + (_arenaB ?? "?"), _labelStyle, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("FIGHT!", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }) && _arenaA != null && _arenaB != null)
			{
				Vector3 val = SpawnPos(8f);
				SendServerSpawn(1, _arenaA, val + Vector3.left * 6f, _arenaCountA, 1, tamed: false);
				SendServerSpawn(1, _arenaB, val + Vector3.right * 6f, _arenaCountB, 1, tamed: false);
				Message($"Arena: {_arenaCountA}x {_arenaA} vs {_arenaCountB}x {_arenaB}");
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Preset:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) });
			_presetName = GUILayout.TextField(_presetName, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			foreach (KeyValuePair<string, string> item in ParseKv(_spawnPresetsCfg.Value))
			{
				if (!GUILayout.Button(item.Key, _buttonStyle, Array.Empty<GUILayoutOption>()))
				{
					continue;
				}
				string[] array = item.Value.Split(new char[1] { ';' });
				for (int num4 = 0; num4 < array.Length; num4++)
				{
					string[] array2 = array[num4].Split(new char[1] { ':' });
					if (array2.Length >= 3 && int.TryParse(array2[1], out var result2) && int.TryParse(array2[2], out var result3))
					{
						SendServerSpawn(1, array2[0], SpawnPos(4f), result2, result3, tamed: false);
					}
				}
				Message("Preset '" + item.Key + "' spawned");
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
			float num5 = ListView(360f);
			if ((int)Event.current.type == 8 || _creWindowList == null)
			{
				_creWindowList = FilteredCreatures();
				_creWindowTotal = _creWindowList.Count;
				_creWindowFirst = Mathf.Clamp(Mathf.FloorToInt(_creatureScroll.y / 32f) - 1, 0, Mathf.Max(0, _creWindowTotal));
				_creWindowVisible = Mathf.Max(0, Mathf.Min(_creWindowTotal - _creWindowFirst, Mathf.CeilToInt(num5 / 32f) + 3));
			}
			List<CreatureEntry> creWindowList = _creWindowList;
			int creWindowTotal = _creWindowTotal;
			int creWindowFirst = _creWindowFirst;
			int creWindowVisible = _creWindowVisible;
			_creatureScroll = GUILayout.BeginScrollView(_creatureScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num5) });
			if (creWindowFirst > 0)
			{
				GUILayout.Space((float)creWindowFirst * 32f);
			}
			for (int num6 = creWindowFirst; num6 < creWindowFirst + creWindowVisible; num6++)
			{
				CreatureEntry creatureEntry = creWindowList[num6];
				GUILayout.BeginHorizontal((num6 % 2 == 0) ? _rowEven : _rowOdd, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
				GUILayout.Label(creatureEntry.Display, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
				GUILayout.Label(creatureEntry.Name + (creatureEntry.Boss ? "  [BOSS]" : "") + (creatureEntry.Tamable ? "  [tamable]" : ""), _dimLabelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.FlexibleSpace();
				if (GUILayout.Button("A", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) }))
				{
					_arenaA = creatureEntry.Name;
					_arenaCountA = Math.Max(1, _creatureCount);
				}
				if (GUILayout.Button("B", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) }))
				{
					_arenaB = creatureEntry.Name;
					_arenaCountB = Math.Max(1, _creatureCount);
				}
				if (GUILayout.Button("Save", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }) && !string.IsNullOrEmpty(_presetName))
				{
					string text = $"{creatureEntry.Name}:{Math.Max(1, _creatureCount)}:{_creatureLevel}";
					Dictionary<string, string> dictionary = ParseKv(_spawnPresetsCfg.Value);
					dictionary[_presetName] = ((dictionary.TryGetValue(_presetName, out var value) && !string.IsNullOrEmpty(value)) ? (value + ";" + text) : text);
					_spawnPresetsCfg.Value = JoinKv(dictionary);
					((BaseUnityPlugin)this).Config.Save();
					Message("Preset '" + _presetName + "' saved");
				}
				if (GUILayout.Button("Spawn", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
				{
					SendServerSpawn(1, creatureEntry.Name, SpawnPos(), Math.Max(1, _creatureCount), _creatureLevel, tamed: false);
					Message("Requested " + creatureEntry.Display);
				}
				if (creatureEntry.Tamable && GUILayout.Button("Tame", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }))
				{
					SendServerSpawn(1, creatureEntry.Name, SpawnPos(), Math.Max(1, _creatureCount), _creatureLevel, tamed: true, _petName);
					Message("Requested tamed " + creatureEntry.Display);
				}
				GUILayout.EndHorizontal();
			}
			int num7 = creWindowTotal - (creWindowFirst + creWindowVisible);
			if (num7 > 0)
			{
				GUILayout.Space((float)num7 * 32f);
			}
			GUILayout.EndScrollView();
			GUILayout.Label($"{creWindowTotal} creatures", _dimLabelStyle, Array.Empty<GUILayoutOption>());
		}

		private void DrawBossesTab()
		{
			//IL_0017: 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_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Bosses — spawn directly, or grab the altar offering items:", _headerStyle, Array.Empty<GUILayoutOption>());
			_bossScroll = GUILayout.BeginScrollView(_bossScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(Mathf.Min(ListView(140f), (float)BossList.Length * 28f + 8f)) });
			(string, string, string, int)[] bossList = BossList;
			for (int i = 0; i < bossList.Length; i++)
			{
				var (text, text2, text3, num) = bossList[i];
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(text2, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) });
				GUILayout.Label(text, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
				GUILayout.FlexibleSpace();
				if (GUILayout.Button($"Offering ({num}x {text3})", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }))
				{
					SendServerGive(SelfUid(), text3, num, 1);
					Message($"Requested {num}x {text3}");
				}
				if (GUILayout.Button("Spawn", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
				{
					SendServerSpawn(1, text, SpawnPos(6f), 1, 1, tamed: false);
					Message("Requested boss " + text2);
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.EndScrollView();
			GUILayout.Label("Raid events (started server-side at your position):", _headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			int num2 = 0;
			string[] raidEvents = RaidEvents;
			foreach (string text4 in raidEvents)
			{
				if (GUILayout.Button(text4, _buttonStyle, Array.Empty<GUILayoutOption>()))
				{
					SrvRpc("AP_SrvEvent", text4, ((Component)LocalPlayer).transform.position);
					Message("Event '" + text4 + "' requested");
				}
				if (++num2 % 5 == 0)
				{
					GUILayout.EndHorizontal();
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				}
			}
			GUILayout.EndHorizontal();
		}

		private void EnsureBaseStats()
		{
			if (!(_baseWalk >= 0f) && !((Object)(object)LocalPlayer == (Object)null))
			{
				_baseWalk = ((Character)LocalPlayer).m_walkSpeed;
				_baseRun = ((Character)LocalPlayer).m_runSpeed;
				_baseSwim = ((Character)LocalPlayer).m_swimSpeed;
				_baseJump = ((Character)LocalPlayer).m_jumpForce;
				_baseWeight = LocalPlayer.m_maxCarryWeight;
				_basePickup = LocalPlayer.m_autoPickupRange;
			}
		}

		private void DrawPlayerTab()
		{
			//IL_000e: 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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_080c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0824: Unknown result type (might be due to invalid IL or missing references)
			//IL_0829: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = LocalPlayer;
			EnsureBaseStats();
			_playerScroll = GUILayout.BeginScrollView(_playerScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(ListView(100f)) });
			GUILayout.Label("Toggles:", _headerStyle, Array.Empty<GUILayoutOption>());
			bool flag = GUILayout.Toggle(_god, " God mode (no damage)", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (flag != _god)
			{
				_god = flag;
				localPlayer.SetGodMode(_god);
				Message("God mode " + (_god ? "ON" : "OFF"));
			}
			bool flag2 = GUILayout.Toggle(_ghost, " Ghost mode (enemies ignore you)", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (flag2 != _ghost)
			{
				_ghost = flag2;
				localPlayer.SetGhostMode(_ghost);
				Message("Ghost mode " + (_ghost ? "ON" : "OFF"));
			}
			bool flag3 = GUILayout.Toggle(_fly, " Fly (debug fly)", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (flag3 != _fly)
			{
				_fly = flag3;
				Player.m_debugMode = true;
				localPlayer.ToggleDebugFly();
				Message("Fly " + (_fly ? "ON — jump to fly, sneak to descend" : "OFF"));
			}
			bool flag4 = GUILayout.Toggle(_noCost, " Free build (no resource cost)", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (flag4 != _noCost)
			{
				_noCost = flag4;
				localPlayer.SetNoPlacementCost(_noCost);
				Message("Free build " + (_noCost ? "ON" : "OFF"));
			}
			bool flag5 = GUILayout.Toggle(_noStamina, " No stamina drain", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (flag5 != _noStamina)
			{
				_noStamina = flag5;
				NoStaminaFlag = flag5;
				Message("No stamina drain " + (flag5 ? "ON" : "OFF"));
			}
			bool flag6 = GUILayout.Toggle(_oneHitKill, " One-hit kill (your attacks deal massive damage)", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (flag6 != _oneHitKill)
			{
				_oneHitKill = flag6;
				OneHitKillFlag = flag6;
				Message("One-hit kill " + (flag6 ? "ON" : "OFF"));
			}
			bool flag7 = GUILayout.Toggle(_infiniteWeight, " Infinite carry weight", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (flag7 != _infiniteWeight)
			{
				_infiniteWeight = flag7;
				localPlayer.m_maxCarryWeight = (flag7 ? 100000f : _baseWeight);
				Message("Infinite carry weight " + (flag7 ? "ON" : "OFF"));
			}
			GUILayout.Space(8f);
			GUILayout.Label("Multipliers:", _headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Speed x{_speedMult:0.0}", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
			float num = GUILayout.HorizontalSlider(_speedMult, 1f, 10f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) });
			if (Math.Abs(num - _speedMult) > 0.05f)
			{
				_speedMult = num;
				((Character)localPlayer).m_walkSpeed = _baseWalk * _speedMult;
				((Character)localPlayer).m_runSpeed = _baseRun * _speedMult;
				((Character)localPlayer).m_swimSpeed = _baseSwim * _speedMult;
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Jump x{_jumpMult:0.0}", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
			float num2 = GUILayout.HorizontalSlider(_jumpMult, 1f, 5f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) });
			if (Math.Abs(num2 - _jumpMult) > 0.05f)
			{
				_jumpMult = num2;
				((Character)localPlayer).m_jumpForce = _baseJump * _jumpMult;
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Pickup {_pickupRange:0}m", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
			float num3 = GUILayout.HorizontalSlider(_pickupRange, 2f, 30f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) });
			if (Math.Abs(num3 - _pickupRange) > 0.3f)
			{
				_pickupRange = num3;
				localPlayer.m_autoPickupRange = _pickupRange;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Full heal", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				((Character)localPlayer).Heal(((Character)localPlayer).GetMaxHealth(), true);
				Message("Healed");
			}
			if (GUILayout.Button("Full stamina", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				((Character)localPlayer).AddStamina(((Character)localPlayer).GetMaxStamina());
				Message("Stamina restored");
			}
			if (GUILayout.Button("Full eitr", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				((Character)localPlayer).AddEitr(((Character)localPlayer).GetMaxEitr());
				Message("Eitr restored");
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Repair all items", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems())
				{
					allItem.m_durability = allItem.GetMaxDurability();
				}
				Message("All items repaired");
			}
			if (GUILayout.Button("Clear status effects", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				((Character)localPlayer).GetSEMan().RemoveAllStatusEffects(false);
				Message("Status effects cleared");
			}
			if (GUILayout.Button("Fix broken inventory items", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				List<ItemData> list = (from i in ((Humanoid)localPlayer).GetInventory().GetAllItems()
					where i.m_shared.m_icons == null || i.m_shared.m_icons.Length == 0
					select i).ToList();
				foreach (ItemData item in list)
				{
					((Humanoid)localPlayer).GetInventory().RemoveItem(item);
				}
				Message($"Removed {list.Count} broken (icon-less) items from inventory");
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.Label("Skills:", _headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("All skills +10", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				ChangeSkills(10f);
			}
			if (GUILayout.Button("All skills 100", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				SetSkills(100f);
			}
			if (GUILayout.Button("Reset skills", _buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				SetSkills(0f);
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			_showStatusEffects = GUILayout.Toggle(_showStatusEffects, " Show status effect browser", _toggleStyle, Array.Empty<GUILayoutOption>());
			if (_showStatusEffects && (Object)(object)ObjectDB.instance != (Object)null)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Search:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
				_seSearch = GUILayout.TextField(_seSearch, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) });
				GUILayout.EndHorizontal();
				List<SeEntry> list2 = FilteredStatusEffects();
				_seScroll = GUILayout.BeginScrollView(_seScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(200f) });
				if (list2.Count == 0)
				{
					GUILayout.Label("No matching status effects.", _dimLabelStyle, Array.Empty<GUILayoutOption>());
				}
				else
				{
					int num4

BepInEx/plugins/AdminPanelCompanion.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("AdminPanelCompanion")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cce838eb8597c27a7129cf93456d314294a36c68")]
[assembly: AssemblyProduct("AdminPanelCompanion")]
[assembly: AssemblyTitle("AdminPanelCompanion")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AdminPanelCompanion
{
	[BepInPlugin("com.halitb.adminpanelcompanion", "AdminPanelCompanion", "2.1.1")]
	public class CompanionPlugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		private static class RpcRegistration
		{
			[HarmonyPatch(typeof(ZNet), "Awake")]
			[HarmonyPostfix]
			private static void ZNetAwakePostfix()
			{
				if (ZRoutedRpc.instance != null)
				{
					ZRoutedRpc.instance.Register<ZPackage>("AP_SrvGive", (Action<long, ZPackage>)OnServerGive);
					ZRoutedRpc.instance.Register<ZPackage>("AP_SrvSpawn", (Action<long, ZPackage>)OnServerSpawn);
					ZRoutedRpc.instance.Register<long>("AP_SrvReqInv", (Action<long, long>)OnServerRequestInventory);
					ZRoutedRpc.instance.Register("AP_SrvUndo", (Action<long>)OnServerUndo);
					ZRoutedRpc.instance.Register<ZPackage>("AP_SrvTeleport", (Action<long, ZPackage>)OnServerTeleport);
					ZRoutedRpc.instance.Register<long>("AP_SrvHeal", (Action<long, long>)OnServerHeal);
					ZRoutedRpc.instance.Register<long>("AP_SrvKick", (Action<long, long>)OnServerKick);
					ZRoutedRpc.instance.Register<long>("AP_SrvBan", (Action<long, long>)OnServerBan);
					ZRoutedRpc.instance.Register<string>("AP_SrvUnban", (Action<long, string>)OnServerUnban);
					ZRoutedRpc.instance.Register<string>("AP_SrvBroadcast", (Action<long, string>)OnServerBroadcast);
					ZRoutedRpc.instance.Register<long, string>("AP_SrvMsg", (Action<long, long, string>)OnServerMessage);
					ZRoutedRpc.instance.Register<string, Vector3>("AP_SrvEvent", (Action<long, string, Vector3>)OnServerEvent);
					ZRoutedRpc.instance.Register<bool>("AP_SrvPeaceful", (Action<long, bool>)OnServerPeaceful);
					ZRoutedRpc.instance.Register<string, int, int, string>("AP_GiveItem", (Method<string, int, int, string>)OnGiveItem);
					ZRoutedRpc.instance.Register<long>("AP_InvRequest", (Action<long, long>)OnInventoryRequest);
					ZRoutedRpc.instance.Register<Vector3>("AP_Teleport", (Action<long, Vector3>)OnTeleport);
					ZRoutedRpc.instance.Register("AP_HealSelf", (Action<long>)OnHealSelf);
					ZRoutedRpc.instance.Register<string>("AP_Msg", (Action<long, string>)OnMessage);
				}
			}
		}

		[HarmonyPatch(typeof(ZRoutedRpc), "RPC_RoutedRPC")]
		private static class RouteRpcSanitizer
		{
			private static void Prefix(ZRpc rpc, ZPackage pkg)
			{
				if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || pkg == null)
				{
					return;
				}
				long num = 0L;
				foreach (ZNetPeer peer in ZNet.instance.GetPeers())
				{
					if (peer != null && peer.m_rpc == rpc)
					{
						num = peer.m_uid;
						break;
					}
				}
				if (num == 0L)
				{
					return;
				}
				int pos = pkg.GetPos();
				try
				{
					pkg.SetPos(8);
					if (pkg.ReadLong() != num)
					{
						pkg.SetPos(8);
						pkg.Write(num);
					}
				}
				catch
				{
				}
				finally
				{
					pkg.SetPos(pos);
				}
			}
		}

		public const string PluginGuid = "com.halitb.adminpanelcompanion";

		public const string PluginName = "AdminPanelCompanion";

		public const string PluginVersion = "2.1.1";

		internal static CompanionPlugin Instance;

		private static readonly List<ZDOID> LastSpawnBatch = new List<ZDOID>();

		private static bool IsDedicatedServer
		{
			get
			{
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					return ZNet.instance.IsServer();
				}
				return false;
			}
		}

		private void Awake()
		{
			Instance = this;
			Harmony.CreateAndPatchAll(typeof(RpcRegistration), (string)null);
			try
			{
				Harmony.CreateAndPatchAll(typeof(RouteRpcSanitizer), (string)null);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("RoutedRPC sender-sanitizer patch failed (server security reduced): " + ex.Message));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"AdminPanelCompanion 2.1.1 loaded.");
		}

		private static void Log(string msg)
		{
			CompanionPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)msg);
			}
		}

		private static long ServerUid()
		{
			return (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null)?.m_uid ?? 0;
		}

		private static bool SenderIsServer(long sender)
		{
			return sender == ServerUid();
		}

		private static string BareId(string host)
		{
			if (string.IsNullOrEmpty(host) || !host.Contains("_"))
			{
				return host;
			}
			return host.Substring(host.IndexOf('_') + 1);
		}

		private static SyncedList GetList(string field)
		{
			object? obj = AccessTools.Field(typeof(ZNet), field)?.GetValue(ZNet.instance);
			return (SyncedList)((obj is SyncedList) ? obj : null);
		}

		private static bool SenderIsAdmin(long sender)
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			ZNetPeer peer = ZNet.instance.GetPeer(sender);
			string text = ((peer != null && peer.m_socket != null) ? peer.m_socket.GetHostName() : null);
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			SyncedList list = GetList("m_adminList");
			int num;
			if (list != null)
			{
				if (!list.Contains(text))
				{
					num = (list.Contains(BareId(text)) ? 1 : 0);
					if (num == 0)
					{
						goto IL_006b;
					}
				}
				else
				{
					num = 1;
				}
				goto IL_0081;
			}
			num = 0;
			goto IL_006b;
			IL_006b:
			Log($"DENIED admin action from non-admin {text} (peer {sender})");
			goto IL_0081;
			IL_0081:
			return (byte)num != 0;
		}

		private static void OnServerGive(long sender, ZPackage pkg)
		{
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				long num;
				string text;
				int num3;
				string text2;
				int num2;
				try
				{
					num = pkg.ReadLong();
					text = pkg.ReadString();
					num2 = pkg.ReadInt();
					num3 = pkg.ReadInt();
					text2 = pkg.ReadString();
				}
				catch (Exception ex)
				{
					Log("AP_SrvGive: malformed packet dropped (" + ex.Message + ")");
					return;
				}
				if (!string.IsNullOrEmpty(text) && num2 > 0)
				{
					num2 = Mathf.Min(num2, 100000);
					Log($"Admin {sender} gives {num2}x {text} (q{num3}) to peer {num}");
					ZRoutedRpc.instance.InvokeRoutedRPC(num, "AP_GiveItem", new object[4] { text, num2, num3, text2 });
				}
			}
		}

		private static void OnServerSpawn(long sender, ZPackage pkg)
		{
			//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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			if (!IsDedicatedServer || !SenderIsAdmin(sender))
			{
				return;
			}
			int num;
			string text;
			Vector3 val;
			int num3;
			bool flag;
			string text2;
			int num2;
			try
			{
				num = pkg.ReadInt();
				text = pkg.ReadString();
				val = pkg.ReadVector3();
				num2 = pkg.ReadInt();
				num3 = pkg.ReadInt();
				flag = pkg.ReadBool();
				text2 = pkg.ReadString();
			}
			catch (Exception ex)
			{
				Log("AP_SrvSpawn: malformed packet dropped (" + ex.Message + ")");
				return;
			}
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			num2 = Mathf.Clamp(num2, 0, 100);
			GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(text) : null);
			if ((Object)(object)val2 == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				val2 = ObjectDB.instance.GetItemPrefab(text);
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Log("AP_SrvSpawn: prefab '" + text + "' not found");
				return;
			}
			Log($"Admin {sender} spawns {num2}x {text} (kind {num}) at {val}");
			LastSpawnBatch.Clear();
			if (num == 0)
			{
				ItemDrop component = val2.GetComponent<ItemDrop>();
				int num4 = ((!((Object)(object)component != (Object)null)) ? 1 : component.m_itemData.m_shared.m_maxStackSize);
				if (num4 < 1)
				{
					num4 = 1;
				}
				int num5 = num2;
				while (num5 > 0)
				{
					int num6 = Mathf.Min(num5, num4);
					num5 -= num6;
					GameObject obj = Object.Instantiate<GameObject>(val2, val, Quaternion.identity);
					RememberSpawn(obj);
					ItemDrop component2 = obj.GetComponent<ItemDrop>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.m_itemData.m_stack = num6;
						component2.m_itemData.m_quality = Mathf.Clamp(num3, 1, component2.m_itemData.m_shared.m_maxQuality);
						component2.m_itemData.m_durability = component2.m_itemData.GetMaxDurability();
					}
				}
				return;
			}
			Vector3 val3 = default(Vector3);
			for (int i = 0; i < num2; i++)
			{
				((Vector3)(ref val3))..ctor(Random.Range(-1.5f, 1.5f), 0.5f, Random.Range(-1.5f, 1.5f));
				GameObject val4 = Object.Instantiate<GameObject>(val2, val + val3, Quaternion.identity);
				RememberSpawn(val4);
				Character component3 = val4.GetComponent<Character>();
				if (!((Object)(object)component3 != (Object)null))
				{
					continue;
				}
				if (num3 > 1)
				{
					component3.SetLevel(Mathf.Clamp(num3, 1, 10));
				}
				if (flag)
				{
					component3.SetTamed(true);
				}
				if (!flag || string.IsNullOrEmpty(text2))
				{
					continue;
				}
				ZNetView component4 = val4.GetComponent<ZNetView>();
				if (component4 != null)
				{
					ZDO zDO = component4.GetZDO();
					if (zDO != null)
					{
						zDO.Set("TamedName", text2);
					}
				}
			}
		}

		private static void RememberSpawn(GameObject go)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = go.GetComponent<ZNetView>();
			ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null);
			if (val != null)
			{
				LastSpawnBatch.Add(val.m_uid);
			}
		}

		private static void OnServerUndo(long sender)
		{
			//IL_0021: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!IsDedicatedServer || !SenderIsAdmin(sender))
			{
				return;
			}
			int num = 0;
			foreach (ZDOID item in LastSpawnBatch)
			{
				ZDO zDO = ZDOMan.instance.GetZDO(item);
				if (zDO != null)
				{
					ZNetView val = ZNetScene.instance.FindInstance(zDO);
					ZNetView val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<ZNetView>() : null);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.ClaimOwnership();
						val2.Destroy();
						num++;
					}
					else
					{
						ZDOMan.instance.DestroyZDO(zDO);
						num++;
					}
				}
			}
			Log($"Admin {sender} undo: removed {num} spawned objects");
			LastSpawnBatch.Clear();
		}

		private static void OnServerRequestInventory(long sender, long targetUid)
		{
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(targetUid, "AP_InvRequest", new object[1] { sender });
			}
		}

		private static void OnServerTeleport(long sender, ZPackage pkg)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				long num;
				Vector3 val;
				try
				{
					num = pkg.ReadLong();
					val = pkg.ReadVector3();
				}
				catch (Exception ex)
				{
					Log("AP_SrvTeleport: malformed packet dropped (" + ex.Message + ")");
					return;
				}
				Log($"Admin {sender} teleports peer {num} to {val}");
				ZRoutedRpc.instance.InvokeRoutedRPC(num, "AP_Teleport", new object[1] { val });
			}
		}

		private static void OnServerHeal(long sender, long targetUid)
		{
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(targetUid, "AP_HealSelf", Array.Empty<object>());
			}
		}

		private static string HostOfPeer(long uid)
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return null;
			}
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				if (peer.m_uid == uid)
				{
					return (peer.m_socket != null) ? peer.m_socket.GetHostName() : null;
				}
			}
			return null;
		}

		private static bool KickByUid(long uid)
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				if (peer.m_uid != uid)
				{
					continue;
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(ZNet), "InternalKick", new Type[1] { typeof(ZNetPeer) }, (Type[])null) ?? AccessTools.Method(typeof(ZNet), "Kick", new Type[1] { typeof(ZNetPeer) }, (Type[])null);
				if (methodInfo != null)
				{
					methodInfo.Invoke(ZNet.instance, new object[1] { peer });
				}
				else
				{
					ZRpc rpc = peer.m_rpc;
					if (rpc != null)
					{
						ISocket socket = rpc.GetSocket();
						if (socket != null)
						{
							socket.Close();
						}
					}
				}
				return true;
			}
			return false;
		}

		private static void OnServerKick(long sender, long uid)
		{
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				bool flag = KickByUid(uid);
				Log(string.Format("Admin {0} kick peer {1}: {2}", sender, uid, flag ? "kicked" : "peer not found"));
			}
		}

		private static void OnServerBan(long sender, long uid)
		{
			if (!IsDedicatedServer || !SenderIsAdmin(sender))
			{
				return;
			}
			string text = BareId(HostOfPeer(uid));
			if (!string.IsNullOrEmpty(text))
			{
				SyncedList list = GetList("m_bannedList");
				if (list != null && !list.Contains(text))
				{
					list.Add(text);
				}
			}
			bool flag = KickByUid(uid);
			Log(string.Format("Admin {0} ban peer {1} ({2}): {3}", sender, uid, text ?? "unknown", flag ? "kicked" : "peer not found"));
		}

		private static void OnServerUnban(long sender, string host)
		{
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				SyncedList list = GetList("m_bannedList");
				string text = BareId(host);
				if (list != null)
				{
					list.Remove(text);
					list.Remove(host);
				}
				Log($"Admin {sender} unbans {text}");
			}
		}

		private static void OnServerBroadcast(long sender, string text)
		{
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				Log("Admin broadcast: " + text);
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AP_Msg", new object[1] { text });
			}
		}

		private static void OnServerMessage(long sender, long targetUid, string text)
		{
			if (IsDedicatedServer && SenderIsAdmin(sender))
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(targetUid, "AP_Msg", new object[1] { text });
			}
		}

		private static void OnServerEvent(long sender, string eventName, Vector3 pos)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (IsDedicatedServer && SenderIsAdmin(sender) && !((Object)(object)RandEventSystem.instance == (Object)null))
			{
				Log($"Admin {sender} starts event '{eventName}' at {pos}");
				RandEventSystem.instance.SetRandomEventByName(eventName, pos);
			}
		}

		private static void OnServerPeaceful(long sender, bool peaceful)
		{
			if (!IsDedicatedServer || !SenderIsAdmin(sender))
			{
				return;
			}
			if (!((AccessTools.Field(typeof(RandEventSystem), "m_events") ?? AccessTools.Field(typeof(RandEventSystem), "m_randomEvents"))?.GetValue(RandEventSystem.instance) is IList list))
			{
				Log("Peaceful toggle: event list not found");
				return;
			}
			int num = 0;
			foreach (object item in list)
			{
				FieldInfo fieldInfo = AccessTools.Field(item.GetType(), "m_enabled");
				if (!(fieldInfo == null))
				{
					fieldInfo.SetValue(item, !peaceful);
					num++;
				}
			}
			if (peaceful && (Object)(object)RandEventSystem.instance != (Object)null)
			{
				RandEventSystem.instance.ResetRandomEvent();
			}
			Log(string.Format("Peaceful mode {0} ({1} events toggled)", peaceful ? "ON" : "OFF", num));
		}

		private static void OnGiveItem(long sender, string prefabName, int amount, int quality, string crafter)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !SenderIsServer(sender))
			{
				return;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefabName) : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || component.m_itemData.m_shared.m_icons == null || component.m_itemData.m_shared.m_icons.Length == 0)
			{
				return;
			}
			int num = component.m_itemData.m_shared.m_maxStackSize;
			if (num < 1)
			{
				num = 1;
			}
			int num2 = amount;
			while (num2 > 0)
			{
				int num3 = Mathf.Min(num2, num);
				num2 -= num3;
				ItemData val2 = component.m_itemData.Clone();
				val2.m_dropPrefab = val;
				val2.m_stack = num3;
				val2.m_quality = Mathf.Clamp(quality, 1, val2.m_shared.m_maxQuality);
				val2.m_durability = val2.GetMaxDurability();
				if (!string.IsNullOrEmpty(crafter))
				{
					val2.m_crafterID = 1L;
					val2.m_crafterName = crafter;
				}
				if (!((Humanoid)localPlayer).GetInventory().AddItem(val2))
				{
					ItemDrop component2 = Object.Instantiate<GameObject>(val, ((Component)localPlayer).transform.position + Vector3.up, Quaternion.identity).GetComponent<ItemDrop>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.m_itemData.m_stack = num3;
						component2.m_itemData.m_quality = Mathf.Clamp(quality, 1, component2.m_itemData.m_shared.m_maxQuality);
					}
				}
			}
			((Character)localPlayer).Message((MessageType)2, $"An admin granted you {amount}x {prefabName}!", 0, (Sprite)null);
		}

		private static void OnInventoryRequest(long sender, long replyTo)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !SenderIsServer(sender))
			{
				return;
			}
			ZPackage val = new ZPackage();
			val.Write(localPlayer.GetPlayerName());
			List<ItemData> allItems = ((Humanoid)localPlayer).GetInventory().GetAllItems();
			val.Write(allItems.Count);
			foreach (ItemData item in allItems)
			{
				val.Write(((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name);
				val.Write(item.m_stack);
				val.Write(item.m_quality);
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(replyTo, "AP_InvData", new object[1] { val });
		}

		private static void OnTeleport(long sender, Vector3 pos)
		{
			//IL_0019: 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)
			//IL_001f: 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)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && SenderIsServer(sender))
			{
				((Character)localPlayer).TeleportTo(pos + Vector3.up, ((Component)localPlayer).transform.rotation, true);
				((Character)localPlayer).Message((MessageType)2, "An admin teleported you!", 0, (Sprite)null);
			}
		}

		private static void OnHealSelf(long sender)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && SenderIsServer(sender))
			{
				((Character)localPlayer).Heal(((Character)localPlayer).GetMaxHealth(), true);
				((Character)localPlayer).Message((MessageType)2, "An admin healed you!", 0, (Sprite)null);
			}
		}

		private static void OnMessage(long sender, string text)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && SenderIsServer(sender))
			{
				((Character)localPlayer).Message((MessageType)2, "[Server] " + text, 0, (Sprite)null);
			}
		}
	}
}