Decompiled source of AuroraBlueprints v1.0.7

plugins/AuroraBlueprints.dll

Decompiled 16 minutes 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 System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("aurora")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Converts modded custom-category hammer pieces into tradeable blueprint consumables")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AuroraBlueprints")]
[assembly: AssemblyTitle("AuroraBlueprints")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 AuroraBlueprints
{
	[HarmonyPatch]
	public static class BlueprintDrops
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__9_0;

			internal void <AddCommands>b__9_0(ConsoleEventArgs args)
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					args.Context.AddString("No local player.");
					return;
				}
				if (BlueprintManager.Blueprints.Count == 0)
				{
					args.Context.AddString("No blueprints available. Has the scan run?");
					return;
				}
				SpawnRandomBlueprint(((Component)localPlayer).transform.position, "admin_command");
				args.Context.AddString("Random blueprint dropped.");
			}
		}

		private const string RPC_BlueprintAnnounce = "AuroraBlueprints_Announce";

		private static bool _rpcRegistered = false;

		private static readonly HashSet<string> BossPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
		{
			"Eikthyr", "gd_king", "Bonemass", "Dragon", "GoblinKing", "SeekerQueen", "Fader", "EikthyrSpirit_RtD", "TrollKing_RtD", "SwampBoss_RtD",
			"TheElder", "TheQueen"
		};

		public static void TryRegisterRPC()
		{
			if (!_rpcRegistered && ZRoutedRpc.instance != null)
			{
				_rpcRegistered = true;
				ZRoutedRpc.instance.Register<string>("AuroraBlueprints_Announce", (Action<long, string>)OnBlueprintAnnounce);
			}
		}

		private static void OnBlueprintAnnounce(long sender, string message)
		{
			MessageHud instance = MessageHud.instance;
			if (instance != null)
			{
				instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false);
			}
		}

		private static void BroadcastAnnouncement(string message)
		{
			TryRegisterRPC();
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null)
			{
				instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AuroraBlueprints_Announce", new object[1] { message });
			}
		}

		[HarmonyPatch(typeof(CharacterDrop), "OnDeath")]
		[HarmonyPostfix]
		public static void CharacterDrop_OnDeath(CharacterDrop __instance)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || BlueprintManager.Blueprints.Count == 0)
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null) && !component.IsPlayer())
			{
				string prefabName = GetPrefabName(((Component)__instance).gameObject);
				float num = ((BossPrefabs.Contains(prefabName) || ((Object)(object)component != (Object)null && component.IsBoss())) ? ((Plugin.BossDropChance?.Value ?? 10f) / 100f) : ((Plugin.MobDropChance?.Value ?? 1f) / 100f));
				if (!(Random.value > num))
				{
					SpawnRandomBlueprint(((Component)__instance).transform.position, prefabName);
				}
			}
		}

		public static void SpawnRandomBlueprint(Vector3 position, string sourceName = "admin")
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (BlueprintManager.Blueprints.Count == 0)
			{
				return;
			}
			List<string> list = new List<string>(BlueprintManager.Blueprints.Keys);
			string text = list[Random.Range(0, list.Count)];
			BlueprintInfo blueprintInfo = BlueprintManager.Blueprints[text];
			if ((Object)(object)blueprintInfo?.BlueprintPrefab == (Object)null)
			{
				return;
			}
			Vector3 val = position + Vector3.up * 0.75f;
			try
			{
				GameObject val2 = Object.Instantiate<GameObject>(blueprintInfo.BlueprintPrefab, val, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f));
				ItemDrop component = val2.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_itemData.m_stack = 1;
					component.m_itemData.m_dropPrefab = blueprintInfo.BlueprintPrefab;
				}
				val2.SetActive(true);
				string displayName = blueprintInfo.DisplayName;
				BroadcastAnnouncement("<color=#b5651d>A Blueprint: " + displayName + " has dropped!</color>");
				Plugin.Log.LogInfo((object)("BlueprintDrop: " + sourceName + " dropped " + text));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("BlueprintDrop: Failed to drop " + text + ": " + ex.Message));
			}
		}

		[HarmonyPatch(typeof(ZRoutedRpc), "SetUID")]
		[HarmonyPostfix]
		public static void ZRoutedRpc_SetUID()
		{
			TryRegisterRPC();
		}

		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		[HarmonyPostfix]
		public static void AddCommands()
		{
			//IL_0033: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			object obj = <>c.<>9__9_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					//IL_0051: Unknown result type (might be due to invalid IL or missing references)
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer == (Object)null)
					{
						args.Context.AddString("No local player.");
					}
					else if (BlueprintManager.Blueprints.Count == 0)
					{
						args.Context.AddString("No blueprints available. Has the scan run?");
					}
					else
					{
						SpawnRandomBlueprint(((Component)localPlayer).transform.position, "admin_command");
						args.Context.AddString("Random blueprint dropped.");
					}
				};
				<>c.<>9__9_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("droprandomabp", "Drop a random blueprint at your position", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		private static string GetPrefabName(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return "";
			}
			string text = ((Object)obj).name;
			int num = text.IndexOf("(Clone)");
			if (num > 0)
			{
				text = text.Substring(0, num);
			}
			return text.Trim();
		}
	}
	public class BlueprintInfo
	{
		public GameObject PiecePrefab;

		public string OriginalPieceName;

		public string DisplayName;

		public Requirement[] OriginalRequirements;

		public CraftingStation OriginalCraftingStation;

		public GameObject BlueprintPrefab;
	}
	public static class BlueprintManager
	{
		[CompilerGenerated]
		private sealed class <UnequipHammerDelayed>d__26 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Player player;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <UnequipHammerDelayed>d__26(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)player != (Object)null)
					{
						((Humanoid)player).HideHandItems(false, true);
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static readonly Dictionary<string, BlueprintInfo> Blueprints = new Dictionary<string, BlueprintInfo>();

		public static readonly Dictionary<string, string> SharedNameToBlueprint = new Dictionary<string, string>();

		private static GameObject _prefabRoot;

		private static bool _scanned = false;

		private static readonly HashSet<string> _vanillaPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly List<GameObject> _removedPieces = new List<GameObject>();

		public static BlueprintInfo ActiveBlueprint;

		public static ItemData ActiveBlueprintItem;

		public static List<GameObject> OriginalHammerPieces;

		public static bool HasActiveBlueprint => ActiveBlueprint != null;

		public static void CaptureVanillaPrefabs(ZNetScene zNetScene)
		{
			if (_vanillaPrefabs.Count > 0)
			{
				return;
			}
			foreach (GameObject prefab in zNetScene.m_prefabs)
			{
				if ((Object)(object)prefab != (Object)null)
				{
					_vanillaPrefabs.Add(((Object)prefab).name);
				}
			}
			Plugin.Log.LogInfo((object)$"[VanillaCapture] Captured {_vanillaPrefabs.Count} vanilla prefab names.");
		}

		public static void ScanAndCreateBlueprints()
		{
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Invalid comparison between Unknown and I4
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected I4, but got Unknown
			if (_scanned || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer");
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return;
			}
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component?.m_itemData?.m_shared?.m_buildPieces == (Object)null)
			{
				return;
			}
			PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces;
			HashSet<string> hashSet = BuildExcludeSet();
			List<GameObject> list = new List<GameObject>();
			foreach (GameObject piece in buildPieces.m_pieces)
			{
				if ((Object)(object)piece == (Object)null)
				{
					continue;
				}
				Piece component2 = piece.GetComponent<Piece>();
				if ((Object)(object)component2 == (Object)null || hashSet.Contains(((Object)piece).name))
				{
					continue;
				}
				string name = Enum.GetName(typeof(PieceCategory), component2.m_category);
				int num = (int)component2.m_category;
				if (name == "Crafting" || num == 1)
				{
					continue;
				}
				bool flag;
				if (_vanillaPrefabs.Count > 0)
				{
					flag = _vanillaPrefabs.Contains(((Object)piece).name);
				}
				else
				{
					int num2;
					switch (name)
					{
					default:
						num2 = ((name == "Max") ? 1 : 0);
						break;
					case "Misc":
					case "Crafting":
					case "BuildingWorkbench":
					case "BuildingStonecutter":
					case "Furniture":
					case "All":
					case "ComfortGroup":
						num2 = 1;
						break;
					case null:
						num2 = 0;
						break;
					}
					bool flag2 = (byte)num2 != 0;
					flag = flag2;
				}
				if (flag || string.IsNullOrEmpty(component2.m_name))
				{
					continue;
				}
				string text = component2.m_name.ToLowerInvariant();
				string text2 = ((Object)piece).name.ToLowerInvariant();
				if (text.Contains("repair") || text2.Contains("repair") || text.Contains("upgrade") || text2.Contains("upgrade"))
				{
					continue;
				}
				StationExtension component3 = piece.GetComponent<StationExtension>();
				if ((Object)(object)component3 != (Object)null)
				{
					continue;
				}
				Collider[] componentsInChildren = piece.GetComponentsInChildren<Collider>(true);
				if (componentsInChildren != null && componentsInChildren.Length != 0)
				{
					string text3 = "ABP_" + ((Object)piece).name;
					if (!Blueprints.ContainsKey(text3))
					{
						BlueprintInfo obj = new BlueprintInfo
						{
							PiecePrefab = piece,
							OriginalPieceName = ((Object)piece).name
						};
						Localization instance = Localization.instance;
						obj.DisplayName = ((instance != null) ? instance.Localize(component2.m_name) : null) ?? component2.m_name;
						obj.OriginalRequirements = component2.m_resources;
						obj.OriginalCraftingStation = component2.m_craftingStation;
						BlueprintInfo blueprintInfo = obj;
						Plugin.Log.LogInfo((object)("[SCAN] Blueprinting: " + ((Object)piece).name + " (category=" + (name ?? ("custom_" + num)) + ", display=" + blueprintInfo.DisplayName + ")"));
						CreateBlueprintItem(blueprintInfo, text3, itemPrefab);
						list.Add(piece);
					}
				}
			}
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				foreach (GameObject item in list)
				{
					buildPieces.m_pieces.Remove(item);
					_removedPieces.Add(item);
				}
			}
			_scanned = true;
			if (Blueprints.Count > 0)
			{
				Plugin.Log.LogInfo((object)$"Created {Blueprints.Count} blueprints from custom-category pieces.");
				RegisterAll();
			}
			else
			{
				Plugin.Log.LogInfo((object)"No custom-category pieces found in hammer.");
			}
		}

		private static HashSet<string> BuildExcludeSet()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string text = Plugin.ExcludePrefabs?.Value ?? "";
			string[] array = text.Split(new char[1] { ',' });
			foreach (string text2 in array)
			{
				string text3 = text2.Trim();
				if (text3.Length > 0)
				{
					hashSet.Add(text3);
				}
			}
			return hashSet;
		}

		private static void CreateBlueprintItem(BlueprintInfo info, string bpName, GameObject hammerPrefab)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00d1: 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_0128: Invalid comparison between Unknown and I4
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_prefabRoot == (Object)null)
			{
				_prefabRoot = new GameObject("AuroraBlueprintPrefabs");
				_prefabRoot.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_prefabRoot);
			}
			try
			{
				GameObject val = Object.Instantiate<GameObject>(hammerPrefab, _prefabRoot.transform);
				((Object)val).name = bpName;
				ItemDrop component = val.GetComponent<ItemDrop>();
				if (component?.m_itemData?.m_shared == null)
				{
					Plugin.Log.LogWarning((object)("Failed to configure blueprint " + bpName + " - no ItemDrop.shared"));
					return;
				}
				SharedData shared = component.m_itemData.m_shared;
				shared.m_name = "$" + bpName;
				shared.m_description = "$" + bpName + "_desc";
				shared.m_itemType = (ItemType)2;
				shared.m_maxStackSize = 50;
				shared.m_weight = 0.1f;
				shared.m_teleportable = true;
				shared.m_maxQuality = 1;
				shared.m_questItem = false;
				shared.m_buildPieces = null;
				shared.m_useDurability = false;
				shared.m_maxDurability = 0f;
				shared.m_durabilityPerLevel = 0f;
				bool flag = (int)SystemInfo.graphicsDeviceType == 4;
				Piece component2 = info.PiecePrefab.GetComponent<Piece>();
				if (!flag && (Object)(object)component2 != (Object)null && (Object)(object)component2.m_icon != (Object)null)
				{
					Sprite val2 = CreateBorderedIcon(component2.m_icon);
					shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 ?? component2.m_icon };
				}
				shared.m_attack = new Attack();
				shared.m_secondaryAttack = new Attack();
				shared.m_animationState = (AnimationState)0;
				component.m_itemData.m_dropPrefab = val;
				info.BlueprintPrefab = val;
				Blueprints[bpName] = info;
				SharedNameToBlueprint["$" + bpName] = bpName;
				Plugin.Log.LogInfo((object)("Blueprint created: " + bpName + " -> " + info.DisplayName));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Failed to create blueprint " + bpName + ": " + ex.Message));
			}
		}

		public static void RegisterAll()
		{
			RegisterInObjectDB(ObjectDB.instance);
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				RegisterInZNetScene(ZNetScene.instance);
			}
			RegisterLocalization();
		}

		public static void RegisterInObjectDB(ObjectDB objectDB)
		{
			if (objectDB?.m_items == null)
			{
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints)
			{
				GameObject prefab = blueprint.Value.BlueprintPrefab;
				if (!((Object)(object)prefab == (Object)null) && !objectDB.m_items.Exists((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)prefab).name))
				{
					objectDB.m_items.Add(prefab);
				}
			}
			string[] array = new string[2] { "m_itemByHash", "m_itemsByHash" };
			foreach (string name in array)
			{
				FieldInfo field = typeof(ObjectDB).GetField(name, bindingAttr);
				if (field == null || !(field.GetValue(objectDB) is Dictionary<int, GameObject> dictionary))
				{
					continue;
				}
				{
					foreach (KeyValuePair<string, BlueprintInfo> blueprint2 in Blueprints)
					{
						if ((Object)(object)blueprint2.Value.BlueprintPrefab != (Object)null)
						{
							dictionary[StringExtensionMethods.GetStableHashCode(((Object)blueprint2.Value.BlueprintPrefab).name)] = blueprint2.Value.BlueprintPrefab;
						}
					}
					break;
				}
			}
		}

		public static void RegisterInZNetScene(ZNetScene zNetScene)
		{
			if ((Object)(object)zNetScene == (Object)null)
			{
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			Dictionary<int, GameObject> dictionary = null;
			string[] array = new string[2] { "m_namedPrefabs", "m_prefabsByHash" };
			foreach (string name in array)
			{
				FieldInfo field = typeof(ZNetScene).GetField(name, bindingAttr);
				if (!(field == null))
				{
					dictionary = field.GetValue(zNetScene) as Dictionary<int, GameObject>;
					if (dictionary != null)
					{
						break;
					}
				}
			}
			if (dictionary == null)
			{
				return;
			}
			foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints)
			{
				GameObject blueprintPrefab = blueprint.Value.BlueprintPrefab;
				if (!((Object)(object)blueprintPrefab == (Object)null))
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)blueprintPrefab).name);
					if (!dictionary.ContainsKey(stableHashCode))
					{
						dictionary[stableHashCode] = blueprintPrefab;
					}
				}
			}
		}

		public static void RegisterLocalization()
		{
			Localization instance = Localization.instance;
			if (instance == null)
			{
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			Dictionary<string, string> dictionary = null;
			string[] array = new string[2] { "m_translations", "m_words" };
			foreach (string name in array)
			{
				FieldInfo field = typeof(Localization).GetField(name, bindingAttr);
				if (!(field == null))
				{
					dictionary = field.GetValue(instance) as Dictionary<string, string>;
					if (dictionary != null)
					{
						break;
					}
				}
			}
			if (dictionary == null)
			{
				return;
			}
			foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints)
			{
				string key = blueprint.Key;
				string displayName = blueprint.Value.DisplayName;
				dictionary[key] = "<color=#b5651d>Blueprint: " + displayName + "</color>";
				dictionary[key + "_desc"] = "Use to place a " + displayName + ".\nNo materials required. One-time use.\nBlueprint is consumed after successful placement.";
			}
		}

		public static void FixDropPrefab(ItemData item)
		{
			if (item != null && !((Object)(object)item.m_dropPrefab != (Object)null))
			{
				string text = item.m_shared?.m_name ?? "";
				if (text.StartsWith("$ABP_") && SharedNameToBlueprint.TryGetValue(text, out var value) && Blueprints.TryGetValue(value, out var value2) && (Object)(object)value2.BlueprintPrefab != (Object)null)
				{
					item.m_dropPrefab = value2.BlueprintPrefab;
				}
			}
		}

		public static bool StartPlacement(Player player, ItemData blueprintItem)
		{
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			string key = blueprintItem.m_shared?.m_name ?? "";
			if (!SharedNameToBlueprint.TryGetValue(key, out var value))
			{
				return false;
			}
			if (!Blueprints.TryGetValue(value, out var value2))
			{
				return false;
			}
			if ((Object)(object)value2.PiecePrefab == (Object)null)
			{
				return false;
			}
			ActiveBlueprint = value2;
			ActiveBlueprintItem = blueprintItem;
			ObjectDB instance = ObjectDB.instance;
			GameObject val = ((instance != null) ? instance.GetItemPrefab("Hammer") : null);
			if ((Object)(object)val == (Object)null)
			{
				ClearState();
				return false;
			}
			PieceTable val2 = val.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces;
			if ((Object)(object)val2 == (Object)null)
			{
				ClearState();
				return false;
			}
			OriginalHammerPieces = new List<GameObject>(val2.m_pieces);
			Piece component = value2.PiecePrefab.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_resources = (Requirement[])(object)new Requirement[0];
				component.m_craftingStation = null;
			}
			val2.m_pieces.Clear();
			val2.m_pieces.Add(value2.PiecePrefab);
			if ((Object)(object)component != (Object)null)
			{
				component.m_category = (PieceCategory)0;
			}
			ItemData val3 = FindHammerInInventory(player);
			if (val3 != null)
			{
				((Humanoid)player).EquipItem(val3, true);
				player.SetSelectedPiece(new Vector2Int(0, 0));
				return true;
			}
			Plugin.Log.LogWarning((object)"Player has no hammer in inventory! Cannot place blueprint.");
			ClearState();
			return false;
		}

		public static void OnPlacementSuccess(Player player)
		{
			if (!HasActiveBlueprint)
			{
				return;
			}
			if (ActiveBlueprintItem != null)
			{
				Inventory inventory = ((Humanoid)player).GetInventory();
				if (inventory != null)
				{
					if (ActiveBlueprintItem.m_stack > 1)
					{
						ItemData activeBlueprintItem = ActiveBlueprintItem;
						activeBlueprintItem.m_stack--;
					}
					else
					{
						inventory.RemoveItem(ActiveBlueprintItem);
					}
				}
			}
			RestoreAndClear();
			((MonoBehaviour)player).StartCoroutine(UnequipHammerDelayed(player));
		}

		public static void OnPlacementCancelled()
		{
			if (HasActiveBlueprint)
			{
				RestoreAndClear();
			}
		}

		private static void RestoreAndClear()
		{
			if (ActiveBlueprint != null)
			{
				GameObject piecePrefab = ActiveBlueprint.PiecePrefab;
				Piece val = ((piecePrefab != null) ? piecePrefab.GetComponent<Piece>() : null);
				if ((Object)(object)val != (Object)null)
				{
					val.m_resources = ActiveBlueprint.OriginalRequirements;
					val.m_craftingStation = ActiveBlueprint.OriginalCraftingStation;
				}
			}
			if (OriginalHammerPieces != null)
			{
				ObjectDB instance = ObjectDB.instance;
				GameObject val2 = ((instance != null) ? instance.GetItemPrefab("Hammer") : null);
				if ((Object)(object)val2 != (Object)null)
				{
					PieceTable val3 = val2.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces;
					if ((Object)(object)val3 != (Object)null)
					{
						val3.m_pieces.Clear();
						val3.m_pieces.AddRange(OriginalHammerPieces);
					}
				}
			}
			ClearState();
		}

		private static void ClearState()
		{
			ActiveBlueprint = null;
			ActiveBlueprintItem = null;
			OriginalHammerPieces = null;
		}

		private static ItemData FindHammerInInventory(Player player)
		{
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return null;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "Hammer")
				{
					return allItem;
				}
				if (allItem.m_shared?.m_name == "$item_hammer")
				{
					return allItem;
				}
			}
			return null;
		}

		[IteratorStateMachine(typeof(<UnequipHammerDelayed>d__26))]
		private static IEnumerator UnequipHammerDelayed(Player player)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <UnequipHammerDelayed>d__26(0)
			{
				player = player
			};
		}

		private static Sprite CreateBorderedIcon(Sprite original)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)original == (Object)null || (Object)(object)original.texture == (Object)null)
			{
				return null;
			}
			try
			{
				Texture2D texture = original.texture;
				Rect rect = original.rect;
				int num = (int)((Rect)(ref rect)).width;
				rect = original.rect;
				int num2 = (int)((Rect)(ref rect)).height;
				rect = original.rect;
				int num3 = (int)((Rect)(ref rect)).x;
				rect = original.rect;
				int num4 = (int)((Rect)(ref rect)).y;
				RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0);
				Graphics.Blit((Texture)(object)texture, temporary);
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(num, num2, (TextureFormat)5, false)
				{
					filterMode = (FilterMode)1,
					hideFlags = (HideFlags)61
				};
				val.ReadPixels(new Rect((float)num3, (float)num4, (float)num, (float)num2), 0, 0);
				val.Apply();
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				Color val2 = default(Color);
				((Color)(ref val2))..ctor(0.55f, 0.35f, 0.15f, 1f);
				int num5 = 3;
				for (int i = 0; i < num; i++)
				{
					for (int j = 0; j < num2; j++)
					{
						if (i < num5 || i >= num - num5 || j < num5 || j >= num2 - num5)
						{
							val.SetPixel(i, j, val2);
						}
					}
				}
				val.Apply();
				return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Failed to create bordered icon: " + ex.Message));
				return null;
			}
		}
	}
	[HarmonyPatch]
	public static class BlueprintPatches
	{
		private static bool _hasScanned;

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		[HarmonyPrefix]
		public static void ZNetScene_Awake_Prefix(ZNetScene __instance)
		{
			if (__instance?.m_prefabs != null)
			{
				BlueprintManager.CaptureVanillaPrefabs(__instance);
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		[HarmonyPostfix]
		public static void ObjectDB_Awake(ObjectDB __instance)
		{
			if (BlueprintManager.Blueprints.Count > 0)
			{
				BlueprintManager.RegisterInObjectDB(__instance);
				BlueprintManager.RegisterLocalization();
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		[HarmonyPostfix]
		public static void ObjectDB_CopyOtherDB(ObjectDB __instance)
		{
			if (BlueprintManager.Blueprints.Count > 0)
			{
				BlueprintManager.RegisterInObjectDB(__instance);
				BlueprintManager.RegisterLocalization();
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		[HarmonyPostfix]
		public static void ZNetScene_Awake(ZNetScene __instance)
		{
			if (BlueprintManager.Blueprints.Count > 0)
			{
				BlueprintManager.RegisterInZNetScene(__instance);
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		[HarmonyPostfix]
		public static void Player_OnSpawned(Player __instance)
		{
			if (!_hasScanned)
			{
				_hasScanned = true;
				BlueprintManager.ScanAndCreateBlueprints();
			}
			if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer))
			{
				return;
			}
			Inventory inventory = ((Humanoid)__instance).GetInventory();
			if (inventory == null)
			{
				return;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				BlueprintManager.FixDropPrefab(allItem);
			}
		}

		[HarmonyPatch(typeof(Inventory), "Load")]
		[HarmonyPostfix]
		public static void Inventory_Load(Inventory __instance)
		{
			foreach (ItemData allItem in __instance.GetAllItems())
			{
				BlueprintManager.FixDropPrefab(allItem);
			}
		}

		[HarmonyPatch(typeof(Humanoid), "DropItem")]
		[HarmonyPrefix]
		public static void DropItem_Fix(ItemData item)
		{
			BlueprintManager.FixDropPrefab(item);
		}

		[HarmonyPatch(typeof(Player), "AutoPickup")]
		[HarmonyPrefix]
		public static void AutoPickup_Fix(Player __instance)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, __instance.m_autoPickupRange, LayerMask.GetMask(new string[1] { "item" }));
				Collider[] array2 = array;
				foreach (Collider val in array2)
				{
					if (!((Object)(object)val == (Object)null))
					{
						ItemDrop componentInParent = ((Component)val).GetComponentInParent<ItemDrop>();
						if (componentInParent?.m_itemData != null)
						{
							BlueprintManager.FixDropPrefab(componentInParent.m_itemData);
						}
					}
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(Player), "ConsumeItem")]
		[HarmonyPrefix]
		public static bool ConsumeItem_Prefix(Player __instance, ItemData item, ref bool __result)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (item?.m_shared == null)
			{
				return true;
			}
			string text = item.m_shared.m_name ?? "";
			if (!text.StartsWith("$ABP_"))
			{
				return true;
			}
			__result = true;
			if (!BlueprintManager.StartPlacement(__instance, item))
			{
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)2, "<color=#ff4444>Cannot use blueprint — need a Hammer in inventory!</color>", 0, (Sprite)null, false);
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		[HarmonyPostfix]
		public static void PlacePiece_Postfix(Player __instance, Piece piece)
		{
			if (BlueprintManager.HasActiveBlueprint && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				BlueprintManager.OnPlacementSuccess(__instance);
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)1, "<color=#b5651d>Blueprint used!</color>", 0, (Sprite)null, false);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetPlaceMode")]
		[HarmonyPostfix]
		public static void SetPlaceMode_Postfix(Player __instance, PieceTable buildPieces)
		{
			if (!((Object)(object)buildPieces != (Object)null) && BlueprintManager.HasActiveBlueprint)
			{
				BlueprintManager.OnPlacementCancelled();
			}
		}

		[HarmonyPatch(typeof(Player), "Update")]
		[HarmonyPostfix]
		public static void Player_Update_Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && BlueprintManager.HasActiveBlueprint)
			{
				ItemData val = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem").Invoke((Humanoid)(object)__instance);
				if (val == null || (!(val.m_shared?.m_name == "$item_hammer") && (!((Object)(object)val.m_dropPrefab != (Object)null) || !(((Object)val.m_dropPrefab).name == "Hammer"))))
				{
					BlueprintManager.OnPlacementCancelled();
				}
			}
		}

		[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
		{
			typeof(Piece),
			typeof(RequirementMode)
		})]
		[HarmonyPrefix]
		public static bool HaveRequirements_Prefix(ref bool __result)
		{
			if (!BlueprintManager.HasActiveBlueprint)
			{
				return true;
			}
			__result = true;
			return false;
		}

		[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
		[HarmonyPrefix]
		public static bool CheckCanRemovePiece_Prefix()
		{
			return true;
		}
	}
	[BepInPlugin("aurora.blueprints", "Aurora Blueprints", "1.0.0")]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "aurora.blueprints";

		public const string PluginName = "Aurora Blueprints";

		public const string PluginVersion = "1.0.0";

		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<float> MobDropChance;

		public static ConfigEntry<float> BossDropChance;

		public static ConfigEntry<string> ExcludePrefabs;

		private static readonly string[] _unused = new string[52]
		{
			"piece_repair", "wood_stack", "wood_fine_stack", "wood_core_stack", "wood_yggdrasil_stack", "blackwood_stack", "stone_pile", "coal_pile", "blackmarble_pile", "grausten_pile",
			"skull_pile", "bone_stack", "fire_pit", "fire_pit_iron", "bonfire", "hearth", "portal_wood", "portal_stone", "guard_stone", "Cart",
			"Raft", "Karve", "VikingShip", "VikingShip_Ashlands", "BatteringRam", "Catapult", "piece_shieldgenerator", "piece_ArcheryTarget", "piece_TrainingDummy", "Placeable_HardRock",
			"piece_asksvinskeleton", "piece_beehive", "piece_sapcollector", "incinerator", "piece_wisplure", "piece_cartographytable", "piece_bathtub", "piece_barber", "fermenter", "piece_turret",
			"piece_trap_troll", "piece_gift1", "piece_gift2", "piece_gift3", "piece_xmastree", "piece_xmasgarland", "piece_xmascrown", "piece_mistletoe", "piece_jackoturnip", "piece_maypole",
			"piece_CelebrationGarland", "piece_FairylightGarland"
		};

		public static readonly string[] DefaultVanillaBuilding = new string[154]
		{
			"wood_wall_quarter", "wood_wall_half", "woodwall", "wood_wall_roof", "wood_wall_roof_upsidedown", "wood_wall_roof_top", "wood_wall_roof_45", "wood_wall_roof_45_upsidedown", "wood_wall_roof_top_45", "wood_window",
			"wood_floor_1x1", "wood_floor", "wood_stair", "wood_stepladder", "wood_roof", "wood_roof_top", "wood_roof_ocorner", "wood_roof_icorner", "wood_roof_45", "wood_roof_top_45",
			"wood_roof_ocorner_45", "wood_roof_icorner_45", "wood_pole", "wood_pole2", "wood_beam_1", "wood_beam", "wood_beam_26", "wood_beam_45", "wood_door", "wood_gate",
			"wood_dragon1", "wood_fence", "stake_wall", "piece_sharpstakes", "wood_pole_log", "wood_pole_log_4", "wood_wall_log", "wood_wall_log_4x0.5", "wood_log_26", "wood_log_45",
			"darkwood_roof", "darkwood_roof_top", "darkwood_roof_ocorner", "darkwood_roof_icorner", "darkwood_roof_45", "darkwood_roof_top_45", "darkwood_roof_ocorner_45", "darkwood_roof_icorner_45", "darkwood_pole", "darkwood_pole4",
			"darkwood_beam", "darkwood_beam_26", "darkwood_beam_45", "darkwood_beam4x4", "darkwood_gate", "darkwood_decowall", "darkwood_arch", "darkwood_raven", "darkwood_wolf", "piece_dvergr_stake_wall",
			"piece_dvergr_sharpstakes", "piece_dvergr_spiralstair", "piece_dvergr_spiralstair_right", "piece_hexagonal_door", "iron_floor_1x1_v2", "iron_floor_2x2", "iron_wall_1x1", "iron_wall_2x2", "piece_dvergr_metal_wall_2x2", "woodiron_pole",
			"woodiron_beam", "woodiron_beam_26", "woodiron_beam_45", "iron_grate", "crystal_wall_1x1", "ashwood_wall_2x2", "ashwood_halfwall_1x2", "ashwood_quarterwall_1x1", "ashwood_wall_arch", "ashwood_decowall_2x2",
			"ashwood_decowall_tree", "ashwood_decowall_divider", "ashwood_floor_2x2", "ashwood_floor_1x1", "ashwood_deco_floor", "ashwood_arch_big", "ashwood_beam_1m", "ashwood_beam_2m", "ashwood_pole_1m", "ashwood_pole_2m",
			"ashwood_wall_beam_26", "ashwood_wall_cross_26", "ashwood_wall_beam_45", "ashwood_wall_cross_45", "ashwood_wall_roof_26", "ashwood_wall_roof_26_upsidedown", "ashwood_wall_roof_45", "ashwood_wall_roof_45_upsidedown", "ashwood_stair", "ashwood_door",
			"piece_stakewall_blackwood", "stone_wall_1x1", "stone_wall_2x1", "stone_wall_4x2", "stone_pillar", "stone_arch", "stone_floor_2x2", "stone_stair", "blackmarble_1x1", "blackmarble_2x1x1",
			"blackmarble_2x2x2", "blackmarble_floor", "blackmarble_floor_triangle", "blackmarble_stair", "blackmarble_tip", "blackmarble_base_1", "blackmarble_basecorner", "blackmarble_out_1", "blackmarble_outcorner", "blackmarble_arch",
			"blackmarble_column_1", "blackmarble_column_2", "Piece_grausten_stone_ladder", "piece_grausten_stonestair", "Piece_grausten_floor_1x1", "Piece_grausten_floor_2x2", "Piece_grausten_floor_4x4", "Piece_grausten_pillarbase_small", "Piece_grausten_pillarbase_medium", "Piece_grausten_pillarbase_tapered",
			"Piece_grausten_pillarbase_tapered_inverted", "Piece_grausten_pillarbeam_small", "Piece_grausten_pillarbeam_medium", "Piece_grausten_pillar_arch_small", "Piece_grausten_pillar_arch", "Piece_grausten_wall_arch", "Piece_grausten_wall_arch_inverted", "Piece_grausten_wall_1x2", "Piece_grausten_wall_2x2", "Piece_grausten_wall_4x2",
			"Piece_grausten_window_2x2", "Piece_grausten_window_4x2", "piece_grausten_roof_45", "piece_grausten_roof_45_corner", "piece_grausten_roof_45_corner2", "piece_grausten_roof_45_arch", "piece_grausten_roof_45_arch_corner", "piece_grausten_roof_45_arch_corner2", "flametal_gate", "Piece_flametal_pillar",
			"Piece_flametal_beam", "raise", "paved_road", "mud_road"
		};

		public static readonly string[] DefaultVanillaFurniture = new string[69]
		{
			"bed", "piece_bed02", "ashwood_bed", "piece_chest_wood", "piece_chest", "piece_chest_private", "piece_chest_blackmetal", "piece_chest_barrel", "piece_chest_treasure", "treasure_pile",
			"treasure_stack", "piece_chair", "piece_chair02", "piece_chair03", "piece_bench01", "piece_logbench01", "piece_blackmarble_bench", "piece_blackwood_bench01", "piece_throne01", "piece_throne02",
			"piece_blackmarble_throne", "piece_bone_throne", "piece_table", "piece_table_round", "piece_table_oak", "piece_blackmarble_table", "piece_walltorch", "piece_groundtorch", "piece_groundtorch_wood", "piece_groundtorch_green",
			"piece_groundtorch_blue", "piece_groundtorch_mist", "piece_brazierfloor01", "piece_brazierfloor02", "piece_brazierceiling01", "Candle_resin", "piece_Lavalantern", "piece_dvergr_lantern", "piece_dvergr_lantern_pole", "itemstand",
			"itemstandh", "ArmorStand", "sign", "rug_Bjorn", "rug_wolf", "rug_deer", "rug_fur", "rug_hare", "rug_asksvin", "rug_straw",
			"jute_carpet", "jute_carpet_blue", "piece_banner01", "piece_banner02", "piece_banner03", "piece_banner04", "piece_banner05", "piece_banner06", "piece_banner07", "piece_banner08",
			"piece_banner09", "piece_banner10", "piece_banner11", "piece_cloth_hanging_door", "piece_cloth_hanging_door_blue", "piece_cloth_hanging_door_blue2", "piece_pot1", "piece_pot2", "piece_pot3"
		};

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			if (ServerGuard.Init(this))
			{
				Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for the mod.");
				ExcludePrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ExcludePrefabs", "piece_aurora_sacrificial_altar", "Comma-separated prefab names that should NEVER be converted to blueprints, even if modded.");
				MobDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("Drops", "MobDropChance", 1f, "Percent chance (0-100) for a regular monster to drop a random blueprint on death.");
				BossDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("Drops", "BossDropChance", 10f, "Percent chance (0-100) for a boss to drop a random blueprint on death.");
				if (!Enabled.Value)
				{
					Log.LogInfo((object)"AuroraBlueprints disabled via config.");
					return;
				}
				_harmony = new Harmony("aurora.blueprints");
				_harmony.PatchAll(typeof(Plugin).Assembly);
				Log.LogInfo((object)"Aurora Blueprints v1.0.0 loaded.");
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class ServerGuard
	{
		private const string PasswordHash = "e7aab22a4200ed38c615552e666633ba96140d314df8e1c00d08b886527a1dd4";

		private const string ConfigSection = "Protection";

		private const string ConfigKey = "password";

		private static ConfigEntry<string> _cfgPassword;

		public static bool Init(Plugin plugin)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			_cfgPassword = ((BaseUnityPlugin)plugin).Config.Bind<string>("Protection", "password", "enter_password_here", "Server password required to run Aurora Blueprints on a dedicated server. Leave as-is on game clients — this check is ignored there.");
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				Plugin.Log.LogInfo((object)"[ServerGuard] Running on client - auth skipped");
				return true;
			}
			string input = _cfgPassword.Value?.Trim() ?? string.Empty;
			if (HashPassword(input) == "e7aab22a4200ed38c615552e666633ba96140d314df8e1c00d08b886527a1dd4")
			{
				Plugin.Log.LogInfo((object)"[ServerGuard] Server auth OK.");
				return true;
			}
			Plugin.Log.LogError((object)"══════════════════════════════════════════════════\n  INVALID PASSWORD — Aurora Blueprints will not load.\n  Set the correct password in:\n  BepInEx/config/aurora.blueprints.cfg\n  under [Protection] > password\n══════════════════════════════════════════════════");
			return false;
		}

		private static string HashPassword(string input)
		{
			using SHA256 sHA = SHA256.Create();
			byte[] bytes = Encoding.UTF8.GetBytes(input);
			byte[] array = sHA.ComputeHash(bytes);
			StringBuilder stringBuilder = new StringBuilder(64);
			byte[] array2 = array;
			foreach (byte b in array2)
			{
				stringBuilder.Append(b.ToString("x2"));
			}
			return stringBuilder.ToString();
		}
	}
}