Decompiled source of PrefabHammer v1.1.6

PrefabHammer.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PrefabHammer;

[BepInPlugin("com.prefabhammer", "PrefabHammer", "1.1.6")]
public class PrefabHammerPlugin : BaseUnityPlugin
{
	public class PlacementRecord
	{
		public string blueprintName;

		public int pieceCount;

		public float timestamp;

		public List<ZNetView> pieces;
	}

	private struct SnapPointInfo
	{
		public string name;

		public Vector3 localPosition;

		public Quaternion localRotation;
	}

	public static ConfigEntry<bool> configEnabled;

	public static ConfigEntry<KeyboardShortcut> configSaveHotkey;

	public static ConfigEntry<float> configRadius;

	public static ConfigEntry<string> configCategory;

	public static ConfigEntry<KeyboardShortcut> configSelectHotkey;

	public static ConfigEntry<int> configBatchSize;

	public static ConfigEntry<int> configMaxUndoHistory;

	public static ConfigEntry<KeyboardShortcut> configManagerHotkey;

	public static ConfigEntry<KeyboardShortcut> configUndoHotkey;

	public static List<PlacementRecord> m_placementHistory = new List<PlacementRecord>();

	public static int m_undoConfirmIndex = -1;

	public static List<GameObject> m_customPrefabs = new List<GameObject>();

	public static Dictionary<string, Blueprint> m_loadedBlueprints = new Dictionary<string, Blueprint>(StringComparer.OrdinalIgnoreCase);

	public static HashSet<Piece> m_selectedPieces = new HashSet<Piece>();

	public static HashSet<ZDOID> m_movingDayZDOIDs = null;

	private static float m_lastCheckTime = 0f;

	public static bool m_showSaveGui = false;

	private static string m_newPrefabName = "";

	private static Piece m_targetAnchorPiece = null;

	private static bool m_recipesAddedToLocalPlayer = false;

	private static bool m_shouldFocusField = false;

	private static Texture2D m_bgTex = null;

	private static Texture2D m_borderTex = null;

	private static Texture2D m_inputBgTex = null;

	private static Texture2D m_btnBgTex = null;

	private static Texture2D m_btnHoverBgTex = null;

	private static Texture2D m_listItemBgTex = null;

	private static Texture2D m_tabBgTex = null;

	private static Texture2D m_tabActiveBgTex = null;

	private static GUIStyle m_labelStyle = null;

	private static GUIStyle m_titleStyle = null;

	private static GUIStyle m_textFieldStyle = null;

	private static GUIStyle m_buttonStyle = null;

	private static GUIStyle m_tabButtonStyle = null;

	private static GUIStyle m_deleteButtonStyle = null;

	public static int m_activeTab = 0;

	public static Vector2 m_scrollPosition = Vector2.zero;

	public static int m_prefabConfirmDeleteIndex = -1;

