Decompiled source of ShelfLabels v1.0.5

Mods/SimpleLabels.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using HarmonyLib;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Persistence.Loaders;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.UI;
using Il2CppSystem;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Utils;
using Newtonsoft.Json;
using SimpleLabels;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(LabelMod), "Simple Labels", "1.0.0", "Tiago", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: AssemblyTitle("Labels")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Labels")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c94728ab-4450-4832-b137-24be7a12cc63")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SimpleLabels;

public class LabelMod : MelonMod
{
	[HarmonyPatch(typeof(StorageMenu), "Open", new Type[] { typeof(StorageEntity) })]
	private class StorageMenu_Open_Patch
	{
		private static void Postfix(StorageMenu __instance, StorageEntity entity)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (debug)
			{
				MelonLogger.Msg("Storage menu opened for: " + entity.StorageEntityName);
			}
			try
			{
				if (entity != null)
				{
					Instance.openEntityGameObject = ((Component)entity).gameObject;
					Instance.openEntityName = ((Object)entity).name;
					LabelMod instance = Instance;
					Guid gUID = ((BuildableItem)Instance.openEntityGameObject.GetComponent<PlaceableStorageEntity>()).GUID;
					instance.openEntityGameObjectGUID = ((object)(Guid)(ref gUID)).ToString();
					if (debug)
					{
						MelonLogger.Msg("StorageEntity GUID: " + Instance.openEntityGameObjectGUID);
					}
				}
			}
			catch
			{
				if (debug)
				{
					MelonLogger.Msg("StorageEntity is NOT a UnityEngine.Object");
				}
			}
			if (!(entity.StorageEntityName == "Small Storage Rack") && !(entity.StorageEntityName == "Medium Storage Rack") && !(entity.StorageEntityName == "Large Storage Rack"))
			{
				return;
			}
			((Component)((Component)__instance).gameObject.transform.Find("CustomInputField")).gameObject.SetActive(true);
			string value2;
			if (Instance.unsavedLabelData.Labels.TryGetValue(Instance.openEntityGameObjectGUID, out var value))
			{
				Instance.customInputField.text = value;
				if (debug)
				{
					MelonLogger.Msg("Loaded existing unsaved label: " + value);
				}
			}
			else if (Instance.labelData.Labels.TryGetValue(Instance.openEntityGameObjectGUID, out value2))
			{
				Instance.customInputField.text = value2;
				if (debug)
				{
					MelonLogger.Msg("Loaded existing label: " + value2);
				}
			}
			else
			{
				Instance.customInputField.text = string.Empty;
			}
			if (Instance.config.AutoFocus)
			{
				if (debug)
				{
					MelonLogger.Msg("Focusing on input field.");
				}
				((Selectable)((Component)((Component)__instance).gameObject.transform.Find("CustomInputField")).GetComponent<TMP_InputField>()).Select();
				((Component)((Component)__instance).gameObject.transform.Find("CustomInputField")).GetComponent<TMP_InputField>().ActivateInputField();
			}
			else if (debug)
			{
				MelonLogger.Msg("Not focusing on input field.");
			}
			Instance.wasStorageRackOpen = true;
			StorageTracker.TrackStorage(Instance.openEntityGameObjectGUID, ((Component)entity).gameObject);
		}
	}

	[HarmonyPatch(typeof(GridItemLoader), "LoadAndCreate")]
	[HarmonyPatch(new Type[] { typeof(string) })]
	private class GridItemLoaderPatch
	{
		private static void Postfix(GridItem __result, string mainPath)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__result != (Object)null))
			{
				return;
			}
			GameObject gameObject = ((Component)__result).gameObject;
			string name = ((Object)__result).name;
			Guid gUID = ((BuildableItem)__result).GUID;
			string text = ((object)(Guid)(ref gUID)).ToString();
			if (name.Contains("StorageRack"))
			{
				if (debug)
				{
					MelonLogger.Msg("Processing storage rack: " + name + " (GUID: " + text + ")");
				}
				try
				{
					Instance.AddLabelPrefabToGameObject(gameObject, name, text);
					StorageTracker.TrackStorage(text, gameObject);
				}
				catch (Exception ex)
				{
					((MelonBase)Instance).LoggerInstance.Error("Failed to process storage rack " + name + ": " + ex.Message);
				}
			}
		}
	}

	public static class StorageTracker
	{
		public static Dictionary<string, GameObject> StorageEntities = new Dictionary<string, GameObject>();

		public static void TrackStorage(string guid, GameObject GO)
		{
			if (string.IsNullOrEmpty(guid))
			{
				((MelonBase)Instance).LoggerInstance.Warning("Attempted to track storage with empty GUID");
			}
			else if ((Object)(object)GO == (Object)null)
			{
				((MelonBase)Instance).LoggerInstance.Warning("Attempted to track null GameObject for GUID: " + guid);
			}
			else if (!StorageEntities.ContainsKey(guid))
			{
				StorageEntities.Add(guid, GO);
			}
			else if ((Object)(object)StorageEntities[guid] != (Object)(object)GO)
			{
				((MelonBase)Instance).LoggerInstance.Warning("GUID conflict detected: " + guid + " already tracked to different GameObject");
			}
		}

		public static void UntrackStorage(string guid)
		{
			if (StorageEntities.ContainsKey(guid))
			{
				StorageEntities.Remove(guid);
			}
			else if (debug)
			{
				((MelonBase)Instance).LoggerInstance.Msg("Attempted to untrack non-existent GUID: " + guid);
			}
		}

		public static void UntrackAllStorage()
		{
			int count = StorageEntities.Count;
			StorageEntities.Clear();
		}
	}

	public class ModConfig
	{
		public bool AutoFocus { get; set; } = true;

	}

	[Serializable]
	public class LabelData
	{
		public Dictionary<string, string> Labels { get; set; } = new Dictionary<string, string>();

	}

	[CompilerGenerated]
	private sealed class <WaitAndHook>d__20 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public LabelMod <>4__this;

		private UnityEvent <onSaveStart>5__1;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if ((Object)(object)Singleton<SaveManager>.Instance == (Object)null && (Object)(object)Singleton<LoadManager>.Instance == (Object)null)
			{
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			<onSaveStart>5__1 = Singleton<SaveManager>.Instance.onSaveStart;
			<onSaveStart>5__1.AddListener(UnityAction.op_Implicit((Action)<>4__this.OnSaveStart));
			return false;
		}

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

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

	[CompilerGenerated]
	private sealed class <WaitAndSubscribe>d__23 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public LabelMod <>4__this;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if ((Object)(object)Singleton<StorageMenu>.Instance == (Object)null)
			{
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			Singleton<StorageMenu>.Instance.onClosed.AddListener(UnityAction.op_Implicit((Action)<>4__this.OnStorageMenuClosed));
			return false;
		}

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

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

	private static readonly bool debug;

	private TMP_InputField customInputField;

	private bool wasStorageRackOpen = false;

	private GameObject openEntityGameObject;

	private string openEntityGameObjectGUID;

	private string openEntityName;

	private ModConfig config;

	private string configFolderPath;

	private string configFilePath;

	private LabelData labelData;

	private string labelDataFilePath;

	private LabelData unsavedLabelData;

	private GameObject labelPrefab;

	public static LabelMod Instance { get; private set; }

	public override void OnInitializeMelon()
	{
		Instance = this;
		((MelonBase)this).LoggerInstance.Msg("SimpleLabels mod initializing...");
		configFolderPath = Path.Combine(MelonEnvironment.ModsDirectory, "SimpleLabels");
		configFilePath = Path.Combine(configFolderPath, "Config.json");
		EnsureConfigDirectoryExists();
		LoadConfig();
		labelDataFilePath = Path.Combine(configFolderPath, "Labels.json");
		unsavedLabelData = new LabelData();
		MelonCoroutines.Start(WaitAndHook());
	}

	public override void OnSceneWasInitialized(int buildIndex, string sceneName)
	{
		if (debug)
		{
			MelonLogger.Msg("Scene loaded: " + sceneName);
		}
		if (sceneName == "Main")
		{
			MelonCoroutines.Start(WaitAndSubscribe());
			InitializeLabelPrefab();
			GameObject val = GameObject.Find("UI/StorageMenu");
			if ((Object)(object)val != (Object)null)
			{
				CreateInputField(val);
				if (debug)
				{
					MelonLogger.Msg("Label input field created.");
				}
			}
			LoadLabelData();
			if ((Object)(object)labelPrefab == (Object)null)
			{
				MelonLogger.Error("Label prefab is null!");
			}
			else
			{
				MelonLogger.Msg("Label prefab is not null.");
			}
		}
		else if (sceneName == "Menu")
		{
			unsavedLabelData = new LabelData();
			if (debug)
			{
				MelonLogger.Msg("Cleared unsaved label data");
			}
		}
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		if (debug)
		{
			MelonLogger.Msg("Scene loaded: " + sceneName);
		}
	}

	[IteratorStateMachine(typeof(<WaitAndHook>d__20))]
	private IEnumerator WaitAndHook()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <WaitAndHook>d__20(0)
		{
			<>4__this = this
		};
	}

	private void OnSaveStart()
	{
		((MelonBase)this).LoggerInstance.Msg("Saving label data...");
		foreach (KeyValuePair<string, string> label in unsavedLabelData.Labels)
		{
			labelData.Labels[label.Key] = label.Value;
		}
		foreach (string key in unsavedLabelData.Labels.Keys)
		{
			if (string.IsNullOrEmpty(unsavedLabelData.Labels[key]))
			{
				labelData.Labels.Remove(key);
			}
		}
		SaveLabelData();
		if (debug)
		{
			MelonLogger.Msg("Saved all label changes");
		}
	}

	[IteratorStateMachine(typeof(<WaitAndSubscribe>d__23))]
	private IEnumerator WaitAndSubscribe()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <WaitAndSubscribe>d__23(0)
		{
			<>4__this = this
		};
	}

	private void OnStorageMenuClosed()
	{
		((Component)((Component)Singleton<StorageMenu>.Instance).gameObject.transform.Find("CustomInputField")).gameObject.SetActive(false);
		try
		{
			if (Instance.wasStorageRackOpen)
			{
				string text = Instance.customInputField.text;
				text = Regex.Replace(text, "[\\n\\r]", "");
				string text2 = Instance.openEntityGameObjectGUID;
				if (debug)
				{
					MelonLogger.Msg("Saved label: " + text + " for GUID: " + text2);
				}
				if (!string.IsNullOrEmpty(text2))
				{
					Instance.unsavedLabelData.Labels[text2] = text;
					Instance.UpdateLabelPrefabInGameObject(text2, text, Instance.openEntityGameObject, Instance.openEntityName);
				}
				Instance.wasStorageRackOpen = false;
			}
		}
		catch (Exception ex)
		{
			((MelonBase)this).LoggerInstance.Error("Error during menu close: " + ex.Message);
		}
	}

	private void CreateInputField(GameObject parentUI)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_003a: 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_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Expected O, but got Unknown
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: 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_01b2: Expected O, but got Unknown
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			GameObject val = new GameObject("CustomInputField");
			val.layer = 5;
			val.transform.SetParent(parentUI.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0.5f, 0.5f);
			val2.anchorMax = new Vector2(0.5f, 0.5f);
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.sizeDelta = new Vector2(550f, 50f);
			GameObject val3 = GameObject.Find("UI/StorageMenu/Container/Title");
			RectTransform component = val3.GetComponent<RectTransform>();
			Vector2 anchoredPosition = component.anchoredPosition;
			Vector2 sizeDelta = component.sizeDelta;
			val2.anchoredPosition = new Vector2(anchoredPosition.x, anchoredPosition.y - sizeDelta.y + 155f);
			Image val4 = val.AddComponent<Image>();
			((Graphic)val4).color = new Color(1f, 1f, 1f, 0.9f);
			Outline val5 = val.AddComponent<Outline>();
			((Shadow)val5).effectColor = new Color(0f, 0f, 0f, 0.5f);
			((Shadow)val5).effectDistance = new Vector2(2f, 2f);
			GameObject val6 = new GameObject("TextArea");
			RectTransform val7 = val6.AddComponent<RectTransform>();
			((Transform)val7).SetParent(val.transform, false);
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = new Vector2(20f, 10f);
			val7.offsetMax = new Vector2(-20f, -10f);
			GameObject val8 = new GameObject("Placeholder");
			RectTransform val9 = val8.AddComponent<RectTransform>();
			((Transform)val9).SetParent(val.transform, false);
			val9.anchorMin = Vector2.zero;
			val9.anchorMax = Vector2.one;
			val9.offsetMin = new Vector2(20f, 10f);
			val9.offsetMax = new Vector2(-20f, -10f);
			customInputField = val.AddComponent<TMP_InputField>();
			TextMeshProUGUI val10 = val6.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val10).fontSize = 24f;
			((Graphic)val10).color = Color.black;
			((TMP_Text)val10).alignment = (TextAlignmentOptions)513;
			((TMP_Text)val10).enableWordWrapping = false;
			TextMeshProUGUI val11 = val8.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val11).text = "Label";
			((TMP_Text)val11).fontSize = 24f;
			((Graphic)val11).color = new Color(0.5f, 0.5f, 0.5f);
			((TMP_Text)val11).alignment = (TextAlignmentOptions)513;
			((TMP_Text)val11).enableWordWrapping = false;
			customInputField.textViewport = val7;
			customInputField.textComponent = (TMP_Text)(object)val10;
			customInputField.placeholder = (Graphic)(object)val11;
			customInputField.characterLimit = 30;
			customInputField.contentType = (ContentType)0;
			((MelonBase)this).LoggerInstance.Msg("Custom input field created successfully");
		}
		catch (Exception ex)
		{
			((MelonBase)this).LoggerInstance.Error("Failed to create input field: " + ex.Message);
		}
	}

	private void EnsureConfigDirectoryExists()
	{
		try
		{
			if (!Directory.Exists(configFolderPath))
			{
				Directory.CreateDirectory(configFolderPath);
				if (debug)
				{
					MelonLogger.Msg("Created SimpleLabels config directory");
				}
			}
		}
		catch (Exception ex)
		{
			MelonLogger.Error("Failed to create config directory: " + ex.Message);
		}
	}

	private void LoadConfig()
	{
		try
		{
			if (File.Exists(configFilePath))
			{
				string text = File.ReadAllText(configFilePath);
				config = JsonConvert.DeserializeObject<ModConfig>(text);
				((MelonBase)this).LoggerInstance.Msg("Config loaded successfully");
			}
			else
			{
				config = new ModConfig();
				SaveConfig();
				((MelonBase)this).LoggerInstance.Msg("Created new config file");
			}
		}
		catch (Exception ex)
		{
			config = new ModConfig();
			((MelonBase)this).LoggerInstance.Error("Failed to load config: " + ex.Message);
			((MelonBase)this).LoggerInstance.Warning("Using default config values");
		}
	}

	private void SaveConfig()
	{
		try
		{
			string contents = JsonConvert.SerializeObject((object)config, (Formatting)1);
			File.WriteAllText(configFilePath, contents);
			if (debug)
			{
				MelonLogger.Msg("Config saved successfully");
			}
		}
		catch (Exception ex)
		{
			MelonLogger.Error("Failed to save config: " + ex.Message);
		}
	}

	private void LoadLabelData()
	{
		try
		{
			if (File.Exists(labelDataFilePath))
			{
				string text = File.ReadAllText(labelDataFilePath);
				labelData = JsonConvert.DeserializeObject<LabelData>(text) ?? new LabelData();
				((MelonBase)this).LoggerInstance.Msg($"Loaded label data with {labelData.Labels.Count} entries");
			}
			else
			{
				labelData = new LabelData();
				((MelonBase)this).LoggerInstance.Msg("Created new empty label data file");
			}
		}
		catch (Exception ex)
		{
			labelData = new LabelData();
			((MelonBase)this).LoggerInstance.Error("Failed to load label data: " + ex.Message);
			((MelonBase)this).LoggerInstance.Warning("Using empty label data");
		}
	}

	private void SaveLabelData()
	{
		try
		{
			string contents = JsonConvert.SerializeObject((object)labelData, (Formatting)1);
			File.WriteAllText(labelDataFilePath, contents);
			((MelonBase)this).LoggerInstance.Msg($"Saved {labelData.Labels.Count} label entries");
		}
		catch (Exception ex)
		{
			((MelonBase)this).LoggerInstance.Error("Failed to save label data: " + ex.Message);
		}
	}

	public void InitializeLabelPrefab()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Expected O, but got Unknown
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Instance.labelPrefab = new GameObject("LabelPrefab");
			Instance.labelPrefab.SetActive(false);
			Instance.labelPrefab.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
			GameObject val = new GameObject("LabelObject");
			val.transform.SetParent(Instance.labelPrefab.transform);
			val.transform.localPosition = Vector3.zero;
			val.transform.localScale = Vector3.one;
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val2).name = "PaperBackground";
			val2.transform.SetParent(val.transform);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localScale = new Vector3(2f, 0.6f, 0.1f);
			GameObject val3 = GameObject.Find("small chemical bottle/Lid");
			object obj;
			if (val3 == null)
			{
				obj = null;
			}
			else
			{
				MeshRenderer component = val3.GetComponent<MeshRenderer>();
				obj = ((component != null) ? ((Renderer)component).material : null);
			}
			Material val4 = (Material)obj;
			if ((Object)(object)val4 != (Object)null)
			{
				val2.GetComponent<Renderer>().material = val4;
			}
			else
			{
				((MelonBase)this).LoggerInstance.Error("Couldn't find material to reuse!");
			}
			GameObject val5 = new GameObject("LabelText");
			val5.transform.SetParent(val.transform);
			val5.transform.localPosition = new Vector3(0f, 0f, -0.051f);
			val5.transform.localScale = Vector3.one;
			TextMeshPro val6 = val5.AddComponent<TextMeshPro>();
			((TMP_Text)val6).fontSizeMin = 1.4f;
			((TMP_Text)val6).fontSizeMax = 3f;
			((TMP_Text)val6).fontSize = 2f;
			((TMP_Text)val6).fontStyle = (FontStyles)1;
			((TMP_Text)val6).enableAutoSizing = true;
			((TMP_Text)val6).alignment = (TextAlignmentOptions)514;
			((Graphic)val6).color = Color.black;
			((TMP_Text)val6).enableWordWrapping = true;
			((TMP_Text)val6).margin = new Vector4(0.1f, 0.1f, 0.1f, 0.1f);
			RectTransform component2 = val5.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(1.8f, 0.5f);
			component2.anchorMin = new Vector2(0.5f, 0.5f);
			component2.anchorMax = new Vector2(0.5f, 0.5f);
			component2.pivot = new Vector2(0.5f, 0.5f);
			((MelonBase)this).LoggerInstance.Msg("Label prefab initialized successfully");
		}
		catch (Exception ex)
		{
			((MelonBase)this).LoggerInstance.Msg("Failed to initialize label prefab: " + ex.Message);
		}
	}

	public void AddLabelPrefabToGameObject(GameObject parentGO, string parentOBName, string parentOBGUID)
	{
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		//IL_031c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: 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)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: 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_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)parentGO == (Object)null)
			{
				((MelonBase)this).LoggerInstance.Error("Cannot add label prefab - parent GameObject is null");
				return;
			}
			if (string.IsNullOrEmpty(parentOBGUID))
			{
				((MelonBase)this).LoggerInstance.Warning("Cannot add label prefab - parent GameObject GUID is empty/null");
				return;
			}
			if (string.IsNullOrEmpty(parentOBName))
			{
				((MelonBase)this).LoggerInstance.Warning("Cannot add label prefab - parent GameObject Name is empty/null");
				return;
			}
			if (debug)
			{
				MelonLogger.Msg("Adding labels to " + parentOBName + " (GUID: " + parentOBGUID + ")");
			}
			Quaternion[] array = (Quaternion[])(object)new Quaternion[4];
			Vector3[] array2 = (Vector3[])(object)(parentOBName.Contains("Large") ? new Vector3[4]
			{
				new Vector3(0f, 0.75f, -0.254f),
				new Vector3(1f, 0.75f, 0f),
				new Vector3(0f, 0.75f, 0.254f),
				new Vector3(-1f, 0.75f, 0f)
			} : ((!parentOBName.Contains("Medium")) ? new Vector3[4]
			{
				new Vector3(0f, 0.75f, -0.254f),
				new Vector3(0.5f, 0.75f, 0f),
				new Vector3(0f, 0.75f, 0.254f),
				new Vector3(-0.5f, 0.75f, 0f)
			} : new Vector3[4]
			{
				new Vector3(0f, 0.75f, -0.254f),
				new Vector3(0.75f, 0.75f, 0f),
				new Vector3(0f, 0.75f, 0.254f),
				new Vector3(-0.75f, 0.75f, 0f)
			}));
			array = (Quaternion[])(object)new Quaternion[4]
			{
				Quaternion.Euler(0f, 0f, 0f),
				Quaternion.Euler(0f, -90f, 0f),
				Quaternion.Euler(0f, 180f, 0f),
				Quaternion.Euler(0f, 90f, 0f)
			};
			int num = 0;
			for (int i = 0; i < 4; i++)
			{
				try
				{
					GameObject val = Object.Instantiate<GameObject>(Instance.labelPrefab, parentGO.transform);
					if ((Object)(object)val == (Object)null)
					{
						((MelonBase)this).LoggerInstance.Error($"Failed to instantiate label {i} for {parentOBName}");
						continue;
					}
					val.transform.localPosition = array2[i];
					val.transform.localRotation = array[i];
					((Object)val).name = $"Label_{i}";
					TextMeshPro componentInChildren = val.GetComponentInChildren<TextMeshPro>();
					if ((Object)(object)componentInChildren == (Object)null)
					{
						((MelonBase)this).LoggerInstance.Warning($"Failed to find TextMeshPro component on label {i}");
						continue;
					}
					string value2;
					if (Instance.unsavedLabelData.Labels.TryGetValue(parentOBGUID, out var value))
					{
						((TMP_Text)componentInChildren).text = value;
						val.SetActive(true);
					}
					else if (Instance.labelData.Labels.TryGetValue(parentOBGUID, out value2))
					{
						((TMP_Text)componentInChildren).text = value2;
						val.SetActive(true);
					}
					else
					{
						val.SetActive(false);
					}
					num++;
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Error($"Error creating label {i} for {parentOBName}: {ex.Message}");
				}
			}
			if (debug)
			{
				MelonLogger.Msg($"Successfully created {num}/4 labels for {parentOBName}");
			}
		}
		catch (Exception arg)
		{
			((MelonBase)this).LoggerInstance.Error($"Failed to add label prefab to {parentOBName}: {arg}");
		}
	}

	public void UpdateLabelPrefabInGameObject(string GUID, string labelText, GameObject parentGO, string parentName)
	{
		try
		{
			if (string.IsNullOrEmpty(GUID))
			{
				((MelonBase)this).LoggerInstance.Warning("UpdateLabelPrefabInGameObject called with empty GUID");
				return;
			}
			if ((Object)(object)parentGO == (Object)null)
			{
				((MelonBase)this).LoggerInstance.Error("Cannot update labels - parent GameObject is null (GUID: " + GUID + ")");
				return;
			}
			if (string.IsNullOrEmpty(parentName))
			{
				((MelonBase)this).LoggerInstance.Warning("UpdateLabelPrefabInGameObject called with empty parentName");
				return;
			}
			if (debug)
			{
				MelonLogger.Msg("Updating labels for " + parentName + " (GUID: " + GUID + ")");
			}
			if (!StorageTracker.StorageEntities.ContainsKey(GUID))
			{
				((MelonBase)this).LoggerInstance.Warning("Storage entity " + parentName + " not tracked (GUID: " + GUID + ")");
				return;
			}
			bool flag = ((IEnumerable<Transform>)parentGO.GetComponentsInChildren<Transform>(true)).Any((Transform child) => ((Object)((Component)child).gameObject).name == "LabelText");
			if (debug)
			{
				MelonLogger.Msg($"Label prefabs exist: {flag}");
			}
			if (!flag)
			{
				AddLabelPrefabToGameObject(parentGO, parentName, GUID);
				return;
			}
			IEnumerable<Transform> enumerable = ((IEnumerable<Transform>)parentGO.GetComponentsInChildren<Transform>(true)).Where((Transform child) => ((Object)((Component)child).gameObject).name.StartsWith("Label_"));
			foreach (Transform item in enumerable)
			{
				try
				{
					if (string.IsNullOrEmpty(labelText))
					{
						((Component)item).gameObject.SetActive(false);
						if (debug)
						{
							((MelonBase)this).LoggerInstance.Msg("Disabled label " + ((Object)((Component)item).gameObject).name + " (empty text)");
						}
						continue;
					}
					((Component)item).gameObject.SetActive(true);
					TextMeshPro componentInChildren = ((Component)item).GetComponentInChildren<TextMeshPro>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						((TMP_Text)componentInChildren).text = labelText;
						if (debug)
						{
							((MelonBase)this).LoggerInstance.Msg("Updated label " + ((Object)((Component)item).gameObject).name + " with text: " + labelText);
						}
					}
					else
					{
						((MelonBase)this).LoggerInstance.Warning("TextMeshPro component missing on " + ((Object)((Component)item).gameObject).name);
					}
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Error("Failed to update label " + ((Object)((Component)item).gameObject).name + ": " + ex.Message);
				}
			}
		}
		catch (Exception arg)
		{
			((MelonBase)this).LoggerInstance.Error($"Failed to update label prefabs for {parentName} (GUID: {GUID}): {arg}");
		}
	}
}