	private void Awake()
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: 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_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Expected O, but got Unknown
		configEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable the mod on the fly.");
		configSaveHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keybinds", "SaveHotkey", new KeyboardShortcut((KeyCode)107, (KeyCode[])(object)new KeyCode[0]), "Hotkey to save hovered build pieces. Must type chat command `/prefabsave` if disabled.");
		configRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DefaultRadius", 5f, "Default radius in meters to capture built pieces around targeted piece.");
		configCategory = ((BaseUnityPlugin)this).Config.Bind<string>("General", "BuildCategory", "Prefab", "Build category to add custom pieces to. Options: Prefab, Misc, Crafting, Building, Furniture");
		configSelectHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keybinds", "SelectHotkey", new KeyboardShortcut((KeyCode)106, (KeyCode[])(object)new KeyCode[0]), "Hotkey to select/deselect a piece for manual prefab building. Must hold Hammer.");
		configBatchSize = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "PlacementBatchSize", 10, "Number of sub-pieces to instantiate per frame when placing a prefab. Lower values reduce stutter on large structures but take longer to finish placing. Range: 1-50.");
		configMaxUndoHistory = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MaxUndoHistory", 5, "Number of recent prefab placements to keep in the undo history (range 1-20).");
		configManagerHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keybinds", "ManagerHotkey", new KeyboardShortcut((KeyCode)107, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Hotkey to open the Prefab Manager to the Library tab.");
		configUndoHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keybinds", "UndoHotkey", new KeyboardShortcut((KeyCode)117, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Hotkey to open the Prefab Manager to the Undo History tab.");
		Directory.CreateDirectory(GetBlueprintsDir());
		Harmony val = new Harmony("com.prefabhammer");
		val.PatchAll();
		Debug.Log((object)"[PrefabHammer] Plugin loaded successfully!");
	}

	private void Start()
	{
		TryLinkSharedSelection();
	}

	private void TryLinkSharedSelection()
	{
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly.GetName().Name == "MovingDay"))
				{
					continue;
				}
				Type type = assembly.GetType("MovingDay.MovingDaySelection");
				if (!(type != null))
				{
					break;
				}
				FieldInfo field = type.GetField("m_selectedPieces", BindingFlags.Static | BindingFlags.Public);
				if (field != null && field.GetValue(null) is HashSet<Piece> selectedPieces)
				{
					m_selectedPieces = selectedPieces;
					Debug.Log((object)"[PrefabHammer] Successfully linked to MovingDay selection HashSet!");
				}
				FieldInfo field2 = type.GetField("m_selectedZDOIDs", BindingFlags.Static | BindingFlags.Public);
				if (field2 != null)
				{
					m_movingDayZDOIDs = field2.GetValue(null) as HashSet<ZDOID>;
					if (m_movingDayZDOIDs != null)
					{
						Debug.Log((object)"[PrefabHammer] Successfully linked to MovingDay selection ZDOID HashSet!");
					}
				}
				break;
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PrefabHammer] Failed to link shared selection with MovingDay: " + ex.Message));
		}
	}

	private void Update()
	{
		//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03da: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_047a: Unknown result type (might be due to invalid IL or missing references)
		//IL_047f: Unknown result type (might be due to invalid IL or missing references)
		//IL_058a: Unknown result type (might be due to invalid IL or missing references)
		//IL_058f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0593: Unknown result type (might be due to invalid IL or missing references)
		//IL_0598: Unknown result type (might be due to invalid IL or missing references)
		//IL_059a: Unknown result type (might be due to invalid IL or missing references)
		//IL_067c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0681: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0861: Unknown result type (might be due to invalid IL or missing references)
		//IL_077b: Unknown result type (might be due to invalid IL or missing references)
		if (!configEnabled.Value)
		{
			if (m_showSaveGui)
			{
				m_showSaveGui = false;
			}
			if (m_selectedPieces != null && m_selectedPieces.Count > 0)
			{
				ClearSelection();
			}
			if ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_pieceSelectionWindow != (Object)null && Hud.instance.m_pieceSelectionWindow.activeSelf)
			{
				Hud_Awake_Patch.ReparentCustomTabs(Hud.instance);
			}
			return;
		}
		if (m_showSaveGui)
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			m_recipesAddedToLocalPlayer = false;
			ClearSelection();
			return;
		}
		if (m_selectedPieces != null)
		{
			m_selectedPieces.RemoveWhere((Piece p) => (Object)(object)p == (Object)null);
		}
		if (!m_showSaveGui)
		{
			ItemData rightItem = GetRightItem(Player.m_localPlayer);
			bool flag = false;
			if (rightItem != null && (Object)(object)rightItem.m_shared.m_buildPieces != (Object)null)
			{
				string text = rightItem.m_shared.m_name.ToLower();
				string text2 = ((Object)rightItem.m_shared.m_buildPieces).name.ToLower();
				if (text.Contains("hammer") || text2.Contains("hammer") || text == "$item_hammer")
				{
					flag = true;
				}
			}
			if (!flag)
			{
				ClearSelection();
			}
		}
		if (!m_recipesAddedToLocalPlayer)
		{
			AddCustomRecipesToPlayer(Player.m_localPlayer);
		}
		if (!TakeInput(Player.m_localPlayer))
		{
			return;
		}
		ItemData rightItem2 = GetRightItem(Player.m_localPlayer);
		if (rightItem2 == null || (Object)(object)rightItem2.m_shared.m_buildPieces == (Object)null)
		{
			return;
		}
		string text3 = rightItem2.m_shared.m_name.ToLower();
		string text4 = ((Object)rightItem2.m_shared.m_buildPieces).name.ToLower();
		if (!text3.Contains("hammer") && !text4.Contains("hammer") && text3 != "$item_hammer")
		{
			return;
		}
		if (Time.time - m_lastCheckTime > 2f)
		{
			m_lastCheckTime = Time.time;
			PieceTable buildPieces = GetBuildPieces(Player.m_localPlayer);
			if ((Object)(object)buildPieces != (Object)null && buildPieces.m_pieces != null)
			{
				bool flag2 = false;
				foreach (GameObject piece in buildPieces.m_pieces)
				{
					if ((Object)(object)piece != (Object)null && ((Object)piece).name.StartsWith("PrefabHammerPiece_"))
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					string blueprintsDir = GetBlueprintsDir();
					if (Directory.Exists(blueprintsDir) && Directory.GetFiles(blueprintsDir, "*.json").Length > 0)
					{
						if (m_customPrefabs.Count == 0)
						{
							Debug.Log((object)"[PrefabHammer] Equipped hammer missing custom pieces, loading from disk...");
							RegisterCustomPieces();
						}
						else
						{
							Debug.Log((object)"[PrefabHammer] Equipped hammer missing custom pieces, restoring existing prefabs...");
							RegisterCustomPieces(reloadFromDisk: false);
						}
					}
				}
			}
		}
		KeyboardShortcut value = configManagerHotkey.Value;
		bool flag3 = ((KeyboardShortcut)(ref value)).IsDown();
		value = configUndoHotkey.Value;
		bool flag4 = ((KeyboardShortcut)(ref value)).IsDown();
		if (Input.GetKeyDown((KeyCode)127) || flag3 || flag4)
		{
			if (m_showSaveGui)
			{
				if (flag4)
				{
					m_activeTab = 2;
				}
				else
				{
					m_activeTab = 1;
				}
				m_prefabConfirmDeleteIndex = -1;
				m_undoConfirmIndex = -1;
			}
			else
			{
				m_activeTab = ((!flag4) ? 1 : 2);
				m_prefabConfirmDeleteIndex = -1;
				m_undoConfirmIndex = -1;
				m_showSaveGui = true;
			}
			return;
		}
		value = configSaveHotkey.Value;
		Piece hoveringPiece;
		if (((KeyboardShortcut)(ref value)).IsDown())
		{
			if (m_showSaveGui)
			{
				return;
			}
			hoveringPiece = GetHoveringPiece(Player.m_localPlayer);
			if ((Object)(object)hoveringPiece != (Object)null)
			{
				m_targetAnchorPiece = hoveringPiece;
				m_newPrefabName = "Prefab_" + DateTime.Now.ToString("yyyyMMdd_HHmmss");
				m_shouldFocusField = true;
				m_activeTab = 0;
				m_prefabConfirmDeleteIndex = -1;
				m_showSaveGui = true;
			}
			else if (m_selectedPieces != null && m_selectedPieces.Count > 0)
			{
				m_targetAnchorPiece = null;
				m_newPrefabName = "Prefab_" + DateTime.Now.ToString("yyyyMMdd_HHmmss");
				m_shouldFocusField = true;
				m_activeTab = 0;
				m_prefabConfirmDeleteIndex = -1;
				m_showSaveGui = true;
			}
			else
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "No piece hovered. Target a piece first.", 0, (Sprite)null);
			}
		}
		value = configSelectHotkey.Value;
		KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
		if (Input.GetKeyDown(mainKey))
		{
			if (m_showSaveGui)
			{
				return;
			}
			if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303) || Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305))
			{
				value = configSelectHotkey.Value;
				if (!((KeyboardShortcut)(ref value)).IsDown())
				{
					if ((m_selectedPieces != null && m_selectedPieces.Count > 0) || (m_movingDayZDOIDs != null && m_movingDayZDOIDs.Count > 0))
					{
						ClearSelection();
						((Character)Player.m_localPlayer).Message((MessageType)2, "Cleared selection.", 0, (Sprite)null);
					}
					return;
				}
			}
		}
		value = configSelectHotkey.Value;
		if (!((KeyboardShortcut)(ref value)).IsDown() || m_showSaveGui)
		{
			return;
		}
		hoveringPiece = GetHoveringPiece(Player.m_localPlayer);
		if ((Object)(object)hoveringPiece != (Object)null)
		{
			string prefabName = GetPrefabName(((Component)hoveringPiece).gameObject);
			if (prefabName.StartsWith("PrefabHammerPiece_"))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "Cannot select custom prefab pieces.", 0, (Sprite)null);
				return;
			}
			if (m_selectedPieces.Contains(hoveringPiece))
			{
				m_selectedPieces.Remove(hoveringPiece);
				if (m_movingDayZDOIDs != null)
				{
					ZNetView component = ((Component)hoveringPiece).GetComponent<ZNetView>();
					if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null)
					{
						m_movingDayZDOIDs.Remove(component.GetZDO().m_uid);
					}
				}
				PrefabSelectionHighlight component2 = ((Component)hoveringPiece).GetComponent<PrefabSelectionHighlight>();
				if ((Object)(object)component2 != (Object)null)
				{
					Object.Destroy((Object)(object)component2);
				}
				Component component3 = ((Component)hoveringPiece).GetComponent("MovingDaySelectionHighlight");
				if ((Object)(object)component3 != (Object)null)
				{
					Object.Destroy((Object)(object)component3);
				}
				((Character)Player.m_localPlayer).Message((MessageType)2, "Deselected piece (total " + m_selectedPieces.Count + ")", 0, (Sprite)null);
				return;
			}
			m_selectedPieces.Add(hoveringPiece);
			if (m_movingDayZDOIDs != null)
			{
				ZNetView component = ((Component)hoveringPiece).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null)
				{
					m_movingDayZDOIDs.Add(component.GetZDO().m_uid);
				}
			}
			if ((Object)(object)((Component)hoveringPiece).GetComponent<PrefabSelectionHighlight>() == (Object)null)
			{
				((Component)hoveringPiece).gameObject.AddComponent<PrefabSelectionHighlight>();
			}
			((Character)Player.m_localPlayer).Message((MessageType)2, "Selected piece (total " + m_selectedPieces.Count + ")", 0, (Sprite)null);
		}
		else if (m_selectedPieces != null && m_selectedPieces.Count > 0)
		{
			ClearSelection();
			((Character)Player.m_localPlayer).Message((MessageType)2, "Cleared selection.", 0, (Sprite)null);
		}
		else
		{
			((Character)Player.m_localPlayer).Message((MessageType)2, "No piece hovered to select.", 0, (Sprite)null);
		}
	}

	public static void ClearSelection()
	{
		if (m_selectedPieces != null && m_selectedPieces.Count > 0)
		{
			foreach (Piece selectedPiece in m_selectedPieces)
			{
				if ((Object)(object)selectedPiece != (Object)null)
				{
					PrefabSelectionHighlight component = ((Component)selectedPiece).GetComponent<PrefabSelectionHighlight>();
					if ((Object)(object)component != (Object)null)
					{
						Object.Destroy((Object)(object)component);
					}
					Component component2 = ((Component)selectedPiece).GetComponent("MovingDaySelectionHighlight");
					if ((Object)(object)component2 != (Object)null)
					{
						Object.Destroy((Object)(object)component2);
					}
				}
			}
			m_selectedPieces.Clear();
		}
		if (m_movingDayZDOIDs != null)
		{
			m_movingDayZDOIDs.Clear();
		}
	}

	public static string GetBlueprintsDir()
	{
		return Path.Combine(Paths.ConfigPath, "PrefabHammer", "Blueprints");
	}

	private static PieceCategory GetBuildCategory(string name)
	{
		//IL_0010: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(name))
		{
			return (PieceCategory)9;
		}
		switch (name.ToLower().Trim())
		{
		case "prefab":
			return (PieceCategory)9;
		case "crafting":
			return (PieceCategory)1;
		case "building":
		case "buildingworkbench":
			return (PieceCategory)2;
		case "buildingstonecutter":
			return (PieceCategory)3;
		case "furniture":
			return (PieceCategory)4;
		case "misc":
			return (PieceCategory)0;
		default:
			return (PieceCategory)9;
		}
	}

	public static bool SaveModularPrefab(string name, float radius, Piece target, HashSet<Piece> selectedPieces = null)
	{
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return false;
		}
		List<Piece> list = new List<Piece>();
		if (selectedPieces != null && selectedPieces.Count > 0)
		{
			foreach (Piece selectedPiece in selectedPieces)
			{
				if (!((Object)(object)selectedPiece == (Object)null))
				{
					string prefabName = GetPrefabName(((Component)selectedPiece).gameObject);
					if (!prefabName.StartsWith("PrefabHammerPiece_"))
					{
						list.Add(selectedPiece);
					}
				}
			}
		}
		else
		{
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			Vector3 position = ((Component)target).transform.position;
			List<Piece> allPieces = GetAllPieces();
			foreach (Piece item in allPieces)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				float num = Vector3.Distance(((Component)item).transform.position, position);
				if (num <= radius)
				{
					string prefabName = GetPrefabName(((Component)item).gameObject);
					if (!prefabName.StartsWith("PrefabHammerPiece_"))
					{
						list.Add(item);
					}
				}
			}
		}
		if (list.Count == 0)
		{
			return false;
		}
		Piece val = list[0];
		float y = ((Component)val).transform.position.y;
		foreach (Piece item2 in list)
		{
			if (((Component)item2).transform.position.y < y)
			{
				y = ((Component)item2).transform.position.y;
				val = item2;
			}
		}
		Blueprint blueprint = new Blueprint();
		blueprint.name = name;
		blueprint.description = "Custom prefab combo piece";
		List<BlueprintComponent> list2 = new List<BlueprintComponent>();
		foreach (Piece item3 in list)
		{
			BlueprintComponent blueprintComponent = new BlueprintComponent();
			blueprintComponent.prefabName = GetPrefabName(((Component)item3).gameObject);
			Vector3 val2 = ((Component)val).transform.InverseTransformPoint(((Component)item3).transform.position);
			Quaternion val3 = Quaternion.Inverse(((Component)val).transform.rotation) * ((Component)item3).transform.rotation;
			blueprintComponent.posX = val2.x;
			blueprintComponent.posY = val2.y;
			blueprintComponent.posZ = val2.z;
			blueprintComponent.rotX = val3.x;
			blueprintComponent.rotY = val3.y;
			blueprintComponent.rotZ = val3.z;
			blueprintComponent.rotW = val3.w;
			list2.Add(blueprintComponent);
		}
		blueprint.components = list2.ToArray();
		string contents = SerializeBlueprint(blueprint);
		string path = Path.Combine(GetBlueprintsDir(), name + ".json");
		File.WriteAllText(path, contents);
		return true;
	}

	private static string GetPrefabName(GameObject obj)
	{
		ZNetView component = obj.GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null)
		{
			int prefab = component.GetZDO().GetPrefab();
			GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab);
			if ((Object)(object)prefab2 != (Object)null)
			{
				return ((Object)prefab2).name;
			}
		}
		return ((Object)obj).name.Replace("(Clone)", "").Trim();
	}

	public static void RegisterCustomPieces(bool reloadFromDisk = true)
	{
		//IL_093f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0946: Expected O, but got Unknown
		//IL_09ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_09b5: Expected O, but got Unknown
		//IL_09e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a14: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b79: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b7e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b8d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bd5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aa7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aae: Expected O, but got Unknown
		//IL_0ae9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aeb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0af4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0af9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b0b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b0f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b14: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_06cc: Expected O, but got Unknown
		//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_073a: Unknown result type (might be due to invalid IL or missing references)
		//IL_073f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
		{
			return;
		}
		HashSet<PieceTable> hashSet = new HashSet<PieceTable>();
		if (ObjectDB.instance.m_items != null)
		{
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.m_itemData.m_shared.m_buildPieces != (Object)null)
				{
					string text = ((Object)component.m_itemData.m_shared.m_buildPieces).name.ToLower();
					string text2 = component.m_itemData.m_shared.m_name.ToLower();
					if (text.Contains("hammer") || text2.Contains("hammer") || text2 == "$item_hammer")
					{
						hashSet.Add(component.m_itemData.m_shared.m_buildPieces);
					}
				}
			}
		}
		GameObject prefab = ZNetScene.instance.GetPrefab("Hammer");
		if ((Object)(object)prefab != (Object)null)
		{
			ItemDrop component = prefab.GetComponent<ItemDrop>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_itemData.m_shared.m_buildPieces != (Object)null)
			{
				hashSet.Add(component.m_itemData.m_shared.m_buildPieces);
			}
		}
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			PieceTable buildPieces = GetBuildPieces(Player.m_localPlayer);
			if ((Object)(object)buildPieces != (Object)null)
			{
				hashSet.Add(buildPieces);
			}
			ItemData rightItem = GetRightItem(Player.m_localPlayer);
			if (rightItem != null && (Object)(object)rightItem.m_shared.m_buildPieces != (Object)null)
			{
				string text = ((Object)rightItem.m_shared.m_buildPieces).name.ToLower();
				string text2 = rightItem.m_shared.m_name.ToLower();
				if (text.Contains("hammer") || text2.Contains("hammer") || text2 == "$item_hammer")
				{
					hashSet.Add(rightItem.m_shared.m_buildPieces);
				}
			}
			if (((Humanoid)Player.m_localPlayer).GetInventory() != null)
			{
				foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
				{
					if (allItem != null && (Object)(object)allItem.m_shared.m_buildPieces != (Object)null)
					{
						string text = ((Object)allItem.m_shared.m_buildPieces).name.ToLower();
						string text2 = allItem.m_shared.m_name.ToLower();
						if (text.Contains("hammer") || text2.Contains("hammer") || text2 == "$item_hammer")
						{
							hashSet.Add(allItem.m_shared.m_buildPieces);
						}
					}
				}
			}
		}
		foreach (PieceTable item2 in hashSet)
		{
			if ((Object)(object)item2 != (Object)null && item2.m_categories != null && !item2.m_categories.Contains((PieceCategory)9))
			{
				item2.m_categories.Add((PieceCategory)9);
				item2.m_categoryLabels.Add("Prefab");
				Debug.Log((object)("[PrefabHammer] Added custom category 'Prefab' to PieceTable: " + ((Object)item2).name));
			}
		}
		if (!reloadFromDisk)
		{
			foreach (PieceTable item3 in hashSet)
			{
				if (item3.m_pieces != null)
				{
					item3.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null);
					foreach (GameObject customPrefab in m_customPrefabs)
					{
						if ((Object)(object)customPrefab != (Object)null && !item3.m_pieces.Contains(customPrefab))
						{
							item3.m_pieces.Add(customPrefab);
							Debug.Log((object)("[PrefabHammer] Soft-registered custom piece: " + ((Object)customPrefab).name + " to " + ((Object)item3).name));
						}
					}
				}
			}
			return;
		}
		foreach (PieceTable item4 in hashSet)
		{
			if (item4.m_pieces != null)
			{
				item4.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ((Object)p).name.StartsWith("PrefabHammerPiece_"));
			}
		}
		foreach (GameObject customPrefab2 in m_customPrefabs)
		{
			if ((Object)(object)customPrefab2 != (Object)null)
			{
				Object.Destroy((Object)(object)customPrefab2);
			}
		}
		m_customPrefabs.Clear();
		m_loadedBlueprints.Clear();
		string blueprintsDir = GetBlueprintsDir();
		if (!Directory.Exists(blueprintsDir))
		{
			return;
		}
		string[] files = Directory.GetFiles(blueprintsDir, "*.json");
		string[] array = files;
		Vector3 val8 = default(Vector3);
		Quaternion val9 = default(Quaternion);
		foreach (string text3 in array)
		{
			try
			{
				string json = File.ReadAllText(text3);
				Blueprint blueprint = DeserializeBlueprint(json);
				if (blueprint == null || blueprint.components == null || blueprint.components.Length == 0)
				{
					continue;
				}
				GameObject val = new GameObject("PrefabHammerPiece_" + blueprint.name);
				val.transform.position = new Vector3(0f, -10000f, 0f);
				Object.DontDestroyOnLoad((Object)(object)val);
				m_loadedBlueprints[blueprint.name] = blueprint;
				Piece val2 = val.AddComponent<Piece>();
				val2.m_name = blueprint.name;
				val2.m_description = blueprint.description;
				val2.m_category = GetBuildCategory(configCategory.Value);
				val2.m_enabled = true;
				val2.m_resources = CalculateRequirements(blueprint);
				CraftingStation val3 = null;
				Sprite val4 = null;
				EffectList val5 = null;
				BlueprintComponent[] components = blueprint.components;
				foreach (BlueprintComponent blueprintComponent in components)
				{
					GameObject prefab2 = ZNetScene.instance.GetPrefab(blueprintComponent.prefabName);
					if (!((Object)(object)prefab2 != (Object)null))
					{
						continue;
					}
					Piece component2 = prefab2.GetComponent<Piece>();
					if (!((Object)(object)component2 != (Object)null))
					{
						continue;
					}
					if ((Object)(object)component2.m_craftingStation != (Object)null)
					{
						string text4 = ((Object)component2.m_craftingStation).name.ToLower();
						if ((Object)(object)val3 == (Object)null || text4.Contains("forge") || text4.Contains("stonecutter"))
						{
							val3 = component2.m_craftingStation;
						}
					}
					if ((Object)(object)val4 == (Object)null && (Object)(object)component2.m_icon != (Object)null)
					{
						val4 = component2.m_icon;
					}
					if (val5 == null && component2.m_placeEffect != null)
					{
						val5 = component2.m_placeEffect;
					}
				}
				val2.m_craftingStation = val3;
				val2.m_icon = val4;
				val2.m_placeEffect = val5;
				FieldInfo field = typeof(Piece).GetField("m_facing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					try
					{
						object value = Enum.Parse(field.FieldType, "Flat");
						field.SetValue(val2, value);
						Debug.Log((object)"[PrefabHammer] Set piece facing mode to Flat via reflection.");
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[PrefabHammer] Could not set facing mode to Flat: " + ex.Message));
					}
				}
				PrefabPieceSpawner prefabPieceSpawner = val.AddComponent<PrefabPieceSpawner>();
				prefabPieceSpawner.blueprint = blueprint;
				GameObject val6 = new GameObject("Visual");
				val6.transform.SetParent(val.transform, false);
				components = blueprint.components;
				foreach (BlueprintComponent blueprintComponent in components)
				{
					GameObject prefab2 = ZNetScene.instance.GetPrefab(blueprintComponent.prefabName);
					if (!((Object)(object)prefab2 != (Object)null))
					{
						continue;
					}
					GameObject val7 = new GameObject(blueprintComponent.prefabName + "_Visual");
					val7.transform.SetParent(val6.transform, false);
					val7.transform.localPosition = new Vector3(blueprintComponent.posX, blueprintComponent.posY, blueprintComponent.posZ);
					val7.transform.localRotation = new Quaternion(blueprintComponent.rotX, blueprintComponent.rotY, blueprintComponent.rotZ, blueprintComponent.rotW);
					CopyVisuals(prefab2, val7);
					List<SnapPointInfo> list = new List<SnapPointInfo>();
					FindSnapPointsRecursive(prefab2.transform, prefab2.transform, list);
					((Vector3)(ref val8))..ctor(blueprintComponent.posX, blueprintComponent.posY, blueprintComponent.posZ);
					((Quaternion)(ref val9))..ctor(blueprintComponent.rotX, blueprintComponent.rotY, blueprintComponent.rotZ, blueprintComponent.rotW);
					foreach (SnapPointInfo item5 in list)
					{
						GameObject val10 = new GameObject(item5.name);
						val10.tag = "snappoint";
						val10.layer = LayerMask.NameToLayer("piece");
						val10.transform.SetParent(val.transform, false);
						val10.transform.localPosition = val8 + val9 * item5.localPosition;
						val10.transform.localRotation = val9 * item5.localRotation;
					}
				}
				Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>();
				if (componentsInChildren.Length > 0)
				{
					Bounds bounds = componentsInChildren[0].bounds;
					for (int num3 = 1; num3 < componentsInChildren.Length; num3++)
					{
						((Bounds)(ref bounds)).Encapsulate(componentsInChildren[num3].bounds);
					}
					BoxCollider val11 = val.AddComponent<BoxCollider>();
					val11.center = val.transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
					val11.size = ((Bounds)(ref bounds)).size;
				}
				val.layer = LayerMask.NameToLayer("piece");
				Sprite val12 = RenderPrefabIcon(val);
				if ((Object)(object)val12 != (Object)null)
				{
					val2.m_icon = val12;
				}
				else
				{
					val2.m_icon = val4;
				}
				m_customPrefabs.Add(val);
				foreach (PieceTable item6 in hashSet)
				{
					if (item6.m_pieces != null && !item6.m_pieces.Contains(val))
					{
						item6.m_pieces.Add(val);
					}
				}
				Debug.Log((object)("[PrefabHammer] Registered custom piece: " + blueprint.name));
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[PrefabHammer] Error registering custom piece from file " + text3 + ": " + ex.Message));
			}
		}
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			AddCustomRecipesToPlayer(Player.m_localPlayer);
		}
	}

	private static void FindSnapPointsRecursive(Transform current, Transform root, List<SnapPointInfo> results)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		if (((Component)current).CompareTag("snappoint"))
		{
			Vector3 val = current.localPosition;
			Quaternion val2 = current.localRotation;
			Transform parent = current.parent;
			while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
			{
				val = parent.localPosition + parent.localRotation * val;
				val2 = parent.localRotation * val2;
				parent = parent.parent;
			}
			results.Add(new SnapPointInfo
			{
				name = ((Object)current).name,
				localPosition = val,
				localRotation = val2
			});
		}
		for (int i = 0; i < current.childCount; i++)
		{
			FindSnapPointsRecursive(current.GetChild(i), root, results);
		}
	}

	private static void CopyVisuals(GameObject source, GameObject target)
	{
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Expected O, but got Unknown
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Expected O, but got Unknown
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Expected O, but got Unknown
		//IL_0140: 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_01a4: Expected O, but got Unknown
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Expected O, but got Unknown
		try
		{
			if (!string.IsNullOrEmpty(source.tag))
			{
				target.tag = source.tag;
			}
		}
		catch (Exception)
		{
		}
		target.layer = source.layer;
		MeshFilter component = source.GetComponent<MeshFilter>();
		if ((Object)(object)component != (Object)null)
		{
			MeshFilter val = target.AddComponent<MeshFilter>();
			val.sharedMesh = component.sharedMesh;
		}
		MeshRenderer component2 = source.GetComponent<MeshRenderer>();
		if ((Object)(object)component2 != (Object)null)
		{
			MeshRenderer val2 = target.AddComponent<MeshRenderer>();
			((Renderer)val2).sharedMaterials = ((Renderer)component2).sharedMaterials;
		}
		Collider[] components = source.GetComponents<Collider>();
		Collider[] array = components;
		foreach (Collider val3 in array)
		{
			if (!((Object)(object)val3 == (Object)null))
			{
				if (val3 is BoxCollider)
				{
					BoxCollider val4 = (BoxCollider)val3;
					BoxCollider val5 = target.AddComponent<BoxCollider>();
					val5.center = val4.center;
					val5.size = val4.size;
					((Collider)val5).isTrigger = true;
				}
				else if (val3 is CapsuleCollider)
				{
					CapsuleCollider val6 = (CapsuleCollider)val3;
					CapsuleCollider val7 = target.AddComponent<CapsuleCollider>();
					val7.center = val6.center;
					val7.radius = val6.radius;
					val7.height = val6.height;
					val7.direction = val6.direction;
					((Collider)val7).isTrigger = true;
				}
				else if (val3 is SphereCollider)
				{
					SphereCollider val8 = (SphereCollider)val3;
					SphereCollider val9 = target.AddComponent<SphereCollider>();
					val9.center = val8.center;
					val9.radius = val8.radius;
					((Collider)val9).isTrigger = true;
				}
				else if (val3 is MeshCollider)
				{
					MeshCollider val10 = (MeshCollider)val3;
					MeshCollider val11 = target.AddComponent<MeshCollider>();
					val11.sharedMesh = val10.sharedMesh;
					val11.convex = val10.convex;
					((Collider)val11).isTrigger = true;
				}
			}
		}
		for (int j = 0; j < source.transform.childCount; j++)
		{
			Transform child = source.transform.GetChild(j);
			GameObject val12 = new GameObject(((Object)child).name);
			val12.transform.SetParent(target.transform, false);
			val12.transform.localPosition = child.localPosition;
			val12.transform.localRotation = child.localRotation;
			val12.transform.localScale = child.localScale;
			CopyVisuals(((Component)child).gameObject, val12);
		}
	}

	private static Sprite RenderPrefabIcon(GameObject prefab)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_003c: 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_0052: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Expected O, but got Unknown
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: 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_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Expected O, but got Unknown
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Expected O, but got Unknown
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Expected O, but got Unknown
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)prefab == (Object)null)
		{
			return null;
		}
		GameObject val = null;
		try
		{
			val = new GameObject("RenderRoot");
			val.transform.position = new Vector3(-1000f, -1000f, -1000f);
			GameObject val2 = new GameObject("VisualCopy");
			val2.transform.SetParent(val.transform, false);
			CopyVisuals(prefab, val2);
			Bounds bounds = default(Bounds);
			((Bounds)(ref bounds))..ctor(Vector3.zero, Vector3.zero);
			bool flag = false;
			Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>();
			foreach (Renderer val3 in componentsInChildren)
			{
				if (!flag)
				{
					bounds = val3.bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref bounds)).Encapsulate(val3.bounds);
				}
			}
			if (!flag)
			{
				Object.DestroyImmediate((Object)(object)val);
				return null;
			}
			GameObject val4 = new GameObject("RenderCamera");
			val4.transform.SetParent(val.transform, false);
			Camera val5 = val4.AddComponent<Camera>();
			val5.clearFlags = (CameraClearFlags)2;
			val5.backgroundColor = new Color(0f, 0f, 0f, 0f);
			val5.fieldOfView = 30f;
			val5.nearClipPlane = 0.1f;
			val5.farClipPlane = 100f;
			Vector3 center = ((Bounds)(ref bounds)).center;
			Vector3 val6 = ((Bounds)(ref bounds)).extents;
			float num = ((Vector3)(ref val6)).magnitude;
			if (num < 0.1f)
			{
				num = 1f;
			}
			val6 = new Vector3(1f, 0.8f, -1f);
			Vector3 val7 = ((Vector3)(ref val6)).normalized * (num * 3f);
			val4.transform.position = center + val7;
			val4.transform.LookAt(center);
			GameObject val8 = new GameObject("RenderLight");
			val8.transform.SetParent(val.transform, false);
			Light val9 = val8.AddComponent<Light>();
			val9.type = (LightType)1;
			val9.intensity = 1.5f;
			val8.transform.rotation = Quaternion.Euler(50f, -30f, 0f);
			int num2 = 128;
			RenderTexture val10 = (val5.targetTexture = new RenderTexture(num2, num2, 24, (RenderTextureFormat)0));
			Texture2D val12 = new Texture2D(num2, num2, (TextureFormat)5, false);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = val10;
			val5.Render();
			val12.ReadPixels(new Rect(0f, 0f, (float)num2, (float)num2), 0, 0);
			val12.Apply();
			RenderTexture.active = active;
			val5.targetTexture = null;
			val10.Release();
			Object.DestroyImmediate((Object)(object)val10);
			Object.DestroyImmediate((Object)(object)val);
			return Sprite.Create(val12, new Rect(0f, 0f, (float)num2, (float)num2), new Vector2(0.5f, 0.5f), 100f);
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[PrefabHammer] Error rendering prefab icon: " + ex.Message));
			if ((Object)(object)val != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val);
			}
			return null;
		}
	}

	private static Requirement[] CalculateRequirements(Blueprint bp)
	{
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		Dictionary<string, int> dictionary = new Dictionary<string, int>();
		BlueprintComponent[] components = bp.components;
		foreach (BlueprintComponent blueprintComponent in components)
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(blueprintComponent.prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				continue;
			}
			Piece component = prefab.GetComponent<Piece>();
			if ((Object)(object)component == (Object)null || component.m_resources == null)
			{
				continue;
			}
			Requirement[] resources = component.m_resources;
			foreach (Requirement val in resources)
			{
				if (!((Object)(object)val.m_resItem == (Object)null))
				{
					string name = ((Object)val.m_resItem).name;
					int amount = val.m_amount;
					if (dictionary.ContainsKey(name))
					{
						dictionary[name] += amount;
					}
					else
					{
						dictionary[name] = amount;
					}
				}
			}
		}
		List<Requirement> list = new List<Requirement>();
		foreach (KeyValuePair<string, int> item in dictionary)
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Key);
			if ((Object)(object)itemPrefab != (Object)null)
			{
				ItemDrop component2 = itemPrefab.GetComponent<ItemDrop>();
				if ((Object)(object)component2 != (Object)null)
				{
					Requirement val = new Requirement();
					val.m_resItem = component2;
					val.m_amount = item.Value;
					val.m_amountPerLevel = 0;
					val.m_recover = true;
					list.Add(val);
				}
			}
		}
		return list.ToArray();
	}

	public static string SerializeBlueprint(Blueprint bp)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("{\n");
		stringBuilder.Append("  \"name\": \"" + EscapeJson(bp.name) + "\",\n");
		stringBuilder.Append("  \"description\": \"" + EscapeJson(bp.description) + "\",\n");
		stringBuilder.Append("  \"components\": [\n");
		for (int i = 0; i < bp.components.Length; i++)
		{
			BlueprintComponent blueprintComponent = bp.components[i];
			stringBuilder.Append("    {\n");
			stringBuilder.Append("      \"prefabName\": \"" + EscapeJson(blueprintComponent.prefabName) + "\",\n");
			stringBuilder.Append("      \"posX\": " + blueprintComponent.posX.ToString("F4") + ",\n");
			stringBuilder.Append("      \"posY\": " + blueprintComponent.posY.ToString("F4") + ",\n");
			stringBuilder.Append("      \"posZ\": " + blueprintComponent.posZ.ToString("F4") + ",\n");
			stringBuilder.Append("      \"rotX\": " + blueprintComponent.rotX.ToString("F4") + ",\n");
			stringBuilder.Append("      \"rotY\": " + blueprintComponent.rotY.ToString("F4") + ",\n");
			stringBuilder.Append("      \"rotZ\": " + blueprintComponent.rotZ.ToString("F4") + ",\n");
			stringBuilder.Append("      \"rotW\": " + blueprintComponent.rotW.ToString("F4") + "\n");
			stringBuilder.Append("    }");
			if (i < bp.components.Length - 1)
			{
				stringBuilder.Append(",");
			}
			stringBuilder.Append("\n");
		}
		stringBuilder.Append("  ]\n");
		stringBuilder.Append("}");
		return stringBuilder.ToString();
	}

	public static Blueprint DeserializeBlueprint(string json)
	{
		Blueprint blueprint = new Blueprint();
		blueprint.name = ExtractJsonString(json, "name");
		blueprint.description = ExtractJsonString(json, "description");
		List<BlueprintComponent> list = new List<BlueprintComponent>();
		int num = json.IndexOf("\"components\"");
		if (num != -1)
		{
			int num2 = json.IndexOf("[", num);
			int num3 = json.LastIndexOf("]");
			if (num2 != -1 && num3 != -1 && num3 > num2)
			{
				string text = json.Substring(num2 + 1, num3 - num2 - 1);
				string[] array = text.Split(new string[1] { "}," }, StringSplitOptions.None);
				string[] array2 = array;
				foreach (string text2 in array2)
				{
					string text3 = text2.Trim().TrimEnd(new char[1] { '}' });
					if (!string.IsNullOrEmpty(text3))
					{
						BlueprintComponent blueprintComponent = new BlueprintComponent();
						blueprintComponent.prefabName = ExtractJsonString(text3, "prefabName");
						blueprintComponent.posX = ExtractJsonFloat(text3, "posX");
						blueprintComponent.posY = ExtractJsonFloat(text3, "posY");
						blueprintComponent.posZ = ExtractJsonFloat(text3, "posZ");
						blueprintComponent.rotX = ExtractJsonFloat(text3, "rotX");
						blueprintComponent.rotY = ExtractJsonFloat(text3, "rotY");
						blueprintComponent.rotZ = ExtractJsonFloat(text3, "rotZ");
						blueprintComponent.rotW = ExtractJsonFloat(text3, "rotW");
						list.Add(blueprintComponent);
					}
				}
			}
		}
		blueprint.components = list.ToArray();
		return blueprint;
	}

	private static string EscapeJson(string s)
	{
		if (string.IsNullOrEmpty(s))
		{
			return "";
		}
		return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
	}

	private static string ExtractJsonString(string json, string key)
	{
		string text = "\"" + key + "\":";
		int num = json.IndexOf(text);
		if (num == -1)
		{
			return "";
		}
		int num2 = json.IndexOf("\"", num + text.Length);
		if (num2 == -1)
		{
			return "";
		}
		int num3 = json.IndexOf("\"", num2 + 1);
		if (num3 == -1)
		{
			return "";
		}
		return json.Substring(num2 + 1, num3 - num2 - 1);
	}

	private static float ExtractJsonFloat(string json, string key)
	{
		string text = "\"" + key + "\":";
		int num = json.IndexOf(text);
		if (num == -1)
		{
			return 0f;
		}
		int num2 = num + text.Length;
		int num3 = json.IndexOfAny(new char[4] { ',', '\n', '}', '\r' }, num2);
		string s = ((num3 != -1) ? json.Substring(num2, num3 - num2).Trim() : json.Substring(num2).Trim());
		if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
		{
			return result;
		}
		return 0f;
	}

	private static bool TakeInput(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		MethodInfo method = typeof(Player).GetMethod("TakeInput", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (method != null)
		{
			return (bool)method.Invoke(player, null);
		}
		return false;
	}

	private static ItemData GetRightItem(Player player)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		if ((Object)(object)player == (Object)null)
		{
			return null;
		}
		FieldInfo field = typeof(Player).GetField("m_rightItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			return (ItemData)field.GetValue(player);
		}
		return null;
	}

	private static PieceTable GetBuildPieces(Player player)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		if ((Object)(object)player == (Object)null)
		{
			return null;
		}
		FieldInfo field = typeof(Player).GetField("m_buildPieces", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			return (PieceTable)field.GetValue(player);
		}
		return null;
	}

	public static Piece GetHoveringPiece(Player player)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		if ((Object)(object)player == (Object)null)
		{
			return null;
		}
		FieldInfo field = typeof(Player).GetField("m_hoveringPiece", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			return (Piece)field.GetValue(player);
		}
		return null;
	}

	private static List<Piece> GetAllPieces()
	{
		FieldInfo field = typeof(Piece).GetField("s_allPieces", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			return (List<Piece>)field.GetValue(null);
		}
		return new List<Piece>();
	}

	public static object GetInputField(Chat chat)
	{
		if ((Object)(object)chat == (Object)null)
		{
			return null;
		}
		FieldInfo field = typeof(Chat).GetField("m_input", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			return field.GetValue(chat);
		}
		return null;
	}

	public static string GetChatText(Chat chat)
	{
		object inputField = GetInputField(chat);
		if (inputField == null)
		{
			return null;
		}
		PropertyInfo property = inputField.GetType().GetProperty("text");
		if (property != null)
		{
			return (string)property.GetValue(inputField, null);
		}
		return null;
	}

	public static void SetChatText(Chat chat, string text)
	{
		object inputField = GetInputField(chat);
		if (inputField != null)
		{
			PropertyInfo property = inputField.GetType().GetProperty("text");
			if (property != null)
			{
				property.SetValue(inputField, text, null);
			}
		}
	}

	public static void DumpHierarchy(Transform t, string label, string indent = "")
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		string[] array = new string[13]
		{
			"[PrefabHammer] ",
			label,
			" ",
			indent,
			((Object)t).name,
			" | localPos=",
			null,
			null,
			null,
			null,
			null,
			null,
			null
		};
		Vector3 val = t.localPosition;
		array[6] = ((Vector3)(ref val)).ToString("F3");
		array[7] = " | localRot=";
		Quaternion val2 = t.localRotation;
		val = ((Quaternion)(ref val2)).eulerAngles;
		array[8] = ((Vector3)(ref val)).ToString("F1");
		array[9] = " | worldPos=";
		val = t.position;
		array[10] = ((Vector3)(ref val)).ToString("F3");
		array[11] = " | worldRot=";
		val2 = t.rotation;
		val = ((Quaternion)(ref val2)).eulerAngles;
		array[12] = ((Vector3)(ref val)).ToString("F1");
		Debug.Log((object)string.Concat(array));
		for (int i = 0; i < t.childCount; i++)
		{
			DumpHierarchy(t.GetChild(i), label, indent + "  ");
		}
	}

	private static Texture2D MakeTex(int width, int height, Color col)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: 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_0035: Expected O, but got Unknown
		Color[] array = (Color[])(object)new Color[width * height];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = col;
		}
		Texture2D val = new Texture2D(width, height);
		val.SetPixels(array);
		val.Apply();
		return val;
	}

	private void OnGUI()
	{
		//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0501: Unknown result type (might be due to invalid IL or missing references)
		//IL_0528: Unknown result type (might be due to invalid IL or missing references)
		//IL_0562: Unknown result type (might be due to invalid IL or missing references)
		//IL_0569: Expected O, but got Unknown
		//IL_004d: 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)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: 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_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Expected O, but got Unknown
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Expected O, but got Unknown
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Expected O, but got Unknown
		//IL_0230: 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_025c: Expected O, but got Unknown
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Expected O, but got Unknown
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Expected O, but got Unknown
		//IL_0343: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_040d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Expected O, but got Unknown
		//IL_0444: Unknown result type (might be due to invalid IL or missing references)
		//IL_0474: Unknown result type (might be due to invalid IL or missing references)
		//IL_048e: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_061c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0623: Expected O, but got Unknown
		//IL_063e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0649: Unknown result type (might be due to invalid IL or missing references)
		//IL_05eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_067e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0685: Expected O, but got Unknown
		//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0720: Unknown result type (might be due to invalid IL or missing references)
		//IL_0727: Expected O, but got Unknown
		//IL_0772: Unknown result type (might be due to invalid IL or missing references)
		//IL_0766: Unknown result type (might be due to invalid IL or missing references)
		//IL_09e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f98: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f9e: Invalid comparison between Unknown and I4
		//IL_0c67: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c74: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a49: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a4b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a50: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a54: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a59: Unknown result type (might be due to invalid IL or missing references)
		//IL_0faf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0fb6: Invalid comparison between Unknown and I4
		//IL_0831: Unknown result type (might be due to invalid IL or missing references)
		//IL_085d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0894: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0fe3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0fea: Invalid comparison between Unknown and I4
		//IL_0cfc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cfe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d03: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d07: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d0c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bcc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0903: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ac6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0947: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f70: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b41: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e72: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e98: Unknown result type (might be due to invalid IL or missing references)
		//IL_0eed: Unknown result type (might be due to invalid IL or missing references)
		if (!m_showSaveGui)
		{
			return;
		}
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
		if ((Object)(object)m_bgTex == (Object)null)
		{
			m_bgTex = MakeTex(2, 2, new Color(0.58f, 0.43f, 0.29f, 1f));
			m_borderTex = MakeTex(2, 2, new Color(0.2f, 0.15f, 0.1f, 1f));
			m_inputBgTex = MakeTex(2, 2, new Color(0.14f, 0.1f, 0.07f, 1f));
			m_btnBgTex = MakeTex(2, 2, new Color(0.35f, 0.26f, 0.17f, 1f));
			m_btnHoverBgTex = MakeTex(2, 2, new Color(0.48f, 0.36f, 0.24f, 1f));
			m_listItemBgTex = MakeTex(2, 2, new Color(0.48f, 0.35f, 0.23f, 1f));
			m_tabBgTex = MakeTex(2, 2, new Color(0.24f, 0.18f, 0.12f, 1f));
			m_tabActiveBgTex = MakeTex(2, 2, new Color(0.35f, 0.26f, 0.17f, 1f));
			m_labelStyle = new GUIStyle();
			m_labelStyle.fontSize = 20;
			m_labelStyle.fontStyle = (FontStyle)1;
			m_labelStyle.normal.textColor = new Color(0.95f, 0.9f, 0.82f, 1f);
			m_labelStyle.alignment = (TextAnchor)3;
			m_titleStyle = new GUIStyle();
			m_titleStyle.fontSize = 24;
			m_titleStyle.fontStyle = (FontStyle)1;
			m_titleStyle.normal.textColor = new Color(0.95f, 0.78f, 0.2f, 1f);
			m_titleStyle.alignment = (TextAnchor)4;
			m_textFieldStyle = new GUIStyle();
			m_textFieldStyle.fontSize = 18;
			m_textFieldStyle.normal.textColor = Color.white;
			m_textFieldStyle.alignment = (TextAnchor)3;
			m_textFieldStyle.padding = new RectOffset(10, 10, 0, 0);
			m_buttonStyle = new GUIStyle();
			m_buttonStyle.fontSize = 18;
			m_buttonStyle.fontStyle = (FontStyle)1;
			m_buttonStyle.normal.background = m_btnBgTex;
			m_buttonStyle.normal.textColor = Color.white;
			m_buttonStyle.hover.background = m_btnHoverBgTex;
			m_buttonStyle.hover.textColor = new Color(0.95f, 0.78f, 0.2f, 1f);
			m_buttonStyle.alignment = (TextAnchor)4;
			m_tabButtonStyle = new GUIStyle(m_buttonStyle);
			m_tabButtonStyle.fontSize = 16;
			m_tabButtonStyle.normal.background = m_tabBgTex;
			m_tabButtonStyle.normal.textColor = new Color(0.82f, 0.76f, 0.68f, 1f);
			m_tabButtonStyle.hover.background = m_btnHoverBgTex;
			m_tabButtonStyle.hover.textColor = new Color(0.95f, 0.9f, 0.82f, 1f);
			m_tabButtonStyle.active.background = m_tabActiveBgTex;
			m_tabButtonStyle.active.textColor = new Color(0.95f, 0.78f, 0.2f, 1f);
			m_tabButtonStyle.focused.background = m_tabBgTex;
			m_tabButtonStyle.focused.textColor = new Color(0.82f, 0.76f, 0.68f, 1f);
			m_deleteButtonStyle = new GUIStyle(m_buttonStyle);
			m_deleteButtonStyle.fontSize = 14;
			m_deleteButtonStyle.normal.background = MakeTex(2, 2, new Color(0.4f, 0.18f, 0.12f, 1f));
			m_deleteButtonStyle.hover.background = MakeTex(2, 2, new Color(0.55f, 0.22f, 0.15f, 1f));
			m_deleteButtonStyle.hover.textColor = Color.white;
		}
		float num = 600f;
		float num2 = 400f;
		float num3 = ((float)Screen.width - num) / 2f;
		float num4 = ((float)Screen.height - num2) / 2f;
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(num3 - 2f, num4 - 2f, num + 4f, num2 + 4f);
		Rect val2 = default(Rect);
		((Rect)(ref val2))..ctor(num3, num4, num, num2);
		GUI.DrawTexture(val, (Texture)(object)m_borderTex);
		GUI.DrawTexture(val2, (Texture)(object)m_bgTex);
		GUI.Label(new Rect(num3 + 20f, num4 + 15f, num - 40f, 35f), "Prefab Hammer Manager", m_titleStyle);
		Rect val3 = default(Rect);
		((Rect)(ref val3))..ctor(num3 + 25f, num4 + 60f, 175f, 35f);
		GUIStyle val4 = new GUIStyle(m_tabButtonStyle);
		if (m_activeTab == 0)
		{
			val4.normal.background = m_tabActiveBgTex;
			val4.normal.textColor = new Color(0.95f, 0.78f, 0.2f, 1f);
		}
		bool flag = (Object)(object)m_targetAnchorPiece != (Object)null || (m_selectedPieces != null && m_selectedPieces.Count > 0);
		if (flag)
		{
			if (GUI.Button(val3, "Save Combo", val4))
			{
				m_activeTab = 0;
				m_prefabConfirmDeleteIndex = -1;
				m_undoConfirmIndex = -1;
			}
		}
		else
		{
			GUIStyle val5 = new GUIStyle(val4);
			val5.normal.textColor = new Color(0.52f, 0.45f, 0.38f, 1f);
			GUI.Box(val3, "Save Combo (No Target)", val5);
		}
		Rect val6 = default(Rect);
		((Rect)(ref val6))..ctor(num3 + 212.5f, num4 + 60f, 175f, 35f);
		GUIStyle val7 = new GUIStyle(m_tabButtonStyle);
		if (m_activeTab == 1)
		{
			val7.normal.background = m_tabActiveBgTex;
			val7.normal.textColor = new Color(0.95f, 0.78f, 0.2f, 1f);
		}
		if (GUI.Button(val6, "Library Catalog", val7))
		{
			m_activeTab = 1;
			m_prefabConfirmDeleteIndex = -1;
			m_undoConfirmIndex = -1;
		}
		Rect val8 = default(Rect);
		((Rect)(ref val8))..ctor(num3 + 400f, num4 + 60f, 175f, 35f);
		GUIStyle val9 = new GUIStyle(m_tabButtonStyle);
		if (m_activeTab == 2)
		{
			val9.normal.background = m_tabActiveBgTex;
			val9.normal.textColor = new Color(0.95f, 0.78f, 0.2f, 1f);
		}
		if (GUI.Button(val8, "Undo History", val9))
		{
			m_activeTab = 2;
			m_prefabConfirmDeleteIndex = -1;
			m_undoConfirmIndex = -1;
		}
		Rect val12 = default(Rect);
		Rect val13 = default(Rect);
		Rect val14 = default(Rect);
		Rect val15 = default(Rect);
		Rect val17 = default(Rect);
		if (m_activeTab == 0 && flag)
		{
			string text = ((m_selectedPieces != null && m_selectedPieces.Count > 0) ? ("Save selected pieces (total " + m_selectedPieces.Count + ")") : ("Save targeted piece: " + (((Object)(object)m_targetAnchorPiece != (Object)null) ? m_targetAnchorPiece.m_name : "")));
			GUI.Label(new Rect(num3 + 25f, num4 + 120f, num - 50f, 25f), text, m_labelStyle);
			GUI.Label(new Rect(num3 + 25f, num4 + 150f, num - 50f, 25f), "Enter prefab name:", m_labelStyle);
			Rect val10 = default(Rect);
			((Rect)(ref val10))..ctor(num3 + 25f, num4 + 185f, num - 50f, 40f);
			GUI.DrawTexture(val10, (Texture)(object)m_inputBgTex);
			GUI.SetNextControlName("PrefabNameField");
			m_newPrefabName = GUI.TextField(val10, m_newPrefabName, m_textFieldStyle);
			if (m_shouldFocusField)
			{
				GUI.FocusControl("PrefabNameField");
				m_shouldFocusField = false;
			}
			Rect val11 = default(Rect);
			((Rect)(ref val11))..ctor(num3 + 25f, num4 + 270f, 260f, 45f);
			if (GUI.Button(val11, "Save Combo", m_buttonStyle))
			{
				SaveAndClose();
			}
			((Rect)(ref val12))..ctor(num3 + num - 285f, num4 + 270f, 260f, 45f);
			if (GUI.Button(val12, "Close Manager", m_buttonStyle))
			{
				m_showSaveGui = false;
			}
		}
		else if (m_activeTab == 1)
		{
			((Rect)(ref val13))..ctor(num3 + 25f, num4 + 110f, num - 50f, 230f);
			((Rect)(ref val14))..ctor(((Rect)(ref val13)).x - 2f, ((Rect)(ref val13)).y - 2f, ((Rect)(ref val13)).width + 4f, ((Rect)(ref val13)).height + 4f);
			GUI.DrawTexture(val14, (Texture)(object)m_borderTex);
			GUI.DrawTexture(val13, (Texture)(object)m_inputBgTex);
			float num5 = 50f;
			float num6 = (float)m_customPrefabs.Count * num5;
			if (num6 < 230f)
			{
				num6 = 230f;
			}
			((Rect)(ref val15))..ctor(0f, 0f, num - 70f, num6);
			m_scrollPosition = GUI.BeginScrollView(val13, m_scrollPosition, val15, false, true);
			Rect val18 = default(Rect);
			for (int i = 0; i < m_customPrefabs.Count; i++)
			{
				float num7 = (float)i * num5;
				GameObject val16 = m_customPrefabs[i];
				if ((Object)(object)val16 == (Object)null)
				{
					continue;
				}
				string text2 = ((Object)val16).name.Replace("PrefabHammerPiece_", "");
				((Rect)(ref val17))..ctor(5f, num7, num - 80f, 40f);
				GUI.DrawTexture(val17, (Texture)(object)m_listItemBgTex);
				GUI.Label(new Rect(15f, num7 + 5f, num - 220f, 30f), text2, m_labelStyle);
				((Rect)(ref val18))..ctor(num - 195f, num7 + 5f, 100f, 30f);
				string text3 = "Delete";
				if (m_prefabConfirmDeleteIndex == i)
				{
					text3 = "Confirm?";
				}
				if (GUI.Button(val18, text3, m_deleteButtonStyle))
				{
					if (m_prefabConfirmDeleteIndex == i)
					{
						DeletePrefab(text2);
						m_prefabConfirmDeleteIndex = -1;
						break;
					}
					m_prefabConfirmDeleteIndex = i;
				}
			}
			GUI.EndScrollView();
			((Rect)(ref val12))..ctor(num3 + 25f, num4 + 355f, num - 50f, 35f);
			if (GUI.Button(val12, "Close Manager", m_buttonStyle))
			{
				m_showSaveGui = false;
			}
		}
		else if (m_activeTab == 2)
		{
			((Rect)(ref val13))..ctor(num3 + 25f, num4 + 110f, num - 50f, 230f);
			((Rect)(ref val14))..ctor(((Rect)(ref val13)).x - 2f, ((Rect)(ref val13)).y - 2f, ((Rect)(ref val13)).width + 4f, ((Rect)(ref val13)).height + 4f);
			GUI.DrawTexture(val14, (Texture)(object)m_borderTex);
			GUI.DrawTexture(val13, (Texture)(object)m_inputBgTex);
			float num5 = 50f;
			m_placementHistory.RemoveAll((PlacementRecord record) => record.pieces == null || record.pieces.Count == 0 || record.pieces.TrueForAll((ZNetView p) => (Object)(object)p == (Object)null));
			int count = m_placementHistory.Count;
			float num6 = (float)count * num5;
			if (num6 < 230f)
			{
				num6 = 230f;
			}
			((Rect)(ref val15))..ctor(0f, 0f, num - 70f, num6);
			m_scrollPosition = GUI.BeginScrollView(val13, m_scrollPosition, val15, false, true);
			Rect val19 = default(Rect);
			for (int i = 0; i < count; i++)
			{
				int num8 = count - 1 - i;
				float num7 = (float)i * num5;
				PlacementRecord placementRecord = m_placementHistory[num8];
				if (placementRecord == null)
				{
					continue;
				}
				int num9 = 0;
				if (placementRecord.pieces != null)
				{
					foreach (ZNetView piece in placementRecord.pieces)
					{
						if ((Object)(object)piece != (Object)null)
						{
							num9++;
						}
					}
				}
				float num10 = Time.time - placementRecord.timestamp;
				string text4 = "";
				text4 = ((!(num10 < 60f)) ? ((int)(num10 / 60f) + "m ago") : ((int)num10 + "s ago"));
				string text5 = placementRecord.blueprintName + " (" + num9 + " pieces, " + text4 + ")";
				((Rect)(ref val17))..ctor(5f, num7, num - 80f, 40f);
				GUI.DrawTexture(val17, (Texture)(object)m_listItemBgTex);
				GUI.Label(new Rect(15f, num7 + 5f, num - 220f, 30f), text5, m_labelStyle);
				((Rect)(ref val19))..ctor(num - 195f, num7 + 5f, 100f, 30f);
				string text3 = "Undo";
				if (m_undoConfirmIndex == num8)
				{
					text3 = "Confirm?";
				}
				if (GUI.Button(val19, text3, m_deleteButtonStyle))
				{
					if (m_undoConfirmIndex == num8)
					{
						UndoPlacement(num8);
						m_undoConfirmIndex = -1;
						break;
					}
					m_undoConfirmIndex = num8;
				}
			}
			GUI.EndScrollView();
			((Rect)(ref val12))..ctor(num3 + 25f, num4 + 355f, num - 50f, 35f);
			if (GUI.Button(val12, "Close Manager", m_buttonStyle))
			{
				m_showSaveGui = false;
			}
		}
		if ((int)Event.current.type != 4)
		{
			return;
		}
		if ((int)Event.current.keyCode == 13)
		{
			if (m_activeTab == 0)
			{
				SaveAndClose();
			}
		}
		else if ((int)Event.current.keyCode == 27)
		{
			m_showSaveGui = false;
		}
	}

	public static void AddPlacementRecord(string name, List<ZNetView> pieces)
	{
		if (pieces != null && pieces.Count != 0)
		{
			PlacementRecord placementRecord = new PlacementRecord();
			placementRecord.blueprintName = name;
			placementRecord.pieceCount = pieces.Count;
			placementRecord.timestamp = Time.time;
			placementRecord.pieces = pieces;
			m_placementHistory.Add(placementRecord);
			int num = 5;
			if (configMaxUndoHistory != null)
			{
				num = Mathf.Clamp(configMaxUndoHistory.Value, 1, 20);
			}
			while (m_placementHistory.Count > num)
			{
				m_placementHistory.RemoveAt(0);
			}
		}
	}

	public static void UndoPlacement(int index)
	{
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		if (index < 0 || index >= m_placementHistory.Count)
		{
			return;
		}
		PlacementRecord placementRecord = m_placementHistory[index];
		m_placementHistory.RemoveAt(index);
		if (placementRecord == null)
		{
			return;
		}
		Debug.Log((object)("[PrefabHammer] UndoPlacement: blueprintName=" + placementRecord.blueprintName + ", pieces=" + ((placementRecord.pieces != null) ? placementRecord.pieces.Count : 0)));
		int num = 0;
		bool flag = (Object)(object)Player.m_localPlayer != (Object)null && !Player.m_localPlayer.NoCostCheat();
		if (placementRecord.pieces != null)
		{
			foreach (ZNetView piece in placementRecord.pieces)
			{
				if (!((Object)(object)piece != (Object)null) || !((Object)(object)((Component)piece).gameObject != (Object)null) || !piece.IsValid())
				{
					continue;
				}
				if (flag)
				{
					try
					{
						Piece component = ((Component)piece).gameObject.GetComponent<Piece>();
						if ((Object)(object)component != (Object)null)
						{
							if (piece.GetZDO() != null)
							{
								((Component)piece).gameObject.transform.position = piece.GetZDO().GetPosition();
							}
							component.DropResources((HitData)null);
						}
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[PrefabHammer] Failed to drop resources for piece: " + ex.Message));
					}
				}
				try
				{
					WearNTear component2 = ((Component)piece).gameObject.GetComponent<WearNTear>();
					if ((Object)(object)component2 != (Object)null && component2.m_destroyedEffect != null)
					{
						component2.m_destroyedEffect.Create(((Component)piece).gameObject.transform.position, ((Component)piece).gameObject.transform.rotation, (Transform)null, 1f, -1);
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[PrefabHammer] Failed to play destroy effect: " + ex.Message));
				}
				Container componentInChildren = ((Component)piece).gameObject.GetComponentInChildren<Container>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					DropContainerItemsInCrates(componentInChildren);
				}
				if (piece.GetZDO() != null)
				{
					try
					{
						piece.ClaimOwnership();
						if (ZDOMan.instance != null)
						{
							ZDOMan.instance.DestroyZDO(piece.GetZDO());
						}
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[PrefabHammer] Failed to claim and destroy ZDO directly: " + ex.Message));
					}
				}
				ZNetScene.instance.Destroy(((Component)piece).gameObject);
				num++;
			}
		}
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)2, "Undid " + placementRecord.blueprintName + " (" + num + " pieces removed)", 0, (Sprite)null);
		}
		else
		{
			Debug.Log((object)("[PrefabHammer] Undid " + placementRecord.blueprintName + " (" + num + " pieces removed)"));
		}
	}

	private static void SaveContainer(Container c)
	{
		if ((Object)(object)c == (Object)null)
		{
			return;
		}
		try
		{
			MethodInfo method = typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(c, null);
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PrefabHammer] Error saving container: " + ex.Message));
		}
	}

	private static void DropContainerItemsInCrates(Container container)
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)container == (Object)null || container.GetInventory() == null || container.GetInventory().NrOfItems() == 0)
		{
			return;
		}
		try
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("CargoCrate") : null);
			if ((Object)(object)val != (Object)null)
			{
				Vector3 position = ((Component)container).transform.position;
				Inventory inventory = container.GetInventory();
				List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
				int num = 0;
				Vector3 val2 = default(Vector3);
				while (list.Count > 0 && num < 10)
				{
					((Vector3)(ref val2))..ctor(position.x, position.y + 0.5f + (float)num * 0.4f, position.z);
					GameObject val3 = Object.Instantiate<GameObject>(val, val2, Quaternion.identity);
					Container component = val3.GetComponent<Container>();
					if ((Object)(object)component == (Object)null)
					{
						Object.Destroy((Object)(object)val3);
						break;
					}
					Inventory inventory2 = component.GetInventory();
					List<ItemData> list2 = new List<ItemData>();
					foreach (ItemData item in list)
					{
						int stack = item.m_stack;
						inventory2.MoveItemToThis(inventory, item);
						if (!inventory.ContainsItem(item) || item.m_stack < stack)
						{
							list2.Add(item);
						}
					}
					SaveContainer(component);
					num++;
					list.Clear();
					list.AddRange(inventory.GetAllItems());
					if (list2.Count == 0)
					{
						break;
					}
				}
				SaveContainer(container);
				Debug.Log((object)("[PrefabHammer] Spawned " + num + " CargoCrate(s) and dropped all items from container at " + position));
			}
			else if ((Object)(object)container.m_destroyedLootPrefab != (Object)null)
			{
				MethodInfo method = typeof(Container).GetMethod("DropAllItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(GameObject) }, null);
				if (method != null)
				{
					method.Invoke(container, new object[1] { container.m_destroyedLootPrefab });
					return;
				}
				MethodInfo method2 = typeof(Container).GetMethod("DropAllItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method2 != null)
				{
					method2.Invoke(container, null);
				}
			}
			else
			{
				MethodInfo method2 = typeof(Container).GetMethod("DropAllItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method2 != null)
				{
					method2.Invoke(container, null);
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PrefabHammer] Failed to drop container items during undo: " + ex.Message));
		}
	}

	private static void SaveAndClose()
	{
		m_showSaveGui = false;
		string text = m_newPrefabName.Trim();
		if (string.IsNullOrEmpty(text))
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "Cannot save: name is empty.", 0, (Sprite)null);
			}
			return;
		}
		float value = configRadius.Value;
		if (SaveModularPrefab(text, value, m_targetAnchorPiece, m_selectedPieces))
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "Saved custom piece: " + text + "!", 0, (Sprite)null);
			}
			m_recipesAddedToLocalPlayer = false;
			ClearSelection();
			RegisterCustomPieces();
		}
		else if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)2, "Failed to save combo.", 0, (Sprite)null);
		}
	}

	public static void DeletePrefab(string name)
	{
		try
		{
			string path = Path.Combine(GetBlueprintsDir(), name + ".json");
			if (File.Exists(path))
			{
				File.Delete(path);
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Deleted custom prefab: " + name, 0, (Sprite)null);
				}
				else
				{
					Debug.Log((object)("[PrefabHammer] Deleted custom prefab: " + name));
				}
				RegisterCustomPieces();
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[PrefabHammer] Error deleting prefab " + name + ": " + ex.Message));
		}
	}

	private static void AddCustomRecipesToPlayer(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		try
		{
			FieldInfo field = typeof(Player).GetField("m_knownRecipes", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field != null))
			{
				return;
			}
			HashSet<string> hashSet = (HashSet<string>)field.GetValue(player);
			if (hashSet == null)
			{
				return;
			}
			foreach (GameObject customPrefab in m_customPrefabs)
			{
				if ((Object)(object)customPrefab != (Object)null)
				{
					Piece component = customPrefab.GetComponent<Piece>();
					if ((Object)(object)component != (Object)null && !hashSet.Contains(component.m_name))
					{
						hashSet.Add(component.m_name);
						Debug.Log((object)("[PrefabHammer] Added " + component.m_name + " to player known recipes."));
					}
				}
			}
			MethodInfo method = typeof(Player).GetMethod("UpdateAvailablePiecesList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(player, null);
				Debug.Log((object)"[PrefabHammer] Force-refreshed player available pieces list.");
			}
			PieceTable buildPieces = GetBuildPieces(player);
			if ((Object)(object)buildPieces != (Object)null)
			{
				try
				{
					FieldInfo field2 = typeof(PieceTable).GetField("m_selectedCategory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						int category = (int)field2.GetValue(buildPieces);
						buildPieces.SetCategory(category);
						Debug.Log((object)"[PrefabHammer] Force-refreshed PieceTable active category grid.");
					}
				}
				catch (Exception)
				{
				}
			}
			m_recipesAddedToLocalPlayer = true;
		}
		catch (Exception ex2)
		{
			Debug.LogError((object)("[PrefabHammer] Failed to add custom recipes: " + ex2.Message));
		}
	}

	public static void InspectWorldOrigin(float radius = 50f)
	{
		//IL_001c: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)("[PrefabHammer] === INSPECTING WORLD ORIGIN (0,0,0) (Scan Radius: " + radius + "m) ==="));
		Vector3 zero = Vector3.zero;
		Collider[] array = Physics.OverlapSphere(zero, radius);
		Dictionary<string, int> dictionary = new Dictionary<string, int>();
		Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
		HashSet<GameObject> hashSet = new HashSet<GameObject>();
		int num = 0;
		int num2 = 0;
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
			{
				continue;
			}
			ZNetView componentInParent = ((Component)val).GetComponentInParent<ZNetView>();
			GameObject val2 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)((Component)val).transform.root).gameObject);
			if (hashSet.Contains(val2))
			{
				continue;
			}
			hashSet.Add(val2);
			float num3 = Vector3.Distance(val2.transform.position, zero);
			string text = ((Object)val2).name.Replace("(Clone)", "").Trim();
			string key = text;
			ItemDrop component = val2.GetComponent<ItemDrop>();
			if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null)
			{
				key = "ItemDrop: " + component.m_itemData.m_shared.m_name + " (stack " + component.m_itemData.m_stack + ")";
			}
			else
			{
				Piece component2 = val2.GetComponent<Piece>();
				if ((Object)(object)component2 != (Object)null && !string.IsNullOrEmpty(component2.m_name))
				{
					key = "Piece: " + component2.m_name + " [" + text + "]";
				}
			}
			if (num3 <= 1f)
			{
				num2++;
			}
			if (dictionary.ContainsKey(key))
			{
				dictionary[key]++;
				if (num3 < dictionary2[key])
				{
					dictionary2[key] = num3;
				}
			}
			else
			{
				dictionary[key] = 1;
				dictionary2[key] = num3;
			}
			num++;
		}
		Debug.Log((object)("[PrefabHammer] Origin Scan Results: Found " + num + " unique entities (" + num2 + " at exact origin <= 1.0m):"));
		foreach (KeyValuePair<string, int> item in dictionary)
		{
			Debug.Log((object)("  - " + item.Key + " | Count: " + item.Value + " | Closest Distance: " + dictionary2[item.Key].ToString("F1") + "m"));
		}
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)2, "Origin Scan: Found " + num + " entities (" + num2 + " at exact 0,0,0). Check BepInEx console log.", 0, (Sprite)null);
		}
	}

	public static void CleanWorldOrigin(float radius = 50f)
	{
		//IL_001c: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)("[PrefabHammer] === CLEANING WORLD ORIGIN (0,0,0) (Scan Radius: " + radius + "m) ==="));
		Vector3 zero = Vector3.zero;
		Collider[] array = Physics.OverlapSphere(zero, radius);
		HashSet<GameObject> hashSet = new HashSet<GameObject>();
		int num = 0;
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
			{
				continue;
			}
			ZNetView componentInParent = ((Component)val).GetComponentInParent<ZNetView>();
			GameObject val2 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)((Component)val).transform.root).gameObject);
			if (hashSet.Contains(val2))
			{
				continue;
			}
			hashSet.Add(val2);
			float num2 = Vector3.Distance(val2.transform.position, zero);
			string text = ((Object)val2).name.Replace("(Clone)", "").Trim();
			bool flag = text.StartsWith("PrefabHammerPiece_") && num2 <= 15f;
			bool flag2 = (Object)(object)val2.GetComponent<ItemDrop>() != (Object)null && num2 <= 15f;
			bool flag3 = (Object)(object)val2.GetComponent<Piece>() != (Object)null && num2 <= 5f;
			if (!flag && !flag2 && !flag3)
			{
				continue;
			}
			try
			{
				if ((Object)(object)componentInParent != (Object)null && componentInParent.IsValid())
				{
					if (componentInParent.GetZDO() != null)
					{
						componentInParent.ClaimOwnership();
						if (ZDOMan.instance != null)
						{
							ZDOMan.instance.DestroyZDO(componentInParent.GetZDO());
						}
					}
					ZNetScene.instance.Destroy(val2);
				}
				else
				{
					Object.Destroy((Object)(object)val2);
				}
				num++;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[PrefabHammer] Error cleaning origin entity " + text + ": " + ex.Message));
			}
		}
		Debug.Log((object)("[PrefabHammer] Origin Clean Complete: Purged " + num + " origin entity/entities near (0,0,0)."));
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)2, "Cleaned " + num + " origin entity/entities near (0,0,0).", 0, (Sprite)null);
		}
	}
}
[HarmonyPatch(typeof(ZNetScene), "Awake")]
public static class ZNetScene_Awake_Patch
{
	public static void Postfix(ZNetScene __instance)
	{
		PrefabHammerPlugin.RegisterCustomPieces();
	}
}
[HarmonyPatch(typeof(Chat), "InputText")]
public static class Chat_InputText_Patch
{
	public static bool Prefix(Chat __instance)
	{
		string chatText = PrefabHammerPlugin.GetChatText(__instance);
		if (string.IsNullOrEmpty(chatText))
		{
			return true;
		}
		if (chatText.StartsWith("/prefab"))
		{
			string[] array = chatText.Split(new char[1] { ' ' });
			string text = array[0].ToLower();
			float result2;
			if (text == "/prefabsave" || (array.Length > 1 && array[1].ToLower() == "save"))
			{
				string text2 = "";
				float radius = PrefabHammerPlugin.configRadius.Value;
				int num = ((text == "/prefabsave") ? 1 : 2);
				if (array.Length > num)
				{
					text2 = array[num];
				}
				int num2 = num + 1;
				if (array.Length > num2 && float.TryParse(array[num2], out var result))
				{
					radius = result;
				}
				if (string.IsNullOrEmpty(text2))
				{
					text2 = "Prefab_" + DateTime.Now.ToString("yyyyMMdd_HHmmss");
				}
				Piece hoveringPiece = PrefabHammerPlugin.GetHoveringPiece(Player.m_localPlayer);
				if (PrefabHammerPlugin.SaveModularPrefab(text2, radius, hoveringPiece, PrefabHammerPlugin.m_selectedPieces))
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Saved custom piece: " + text2 + "!", 0, (Sprite)null);
					PrefabHammerPlugin.ClearSelection();
					PrefabHammerPlugin.RegisterCustomPieces();
				}
				else
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Failed to save: aim at a piece first.", 0, (Sprite)null);
				}
				PrefabHammerPlugin.SetChatText(__instance, "");
			}
			else if (text == "/prefabreload" || (array.Length > 1 && array[1].ToLower() == "reload"))
			{
				PrefabHammerPlugin.RegisterCustomPieces();
				((Character)Player.m_localPlayer).Message((MessageType)2, "Reloaded prefab pieces!", 0, (Sprite)null);
				PrefabHammerPlugin.SetChatText(__instance, "");
			}
			else if (text == "/prefablist" || text == "/prefablibrary" || (array.Length > 1 && (array[1].ToLower() == "list" || array[1].ToLower() == "library")))
			{
				PrefabHammerPlugin.m_activeTab = 1;
				PrefabHammerPlugin.m_prefabConfirmDeleteIndex = -1;
				PrefabHammerPlugin.m_showSaveGui = true;
				PrefabHammerPlugin.SetChatText(__instance, "");
			}
			else if (text == "/prefabdelete" || (array.Length > 1 && array[1].ToLower() == "delete"))
			{
				string text2 = "";
				int num3 = ((text == "/prefabdelete") ? 1 : 2);
				if (array.Length > num3)
				{
					text2 = array[num3];
				}
				if (string.IsNullOrEmpty(text2))
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Specify a prefab name to delete.", 0, (Sprite)null);
				}
				else
				{
					PrefabHammerPlugin.DeletePrefab(text2);
				}
				PrefabHammerPlugin.SetChatText(__instance, "");
			}
			else if (text == "/prefabinspectorigin" || text == "/prefabinspect" || (array.Length > 1 && array[1].ToLower() == "inspect"))
			{
				float radius2 = 50f;
				if (array.Length > 1 && float.TryParse(array[^1], out result2))
				{
					radius2 = result2;
				}
				PrefabHammerPlugin.InspectWorldOrigin(radius2);
				PrefabHammerPlugin.SetChatText(__instance, "");
			}
			else if (text == "/prefabcleanorigin" || text == "/prefabclean" || (array.Length > 1 && array[1].ToLower() == "clean"))
			{
				float radius2 = 50f;
				if (array.Length > 1 && float.TryParse(array[^1], out result2))
				{
					radius2 = result2;
				}
				PrefabHammerPlugin.CleanWorldOrigin(radius2);
				PrefabHammerPlugin.SetChatText(__instance, "");
			}
		}
		return true;
	}
}
[HarmonyPatch(typeof(KeyHints), "UpdateHints")]
public static class KeyHints_UpdateHints_SafetyPatch
{
	private static FieldInfo s_buildPiecesField;

	private static MethodInfo s_getSelectedPieceMethod;

	[HarmonyPriority(800)]
	[HarmonyPrefix]
	public static bool Prefix(KeyHints __instance)
	{
		try
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return true;
			}
			if (s_buildPiecesField == null)
			{
				s_buildPiecesField = typeof(Player).GetField("m_buildPieces", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (s_buildPiecesField == null)
			{
				return true;
			}
			object value = s_buildPiecesField.GetValue(Player.m_localPlayer);
			if (value == null)
			{
				return true;
			}
			if (s_getSelectedPieceMethod == null)
			{
				s_getSelectedPieceMethod = value.GetType().GetMethod("GetSelectedPiece", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (s_getSelectedPieceMethod == null)
			{
				return true;
			}
			object? obj = s_getSelectedPieceMethod.Invoke(value, null);
			Piece val = (Piece)((obj is Piece) ? obj : null);
			if (!object.ReferenceEquals(val, null) && (Object)(object)val == (Object)null)
			{
				return false;
			}
		}
		catch (Exception)
		{
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
public static class Player_UpdatePlacementGhost_Patch
{
	private static float lastLogTime = 0f;

	public static void Postfix(Player __instance)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		if (!(Time.time - lastLogTime > 5f))
		{
			return;
		}
		lastLogTime = Time.time;
		try
		{
			FieldInfo field = typeof(Player).GetField("m_placementGhost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				GameObject val = (GameObject)field.GetValue(__instance);
				if ((Object)(object)val != (Object)null && ((Object)val).name.StartsWith("PrefabHammerPiece_"))
				{
					object[] array = new object[10] { "[PrefabHammer] Ghost: pos=", null, null, null, null, null, null, null, null, null };
					Vector3 val2 = val.transform.position;
					array[1] = ((Vector3)(ref val2)).ToString("F1");
					array[2] = " rot=";
					val2 = val.transform.eulerAngles;
					array[3] = ((Vector3)(ref val2)).ToString("F1");
					array[4] = " active=";
					array[5] = val.activeInHierarchy;
					array[6] = " layer=";
					array[7] = val.layer;
					array[8] = " nview=";
					array[9] = (Object)(object)val.GetComponent<ZNetView>() != (Object)null;
					Debug.Log((object)string.Concat(array));
				}
			}
		}
		catch (Exception)
		{
		}
	}
}
[HarmonyPatch(typeof(Player), "TakeInput")]
public static class Player_TakeInput_Patch
{
	public static void Postfix(ref bool __result)
	{
		if (PrefabHammerPlugin.m_showSaveGui)
		{
			__result = false;
		}
	}
}
[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
public static class GameCamera_UpdateMouseCapture_Patch
{
	public static bool Prefix()
	{
		if (PrefabHammerPlugin.m_showSaveGui)
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(TextInput), "IsVisible")]
public static class TextInput_IsVisible_Patch
{
	public static bool Prefix(ref bool __result)
	{
		if (PrefabHammerPlugin.m_showSaveGui)
		{
			__result = true;
			return false;
		}
		return true;
	}
}
public class PrefabSelectionHighlight : MonoBehaviour
{
	private GameObject m_highlightRoot;

	private Material m_material;

	private float m_time;

	private List<MeshRenderer> m_renderers = new List<MeshRenderer>();

	private void Awake()
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Expected O, but got Unknown
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Expected O, but got Unknown
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_0359: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cd: 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_0259: Expected O, but got Unknown
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		Shader val = Shader.Find("Legacy Shaders/Transparent/Diffuse");
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Transparent/Diffuse");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("UI/Default");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Standard");
		}
		if ((Object)(object)val != (Object)null)
		{
			m_material = new Material(val);
		}
		else
		{
			m_material = new Material(Shader.Find("Sprites/Default"));
		}
		if (m_material.HasProperty("_Color"))
		{
			m_material.color = new Color(0.2f, 0.8f, 0.2f, 0.4f);
		}
		m_highlightRoot = new GameObject("PrefabSelectionHighlightRoot");
		m_highlightRoot.transform.SetParent(((Component)this).transform, false);
		m_highlightRoot.transform.localPosition = Vector3.zero;
		m_highlightRoot.transform.localRotation = Quaternion.identity;
		m_highlightRoot.transform.localScale = Vector3.one;
		MeshFilter[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshFilter>(true);
		bool flag = false;
		MeshFilter[] array = componentsInChildren;
		foreach (MeshFilter val2 in array)
		{
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sharedMesh == (Object)null)
			{
				continue;
			}
			Renderer component = ((Component)val2).GetComponent<Renderer>();
			if ((Object)(object)component == (Object)null || !component.enabled || !((Component)component).gameObject.activeInHierarchy)
			{
				continue;
			}
			string text = ((Object)((Component)val2).gameObject).name.ToLower();
			if (!text.Contains("collision") && !text.Contains("collider") && !text.Contains("trigger") && !text.Contains("preview") && !text.Contains("ghost") && !text.Contains("helper") && !text.Contains("dummy"))
			{
				GameObject val3 = new GameObject(((Object)((Component)val2).gameObj